sneakoscope 6.0.2 → 6.1.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 (242) hide show
  1. package/README.md +5 -3
  2. package/config/codex-releases/{rust-v0.142.0.json → rust-v0.144.1.json} +6 -6
  3. package/crates/sks-core/Cargo.lock +1 -1
  4. package/crates/sks-core/Cargo.toml +1 -1
  5. package/dist/cli/install-helpers.js +255 -440
  6. package/dist/cli/router.js +53 -4
  7. package/dist/commands/codex-app.js +8 -3
  8. package/dist/commands/codex-lb.js +169 -40
  9. package/dist/commands/codex.js +6 -5
  10. package/dist/commands/doctor.js +60 -26
  11. package/dist/commands/versioning.js +7 -0
  12. package/dist/config/skills-manifest.json +57 -57
  13. package/dist/core/agents/agent-central-ledger.js +9 -0
  14. package/dist/core/agents/agent-cleanup-executor.js +334 -41
  15. package/dist/core/agents/agent-cleanup.js +20 -1
  16. package/dist/core/agents/agent-command-surface.js +2 -1
  17. package/dist/core/agents/agent-effort-policy.js +46 -33
  18. package/dist/core/agents/agent-janitor.js +9 -10
  19. package/dist/core/agents/agent-namespace-safety.js +56 -0
  20. package/dist/core/agents/agent-orchestrator.js +26 -4
  21. package/dist/core/agents/agent-output-validator.js +1 -1
  22. package/dist/core/agents/agent-proof-evidence.js +16 -2
  23. package/dist/core/agents/agent-role-config.js +3 -6
  24. package/dist/core/agents/agent-roster.js +2 -2
  25. package/dist/core/agents/agent-runner-codex-exec.js +2 -0
  26. package/dist/core/agents/agent-runner-process.js +1 -0
  27. package/dist/core/agents/fast-mode-policy.js +3 -5
  28. package/dist/core/agents/native-cli-session-swarm.js +18 -1
  29. package/dist/core/agents/native-worker-backend-router.js +180 -108
  30. package/dist/core/agents/parallel-write-fixture.js +15 -10
  31. package/dist/core/agents/runtime-proof-summary.js +21 -3
  32. package/dist/core/agents/work-partition/repo-inventory.js +68 -7
  33. package/dist/core/code-structure.js +5 -4
  34. package/dist/core/codex/codex-config-guard.js +31 -9
  35. package/dist/core/codex-app/codex-app-fast-ui-repair.js +51 -20
  36. package/dist/core/codex-app/codex-app-restart.js +38 -8
  37. package/dist/core/codex-app/codex-app-ui-state-snapshot.js +11 -3
  38. package/dist/core/codex-app/sks-menubar.js +100 -40
  39. package/dist/core/codex-app.js +60 -17
  40. package/dist/core/codex-compat/codex-hook-warning-detector.js +10 -1
  41. package/dist/core/codex-compat/codex-release-manifest.js +6 -6
  42. package/dist/core/codex-control/codex-0139-doctor-real-probe.js +7 -1
  43. package/dist/core/codex-control/codex-0139-image-path-real-probe.js +14 -8
  44. package/dist/core/codex-control/codex-0139-probe-runner.js +103 -28
  45. package/dist/core/codex-control/codex-0139-real-probe-summary.js +7 -3
  46. package/dist/core/codex-control/codex-0139-real-probes.js +21 -6
  47. package/dist/core/codex-control/codex-0139-sandbox-real-probe.js +39 -13
  48. package/dist/core/codex-control/codex-0139-web-search-probe.js +11 -8
  49. package/dist/core/codex-control/{codex-0142-capability.js → codex-0144-capability.js} +22 -22
  50. package/dist/core/codex-control/codex-0144-collab-agent-real-probe.js +63 -0
  51. package/dist/core/codex-control/codex-model-metadata.js +8 -4
  52. package/dist/core/codex-control/codex-multi-agent-event-normalizer.js +5 -1
  53. package/dist/core/codex-control/codex-reliability-shield.js +4 -1
  54. package/dist/core/codex-control/codex-sdk-adapter.js +53 -6
  55. package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
  56. package/dist/core/codex-control/codex-sdk-sandbox-policy.js +6 -3
  57. package/dist/core/codex-lb/codex-lb-env.js +107 -0
  58. package/dist/core/codex-lb/codex-lb-tool-catalog.js +478 -0
  59. package/dist/core/codex-native/codex-native-feature-broker.js +22 -22
  60. package/dist/core/codex-native/codex-native-feature-matrix.js +2 -2
  61. package/dist/core/codex-native/native-capability-postcheck.js +16 -8
  62. package/dist/core/codex-native/native-capability-repair-matrix.js +76 -27
  63. package/dist/core/codex-plugins/codex-plugin-json.js +67 -21
  64. package/dist/core/codex-plugins/codex-plugin-repair.js +118 -0
  65. package/dist/core/codex-runtime/codex-desktop-config-policy.js +306 -0
  66. package/dist/core/commands/agent-command.js +19 -0
  67. package/dist/core/commands/basic-cli.js +45 -24
  68. package/dist/core/commands/gc-command.js +27 -4
  69. package/dist/core/commands/image-ux-review-command.js +55 -24
  70. package/dist/core/commands/mad-sks-command.js +152 -132
  71. package/dist/core/commands/naruto-command.js +41 -10
  72. package/dist/core/commands/pipeline-command.js +1 -0
  73. package/dist/core/commands/wiki-command.js +179 -83
  74. package/dist/core/computer-use-live-evidence.js +166 -3
  75. package/dist/core/computer-use-status.js +5 -2
  76. package/dist/core/daemon/sksd-hook-daemon-entrypoint.js +2 -2
  77. package/dist/core/daemon/sksd-hook-daemon.js +171 -28
  78. package/dist/core/daemon/sksd-hook-dispatch.js +2 -2
  79. package/dist/core/dfix/verification-selector.js +6 -4
  80. package/dist/core/doctor/browser-use-repair.js +54 -13
  81. package/dist/core/doctor/codex-0139-doctor.js +3 -2
  82. package/dist/core/doctor/computer-use-repair.js +28 -39
  83. package/dist/core/doctor/doctor-codex-startup-repair.js +19 -9
  84. package/dist/core/doctor/doctor-context7-repair.js +1 -1
  85. package/dist/core/doctor/doctor-dirty-planner.js +1 -1
  86. package/dist/core/doctor/doctor-native-capability-repair.js +74 -3
  87. package/dist/core/doctor/imagegen-repair.js +47 -12
  88. package/dist/core/doctor/legacy-global-hook-cleanup.js +179 -0
  89. package/dist/core/feature-registry.js +25 -31
  90. package/dist/core/fsx.js +54 -6
  91. package/dist/core/harness-conflicts.js +1 -1
  92. package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +5 -4
  93. package/dist/core/hooks-runtime/hook-invocation-dedupe.js +147 -0
  94. package/dist/core/hooks-runtime/hook-io.js +6 -0
  95. package/dist/core/hooks-runtime.js +17 -2
  96. package/dist/core/image/image-artifact-path-contract.js +8 -6
  97. package/dist/core/image/image-artifact-registry.js +5 -1
  98. package/dist/core/image-ux-review/imagegen-adapter.js +5 -2
  99. package/dist/core/imagegen/imagegen-capability.js +10 -13
  100. package/dist/core/imagegen/require-imagegen.js +37 -11
  101. package/dist/core/managed-assets/managed-assets-manifest.js +1 -5
  102. package/dist/core/naruto/naruto-work-graph.js +70 -4
  103. package/dist/core/naruto/naruto-write-e2e.js +3 -4
  104. package/dist/core/ops/reporting.js +3 -0
  105. package/dist/core/pipeline-internals/runtime-core.js +12 -7
  106. package/dist/core/pipeline-internals/runtime-gates.js +17 -1
  107. package/dist/core/ppt/style-tokens.js +1 -1
  108. package/dist/core/ppt-review/index.js +1 -1
  109. package/dist/core/ppt-review/slide-exporter.js +23 -17
  110. package/dist/core/ppt-review/slide-imagegen-review.js +1 -1
  111. package/dist/core/ppt-review/slide-issue-extraction.js +4 -2
  112. package/dist/core/product-design-plugin.js +2 -2
  113. package/dist/core/proof/route-finalizer.js +1 -1
  114. package/dist/core/proof-field.js +3 -3
  115. package/dist/core/provider/model-router.js +68 -3
  116. package/dist/core/release/gate-manifest.js +18 -12
  117. package/dist/core/release/gate-pack-manifest.js +1 -1
  118. package/dist/core/release/package-size-budget.js +2 -0
  119. package/dist/core/release/release-gate-affected-selector.js +1 -1
  120. package/dist/core/release/release-gate-dag.js +43 -3
  121. package/dist/core/release/release-gate-hermetic-env.js +28 -17
  122. package/dist/core/release/release-real-contract.js +416 -0
  123. package/dist/core/retention/retention-budget.js +25 -6
  124. package/dist/core/retention.js +980 -101
  125. package/dist/core/routes/constants.js +1 -1
  126. package/dist/core/routes/evidence.js +4 -4
  127. package/dist/core/routes/model-mode-router.js +3 -0
  128. package/dist/core/routes/ppt-policy.js +1 -1
  129. package/dist/core/routes.js +11 -12
  130. package/dist/core/secret-redaction.js +4 -0
  131. package/dist/core/triwiki/code-pack.js +8 -2
  132. package/dist/core/triwiki/triwiki-cache-key.js +108 -29
  133. package/dist/core/triwiki-attention.js +13 -6
  134. package/dist/core/triwiki-provenance.js +274 -0
  135. package/dist/core/triwiki-runtime.js +21 -7
  136. package/dist/core/triwiki-wrongness/wrongness-ledger.js +178 -59
  137. package/dist/core/triwiki-wrongness/wrongness-retrieval.js +11 -2
  138. package/dist/core/triwiki-wrongness/wrongness-trust-policy.js +2 -0
  139. package/dist/core/update/update-migration-state.js +1 -1
  140. package/dist/core/update/update-notice.js +23 -0
  141. package/dist/core/update-check.js +69 -25
  142. package/dist/core/version.js +1 -1
  143. package/dist/core/wiki-coordinate.js +128 -12
  144. package/dist/core/work-order-ledger.js +168 -9
  145. package/dist/core/zellij/zellij-command.js +12 -1
  146. package/dist/core/zellij/zellij-dashboard-pane.js +3 -3
  147. package/dist/core/zellij/zellij-launcher.js +15 -14
  148. package/dist/core/zellij/zellij-pane-proof.js +32 -6
  149. package/dist/core/zellij/zellij-worker-pane-manager.js +5 -3
  150. package/dist/scripts/agent-fast-mode-default-check.js +48 -29
  151. package/dist/scripts/agent-role-config-repair-check.js +25 -4
  152. package/dist/scripts/agent-wiki-context-proof-check.js +16 -2
  153. package/dist/scripts/all-feature-deep-completion-check.js +14 -4
  154. package/dist/scripts/build-dist.js +17 -5
  155. package/dist/scripts/canonical-test-runner.js +188 -0
  156. package/dist/scripts/check-command-module-budget.js +38 -16
  157. package/dist/scripts/check-legacy-free.js +1 -1
  158. package/dist/scripts/codex-0139-interrupt-agent-check.js +5 -1
  159. package/dist/scripts/{codex-0142-app-server-v2-check.js → codex-0144-app-server-v2-check.js} +11 -10
  160. package/dist/scripts/{codex-0142-binary-identity-check.js → codex-0144-binary-identity-check.js} +4 -4
  161. package/dist/scripts/codex-0144-capability-check.js +21 -0
  162. package/dist/scripts/{codex-0139-real-probes-check.js → codex-0144-core-real-probes-check.js} +19 -5
  163. package/dist/scripts/{codex-0142-doctor-wiring-check.js → codex-0144-doctor-wiring-check.js} +6 -6
  164. package/dist/scripts/{codex-0142-manifest-check.js → codex-0144-manifest-check.js} +11 -3
  165. package/dist/scripts/{codex-0142-policy-check.js → codex-0144-policy-check.js} +2 -2
  166. package/dist/scripts/{codex-0142-thread-store-check.js → codex-0144-thread-store-check.js} +3 -3
  167. package/dist/scripts/codex-app-provider-model-ui-check.js +57 -8
  168. package/dist/scripts/codex-app-ui-preservation-check.js +35 -4
  169. package/dist/scripts/codex-control-side-effect-scope-check.js +2 -2
  170. package/dist/scripts/codex-effort-auto-discovery-check.js +1 -1
  171. package/dist/scripts/codex-lb-fast-mode-truth-check.js +1 -0
  172. package/dist/scripts/{codex-lb-gpt55-fast-profile-check.js → codex-lb-gpt56-fast-profile-check.js} +56 -5
  173. package/dist/scripts/codex-model-metadata-check.js +1 -1
  174. package/dist/scripts/codex-sdk-sandbox-policy-check.js +5 -1
  175. package/dist/scripts/codex-sdk-version-compat-check.js +2 -1
  176. package/dist/scripts/dfix-fixture-check.js +1 -1
  177. package/dist/scripts/docs-truthfulness-check.js +1 -1
  178. package/dist/scripts/doctor-codex-startup-repair-check.js +35 -10
  179. package/dist/scripts/doctor-context7-repair-check.js +2 -1
  180. package/dist/scripts/doctor-fix-proves-codex-read-check.js +1 -1
  181. package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +34 -7
  182. package/dist/scripts/doctor-imagegen-repair-check.js +14 -4
  183. package/dist/scripts/doctor-startup-config-repair-blackbox.js +1 -1
  184. package/dist/scripts/doctor-startup-config-repair-check.js +1 -1
  185. package/dist/scripts/gate-policy-audit-check.js +2 -2
  186. package/dist/scripts/install-update-preserves-config-check.js +1 -1
  187. package/dist/scripts/legacy-gate-inventory-check.js +7 -5
  188. package/dist/scripts/legacy-strong-inventory-check.js +7 -5
  189. package/dist/scripts/legacy-upgrade-matrix-check.js +5 -5
  190. package/dist/scripts/lib/native-cli-session-swarm-check-lib.js +175 -14
  191. package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +166 -6
  192. package/dist/scripts/mutation-callsite-coverage-check.js +0 -11
  193. package/dist/scripts/naruto-shadow-clone-swarm-check.js +88 -50
  194. package/dist/scripts/npm-publish-performance-check.js +2 -1
  195. package/dist/scripts/package-published-contract-check.js +9 -0
  196. package/dist/scripts/packlist-performance-check.js +5 -2
  197. package/dist/scripts/postinstall-safe-side-effects-check.js +8 -3
  198. package/dist/scripts/ppt-no-mock-as-real-check.js +3 -1
  199. package/dist/scripts/product-design-plugin-routing-check.js +1 -1
  200. package/dist/scripts/release-check-stamp.js +182 -2
  201. package/dist/scripts/release-dag-full-coverage-check.js +7 -7
  202. package/dist/scripts/release-dynamic-presets-check.js +8 -0
  203. package/dist/scripts/release-gate-dag-runner-check.js +3 -2
  204. package/dist/scripts/release-gate-dag-runner.js +24 -11
  205. package/dist/scripts/release-gate-existence-audit.js +8 -9
  206. package/dist/scripts/release-gate-script-parity-check.js +1 -1
  207. package/dist/scripts/release-real-check.js +368 -157
  208. package/dist/scripts/release-runtime-truth-matrix-check.js +22 -0
  209. package/dist/scripts/route-proof-artifact-structure-check.js +1 -0
  210. package/dist/scripts/scheduler-batch-dispatch-check.js +1 -1
  211. package/dist/scripts/search-visibility-gate-lib.js +1 -1
  212. package/dist/scripts/seo-geo-route-identity-check.js +30 -4
  213. package/dist/scripts/sizecheck.js +7 -2
  214. package/dist/scripts/sks-1-11-gate-lib.js +53 -6
  215. package/dist/scripts/sks-menubar-install-check.js +7 -0
  216. package/dist/scripts/sks-uninstall-regression-check.js +1 -1
  217. package/dist/scripts/sksd-daemon-check.js +16 -6
  218. package/dist/scripts/update-default-command-check.js +4 -2
  219. package/dist/scripts/write-build-manifest.js +2 -1
  220. package/dist/scripts/zellij-layout-valid-check.js +31 -6
  221. package/dist/scripts/zellij-pane-proof-check.js +33 -2
  222. package/dist/scripts/zellij-real-session-cleanup-check.js +122 -2
  223. package/dist/scripts/zellij-real-session-launch-check.js +76 -5
  224. package/dist/scripts/zellij-slot-pane-renderer-check.js +4 -4
  225. package/package.json +27 -30
  226. package/schemas/codex/{app-server-0.142 → app-server-0.144}/codex_app_server_protocol.v2.schemas.json +1146 -781
  227. package/schemas/codex/codex-0139-real-probe-result.schema.json +39 -5
  228. package/schemas/codex/ppt-slide-issue-ledger.schema.json +2 -1
  229. package/dist/core/codex-control/codex-0139-multi-agent-real-probe.js +0 -107
  230. package/dist/scripts/agent-native-release-gate.js +0 -274
  231. package/dist/scripts/codex-0142-capability-check.js +0 -21
  232. package/dist/scripts/command-performance-scorecard-check.js +0 -204
  233. package/dist/scripts/config-managed-merge-callsite-coverage-check.js +0 -212
  234. package/dist/scripts/dollar-performance-scorecard-check.js +0 -257
  235. package/dist/scripts/gate-timing-check.js +0 -16
  236. package/dist/scripts/ops-maturity-scorecard-check.js +0 -12
  237. package/dist/scripts/performance-baseline-check.js +0 -12
  238. package/dist/scripts/performance-improvement-report-check.js +0 -58
  239. package/dist/scripts/release-parallel-check.js +0 -389
  240. package/dist/scripts/release-runner-efficiency-check.js +0 -15
  241. package/dist/scripts/retention-long-run-smoke-check.js +0 -299
  242. package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
