sneakoscope 8.2.0 → 8.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +46 -110
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/dist/cli/command-manifest-lite.js +0 -2
  5. package/dist/cli/command-registry.js +0 -2
  6. package/dist/commands/codex.js +3 -3
  7. package/dist/commands/doctor.js +5 -157
  8. package/dist/config/skills-manifest.json +1 -1
  9. package/dist/core/codex/codex-cli-syntax-builder.js +0 -8
  10. package/dist/core/codex-app/codex-models-cache.js +2 -1
  11. package/dist/core/codex-app/menubar/constants.js +0 -7
  12. package/dist/core/codex-compat/codex-capability-matrix.js +7 -7
  13. package/dist/core/codex-compat/codex-compat-report.js +8 -12
  14. package/dist/core/codex-compat/codex-runtime-contract.js +62 -0
  15. package/dist/core/codex-compat/codex-version-policy.js +7 -7
  16. package/dist/core/codex-control/codex-current-app-capability.js +3 -3
  17. package/dist/core/codex-control/codex-current-capability.js +67 -94
  18. package/dist/core/codex-control/codex-current-core-capability.js +3 -3
  19. package/dist/core/codex-control/codex-current-core-probe-runner.js +4 -4
  20. package/dist/core/codex-control/codex-current-core-real-probes.js +2 -2
  21. package/dist/core/codex-control/codex-current-feature-capability.js +4 -4
  22. package/dist/core/codex-control/codex-current-image-path-real-probe.js +1 -1
  23. package/dist/core/codex-control/codex-current-web-search-probe.js +1 -1
  24. package/dist/core/codex-control/codex-sdk-capability.js +2 -2
  25. package/dist/core/commands/remote-command.js +2 -2
  26. package/dist/core/context7-client.js +5 -2
  27. package/dist/core/doctor/codex-current-core-probe-doctor.js +2 -2
  28. package/dist/core/doctor/doctor-dirty-planner.js +1 -1
  29. package/dist/core/doctor/doctor-readiness-matrix.js +0 -7
  30. package/dist/core/feature-fixtures.js +0 -4
  31. package/dist/core/feature-registry.js +0 -1
  32. package/dist/core/image-ux-review.js +3 -3
  33. package/dist/core/install/installed-package-smoke.js +2 -3
  34. package/dist/core/mad-sks/sql-plane/mcp-executor.js +4 -3
  35. package/dist/core/mcp/modern-protocol.js +36 -0
  36. package/dist/core/mcp-config/health-check.js +45 -30
  37. package/dist/core/perf/release-latency-slo.js +1 -2
  38. package/dist/core/proof/runtime-truth-matrix.js +1 -1
  39. package/dist/core/release/canonical-test-proof.js +1 -2
  40. package/dist/core/release/gate-manifest.js +5 -2
  41. package/dist/core/release/physical-release-gates.js +0 -26
  42. package/dist/core/release/release-gate-affected-selector.js +2 -1
  43. package/dist/core/release/release-gate-contract.js +3 -1
  44. package/dist/core/release/release-pack-receipt.js +0 -1
  45. package/dist/core/release/stage-publish.js +1 -1
  46. package/dist/core/version-manager.js +4 -0
  47. package/dist/core/version.js +1 -1
  48. package/dist/native/sks-menubar/Sources/AppDelegate.swift +1 -12
  49. package/dist/native/sks-menubar/Sources/ControlCenterWindowController.swift +2 -6
  50. package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +28 -471
  51. package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +1 -43
  52. package/dist/scripts/codex-current-app-server-v2-check.js +9 -8
  53. package/dist/scripts/codex-current-binary-identity-check.js +2 -2
  54. package/dist/scripts/codex-current-capability-check.js +9 -7
  55. package/dist/scripts/codex-current-dependency-check.js +21 -0
  56. package/dist/scripts/docs-truthfulness-check.js +4 -19
  57. package/dist/scripts/fast-codex-service-tier-proof-check.js +0 -1
  58. package/dist/scripts/install-surface-ssot-check.js +2 -2
  59. package/dist/scripts/latest-version-guidance-check.js +1 -1
  60. package/dist/scripts/packlist-performance-check.js +0 -1
  61. package/dist/scripts/release-metadata-check.js +4 -1
  62. package/dist/scripts/release-version-truth-check.js +149 -0
  63. package/dist/vendor/openai-codex/latest/hooks/permission-request.command.input.schema.json +6 -0
  64. package/dist/vendor/openai-codex/latest/hooks/permission-request.command.output.schema.json +2 -16
  65. package/dist/vendor/openai-codex/latest/hooks/post-compact.command.input.schema.json +6 -0
  66. package/dist/vendor/openai-codex/latest/hooks/post-tool-use.command.input.schema.json +6 -0
  67. package/dist/vendor/openai-codex/latest/hooks/post-tool-use.command.output.schema.json +2 -16
  68. package/dist/vendor/openai-codex/latest/hooks/pre-compact.command.input.schema.json +6 -0
  69. package/dist/vendor/openai-codex/latest/hooks/pre-tool-use.command.input.schema.json +6 -0
  70. package/dist/vendor/openai-codex/latest/hooks/pre-tool-use.command.output.schema.json +2 -16
  71. package/dist/vendor/openai-codex/latest/hooks/session-start.command.output.schema.json +2 -16
  72. package/dist/vendor/openai-codex/latest/hooks/snapshot-metadata.json +7 -5
  73. package/dist/vendor/openai-codex/latest/hooks/subagent-start.command.output.schema.json +4 -18
  74. package/dist/vendor/openai-codex/latest/hooks/user-prompt-submit.command.input.schema.json +6 -0
  75. package/dist/vendor/openai-codex/latest/hooks/user-prompt-submit.command.output.schema.json +2 -16
  76. package/package.json +4 -7
  77. package/release-gates.v2.json +49 -19
  78. package/config/codex-releases/rust-v0.146.0.json +0 -45
  79. package/dist/core/agents/agent-runner-codex-exec.js +0 -177
  80. package/dist/core/codex-compat/codex-release-manifest.js +0 -72
  81. package/dist/core/commands/telegram-command.js +0 -447
  82. package/dist/core/telegram/access.js +0 -58
  83. package/dist/core/telegram/client.js +0 -157
  84. package/dist/core/telegram/confirmation.js +0 -37
  85. package/dist/core/telegram/doctor.js +0 -154
  86. package/dist/core/telegram/index.js +0 -9
  87. package/dist/core/telegram/keychain.js +0 -317
  88. package/dist/core/telegram/liveness.js +0 -124
  89. package/dist/core/telegram/poller.js +0 -90
  90. package/dist/core/telegram/redaction.js +0 -15
  91. package/dist/core/telegram/state-lock.js +0 -416
  92. package/dist/core/telegram/types.js +0 -1
  93. package/dist/native/sks-menubar/Sources/TelegramPrivateFileStore.swift +0 -498
  94. package/dist/native/sks-menubar/Sources/TelegramPrivateFileSupport.swift +0 -236
  95. package/dist/native/sks-menubar/Sources/TelegramProcessGateway.swift +0 -454
  96. package/dist/native/sks-menubar/Sources/TelegramRuntimeSupport.swift +0 -56
  97. package/dist/native/sks-menubar/Sources/TelegramStateLock.swift +0 -448
  98. package/dist/native/sks-menubar/Sources/TelegramSupport.swift +0 -243
  99. package/dist/native/sks-menubar/Sources/TelegramTransport.swift +0 -499
  100. package/dist/scripts/codex-current-manifest-check.js +0 -29
  101. package/schemas/codex/app-server-0.146/codex_app_server_protocol.v2.schemas.json +0 -19858
@@ -1,5 +1,5 @@
1
1
  import { runProcess } from '../fsx.js';
2
- import { CURRENT_CODEX_RELEASE_MANIFEST, NARUTO_REQUIRED_CODEX_VERSION } from './codex-release-manifest.js';
2
+ import { CURRENT_CODEX_RUNTIME_CONTRACT, NARUTO_REQUIRED_CODEX_VERSION } from './codex-runtime-contract.js';
3
3
  import { compareSemverLike, parseCodexVersionText } from './codex-version-policy.js';
4
4
  export const CODEX_CAPABILITY_MATRIX_SCHEMA = 'sks.codex-capability-matrix.v1';
5
5
  export const SKS_CODEX_CAPABILITY_IDS = [
@@ -13,10 +13,10 @@ export const SKS_CODEX_CAPABILITY_IDS = [
13
13
  ];
14
14
  const UPDATE_CTA = 'Update Codex CLI to the preferred latest: `sks codex update` or Menu Bar / SKS Center → Update Codex CLI Now.';
15
15
  export function preferredCodexCliVersion() {
16
- return CURRENT_CODEX_RELEASE_MANIFEST.preferredCliVersion || CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion;
16
+ return CURRENT_CODEX_RUNTIME_CONTRACT.preferredCliVersion || CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion;
17
17
  }
18
18
  export function softMinimumCodexCliVersion() {
19
- return CURRENT_CODEX_RELEASE_MANIFEST.minimumSupportedVersion;
19
+ return CURRENT_CODEX_RUNTIME_CONTRACT.minimumSupportedVersion;
20
20
  }
21
21
  export function narutoCodexFloorVersion() {
22
22
  return NARUTO_REQUIRED_CODEX_VERSION;
@@ -26,7 +26,7 @@ export function buildCodexCapabilityMatrix(input = {}) {
26
26
  const help = String(input.helpText || '');
27
27
  const config = String(input.configText || '');
28
28
  const schema = String(input.schemaText || '');
29
- const policies = CURRENT_CODEX_RELEASE_MANIFEST.featurePolicies;
29
+ const policies = CURRENT_CODEX_RUNTIME_CONTRACT.featurePolicies;
30
30
  const warnings = [];
31
31
  if (detected && compareSemverLike(detected, preferredCodexCliVersion()) < 0) {
32
32
  warnings.push(`detected Codex ${detected} is below preferred ${preferredCodexCliVersion()}; prefer latest via SKS update inducement`);
@@ -122,8 +122,8 @@ export async function probeNarutoCodexCapability(input) {
122
122
  return { matrix, naruto: assertNarutoMultiAgentV2Capability(matrix) };
123
123
  }
124
124
  function resolveMultiAgentV2(input) {
125
- const policy = CURRENT_CODEX_RELEASE_MANIFEST.featurePolicies.multiAgentV2
126
- || CURRENT_CODEX_RELEASE_MANIFEST.featurePolicies.multiAgentMode
125
+ const policy = CURRENT_CODEX_RUNTIME_CONTRACT.featurePolicies.multiAgentV2
126
+ || CURRENT_CODEX_RUNTIME_CONTRACT.featurePolicies.multiAgentMode
127
127
  || 'delegate';
128
128
  const evidence = [];
129
129
  const helpHit = /\bmulti_agent_v2\b/.test(input.help);
@@ -167,7 +167,7 @@ function resolveMultiAgentV2(input) {
167
167
  };
168
168
  }
169
169
  function resolveAgentsConcurrency(input) {
170
- const policy = CURRENT_CODEX_RELEASE_MANIFEST.featurePolicies.agentsMaxConcurrentThreads || 'delegate';
170
+ const policy = CURRENT_CODEX_RUNTIME_CONTRACT.featurePolicies.agentsMaxConcurrentThreads || 'delegate';
171
171
  const hit = /max_concurrent_threads_per_session/.test(input.help)
172
172
  || /max_concurrent_threads_per_session/.test(input.config);
173
173
  const available = hit || input.multiAgentV2;
@@ -2,21 +2,18 @@ import { projectRoot } from '../fsx.js';
2
2
  import { detectCodexCurrentCapability } from '../codex-control/codex-current-capability.js';
3
3
  import { codexVersionReport } from './codex-version.js';
4
4
  import { CODEX_COMPAT_SCHEMA, CODEX_HOOK_SCHEMA_BASELINE_TAG, CODEX_REQUIRED_BASELINE_TAG } from './codex-version-policy.js';
5
- import { codexReleaseManifestParity } from './codex-release-manifest.js';
5
+ import { CURRENT_CODEX_RUNTIME_CONTRACT } from './codex-runtime-contract.js';
6
6
  import { codexSchemaSnapshotReport } from './codex-schema-snapshot.js';
7
7
  import { codexHookWarningCheck } from './codex-hook-warning-detector.js';
8
8
  export async function codexCompatibilityReport(opts = {}) {
9
9
  const root = opts.root || await projectRoot();
10
10
  const requiredBaseline = opts.requiredBaseline || opts.require || CODEX_REQUIRED_BASELINE_TAG;
11
11
  const version = await codexVersionReport({ ...opts, requiredBaseline });
12
- const releaseManifest = await codexReleaseManifestParity(root).catch((err) => ({
13
- ok: false,
14
- mismatches: ['manifest_load_failed'],
15
- manifest: null,
16
- manifest_path: null,
17
- manifest_sha256: null,
18
- error: err?.message || String(err)
19
- }));
12
+ const releaseContract = {
13
+ ok: true,
14
+ dependency_source: CURRENT_CODEX_RUNTIME_CONTRACT.dependencySource,
15
+ contract: CURRENT_CODEX_RUNTIME_CONTRACT
16
+ };
20
17
  const snapshot = await codexSchemaSnapshotReport();
21
18
  const hooks = await codexHookWarningCheck(root, { recordWrongness: false });
22
19
  const current = await detectCodexCurrentCapability({
@@ -24,11 +21,11 @@ export async function codexCompatibilityReport(opts = {}) {
24
21
  codexBin: opts.codexBin || null,
25
22
  requireReal: opts.requireReal === true
26
23
  });
27
- const ok = Boolean(version.policy.ok && releaseManifest.ok && snapshot.ok && hooks.ok && current.ok);
24
+ const ok = Boolean(version.policy.ok && snapshot.ok && hooks.ok && current.ok);
28
25
  return {
29
26
  schema: CODEX_COMPAT_SCHEMA,
30
27
  required_baseline: requiredBaseline,
31
- release_manifest: releaseManifest,
28
+ release_contract: releaseContract,
32
29
  detected: version.detected,
33
30
  current_capability: current,
34
31
  capabilities: current.feature_states,
@@ -58,7 +55,6 @@ export async function codexCompatibilityReport(opts = {}) {
58
55
  ],
59
56
  blockers: [
60
57
  ...(version.policy.ok ? [] : ['codex_version_policy_failed']),
61
- ...(releaseManifest.ok ? [] : ['codex_release_manifest_mismatch']),
62
58
  ...(snapshot.ok ? [] : ['codex_hook_schema_snapshot_invalid']),
63
59
  ...(hooks.ok ? [] : ['codex_hook_semantic_warning']),
64
60
  ...current.blockers
@@ -0,0 +1,62 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { packageRoot } from '../fsx.js';
4
+ export const CODEX_RUNTIME_CONTRACT_SCHEMA = 'sks.codex-runtime-contract.v2';
5
+ const sdkVersion = codexSdkDependencyVersion();
6
+ export const CURRENT_CODEX_RUNTIME_CONTRACT = {
7
+ schema: CODEX_RUNTIME_CONTRACT_SCHEMA,
8
+ targetTag: `rust-v${sdkVersion}`,
9
+ requiredCliVersion: sdkVersion,
10
+ preferredCliVersion: sdkVersion,
11
+ sdkVersion,
12
+ minimumSupportedVersion: sdkVersion,
13
+ narutoCapabilityFloorVersion: sdkVersion,
14
+ protocolMode: 'app-server-v2',
15
+ dependencySource: 'package.json#dependencies.@openai/codex-sdk',
16
+ featurePolicies: {
17
+ multiAgentMode: 'delegate',
18
+ multiAgentV2: 'delegate',
19
+ agentsMaxConcurrentThreads: 'delegate',
20
+ indexedWebSearch: 'probe',
21
+ currentTimeRead: 'wrap',
22
+ threadListSearchRead: 'probe',
23
+ pluginCatalogRefresh: 'probe',
24
+ terminalSubagentErrorPropagation: 'probe',
25
+ execMcpTransientRecovery: 'probe',
26
+ remoteNativeEnvironment: 'probe',
27
+ rolloutTokenBudget: 'probe',
28
+ mcpStartupToolTimeouts: 'wrap',
29
+ gpt56TerraLunaSolRouting: 'delegate',
30
+ mcpPaginatedDiscovery: 'wrap',
31
+ portableAgentPlugins: 'delegate',
32
+ automaticApprovalReview: 'delegate'
33
+ },
34
+ requiredRealProbes: [
35
+ 'runtime_identity',
36
+ 'protocol_schema_generation',
37
+ 'multi_agent_mode_schema',
38
+ 'indexed_web_search_schema',
39
+ 'current_time_read_schema',
40
+ 'thread_list_search_schema',
41
+ 'terminal_error_schema',
42
+ 'rollout_budget_schema'
43
+ ],
44
+ supportedPlatforms: [
45
+ 'darwin-arm64',
46
+ 'darwin-x64',
47
+ 'linux-arm64',
48
+ 'linux-x64',
49
+ 'win32-arm64',
50
+ 'win32-x64'
51
+ ]
52
+ };
53
+ export const NARUTO_REQUIRED_CODEX_VERSION = CURRENT_CODEX_RUNTIME_CONTRACT.narutoCapabilityFloorVersion;
54
+ export function codexSdkDependencyVersion(root = packageRoot()) {
55
+ const packagePath = path.join(root, 'package.json');
56
+ const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
57
+ const value = String(pkg.dependencies?.['@openai/codex-sdk'] || '').trim();
58
+ if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(value)) {
59
+ throw new Error(`@openai/codex-sdk must be an exact semver in ${packagePath}`);
60
+ }
61
+ return value;
62
+ }
@@ -1,12 +1,12 @@
1
- import { CURRENT_CODEX_RELEASE_MANIFEST } from './codex-release-manifest.js';
1
+ import { CURRENT_CODEX_RUNTIME_CONTRACT } from './codex-runtime-contract.js';
2
2
  export const CODEX_COMPAT_SCHEMA = 'sks.codex-compat.v2';
3
- export const CODEX_REQUIRED_BASELINE_TAG = CURRENT_CODEX_RELEASE_MANIFEST.targetTag;
4
- export const CODEX_REQUIRED_VERSION = CURRENT_CODEX_RELEASE_MANIFEST.preferredCliVersion
5
- || CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion;
3
+ export const CODEX_REQUIRED_BASELINE_TAG = CURRENT_CODEX_RUNTIME_CONTRACT.targetTag;
4
+ export const CODEX_REQUIRED_VERSION = CURRENT_CODEX_RUNTIME_CONTRACT.preferredCliVersion
5
+ || CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion;
6
6
  export const CODEX_PREFERRED_VERSION = CODEX_REQUIRED_VERSION;
7
- export const CODEX_MINIMUM_SUPPORTED_VERSION = CURRENT_CODEX_RELEASE_MANIFEST.minimumSupportedVersion;
8
- export const CODEX_HOOK_SCHEMA_BASELINE_TAG = CURRENT_CODEX_RELEASE_MANIFEST.targetTag;
9
- export const CODEX_HOOK_SCHEMA_VERSION = CURRENT_CODEX_RELEASE_MANIFEST.targetTag;
7
+ export const CODEX_MINIMUM_SUPPORTED_VERSION = CURRENT_CODEX_RUNTIME_CONTRACT.minimumSupportedVersion;
8
+ export const CODEX_HOOK_SCHEMA_BASELINE_TAG = 'latest';
9
+ export const CODEX_HOOK_SCHEMA_VERSION = 'latest';
10
10
  const UPDATE_CTA = 'prefer latest Codex CLI via `sks codex update` or Menu Bar / SKS Center → Update Codex CLI Now';
11
11
  export function compareSemverLike(a, b) {
12
12
  const pa = parseVersionParts(a);
@@ -1,7 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import { findCodexBinary } from '../codex-adapter.js';
3
3
  import { compareSemverLike, parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
4
- import { CURRENT_CODEX_RELEASE_MANIFEST } from '../codex-compat/codex-release-manifest.js';
4
+ import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
5
5
  import { nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
6
6
  export async function detectCodexCurrentAppCapability(input = {}) {
7
7
  const fake = process.env.SKS_CODEX_CURRENT_APP_FAKE === '1';
@@ -9,10 +9,10 @@ export async function detectCodexCurrentAppCapability(input = {}) {
9
9
  ? input.codexBin || process.env.CODEX_BIN || 'codex'
10
10
  : input.codexBin || process.env.CODEX_BIN || await findCodexBinary();
11
11
  const versionText = fake
12
- ? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion}`)
12
+ ? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion}`)
13
13
  : await readCodexVersionText(codexBin);
14
14
  const parsed = parseCodexVersion(versionText);
15
- const currentRelease = Boolean(parsed && semverGte(parsed, CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion));
15
+ const currentRelease = Boolean(parsed && semverGte(parsed, CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion));
16
16
  const probeMode = process.env.SKS_CODEX_CURRENT_APP_PROBE === '1' ? 'feature-probe' : 'version-only';
17
17
  const featureProbeResults = probeMode === 'feature-probe'
18
18
  ? await probeCodexCurrentAppFeatures(codexBin, { fake })
@@ -1,9 +1,8 @@
1
1
  import fsp from 'node:fs/promises';
2
- import os from 'node:os';
3
2
  import path from 'node:path';
4
- import { CURRENT_CODEX_RELEASE_MANIFEST } from '../codex-compat/codex-release-manifest.js';
3
+ import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
5
4
  import { compareSemverLike } from '../codex-compat/codex-version-policy.js';
6
- import { ensureDir, nowIso, packageRoot, readJson, runProcess, sha256, writeJsonAtomic } from '../fsx.js';
5
+ import { nowIso, packageRoot, readJson, runProcess, sha256, withScratchDir, writeJsonAtomic } from '../fsx.js';
7
6
  import { resolveCodexRuntime } from '../codex-runtime/resolve-codex-runtime.js';
8
7
  export const CODEX_CURRENT_FEATURE_KEYS = [
9
8
  'runtime_identity',
@@ -30,11 +29,13 @@ export async function detectCodexCurrentCapability(input = {}) {
30
29
  if (!runtime.identity) {
31
30
  return blockedCapability('blocked', null, null, [...runtime.blockers]);
32
31
  }
33
- const versionOk = compareSemverLike(runtime.identity.version, CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion) >= 0;
34
- const schemaProbe = await schemaProbeForMode(root, runtime.identity.realpath, input.requireReal === true);
32
+ const versionOk = compareSemverLike(runtime.identity.version, CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion) >= 0;
33
+ const schemaProbe = await generateSchemaProbe(root, runtime.identity, {
34
+ allowCache: input.requireReal !== true
35
+ });
35
36
  const implementationRoot = packageRoot();
36
37
  const appServerClientText = await fsp.readFile(path.join(implementationRoot, 'src', 'core', 'codex-control', 'codex-app-server-v2-client.ts'), 'utf8').catch(() => '');
37
- const states = featureStatesFromSchema(schemaProbe.text, schemaProbe.ok, appServerClientText);
38
+ const states = featureStatesFromSchema(schemaProbe.text, schemaProbe.ok, schemaProbe.mode, appServerClientText);
38
39
  const blockers = [
39
40
  ...(versionOk ? [] : ['codex_current_release_required']),
40
41
  ...(schemaProbe.ok ? [] : ['codex_current_schema_generation_failed']),
@@ -43,24 +44,21 @@ export async function detectCodexCurrentCapability(input = {}) {
43
44
  const realEnough = blockers.length === 0
44
45
  && schemaProbe.mode === 'real-schema'
45
46
  && schemaProbe.sha256 !== null
46
- && CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256 !== 'pending-generated-schema'
47
- && schemaProbe.sha256 === CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256
48
47
  && Object.values(states).every((state) => state.certainty === 'actual' || state.certainty === 'discovered');
49
48
  return {
50
49
  schema: 'sks.codex-current-capability.v1',
51
50
  generated_at: nowIso(),
52
51
  ok: blockers.length === 0,
53
52
  release_authorizing: realEnough,
54
- target_tag: CURRENT_CODEX_RELEASE_MANIFEST.targetTag,
55
- required_version: CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion,
53
+ target_tag: CURRENT_CODEX_RUNTIME_CONTRACT.targetTag,
54
+ required_version: CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion,
56
55
  runtime_identity: runtime.identity,
57
56
  generated_schema_sha256: schemaProbe.sha256,
58
- manifest_schema_sha256: CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256,
59
57
  probe_mode: schemaProbe.ok ? schemaProbe.mode : 'blocked',
60
58
  feature_states: states,
61
59
  blockers,
62
60
  warnings: [
63
- ...(realEnough ? [] : ['codex_current_not_release_authorizing_until_schema_hash_and_all_required_real_probes_match']),
61
+ ...(realEnough ? [] : ['codex_current_not_release_authorizing_until_runtime_schema_and_required_probes_pass']),
64
62
  ...(input.requireReal && blockers.length ? ['required_real_probe_blocked'] : [])
65
63
  ]
66
64
  };
@@ -81,14 +79,15 @@ export async function writeCodexCurrentCapabilityArtifacts(root, input = {}) {
81
79
  }
82
80
  return { report, root_artifact: rootArtifact, mission_artifact: missionArtifact };
83
81
  }
84
- function featureStatesFromSchema(schemaText, schemaOk, appServerClientText = '') {
82
+ function featureStatesFromSchema(schemaText, schemaOk, schemaMode, appServerClientText = '') {
85
83
  const lower = schemaText.toLowerCase();
84
+ const schemaCertainty = schemaMode === 'real-schema' ? 'actual' : 'discovered';
86
85
  const actual = (key, needles) => {
87
86
  const found = schemaOk && needles.every((needle) => lower.includes(needle.toLowerCase()));
88
87
  return {
89
88
  supported: found,
90
- certainty: found ? 'actual' : schemaOk ? 'unverified' : 'failed',
91
- evidence: found ? needles.map((needle) => `generated_schema_contains:${needle}`) : [],
89
+ certainty: found ? schemaCertainty : schemaOk ? 'unverified' : 'failed',
90
+ evidence: found ? needles.map((needle) => `${schemaMode}_contains:${needle}`) : [],
92
91
  blockers: found ? [] : [`codex_current_${key}_not_verified`]
93
92
  };
94
93
  };
@@ -101,14 +100,16 @@ function featureStatesFromSchema(schemaText, schemaOk, appServerClientText = '')
101
100
  },
102
101
  protocol_schema_generation: {
103
102
  supported: schemaOk,
104
- certainty: schemaOk ? 'actual' : 'failed',
105
- evidence: schemaOk ? ['codex_app_server_generate_json_schema'] : [],
103
+ certainty: schemaOk ? schemaCertainty : 'failed',
104
+ evidence: schemaOk
105
+ ? [schemaMode === 'real-schema' ? 'codex_app_server_generate_json_schema' : 'cached_schema_non_authorizing']
106
+ : [],
106
107
  blockers: schemaOk ? [] : ['codex_app_server_schema_generation_failed']
107
108
  },
108
109
  multi_agent_mode_schema: actual('multi_agent_mode_schema', ['MultiAgentMode']),
109
110
  rollout_budget_schema: actual('rollout_budget_schema', ['budgetLimited']),
110
111
  indexed_web_search_schema: actual('indexed_web_search_schema', ['indexed']),
111
- current_time_read_schema: currentTimeState(lower, schemaOk, appServerClientText),
112
+ current_time_read_schema: currentTimeState(lower, schemaOk, schemaMode, appServerClientText),
112
113
  native_thread_list_search_schema: actual('native_thread_list_search_schema', ['thread/list', 'ThreadSearchResult', 'thread/read']),
113
114
  plugin_catalog_refresh_schema: actual('plugin_catalog_refresh_schema', ['plugin/list', 'plugin/install', 'AppListUpdatedNotification']),
114
115
  terminal_subagent_error_schema: actual('terminal_subagent_error_schema', ['subagentStart', 'subagentStop', 'error']),
@@ -117,13 +118,13 @@ function featureStatesFromSchema(schemaText, schemaOk, appServerClientText = '')
117
118
  app_server_overload_schema: actual('app_server_overload_schema', ['JSONRPCError'])
118
119
  };
119
120
  }
120
- function currentTimeState(schemaTextLower, schemaOk, appServerClientText) {
121
+ function currentTimeState(schemaTextLower, schemaOk, schemaMode, appServerClientText) {
121
122
  const schemaHasCurrentTime = schemaOk && schemaTextLower.includes('currenttime') && schemaTextLower.includes('read');
122
123
  if (schemaHasCurrentTime) {
123
124
  return {
124
125
  supported: true,
125
- certainty: 'actual',
126
- evidence: ['generated_schema_contains:currentTime/read'],
126
+ certainty: schemaMode === 'real-schema' ? 'actual' : 'discovered',
127
+ evidence: [`${schemaMode}_contains:currentTime/read`],
127
128
  blockers: []
128
129
  };
129
130
  }
@@ -135,76 +136,50 @@ function currentTimeState(schemaTextLower, schemaOk, appServerClientText) {
135
136
  blockers: clientHandlesCurrentTime ? [] : ['codex_current_current_time_read_handler_not_verified']
136
137
  };
137
138
  }
138
- async function schemaProbeForMode(root, codexBin, requireReal) {
139
- if (!requireReal && process.env.SKS_CODEX_CURRENT_REFRESH !== '1') {
140
- const shipped = await shippedSchemaProbe();
141
- if (shipped.ok)
142
- return shipped;
139
+ async function generateSchemaProbe(root, runtime, options) {
140
+ const cachePath = codexCurrentSchemaCachePath(root, runtime);
141
+ if (options.allowCache) {
142
+ const cached = await readJson(cachePath, null).catch(() => null);
143
+ if (cached?.ok === true && typeof cached.text === 'string' && cached.sha256) {
144
+ return { ok: true, text: cached.text, sha256: cached.sha256, mode: 'cached-schema' };
145
+ }
143
146
  }
144
- return generateSchemaProbe(root, codexBin);
145
- }
146
- async function shippedSchemaProbe() {
147
- const schemaRoot = path.join(packageRoot(), 'schemas', 'codex', 'app-server-0.146');
148
- const files = await listFiles(schemaRoot).catch(() => []);
149
- if (!files.length)
150
- return { ok: false, text: 'shipped schema cache missing', sha256: null, mode: 'shipped-manifest-cache' };
151
- const rows = await Promise.all(files.map(async (file) => {
152
- const text = await fsp.readFile(file, 'utf8');
153
- return {
154
- relative: path.relative(schemaRoot, file),
155
- text,
156
- canonicalText: canonicalSchemaContent(file, text)
157
- };
158
- }));
159
- const joined = rows.map((row) => `${row.relative}\n${row.text}`).join('\n');
160
- const canonicalJoined = rows.map((row) => `${row.relative}\n${row.canonicalText}`).join('\n');
161
- return { ok: true, text: joined, sha256: sha256(canonicalJoined), mode: 'shipped-manifest-cache' };
162
- }
163
- async function generateSchemaProbe(root, codexBin) {
164
- const cachePath = await schemaCachePath(root, codexBin);
165
- const cached = await readJson(cachePath, null).catch(() => null);
166
- if (cached?.ok === true && typeof cached.text === 'string' && cached.sha256) {
167
- return { ok: true, text: cached.text, sha256: cached.sha256, mode: 'real-schema' };
168
- }
169
- const out = path.join(os.tmpdir(), `sks-codex-current-schema-${process.pid}-${Date.now()}`);
170
- await ensureDir(out);
171
- const result = await runProcess(codexBin, ['app-server', 'generate-json-schema', '--out', out], {
172
- cwd: root,
173
- timeoutMs: 60_000,
174
- maxOutputBytes: 256 * 1024
175
- }).catch((err) => ({
176
- code: 1,
177
- stdout: '',
178
- stderr: err instanceof Error ? err.message : String(err),
179
- stdoutBytes: 0,
180
- stderrBytes: 0,
181
- truncated: false,
182
- timedOut: false
183
- }));
184
- if (result.code !== 0)
185
- return { ok: false, text: `${result.stdout}\n${result.stderr}`, sha256: null, mode: 'real-schema' };
186
- const files = await listFiles(out);
187
- const rows = await Promise.all(files.map(async (file) => {
188
- const text = await fsp.readFile(file, 'utf8');
189
- return {
190
- relative: path.relative(out, file),
191
- text,
192
- canonicalText: canonicalSchemaContent(file, text)
193
- };
194
- }));
195
- const joined = rows.map((row) => `${row.relative}\n${row.text}`).join('\n');
196
- const canonicalJoined = rows.map((row) => `${row.relative}\n${row.canonicalText}`).join('\n');
197
- await fsp.rm(out, { recursive: true, force: true }).catch(() => { });
198
- const probe = { ok: true, text: joined, sha256: sha256(canonicalJoined), mode: 'real-schema' };
199
- await writeJsonAtomic(cachePath, probe).catch(() => undefined);
200
- return probe;
147
+ return withScratchDir('codex-current-schema-', async (out) => {
148
+ const result = await runProcess(runtime.realpath, ['app-server', 'generate-json-schema', '--out', out], {
149
+ cwd: root,
150
+ timeoutMs: 60_000,
151
+ maxOutputBytes: 256 * 1024
152
+ }).catch((err) => ({
153
+ code: 1,
154
+ stdout: '',
155
+ stderr: err instanceof Error ? err.message : String(err),
156
+ stdoutBytes: 0,
157
+ stderrBytes: 0,
158
+ truncated: false,
159
+ timedOut: false
160
+ }));
161
+ if (result.code !== 0)
162
+ return { ok: false, text: `${result.stdout}\n${result.stderr}`, sha256: null, mode: 'real-schema' };
163
+ const files = await listFiles(out);
164
+ const rows = await Promise.all(files.map(async (file) => {
165
+ const text = await fsp.readFile(file, 'utf8');
166
+ return {
167
+ relative: path.relative(out, file),
168
+ text,
169
+ canonicalText: canonicalSchemaContent(file, text)
170
+ };
171
+ }));
172
+ const joined = rows.map((row) => `${row.relative}\n${row.text}`).join('\n');
173
+ const canonicalJoined = rows.map((row) => `${row.relative}\n${row.canonicalText}`).join('\n');
174
+ const probe = { ok: true, text: joined, sha256: sha256(canonicalJoined), mode: 'real-schema' };
175
+ await writeJsonAtomic(cachePath, probe).catch(() => undefined);
176
+ return probe;
177
+ });
201
178
  }
202
- async function schemaCachePath(root, codexBin) {
203
- const realpath = await fsp.realpath(codexBin).catch(() => codexBin);
179
+ export function codexCurrentSchemaCachePath(root, runtime) {
204
180
  const key = sha256(JSON.stringify({
205
- realpath,
206
- target: CURRENT_CODEX_RELEASE_MANIFEST.targetTag,
207
- manifest_schema_sha256: CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256,
181
+ realpath: runtime.realpath,
182
+ binary_sha256: runtime.sha256,
208
183
  platform: process.platform,
209
184
  arch: process.arch
210
185
  }));
@@ -251,11 +226,10 @@ function blockedCapability(probeMode, runtime, schemaSha, blockers) {
251
226
  generated_at: nowIso(),
252
227
  ok: false,
253
228
  release_authorizing: false,
254
- target_tag: CURRENT_CODEX_RELEASE_MANIFEST.targetTag,
255
- required_version: CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion,
229
+ target_tag: CURRENT_CODEX_RUNTIME_CONTRACT.targetTag,
230
+ required_version: CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion,
256
231
  runtime_identity: runtime,
257
232
  generated_schema_sha256: schemaSha,
258
- manifest_schema_sha256: CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256,
259
233
  probe_mode: probeMode,
260
234
  feature_states: state,
261
235
  blockers,
@@ -274,11 +248,10 @@ function fakeCapability() {
274
248
  generated_at: nowIso(),
275
249
  ok: true,
276
250
  release_authorizing: false,
277
- target_tag: CURRENT_CODEX_RELEASE_MANIFEST.targetTag,
278
- required_version: CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion,
251
+ target_tag: CURRENT_CODEX_RUNTIME_CONTRACT.targetTag,
252
+ required_version: CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion,
279
253
  runtime_identity: null,
280
254
  generated_schema_sha256: 'fixture',
281
- manifest_schema_sha256: CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256,
282
255
  probe_mode: 'hermetic-fixture',
283
256
  feature_states: state,
284
257
  blockers: [],
@@ -1,7 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import { findCodexBinary } from '../codex-adapter.js';
3
3
  import { compareSemverLike, parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
4
- import { CURRENT_CODEX_RELEASE_MANIFEST } from '../codex-compat/codex-release-manifest.js';
4
+ import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
5
5
  import { nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
6
6
  export async function detectCodexCurrentCoreCapability(input = {}) {
7
7
  const fake = process.env.SKS_CODEX_CURRENT_CORE_FAKE === '1';
@@ -9,10 +9,10 @@ export async function detectCodexCurrentCoreCapability(input = {}) {
9
9
  ? input.codexBin || process.env.CODEX_BIN || 'codex'
10
10
  : input.codexBin || process.env.CODEX_BIN || await findCodexBinary();
11
11
  const versionText = fake
12
- ? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion}`)
12
+ ? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion}`)
13
13
  : await readCodexVersionText(codexBin);
14
14
  const parsed = parseCodexVersionText(versionText);
15
- const currentRelease = Boolean(parsed && compareSemverLike(parsed, CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion) >= 0);
15
+ const currentRelease = Boolean(parsed && compareSemverLike(parsed, CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion) >= 0);
16
16
  const probeMode = process.env.SKS_CODEX_CURRENT_CORE_PROBE === '1' ? 'feature-probe' : 'version-only';
17
17
  const probeTimeoutMs = Math.max(1, Number(process.env.SKS_CODEX_CURRENT_CORE_PROBE_TIMEOUT_MS || 3000) || 3000);
18
18
  const featureProbeResults = probeMode === 'feature-probe'
@@ -2,7 +2,7 @@ import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { findCodexBinary } from '../codex-adapter.js';
4
4
  import { parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
5
- import { CURRENT_CODEX_RELEASE_MANIFEST } from '../codex-compat/codex-release-manifest.js';
5
+ import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
6
6
  import { runProcess } from '../fsx.js';
7
7
  import { runCodexCurrentCoreDoctorEnvRealProbe } from './codex-current-doctor-real-probe.js';
8
8
  import { runCodexCurrentCoreImageReferencedPathRealProbe } from './codex-current-image-path-real-probe.js';
@@ -18,7 +18,7 @@ export async function runCodexCurrentCoreRealProbes(input) {
18
18
  const codexBin = input.codexBin || await findCurrentCodexRealProbeBinary();
19
19
  const versionText = await readCodexVersionText(codexBin, timeoutMs);
20
20
  const parsedVersion = parseCodexVersionText(versionText);
21
- const currentVersion = parsedVersion === CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion;
21
+ const currentVersion = parsedVersion === CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion;
22
22
  const requestedRaw = input.probes?.length ? input.probes : CODEX_CURRENT_CORE_REAL_PROBE_NAMES;
23
23
  const unknownProbeNames = requestedRaw.filter((name) => !CODEX_CURRENT_CORE_REAL_PROBE_NAMES.includes(name));
24
24
  const requested = [...new Set(requestedRaw.filter((name) => CODEX_CURRENT_CORE_REAL_PROBE_NAMES.includes(name)))];
@@ -27,7 +27,7 @@ export async function runCodexCurrentCoreRealProbes(input) {
27
27
  if (!codexBin)
28
28
  extraBlockers.push('codex_cli_missing');
29
29
  if (!currentVersion)
30
- extraBlockers.push(`codex_${CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion.replaceAll('.', '_')}_required`);
30
+ extraBlockers.push(`codex_${CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion.replaceAll('.', '_')}_required`);
31
31
  if (!codexBin || !currentVersion) {
32
32
  for (const name of requested) {
33
33
  probes[name] = skippedCodexCurrentCoreProbe(!codexBin ? 'codex_cli_missing' : 'codex_current_release_required', { parsed_version: parsedVersion });
@@ -119,7 +119,7 @@ export async function findCurrentCodexRealProbeBinary() {
119
119
  firstExisting = candidate;
120
120
  const versionText = await readCodexVersionText(candidate, 30000);
121
121
  const parsed = parseCodexVersionText(versionText);
122
- if (parsed === CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion)
122
+ if (parsed === CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion)
123
123
  return candidate;
124
124
  }
125
125
  return firstExisting || await findCodexBinary();
@@ -1,5 +1,5 @@
1
1
  import path from 'node:path';
2
- import { CURRENT_CODEX_RELEASE_MANIFEST } from '../codex-compat/codex-release-manifest.js';
2
+ import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
3
3
  import { nowIso, writeJsonAtomic } from '../fsx.js';
4
4
  export const CODEX_CURRENT_CORE_REAL_PROBE_NAMES = [
5
5
  'code_mode_web_search',
@@ -63,7 +63,7 @@ export function buildCodexCurrentCoreRealProbeResult(input) {
63
63
  const overallOk = input.requireReal ? blockers.length === 0 && failed.length === 0 && skipped.length === 0 : failed.length === 0;
64
64
  return {
65
65
  schema: 'sks.codex-current-core-real-probe-result.v1',
66
- target_version: CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion,
66
+ target_version: CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion,
67
67
  compatibility_origin: 'codex-current-core-real-probe-result-v1',
68
68
  compatibility_authority: 'deprecated_non_authoritative_lineage_only',
69
69
  generated_at: nowIso(),
@@ -1,15 +1,15 @@
1
1
  import path from 'node:path';
2
2
  import { findCodexBinary } from '../codex-adapter.js';
3
3
  import { compareSemverLike, parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
4
- import { CURRENT_CODEX_RELEASE_MANIFEST } from '../codex-compat/codex-release-manifest.js';
4
+ import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
5
5
  import { nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
6
6
  import { CODEX_CURRENT_FEATURE_FEATURE_KEYS, probeCodexCurrentFeatureFeatureDetails, probeCodexCurrentFeatureFeatures } from './codex-current-feature-probes.js';
7
7
  export async function detectCodexCurrentFeatureCapability(input = {}) {
8
8
  const fake = process.env.SKS_CODEX_CURRENT_FEATURE_FAKE === '1';
9
9
  const codexBin = fake ? input.codexBin || process.env.CODEX_BIN || 'codex' : input.codexBin || process.env.CODEX_BIN || await findCodexBinary();
10
- const versionText = fake ? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion}`) : await readCodexVersionText(codexBin);
10
+ const versionText = fake ? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion}`) : await readCodexVersionText(codexBin);
11
11
  const parsed = parseCodexVersionText(versionText);
12
- const supportsCurrentContract = Boolean(parsed && compareSemverLike(parsed, CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion) >= 0);
12
+ const supportsCurrentContract = Boolean(parsed && compareSemverLike(parsed, CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion) >= 0);
13
13
  const probeMode = process.env.SKS_CODEX_CURRENT_FEATURE_PROBE === '1' ? 'feature-probe' : 'version-only';
14
14
  const probeTimeoutMs = Number(process.env.SKS_CODEX_CURRENT_FEATURE_PROBE_TIMEOUT_MS || 3000);
15
15
  const probeDetails = probeMode === 'feature-probe'
@@ -77,7 +77,7 @@ function featureStateFor(key, supportsCurrentContract, probeMode, probeDetails)
77
77
  return {
78
78
  supported: true,
79
79
  certainty: 'assumed_by_version',
80
- evidence: [`codex_version>=${CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion}`],
80
+ evidence: [`codex_version>=${CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion}`],
81
81
  blockers: []
82
82
  };
83
83
  }
@@ -49,7 +49,7 @@ export async function runCodexCurrentCoreImageReferencedPathRealProbe(input) {
49
49
  }
50
50
  const outputFile = path.join(tempDir, 'last-message.txt');
51
51
  const prompt = [
52
- 'This is a Current Codex 0.146.0 image path routing probe.',
52
+ 'This is a current Codex image path routing probe.',
53
53
  `Only the image file named ${path.basename(inputB)} is intentionally referenced.`,
54
54
  `Return compact JSON {"referenced_path":"${inputB.replace(/\\/g, '\\\\')}","saw_image":true}.`,
55
55
  'Do not edit files and do not reference any other image path.'
@@ -15,7 +15,7 @@ export async function runCodexCurrentCoreWebSearchRealProbe(input) {
15
15
  return skippedCodexCurrentCoreProbe('codex_cli_missing');
16
16
  const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-current-core-real-probes', `web-search-${Date.now()}`);
17
17
  await ensureDir(tempDir);
18
- await writeTextAtomic(path.join(tempDir, 'README.md'), 'Temporary Current Codex 0.146.0 web-search real probe workspace.\n');
18
+ await writeTextAtomic(path.join(tempDir, 'README.md'), 'Temporary current Codex web-search real probe workspace.\n');
19
19
  const outputFile = path.join(tempDir, 'last-message.txt');
20
20
  const prompt = 'In code mode, use standalone web search to find the title of https://example.com. Return JSON {"used_web_search":true,"answer":"...","sources":[...]}.';
21
21
  const args = buildCodexExecArgs({ root: tempDir, prompt, outputFile, json: true, extraArgs: ['-c', 'mcp_servers={}'] });
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module';
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
- import { CURRENT_CODEX_RELEASE_MANIFEST } from '../codex-compat/codex-release-manifest.js';
5
+ import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
6
6
  export async function detectCodexSdkCapability(input = {}) {
7
7
  let dynamicImportOk = false;
8
8
  let version = null;
@@ -38,7 +38,7 @@ export async function detectCodexSdkCapability(input = {}) {
38
38
  node_compatible: nodeCompatible,
39
39
  dynamic_import_ok: dynamicImportOk,
40
40
  structured_output_fake_smoke: structuredFake,
41
- setup_action: blockers.includes('codex_sdk_unavailable') ? `npm install @openai/codex-sdk@${CURRENT_CODEX_RELEASE_MANIFEST.sdkVersion}` : null,
41
+ setup_action: blockers.includes('codex_sdk_unavailable') ? `npm install @openai/codex-sdk@${CURRENT_CODEX_RUNTIME_CONTRACT.sdkVersion}` : null,
42
42
  blockers
43
43
  };
44
44
  }
@@ -105,8 +105,8 @@ Usage:
105
105
  sks remote worker --stdio
106
106
 
107
107
  This command manages SKS remote readiness, registered machines, and the JSONL worker transport.
108
- It does not install a messaging bridge or create remote sessions. For the supported mobile-first
109
- integration, create a bot with BotFather and run sks telegram --help.
108
+ It does not install a messaging bridge or create remote sessions. For mobile-first workflows,
109
+ use a separately installed independent companion such as Paseo.
110
110
  `);
111
111
  }
112
112
  function fail(error, supported, json) {