@@ -9,7 +9,8 @@ import { PRODUCT_DESIGN_AUTO_INSTALL_ENV, ensureProductDesignPluginInstalled, pr
9
9
  import { GLM_CODEX_CONFIG_PROVIDER_ID, GLM_CODEX_CONFIG_REASONING_PROFILES } from './codex-app/glm-model-profile.js';
10
10
  import { GLM_52_OPENROUTER_MODEL } from './providers/glm/glm-52-settings.js';
11
11
  import { resolveOpenRouterApiKey } from './providers/openrouter/openrouter-secret-store.js';
12
- import { codexLbEnvPath, parseShellEnvValue } from './codex-lb/codex-lb-env.js';
12
+ import { codexLbEnvPath, loadCodexLbEnv, parseShellEnvValue, readCodexLbModelCatalog } from './codex-lb/codex-lb-env.js';
13
+ import { redactString } from './secret-redaction.js';
13
14
  export const CODEX_APP_DOCS_URL = 'https://developers.openai.com/codex/app/features';
14
15
  export const CODEX_CHANGELOG_URL = 'https://developers.openai.com/codex/changelog';
15
16
  export const CODEX_ACCESS_TOKENS_DOCS_URL = 'https://developers.openai.com/codex/enterprise/access-tokens';
@@ -35,6 +36,8 @@ export function codexAppCandidatePaths(home = os.homedir(), env = process.env) {
35
36
  if (env.SKS_CODEX_APP_PATH)
36
37
  candidates.push(env.SKS_CODEX_APP_PATH);
37
38
  if (process.platform === 'darwin') {
39
+ candidates.push('/Applications/ChatGPT.app');
40
+ candidates.push(path.join(home || '', 'Applications', 'ChatGPT.app'));
38
41
  candidates.push('/Applications/Codex.app');
39
42
  candidates.push(path.join(home || '', 'Applications', 'Codex.app'));
40
43
  }
@@ -96,30 +99,32 @@ export async function codexMcpList(opts = {}) {
96
99
  const codex = opts.codex || await getCodexInfo().catch(() => EMPTY_CODEX_INFO);
97
100
  if (!codex.bin)
98
101
  return { ok: false, checked: false, stdout: '', stderr: 'Codex CLI missing.' };
99
- const out = await runProcess(codex.bin, ['mcp', 'list'], {
102
+ const execute = opts.runProcess || runProcess;
103
+ const out = await execute(codex.bin, ['mcp', 'list'], {
100
104
  timeoutMs: opts.timeoutMs || 10000,
101
105
  maxOutputBytes: 64 * 1024
102
106
  }).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
103
107
  return {
104
108
  ok: out.code === 0,
105
109
  checked: true,
106
- stdout: out.stdout || '',
107
- stderr: out.stderr || ''
110
+ stdout: redactString(out.stdout || ''),
111
+ stderr: redactString(out.stderr || '')
108
112
  };
109
113
  }
110
114
  export async function codexFeatureList(opts = {}) {
111
115
  const codex = opts.codex || await getCodexInfo().catch(() => EMPTY_CODEX_INFO);
112
116
  if (!codex.bin)
113
117
  return { ok: false, checked: false, stdout: '', stderr: 'Codex CLI missing.' };
114
- const out = await runProcess(codex.bin, ['features', 'list'], {
118
+ const execute = opts.runProcess || runProcess;
119
+ const out = await execute(codex.bin, ['features', 'list'], {
115
120
  timeoutMs: opts.timeoutMs || 10000,
116
121
  maxOutputBytes: 64 * 1024
117
122
  }).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
118
123
  return {
119
124
  ok: out.code === 0,
120
125
  checked: true,
121
- stdout: out.stdout || '',
122
- stderr: out.stderr || ''
126
+ stdout: redactString(out.stdout || ''),
127
+ stderr: redactString(out.stderr || '')
123
128
  };
124
129
  }
125
130
  export async function codexAppIntegrationStatus(opts = {}) {
@@ -161,7 +166,8 @@ export async function codexAppIntegrationStatus(opts = {}) {
161
166
  });
162
167
  const pluginPickerReady = requiredFeatureFlags.tool_suggest && requiredFeatureFlags.plugins && requiredFeatureFlags.apps && defaultPlugins.ok && pluginSkillShadows.ok && fastModeConfig.ok;
163
168
  const gitActions = codexGitActionReadiness({ requiredFeatureFlags, remoteControl });
164
- const ready = appInstalled && Boolean(codex.bin) && mcpList.ok && featureList.ok && requiredFeatureFlagsOk && pluginPickerReady && fastModeConfig.ok && imageGenerationReady && gitActions.ok && computerUseReady && browserToolReady && chromeExtension.ok;
169
+ const selectedProviderReady = providerModelUi.selected_provider_ok !== false;
170
+ const ready = appInstalled && Boolean(codex.bin) && mcpList.ok && featureList.ok && requiredFeatureFlagsOk && pluginPickerReady && fastModeConfig.ok && selectedProviderReady && imageGenerationReady && gitActions.ok && computerUseReady && browserToolReady && chromeExtension.ok;
165
171
  return {
166
172
  ok: ready,
167
173
  app: {
@@ -194,6 +200,7 @@ export async function codexAppIntegrationStatus(opts = {}) {
194
200
  required_flags_ok: requiredFeatureFlagsOk,
195
201
  fast_mode_config: fastModeConfig,
196
202
  provider_model_ui: providerModelUi,
203
+ selected_provider_ready: selectedProviderReady,
197
204
  git_actions: gitActions,
198
205
  image_generation: imageGenerationReady,
199
206
  image_generation_source: imageGenerationReady ? 'codex_features_list' : 'missing',
@@ -545,7 +552,8 @@ export function codexAppGuidance({ appInstalled, codex, mcpList, featureList, re
545
552
  lines.push(`Run: ${providerModelUi.glm.key_command}; then ${providerModelUi.glm.install_command}; restart Codex App if the model picker was already open.`);
546
553
  }
547
554
  if (providerModelUi?.codex_lb?.key_entry_visible && providerModelUi.codex_lb.key_present && providerModelUi.codex_lb.provider_present && providerModelUi.codex_lb.provider_contract_ok && providerModelUi.codex_lb.base_url_present) {
548
- lines.push(`codex-lb key entry path is visible and configured; update command ${providerModelUi.codex_lb.set_key_command}.`);
555
+ lines.push(`codex-lb key entry path is configured; provider catalog ${providerModelUi.codex_lb.expected_models_present ? 'contains GPT-5.6 Sol/Terra/Luna' : 'is not verified'}. Update command: ${providerModelUi.codex_lb.set_key_command}.`);
556
+ lines.push('Provider/config readiness does not by itself prove the already-running Desktop picker; auth/profile actions restart ChatGPT/Codex so it reloads model/list.');
549
557
  }
550
558
  else if (providerModelUi?.codex_lb?.key_entry_visible) {
551
559
  lines.push(`codex-lb key entry path is visible, but setup is incomplete: ${providerModelUi.codex_lb.blockers.join(', ') || 'setup required'}.`);
@@ -938,6 +946,14 @@ export async function codexProviderModelUiStatus(opts = {}) {
938
946
  && hasTomlBoolean(codexLbProvider, 'supports_websockets', true)
939
947
  && hasTomlBoolean(codexLbProvider, 'requires_openai_auth', true);
940
948
  const codexLbSelectedDefault = /(?:^|\n)\s*model_provider\s*=\s*"codex-lb"\s*(?:#.*)?(?=\n|$)/.test(topLevelToml(globalConfig));
949
+ let codexLbModelCatalog = opts.codexLbModelCatalog || null;
950
+ if (!codexLbModelCatalog && codexLbProviderContractOk && codexLbApiKeySource !== 'missing' && codexLbBaseUrlSource !== 'missing') {
951
+ const loadedEnv = await loadCodexLbEnv({ home, envPath: codexLbEnvFilePath }).catch(() => null);
952
+ codexLbModelCatalog = loadedEnv ? await readCodexLbModelCatalog({ loadedEnv }).catch(() => null) : null;
953
+ }
954
+ const expectedCodexLbModels = ['gpt-5.6-luna', 'gpt-5.6-terra', 'gpt-5.6-sol'];
955
+ const catalogModels = Array.isArray(codexLbModelCatalog?.models) ? codexLbModelCatalog.models.map(String) : [];
956
+ const expectedCodexLbModelsPresent = expectedCodexLbModels.every((model) => catalogModels.includes(model));
941
957
  const glmBlockers = [
942
958
  ...(glmProviderPresent ? [] : ['glm_openrouter_provider_missing']),
943
959
  ...glmProfileBlockers,
@@ -947,18 +963,34 @@ export async function codexProviderModelUiStatus(opts = {}) {
947
963
  ...(codexLbProviderPresent ? [] : ['codex_lb_provider_missing']),
948
964
  ...(codexLbProviderPresent && !codexLbProviderContractOk ? ['codex_lb_provider_contract_drift'] : []),
949
965
  ...(codexLbApiKeySource !== 'missing' ? [] : ['codex_lb_api_key_missing']),
950
- ...(codexLbBaseUrlSource !== 'missing' ? [] : ['codex_lb_base_url_missing'])
966
+ ...(codexLbBaseUrlSource !== 'missing' ? [] : ['codex_lb_base_url_missing']),
967
+ ...(codexLbProviderContractOk && codexLbApiKeySource !== 'missing' && codexLbBaseUrlSource !== 'missing' && !expectedCodexLbModelsPresent
968
+ ? ['codex_lb_gpt_5_6_catalog_unverified']
969
+ : [])
951
970
  ];
952
- const blockers = [...glmBlockers, ...codexLbBlockers];
971
+ const selectedProviderBlockers = codexLbSelectedDefault ? codexLbBlockers : [];
972
+ const optionalProviderBlockers = codexLbSelectedDefault
973
+ ? glmBlockers
974
+ : [...glmBlockers, ...codexLbBlockers];
953
975
  const keyCommand = 'sks codex-app set-openrouter-key --api-key-stdin';
954
976
  const installCommand = 'sks codex-app glm-profile install';
955
977
  const setupCommand = 'sks codex-lb setup --host <domain> --api-key-stdin --yes';
956
978
  const setKeyCommand = 'sks codex-lb set-key --api-key-stdin';
957
979
  return {
958
980
  schema: 'sks.codex-app-provider-model-ui.v1',
959
- ok: blockers.length === 0,
981
+ // The top-level readiness contract is intentionally scoped to the active
982
+ // provider. Optional GLM/OpenRouter and codex-lb setup diagnostics remain
983
+ // visible below without making an unrelated provider selection fail.
984
+ ok: selectedProviderBlockers.length === 0,
985
+ selected_provider_ok: selectedProviderBlockers.length === 0,
986
+ selected_provider: codexLbSelectedDefault ? 'codex-lb' : 'oauth',
987
+ selected_provider_blockers: selectedProviderBlockers,
988
+ optional_provider_blockers: optionalProviderBlockers,
960
989
  checked: true,
961
- status: blockers.length === 0 ? 'ready' : 'setup_required',
990
+ verification_scope: 'config_and_provider_catalog',
991
+ desktop_picker_verified: false,
992
+ status: selectedProviderBlockers.length === 0 ? 'ready' : 'setup_required',
993
+ optional_provider_status: optionalProviderBlockers.length === 0 ? 'ready' : 'setup_available',
962
994
  config_paths: {
963
995
  codex_config: globalConfigPath,
964
996
  project_config: projectConfig ? projectConfigPath : null,
@@ -988,6 +1020,12 @@ export async function codexProviderModelUiStatus(opts = {}) {
988
1020
  api_key_source: codexLbApiKeySource,
989
1021
  base_url_present: codexLbBaseUrlSource !== 'missing',
990
1022
  base_url_source: codexLbBaseUrlSource,
1023
+ model_catalog_checked: Boolean(codexLbModelCatalog),
1024
+ model_catalog_ok: codexLbModelCatalog?.ok === true,
1025
+ model_catalog_models: catalogModels,
1026
+ expected_models: expectedCodexLbModels,
1027
+ expected_models_present: expectedCodexLbModelsPresent,
1028
+ model_catalog_blockers: codexLbModelCatalog?.blockers || [],
991
1029
  setup_command: setupCommand,
992
1030
  set_key_command: setKeyCommand,
993
1031
  status_command: 'sks codex-lb status',
@@ -1000,7 +1038,7 @@ export async function codexProviderModelUiStatus(opts = {}) {
1000
1038
  setKeyCommand,
1001
1039
  'sks codex-app status'
1002
1040
  ],
1003
- blockers
1041
+ blockers: selectedProviderBlockers
1004
1042
  };
1005
1043
  }
1006
1044
  async function readTextIfExists(file) {
@@ -1065,9 +1103,14 @@ function productDesignStatusSummary(status = {}) {
1065
1103
  function providerModelUiSummary(status = {}) {
1066
1104
  if (!status?.checked)
1067
1105
  return ' not checked';
1068
- if (status.ok)
1069
- return ' ok (GLM + codex-lb)';
1070
- return ` setup ${(status.blockers || []).join(', ') || 'required'}`;
1106
+ const selected = status.selected_provider || 'oauth';
1107
+ if (status.ok) {
1108
+ const optionalSetup = (status.optional_provider_blockers || []).length > 0
1109
+ ? ', optional providers can be configured'
1110
+ : '';
1111
+ return ` ${selected} ready${optionalSetup} (live picker reload required)`;
1112
+ }
1113
+ return ` ${selected} setup ${(status.selected_provider_blockers || status.blockers || []).join(', ') || 'required'}`;
1071
1114
  }
1072
1115
  function sksNativeMenuSummary(status = {}) {
1073
1116
  if (!status)
@@ -15,7 +15,8 @@ export async function detectCodexHookOutputWarnings(eventLike, output) {
15
15
  const issues = [
16
16
  ...validation.structured_issues,
17
17
  ...semantic.issues,
18
- ...snakeCaseKeyIssues(output)
18
+ ...snakeCaseKeyIssues(output),
19
+ ...unknownTopLevelKeyIssues(output)
19
20
  ];
20
21
  for (const key of LEGACY_TOP_LEVEL_KEYS) {
21
22
  if (output && typeof output === 'object' && Object.prototype.hasOwnProperty.call(output, key)) {
@@ -52,6 +53,14 @@ export async function detectCodexHookOutputWarnings(eventLike, output) {
52
53
  warnings: [...new Set(warnings)]
53
54
  };
54
55
  }
56
+ function unknownTopLevelKeyIssues(output) {
57
+ if (!output || typeof output !== 'object' || Array.isArray(output))
58
+ return [];
59
+ const allowed = new Set(['continue', 'decision', 'reason', 'hookSpecificOutput']);
60
+ return Object.keys(output)
61
+ .filter((key) => !allowed.has(key))
62
+ .map((key) => makeCodexHookIssue('policy_disallowed', `unknown_field_${key}`, `Unknown top-level hook field is not accepted by the SKS zero-warning contract: ${key}.`, { path: `$.${key}`, upstream_supported: false, sks_disallowed: true }));
63
+ }
55
64
  export async function codexHookWarningCheck(root, opts = {}) {
56
65
  root ||= await projectRoot();
57
66
  const fixtureValidation = await validateCodexFixtureOutputs(root);
@@ -3,13 +3,13 @@ import { packageRoot, readJson, readText, sha256 } from '../fsx.js';
3
3
  export const CODEX_RELEASE_MANIFEST_SCHEMA = 'sks.codex-release-manifest.v1';
4
4
  export const CURRENT_CODEX_RELEASE_MANIFEST = {
5
5
  schema: CODEX_RELEASE_MANIFEST_SCHEMA,
6
- targetTag: 'rust-v0.142.0',
7
- requiredCliVersion: '0.142.0',
8
- sdkVersion: '0.142.0',
9
- minimumSupportedVersion: '0.142.0',
6
+ targetTag: 'rust-v0.144.1',
7
+ requiredCliVersion: '0.144.1',
8
+ sdkVersion: '0.144.1',
9
+ minimumSupportedVersion: '0.144.1',
10
10
  protocolMode: 'app-server-v2',
11
- generatedSchemaSha256: 'fc3c48943de51865e81c8320876fd5310e9d96bd066fc63b74616d26c0e6dd12',
12
- upstreamCommit: 'rust-v0.142.0',
11
+ generatedSchemaSha256: '2b3f14fa2e728f77a16385ff39f3a1d85ab255c1020498a85c1c0fb24f3d2f3c',
12
+ upstreamCommit: 'rust-v0.144.1',
13
13
  featurePolicies: {
14
14
  multiAgentMode: 'probe',
15
15
  indexedWebSearch: 'probe',
@@ -10,8 +10,13 @@ export async function runCodex0139DoctorEnvRealProbe(input) {
10
10
  return skippedCodex0139Probe('codex_cli_missing');
11
11
  const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-0139-real-probes', `doctor-${Date.now()}`);
12
12
  await ensureDir(tempDir);
13
+ const isolatedHome = path.join(tempDir, 'home');
14
+ const isolatedCodexHome = path.join(isolatedHome, '.codex');
15
+ await ensureDir(isolatedCodexHome);
13
16
  const env = {
14
17
  ...process.env,
18
+ HOME: isolatedHome,
19
+ CODEX_HOME: isolatedCodexHome,
15
20
  EDITOR: 'vim',
16
21
  PAGER: 'less',
17
22
  TERM: 'xterm-256color',
@@ -48,7 +53,8 @@ export async function runCodex0139DoctorEnvRealProbe(input) {
48
53
  redacted_marker_or_omitted: redactedMarkerOrOmitted,
49
54
  redacted_sample_contains_secret: redactedText.includes('sk-test-secret-value') || redactedText.includes('test-secret-token'),
50
55
  process_exited_successfully: processExitedSuccessfully,
51
- process_warning: processExitedSuccessfully ? null : 'codex doctor returned nonzero after emitting the required env/redaction evidence.'
56
+ process_warning: processExitedSuccessfully ? null : 'codex doctor returned nonzero after emitting the scoped env/redaction evidence.',
57
+ isolated_codex_home: true
52
58
  },
53
59
  blockers: ok ? [] : ['codex_doctor_env_redaction_real_probe_failed']
54
60
  };
@@ -4,7 +4,7 @@ import { buildCodexExecArgs, findCodexBinary } from '../codex-adapter.js';
4
4
  import { ensureDir, runProcess, writeBinaryAtomic } from '../fsx.js';
5
5
  import { buildImageArtifactPathContract } from '../image/image-artifact-path-contract.js';
6
6
  import { codex0139ProbeTail, skippedCodex0139Probe } from './codex-0139-real-probes.js';
7
- const ONE_BY_ONE_PNG = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII=', 'base64');
7
+ const ONE_BY_ONE_PNG = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4//8/AAX+Av4N70a4AAAAAElFTkSuQmCC', 'base64');
8
8
  export async function runCodex0139ImageReferencedPathRealProbe(input) {
9
9
  const started = Date.now();
10
10
  const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-0139-real-probes', `image-path-${Date.now()}`);
@@ -14,10 +14,10 @@ export async function runCodex0139ImageReferencedPathRealProbe(input) {
14
14
  await writeBinaryAtomic(inputA, ONE_BY_ONE_PNG);
15
15
  await writeBinaryAtomic(inputB, ONE_BY_ONE_PNG);
16
16
  const contract = await buildImageArtifactPathContract(input.root, {
17
- missionId: 'codex-0139-image-path-real-probe',
17
+ missionId: 'codex-0144-image-path-real-probe',
18
18
  images: [
19
- { id: 'input-a', kind: 'input_attachment', filePath: inputA, route: 'codex-0139-real-probe', stage: 'candidate' },
20
- { id: 'input-b', kind: 'input_attachment', filePath: inputB, route: 'codex-0139-real-probe', stage: 'referenced' }
19
+ { id: 'input-a', kind: 'input_attachment', filePath: inputA, route: 'codex-0144-core-real-probe', stage: 'candidate' },
20
+ { id: 'input-b', kind: 'input_attachment', filePath: inputB, route: 'codex-0144-core-real-probe', stage: 'referenced' }
21
21
  ]
22
22
  });
23
23
  const codexBin = input.codexBin || await findCodexBinary();
@@ -34,7 +34,7 @@ export async function runCodex0139ImageReferencedPathRealProbe(input) {
34
34
  artifact_paths: [tempDir]
35
35
  };
36
36
  }
37
- if (process.env.SKS_CODEX_0139_IMAGE_REAL_PROBE_ALLOW_SKIP === '1') {
37
+ if (process.env.SKS_CODEX_0144_IMAGE_REAL_PROBE_ALLOW_SKIP === '1' || process.env.SKS_CODEX_0139_IMAGE_REAL_PROBE_ALLOW_SKIP === '1') {
38
38
  return {
39
39
  ...skippedCodex0139Probe('codex_image_edit_actual_api_skipped', {
40
40
  codex_bin: codexBin,
@@ -48,12 +48,12 @@ export async function runCodex0139ImageReferencedPathRealProbe(input) {
48
48
  }
49
49
  const outputFile = path.join(tempDir, 'last-message.txt');
50
50
  const prompt = [
51
- 'This is a Codex 0.139 image path routing probe.',
51
+ 'This is a Codex 0.144.1 image path routing probe.',
52
52
  `Only the image file named ${path.basename(inputB)} is intentionally referenced.`,
53
53
  `Return compact JSON {"referenced_path":"${inputB.replace(/\\/g, '\\\\')}","saw_image":true}.`,
54
54
  'Do not edit files and do not reference any other image path.'
55
55
  ].join(' ');
56
- const extraArgs = ['--image', inputB, '--skip-git-repo-check', '--ephemeral'];
56
+ const extraArgs = ['-c', 'mcp_servers={}', '--image', inputB, '--skip-git-repo-check', '--ephemeral'];
57
57
  const args = buildCodexExecArgs({ root: tempDir, prompt, outputFile, json: true, extraArgs });
58
58
  const result = await runProcess(codexBin, args, {
59
59
  cwd: tempDir,
@@ -68,6 +68,7 @@ export async function runCodex0139ImageReferencedPathRealProbe(input) {
68
68
  const ok = exactReferencedPath
69
69
  && commandReferencesOnlyInputB
70
70
  && outputReferencesInputB
71
+ && processExitedSuccessfully
71
72
  && contract.blockers.length === 0;
72
73
  return {
73
74
  ok,
@@ -88,7 +89,12 @@ export async function runCodex0139ImageReferencedPathRealProbe(input) {
88
89
  output_file: outputFile,
89
90
  contract_blockers: contract.blockers
90
91
  },
91
- blockers: ok ? [] : ['codex_image_referenced_path_actual_cli_probe_failed']
92
+ blockers: ok ? [] : [
93
+ ...(processExitedSuccessfully ? [] : ['codex_image_referenced_path_process_failed_or_timed_out']),
94
+ ...(!exactReferencedPath || !commandReferencesOnlyInputB || !outputReferencesInputB || contract.blockers.length > 0
95
+ ? ['codex_image_referenced_path_actual_cli_probe_failed']
96
+ : [])
97
+ ]
92
98
  };
93
99
  }
94
100
  //# sourceMappingURL=codex-0139-image-path-real-probe.js.map
@@ -1,11 +1,12 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { findCodexBinary } from '../codex-adapter.js';
4
- import { compareSemverLike, parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
4
+ import { parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
5
+ import { CURRENT_CODEX_RELEASE_MANIFEST } from '../codex-compat/codex-release-manifest.js';
5
6
  import { runProcess } from '../fsx.js';
6
7
  import { runCodex0139DoctorEnvRealProbe } from './codex-0139-doctor-real-probe.js';
7
8
  import { runCodex0139ImageReferencedPathRealProbe } from './codex-0139-image-path-real-probe.js';
8
- import { runCodex0139InterruptAgentRealProbe } from './codex-0139-multi-agent-real-probe.js';
9
+ import { runCodex0144CollabAgentToolSchemaRealProbe } from './codex-0144-collab-agent-real-probe.js';
9
10
  import { runCodex0139MarketplaceSourceRealProbe, runCodex0139PluginCacheRealProbe } from './codex-0139-plugin-real-probes.js';
10
11
  import { buildCodex0139RealProbeResult, CODEX_0139_REAL_PROBE_NAMES, skippedCodex0139Probe } from './codex-0139-real-probes.js';
11
12
  import { runCodex0139RichSchemaRealProbe } from './codex-0139-rich-schema-real-probe.js';
@@ -14,34 +15,68 @@ import { runCodex0139WebSearchRealProbe } from './codex-0139-web-search-probe.js
14
15
  export async function runCodex0139RealProbes(input) {
15
16
  const timeoutMs = Math.max(1, Number(input.timeoutMs || 120000) || 120000);
16
17
  const requireReal = input.requireReal === true;
17
- const codexBin = input.codexBin || await findCodex0139RealProbeBinary();
18
+ const codexBin = input.codexBin || await findCurrentCodexRealProbeBinary();
18
19
  const versionText = await readCodexVersionText(codexBin, timeoutMs);
19
20
  const parsedVersion = parseCodexVersionText(versionText);
20
- const atLeast139 = Boolean(parsedVersion && compareSemverLike(parsedVersion, '0.139.0') >= 0);
21
- const requested = new Set((input.probes?.length ? input.probes : CODEX_0139_REAL_PROBE_NAMES).filter((name) => CODEX_0139_REAL_PROBE_NAMES.includes(name)));
21
+ const currentVersion = parsedVersion === CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion;
22
+ const requestedRaw = input.probes?.length ? input.probes : CODEX_0139_REAL_PROBE_NAMES;
23
+ const unknownProbeNames = requestedRaw.filter((name) => !CODEX_0139_REAL_PROBE_NAMES.includes(name));
24
+ const requested = [...new Set(requestedRaw.filter((name) => CODEX_0139_REAL_PROBE_NAMES.includes(name)))];
22
25
  const probes = Object.fromEntries(CODEX_0139_REAL_PROBE_NAMES.map((name) => [name, skippedCodex0139Probe('probe_not_requested')]));
23
- const extraBlockers = [];
26
+ const extraBlockers = unknownProbeNames.map((name) => `unknown_real_probe:${name}`);
24
27
  if (!codexBin)
25
28
  extraBlockers.push('codex_cli_missing');
26
- if (!atLeast139)
27
- extraBlockers.push('codex_0_139_required');
28
- if (!codexBin || !atLeast139) {
29
+ if (!currentVersion)
30
+ extraBlockers.push(`codex_${CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion.replaceAll('.', '_')}_required`);
31
+ if (!codexBin || !currentVersion) {
29
32
  for (const name of requested) {
30
- probes[name] = skippedCodex0139Probe(!codexBin ? 'codex_cli_missing' : 'codex_0_139_required', { parsed_version: parsedVersion });
33
+ probes[name] = skippedCodex0139Probe(!codexBin ? 'codex_cli_missing' : 'codex_current_release_required', { parsed_version: parsedVersion });
31
34
  }
32
- return buildCodex0139RealProbeResult({ codexBin, versionText, parsedVersion, requireReal, timeoutMs, probes, extraBlockers });
35
+ const tempCleanup = await cleanupProbeTempRoot(input.root);
36
+ return buildCodex0139RealProbeResult({ codexBin, versionText, parsedVersion, requireReal, timeoutMs, probes, requiredProbeNames: requested, releaseAuthorizing: false, tempCleanup, extraBlockers });
33
37
  }
34
- for (const name of requested) {
35
- probes[name] = await runOne(name, {
36
- root: input.root,
37
- requireReal,
38
- timeoutMs,
39
- codexBin,
40
- allowNetwork: input.allowNetwork,
41
- allowDesktop: input.allowDesktop
42
- });
38
+ let rows = [];
39
+ let tempCleanup;
40
+ try {
41
+ rows = await Promise.all(requested.map(async (name) => {
42
+ try {
43
+ const probe = await runOne(name, {
44
+ root: input.root,
45
+ requireReal,
46
+ timeoutMs,
47
+ codexBin,
48
+ allowNetwork: input.allowNetwork,
49
+ allowDesktop: input.allowDesktop
50
+ });
51
+ return [name, surfaceRuntimeWarnings(probe)];
52
+ }
53
+ catch (err) {
54
+ const errorClass = err instanceof Error ? err.name : typeof err;
55
+ extraBlockers.push(`codex_real_probe_runner_failed:${name}`);
56
+ return [name, skippedCodex0139Probe('codex_real_probe_runner_failed', { error_class: errorClass })];
57
+ }
58
+ }));
59
+ }
60
+ finally {
61
+ tempCleanup = await cleanupProbeTempRoot(input.root);
43
62
  }
44
- return buildCodex0139RealProbeResult({ codexBin, versionText, parsedVersion, requireReal, timeoutMs, probes, extraBlockers });
63
+ for (const [name, probe] of rows)
64
+ probes[name] = probe;
65
+ sanitizeCleanedTempArtifacts(probes, input.root);
66
+ if (!tempCleanup.ok)
67
+ extraBlockers.push('codex_real_probe_temp_cleanup_failed');
68
+ return buildCodex0139RealProbeResult({
69
+ codexBin,
70
+ versionText,
71
+ parsedVersion,
72
+ requireReal,
73
+ timeoutMs,
74
+ probes,
75
+ requiredProbeNames: requested,
76
+ releaseAuthorizing: requireReal && currentVersion,
77
+ tempCleanup,
78
+ extraBlockers
79
+ });
45
80
  }
46
81
  async function runOne(name, input) {
47
82
  switch (name) {
@@ -57,11 +92,11 @@ async function runOne(name, input) {
57
92
  return runCodex0139PluginCacheRealProbe(input);
58
93
  case 'sandbox_profile_alias':
59
94
  return runCodex0139SandboxProfileAliasProbe(input);
60
- case 'interrupt_agent_event':
61
- return runCodex0139InterruptAgentRealProbe(input);
95
+ case 'collab_agent_tool_schema':
96
+ return runCodex0144CollabAgentToolSchemaRealProbe(input);
62
97
  case 'image_referenced_path':
63
98
  return runCodex0139ImageReferencedPathRealProbe(input);
64
- case 'sandbox_proxy_preservation':
99
+ case 'sandbox_proxy_environment':
65
100
  return runCodex0139SandboxProxyPreservationProbe(input);
66
101
  }
67
102
  }
@@ -76,7 +111,7 @@ async function readCodexVersionText(codexBin, timeoutMs) {
76
111
  const text = `${result.stdout || ''}${result.stderr || ''}`.trim();
77
112
  return text || null;
78
113
  }
79
- export async function findCodex0139RealProbeBinary() {
114
+ export async function findCurrentCodexRealProbeBinary() {
80
115
  const candidates = await codexBinaryCandidates();
81
116
  let firstExisting = null;
82
117
  for (const candidate of candidates) {
@@ -84,18 +119,18 @@ export async function findCodex0139RealProbeBinary() {
84
119
  firstExisting = candidate;
85
120
  const versionText = await readCodexVersionText(candidate, 30000);
86
121
  const parsed = parseCodexVersionText(versionText);
87
- if (parsed && compareSemverLike(parsed, '0.139.0') >= 0)
122
+ if (parsed === CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion)
88
123
  return candidate;
89
124
  }
90
125
  return firstExisting || await findCodexBinary();
91
126
  }
92
127
  async function codexBinaryCandidates() {
93
128
  const raw = [
129
+ path.join(process.cwd(), 'node_modules', '.bin', process.platform === 'win32' ? 'codex.cmd' : 'codex'),
94
130
  process.env.SKS_CODEX_BIN,
95
131
  process.env.DCODEX_CODEX_BIN,
96
132
  process.env.CODEX_BIN,
97
- ...pathCandidates('codex'),
98
- path.join(process.cwd(), 'node_modules', '.bin', process.platform === 'win32' ? 'codex.cmd' : 'codex')
133
+ ...pathCandidates('codex')
99
134
  ].filter(Boolean).map(String);
100
135
  const out = [];
101
136
  for (const candidate of raw) {
@@ -110,6 +145,46 @@ async function codexBinaryCandidates() {
110
145
  }
111
146
  return out;
112
147
  }
148
+ function surfaceRuntimeWarnings(probe) {
149
+ const warnings = [...(probe.warnings || [])];
150
+ const blockers = [...probe.blockers];
151
+ const stderr = String(probe.stderr_tail || '');
152
+ if (/AuthRequired|Auth required|No access token was provided/i.test(stderr)) {
153
+ warnings.push('codex_real_probe_external_mcp_auth_required');
154
+ }
155
+ if (probe.evidence?.process_warning)
156
+ warnings.push('codex_real_probe_process_warning');
157
+ return {
158
+ ...probe,
159
+ ok: probe.ok && blockers.length === 0,
160
+ warnings: [...new Set(warnings)],
161
+ blockers: [...new Set(blockers)]
162
+ };
163
+ }
164
+ async function cleanupProbeTempRoot(root) {
165
+ const tempRoot = path.join(root, '.sneakoscope', 'tmp', 'codex-0139-real-probes');
166
+ await fs.rm(tempRoot, { recursive: true, force: true }).catch(() => undefined);
167
+ const remainingEntries = await fs.readdir(tempRoot).catch(() => []);
168
+ return { root: tempRoot, ok: remainingEntries.length === 0, remaining_entries: remainingEntries };
169
+ }
170
+ function sanitizeCleanedTempArtifacts(probes, root) {
171
+ const tempRoot = path.resolve(root, '.sneakoscope', 'tmp', 'codex-0139-real-probes');
172
+ for (const probe of Object.values(probes)) {
173
+ const tempArtifacts = probe.artifact_paths.filter((artifact) => {
174
+ const resolved = path.resolve(artifact);
175
+ return resolved === tempRoot || resolved.startsWith(`${tempRoot}${path.sep}`);
176
+ });
177
+ if (!tempArtifacts.length)
178
+ continue;
179
+ probe.artifact_paths = probe.artifact_paths.filter((artifact) => !tempArtifacts.includes(artifact));
180
+ probe.evidence = {
181
+ ...probe.evidence,
182
+ observed_temp_artifact_count: tempArtifacts.length,
183
+ temp_artifacts_cleaned: true,
184
+ durable_evidence: 'embedded_in_codex_real_probe_report'
185
+ };
186
+ }
187
+ }
113
188
  function pathCandidates(command) {
114
189
  const exts = process.platform === 'win32' ? ['.cmd', '.exe', '.bat', ''] : [''];
115
190
  return (process.env.PATH || '').split(path.delimiter).flatMap((dir) => exts.map((ext) => path.join(dir, `${command}${ext}`)));
@@ -3,17 +3,21 @@ import { codex0139ProbeArtifactPath } from './codex-0139-real-probes.js';
3
3
  import { readJson, writeJsonAtomic } from '../fsx.js';
4
4
  export async function buildCodex0139RealProbeSummary(root) {
5
5
  const result = await readJson(codex0139ProbeArtifactPath(root));
6
- const probes = Object.fromEntries(Object.entries(result.probes || {}).map(([name, probe]) => [name, {
6
+ const requested = new Set((result.requested_probes?.length ? result.requested_probes : Object.keys(result.probes || {})).map(String));
7
+ const requestedEntries = Object.entries(result.probes || {}).filter(([name]) => requested.has(name));
8
+ const probes = Object.fromEntries(requestedEntries.map(([name, probe]) => [name, {
7
9
  ok: probe.ok === true,
8
10
  mode: probe.mode,
9
11
  blockers: probe.blockers || []
10
12
  }]));
11
- const values = Object.values(result.probes || {});
13
+ const values = requestedEntries.map(([, probe]) => probe);
12
14
  const skippedCount = values.filter((probe) => probe.mode === 'skipped').length;
13
15
  const failedCount = values.filter((probe) => probe.ok !== true && probe.mode !== 'skipped').length;
14
16
  return {
15
17
  schema: 'sks.codex-0139-real-probe-summary.v1',
16
- ok: result.require_real ? skippedCount === 0 && failedCount === 0 : result.overall_ok === true,
18
+ target_version: result.target_version,
19
+ compatibility_authority: 'deprecated_non_authoritative_lineage_only',
20
+ ok: result.overall_ok === true,
17
21
  require_real: result.require_real,
18
22
  codex_bin: result.codex_bin,
19
23
  parsed_version: result.parsed_version,
@@ -1,4 +1,5 @@
1
1
  import path from 'node:path';
2
+ import { CURRENT_CODEX_RELEASE_MANIFEST } from '../codex-compat/codex-release-manifest.js';
2
3
  import { nowIso, writeJsonAtomic } from '../fsx.js';
3
4
  export const CODEX_0139_REAL_PROBE_NAMES = [
4
5
  'code_mode_web_search',
@@ -7,9 +8,9 @@ export const CODEX_0139_REAL_PROBE_NAMES = [
7
8
  'marketplace_source_json',
8
9
  'plugin_catalog_cache',
9
10
  'sandbox_profile_alias',
10
- 'interrupt_agent_event',
11
+ 'collab_agent_tool_schema',
11
12
  'image_referenced_path',
12
- 'sandbox_proxy_preservation'
13
+ 'sandbox_proxy_environment'
13
14
  ];
14
15
  export function codex0139ProbeArtifactPath(root) {
15
16
  return path.join(root, '.sneakoscope', 'codex-0139-real-probes.json');
@@ -50,24 +51,38 @@ export function codex0139ProbeTail(text, limit = 4000) {
50
51
  return raw.length <= limit ? raw : raw.slice(raw.length - limit);
51
52
  }
52
53
  export function buildCodex0139RealProbeResult(input) {
53
- const skipped = CODEX_0139_REAL_PROBE_NAMES.filter((name) => input.probes[name]?.mode === 'skipped');
54
- const failed = CODEX_0139_REAL_PROBE_NAMES.filter((name) => input.probes[name] && input.probes[name].ok !== true && input.probes[name].mode !== 'skipped');
54
+ const requiredProbeNames = input.requiredProbeNames ? [...new Set(input.requiredProbeNames)] : [...CODEX_0139_REAL_PROBE_NAMES];
55
+ const skipped = requiredProbeNames.filter((name) => input.probes[name]?.mode === 'skipped');
56
+ const failed = requiredProbeNames.filter((name) => input.probes[name] && input.probes[name].ok !== true && input.probes[name].mode !== 'skipped');
55
57
  const blockers = [
56
58
  ...(input.extraBlockers || []),
57
- ...CODEX_0139_REAL_PROBE_NAMES.flatMap((name) => input.probes[name]?.blockers || []),
59
+ ...requiredProbeNames.flatMap((name) => input.probes[name]?.blockers || []),
58
60
  ...(input.requireReal && skipped.length ? skipped.map((name) => `require_real_skipped:${name}`) : [])
59
61
  ];
62
+ const warnings = requiredProbeNames.flatMap((name) => input.probes[name]?.warnings || []);
63
+ const overallOk = input.requireReal ? blockers.length === 0 && failed.length === 0 && skipped.length === 0 : failed.length === 0;
60
64
  return {
61
65
  schema: 'sks.codex-0139-real-probe-result.v1',
66
+ target_version: CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion,
67
+ compatibility_origin: 'codex-0139-real-probe-result-v1',
68
+ compatibility_authority: 'deprecated_non_authoritative_lineage_only',
62
69
  generated_at: nowIso(),
63
70
  codex_bin: input.codexBin,
64
71
  version_text: input.versionText,
65
72
  parsed_version: input.parsedVersion,
66
73
  require_real: input.requireReal,
67
- overall_ok: input.requireReal ? blockers.length === 0 && failed.length === 0 && skipped.length === 0 : failed.length === 0,
74
+ release_authorizing: Boolean(input.releaseAuthorizing && overallOk),
75
+ overall_ok: overallOk,
68
76
  probe_timeout_ms: input.timeoutMs,
77
+ requested_probes: requiredProbeNames,
69
78
  probes: input.probes,
70
79
  skipped,
80
+ warnings: [...new Set(warnings)],
81
+ external_integration_status: {
82
+ mcp_auth: warnings.includes('codex_real_probe_external_mcp_auth_required') ? 'authentication_required' : 'not_observed',
83
+ release_authorization_scope: 'codex_core_compatibility_only'
84
+ },
85
+ temp_cleanup: input.tempCleanup || { root: '', ok: false, remaining_entries: [] },
71
86
  blockers: [...new Set(blockers)]
72
87
  };
73
88
  }