sneakoscope 6.4.0 → 6.7.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 (187) hide show
  1. package/README.md +26 -34
  2. package/config/codex-releases/{rust-v0.144.1.json → rust-v0.144.5.json} +5 -5
  3. package/crates/sks-core/Cargo.lock +1 -1
  4. package/crates/sks-core/Cargo.toml +1 -1
  5. package/dist/bin/install.js +1 -1
  6. package/dist/cli/command-manifest-lite.js +2 -3
  7. package/dist/cli/command-registry.js +6 -4
  8. package/dist/cli/help-fast.js +0 -1
  9. package/dist/cli/router.js +24 -3
  10. package/dist/commands/zellij.js +18 -29
  11. package/dist/config/skills-manifest.json +62 -62
  12. package/dist/core/agent-bridge/agent-manifest.js +22 -1
  13. package/dist/core/agents/agent-codex-cockpit.js +1 -81
  14. package/dist/core/agents/agent-effort-policy.js +13 -7
  15. package/dist/core/agents/agent-orchestrator.js +0 -6
  16. package/dist/core/agents/agent-output-validator.js +2 -1
  17. package/dist/core/agents/agent-patch-queue-store.js +0 -8
  18. package/dist/core/agents/agent-proof-evidence.js +0 -6
  19. package/dist/core/agents/agent-worker-pipeline.js +12 -6
  20. package/dist/core/agents/native-cli-worker-runtime.js +1 -16
  21. package/dist/core/agents/native-worker-backend-router.js +1 -1
  22. package/dist/core/bench.js +1 -1
  23. package/dist/core/codex/official-goal-mode.js +4 -2
  24. package/dist/core/codex-app/codex-app-fast-ui-repair.js +11 -17
  25. package/dist/core/codex-app/codex-app-ui-state-snapshot.js +34 -6
  26. package/dist/core/codex-app/menubar/constants.js +0 -1
  27. package/dist/core/codex-app.js +1 -1
  28. package/dist/core/codex-compat/codex-release-manifest.js +5 -5
  29. package/dist/core/codex-control/codex-0139-image-path-real-probe.js +1 -1
  30. package/dist/core/codex-control/codex-0139-web-search-probe.js +1 -1
  31. package/dist/core/codex-control/codex-control-proof.js +1 -0
  32. package/dist/core/codex-control/codex-fake-sdk-adapter.js +1 -1
  33. package/dist/core/codex-control/codex-lb-launch-recovery.js +7 -3
  34. package/dist/core/codex-control/codex-sdk-adapter.js +8 -7
  35. package/dist/core/codex-control/codex-sdk-config-policy.js +4 -24
  36. package/dist/core/codex-control/codex-sdk-env-policy.js +396 -11
  37. package/dist/core/codex-control/codex-task-runner.js +112 -57
  38. package/dist/core/codex-control/gpt-final-arbiter.js +1 -2
  39. package/dist/core/codex-control/python-codex-sdk-adapter.js +38 -15
  40. package/dist/core/codex-lb/codex-lb-tool-catalog.js +3 -3
  41. package/dist/core/codex-native/core-skill-manifest.js +4 -7
  42. package/dist/core/codex-runtime/resolve-codex-runtime.js +199 -0
  43. package/dist/core/commands/agent-bridge-command.js +46 -15
  44. package/dist/core/commands/basic-cli.js +1 -1
  45. package/dist/core/commands/command-utils.js +2 -2
  46. package/dist/core/commands/eval-command.js +19 -2
  47. package/dist/core/commands/goal-command.js +37 -86
  48. package/dist/core/commands/mad-sks-command.js +0 -2
  49. package/dist/core/commands/naruto-command.js +236 -176
  50. package/dist/core/doctor/current-project-guidance.js +1 -1
  51. package/dist/core/doctor/doctor-dirty-planner.js +1 -1
  52. package/dist/core/doctor/retired-managed-residue-missions.js +26 -11
  53. package/dist/core/doctor/retired-managed-residue-private.js +1 -1
  54. package/dist/core/doctor/retired-managed-residue-runtime.js +12 -2
  55. package/dist/core/doctor/retired-managed-residue-state.js +7 -7
  56. package/dist/core/evaluation.js +83 -21
  57. package/dist/core/feature-fixtures.js +4 -7
  58. package/dist/core/feature-registry.js +0 -1
  59. package/dist/core/fsx.js +169 -14
  60. package/dist/core/goal-workflow.js +71 -140
  61. package/dist/core/hooks-runtime/hook-io.js +2 -2
  62. package/dist/core/hooks-runtime.js +228 -50
  63. package/dist/core/init/skills.js +7 -6
  64. package/dist/core/init.js +52 -33
  65. package/dist/core/install/installed-package-smoke.js +1 -1
  66. package/dist/core/lean-engineering-policy.js +25 -23
  67. package/dist/core/locks/file-lock.js +74 -21
  68. package/dist/core/managed-assets/managed-assets-manifest.js +1 -1
  69. package/dist/core/mcp-config/health-check.js +7 -2
  70. package/dist/core/mission.js +99 -3
  71. package/dist/core/ops/upgrade-migration-fixtures.js +30 -2
  72. package/dist/core/pipeline-internals/runtime-core.js +67 -95
  73. package/dist/core/pipeline-internals/runtime-gates.js +25 -6
  74. package/dist/core/proof/fake-real-proof-policy.js +32 -9
  75. package/dist/core/proof/route-proof-gate.js +49 -1
  76. package/dist/core/provider/model-router.js +2 -0
  77. package/dist/core/questions.js +31 -5
  78. package/dist/core/recallpulse.js +2 -2
  79. package/dist/core/release/canonical-test-proof.js +135 -0
  80. package/dist/core/release/release-closure-contract.js +1 -0
  81. package/dist/core/release/release-closure-validation.js +25 -12
  82. package/dist/core/release/release-closure.js +34 -5
  83. package/dist/core/release/release-gate-contract.js +4 -3
  84. package/dist/core/release/release-gate-dag.js +4 -2
  85. package/dist/core/release/release-pack-content-scanner.js +7 -6
  86. package/dist/core/release/release-pack-receipt.js +33 -12
  87. package/dist/core/release/release-real-contract.js +41 -2
  88. package/dist/core/retention.js +95 -16
  89. package/dist/core/routes/constants.js +1 -1
  90. package/dist/core/routes/dollar-manifest-lite.js +1 -1
  91. package/dist/core/routes.js +18 -20
  92. package/dist/core/safety/command-contract/contracts.js +33 -0
  93. package/dist/core/safety/command-contract/types.js +1 -1
  94. package/dist/core/safety/ssot-guard.js +1 -54
  95. package/dist/core/stop-gate/stop-gate-check.js +0 -14
  96. package/dist/core/stop-gate/stop-gate-writer.js +0 -4
  97. package/dist/core/strategy/adhd-orchestrating-gate.js +2 -2
  98. package/dist/core/subagents/agent-catalog.js +28 -5
  99. package/dist/core/subagents/model-policy.js +52 -11
  100. package/dist/core/subagents/naruto-help-contract.js +2 -1
  101. package/dist/core/subagents/naruto-proof-projection.js +449 -0
  102. package/dist/core/subagents/official-subagent-preparation.js +641 -51
  103. package/dist/core/subagents/official-subagent-prompt.js +16 -6
  104. package/dist/core/subagents/official-subagent-runner.js +132 -12
  105. package/dist/core/subagents/subagent-evidence.js +44 -8
  106. package/dist/core/subagents/wave-lifecycle.js +238 -0
  107. package/dist/core/update-check.js +13 -4
  108. package/dist/core/verification/machine-feedback.js +39 -19
  109. package/dist/core/version.js +1 -1
  110. package/dist/core/zellij/zellij-lane-renderer.js +19 -19
  111. package/dist/core/zellij/zellij-official-subagent-activity.js +2 -0
  112. package/dist/core/zellij/zellij-right-column-manager.js +6 -55
  113. package/dist/core/zellij/zellij-slot-column-anchor.js +4 -5
  114. package/dist/core/zellij/zellij-slot-pane-renderer.js +1 -1
  115. package/dist/core/zellij/zellij-ui-mode.js +0 -7
  116. package/dist/core/zellij/zellij-worker-pane-manager.js +3 -11
  117. package/dist/native/sks-menubar/Sources/AppDelegate.swift +0 -1
  118. package/dist/native/sks-menubar/Sources/NotificationCoordinator.swift +1 -3
  119. package/dist/native/sks-menubar/Sources/OverviewViewController.swift +194 -24
  120. package/dist/native/sks-menubar/Sources/ProcessClient.swift +49 -4
  121. package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +38 -10
  122. package/dist/native/sks-menubar/Sources/StatusItemController.swift +73 -11
  123. package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +27 -2
  124. package/dist/scripts/architecture-guard-check.js +1 -9
  125. package/dist/scripts/canonical-test-runner.js +51 -8
  126. package/dist/scripts/check-architecture.js +11 -1
  127. package/dist/scripts/cli-output-consistency-check.js +0 -2
  128. package/dist/scripts/codex-0144-app-server-v2-check.js +4 -4
  129. package/dist/scripts/codex-0144-binary-identity-check.js +10 -4
  130. package/dist/scripts/codex-0144-capability-check.js +5 -5
  131. package/dist/scripts/codex-0144-policy-check.js +4 -0
  132. package/dist/scripts/codex-control-all-pipelines-check.js +2 -1
  133. package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +3 -3
  134. package/dist/scripts/codex-sdk-all-pipelines-check.js +2 -1
  135. package/dist/scripts/codex-sdk-real-smoke-check.js +20 -2
  136. package/dist/scripts/current-command-surface-check.js +5 -3
  137. package/dist/scripts/current-surface-update-e2e-check.js +2 -2
  138. package/dist/scripts/docs-truthfulness-check.js +8 -6
  139. package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +3 -2
  140. package/dist/scripts/gate-policy-audit-check.js +7 -1
  141. package/dist/scripts/harness-benchmark-check.js +4 -4
  142. package/dist/scripts/hook-latency-quantum-check.js +2 -2
  143. package/dist/scripts/legacy-gate-purge-check.js +4 -2
  144. package/dist/scripts/loop-directive-check-lib.js +14 -13
  145. package/dist/scripts/naruto-codex-e2e-check.js +2 -2
  146. package/dist/scripts/naruto-ssot-gate-aliases-check.js +9 -0
  147. package/dist/scripts/naruto-ssot-pipeline-default-check.js +10 -0
  148. package/dist/scripts/naruto-ssot-route-normalization-check.js +8 -0
  149. package/dist/scripts/naruto-ssot-routing-check.js +12 -0
  150. package/dist/scripts/product-design-plugin-routing-check.js +4 -9
  151. package/dist/scripts/release-affected-selector-check.js +7 -1
  152. package/dist/scripts/release-check-stamp.js +151 -18
  153. package/dist/scripts/release-dynamic-presets-check.js +5 -2
  154. package/dist/scripts/release-metadata-1-19-check.js +4 -0
  155. package/dist/scripts/release-real-check.js +21 -3
  156. package/dist/scripts/sks-menubar-install-check.js +5 -5
  157. package/dist/scripts/upgrade-migration-matrix-check.js +278 -5
  158. package/dist/scripts/zellij-developer-controls-check.js +3 -5
  159. package/dist/scripts/zellij-initial-main-only-blackbox.js +3 -8
  160. package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +1 -2
  161. package/dist/scripts/zellij-right-column-headless-overflow-check.js +1 -1
  162. package/dist/scripts/zellij-right-column-manager-check.js +3 -4
  163. package/dist/scripts/zellij-slot-only-ui-check.js +2 -2
  164. package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +1 -2
  165. package/docs/demo.tape +1 -1
  166. package/infra-harness-gates.json +0 -27
  167. package/package.json +11 -6
  168. package/release-gates.v2.json +150 -22
  169. package/schemas/codex/agent-result.schema.json +4 -0
  170. package/schemas/codex/app-server-0.144/codex_app_server_protocol.v2.schemas.json +1 -18812
  171. package/schemas/codex/codex-0139-real-probe-result.schema.json +2 -2
  172. package/schemas/zellij/zellij-right-column-state.schema.json +0 -1
  173. package/dist/core/commands/ui-command.js +0 -198
  174. package/dist/core/loops/goal-to-loop-compat.js +0 -22
  175. package/dist/core/naruto/naruto-allocation-policy.js +0 -98
  176. package/dist/core/naruto/naruto-finalizer.js +0 -22
  177. package/dist/core/naruto/naruto-gpt-final-pack.js +0 -50
  178. package/dist/core/naruto/naruto-real-worker-child.js +0 -209
  179. package/dist/core/naruto/naruto-real-worker-runtime.js +0 -178
  180. package/dist/core/naruto/naruto-rebalance-policy.js +0 -47
  181. package/dist/core/naruto/naruto-verification-pool.js +0 -17
  182. package/dist/core/ui/dashboard-html.js +0 -110
  183. package/dist/core/zellij/zellij-dashboard-pane.js +0 -70
  184. package/dist/core/zellij/zellij-dashboard-renderer.js +0 -59
  185. package/dist/core/zellij/zellij-naruto-dashboard.js +0 -44
  186. package/dist/scripts/zellij-dashboard-pane-check.js +0 -69
  187. package/dist/scripts/zellij-dashboard-watch.js +0 -40
@@ -71,11 +71,17 @@ export function decideOfficialSubagentModel(input = {}) {
71
71
  const role = String(persona.role || '');
72
72
  const agentId = String(input.agentId || persona.id || 'subagent');
73
73
  const routingRole = [agentId, persona.naruto_role, persona.work_kind, role].filter(Boolean).join(' ');
74
- const taskClass = /(?:implementation_specialist|ui_implementer|native_app_specialist)/i.test(routingRole)
75
- ? 'implementation'
76
- : /(?:explorer|docs_maintainer|long_context_analyst|computer_use_operator|browser_use_operator|image_generation_operator)/i.test(routingRole)
77
- ? 'context_tools'
78
- : undefined;
74
+ const promptIsDocsExploration = /\b(?:read|scan|explore|compare|summarize|review)\b[^\n]{0,64}\b(?:docs?|documentation|manual|notes?|references?)\b/i.test(prompt);
75
+ const promptIsFocusedJudgment = !promptIsDocsExploration
76
+ && /^(?:\s*)(?:review|audit|debug(?:ger|ging)?|diagnos|investigat|plan|assess)\b|\b(?:security|database|release|production|high[- ]?risk)\b[^\n]{0,48}\b(?:review|audit|decision|plan|assessment)\b/i.test(prompt);
77
+ const taskClass = promptIsFocusedJudgment
78
+ || /(?:debugger|expert|_reviewer|research_synthesizer)/i.test(routingRole)
79
+ ? 'judgment'
80
+ : /(?:implementation_specialist|ui_implementer|native_app_specialist)/i.test(routingRole)
81
+ ? 'implementation'
82
+ : /(?:explorer|docs_maintainer|long_context_analyst|computer_use_operator|browser_use_operator|image_generation_operator)/i.test(routingRole)
83
+ ? 'context_tools'
84
+ : undefined;
79
85
  const routed = decideSubagentModel({
80
86
  title: routingRole,
81
87
  description: [prompt, persona.risk_focus, persona.write_policy].filter(Boolean).join(' '),
@@ -106,8 +112,8 @@ export function decideOfficialSubagentModel(input = {}) {
106
112
  reason: routed.reason,
107
113
  dynamic: true,
108
114
  escalation_triggers: [
109
- 'review, debugging, planning, architecture, integration, security, database, research, release, or ambiguity selects Sol Max',
110
- 'mixed tool-and-judgment work is split; an unsplittable slice selects Sol Max',
115
+ 'focused review, debugging, planning, integration, security, database, research, release, or unresolved ambiguity selects Sol Max',
116
+ 'incidental judgment vocabulary does not override a clearly classified implementation or context/tools slice',
111
117
  'requested model/effort profile unavailable blocks instead of silently falling back'
112
118
  ],
113
119
  downshift_triggers: [
@@ -1158,9 +1158,6 @@ function enforceWorkerQualityProtocolForSlice(result, slice) {
1158
1158
  const kind = String(slice?.work_item_kind || result?.work_item_kind || '').toLowerCase();
1159
1159
  const text = [kind, slice?.id, slice?.title].join(' ').toLowerCase();
1160
1160
  const blockers = [];
1161
- if ((kind === 'bugfix' || /\b(fix|bug|regression|broken|failure|crash|error)\b|버그|회귀/.test(text)) && !validRegressionProof(result.regression_proof || firstEnvelopeField(result, 'regression_proof'))) {
1162
- blockers.push('tdd_evidence_missing');
1163
- }
1164
1161
  if ((kind === 'conflict_resolution' || /\b(repair|conflict|rebase|rollback)\b|수리|충돌/.test(text)) && !(result.repair_hypothesis || firstEnvelopeField(result, 'repair_hypothesis'))) {
1165
1162
  blockers.push('repair_without_hypothesis');
1166
1163
  }
@@ -1176,9 +1173,6 @@ function enforceWorkerQualityProtocolForSlice(result, slice) {
1176
1173
  function firstEnvelopeField(result, field) {
1177
1174
  return (Array.isArray(result?.patch_envelopes) ? result.patch_envelopes : []).find((envelope) => envelope?.[field])?.[field] || null;
1178
1175
  }
1179
- function validRegressionProof(proof) {
1180
- return Boolean(proof && proof.failed_before === true && proof.passed_after === true && String(proof.test_file || '').trim());
1181
- }
1182
1176
  function normalizePathList(values) {
1183
1177
  return (Array.isArray(values) ? values : []).map((file) => String(file || '').replace(/\\/g, '/').replace(/^\.\/+/, '').replace(/\/+$/, '')).filter(Boolean);
1184
1178
  }
@@ -62,7 +62,8 @@ export const AGENT_RESULT_RUNTIME_SCHEMA = {
62
62
  required: ['status', 'checks'],
63
63
  properties: {
64
64
  status: { type: 'string' },
65
- checks: { type: 'array', items: { type: 'string' } }
65
+ checks: { type: 'array', items: { type: 'string' } },
66
+ reason: { type: 'string', minLength: 1 }
66
67
  },
67
68
  additionalProperties: false
68
69
  },
@@ -64,7 +64,6 @@ export class PersistentAgentPatchQueueStore {
64
64
  ...(impact.cochange_required?.length && !cochangeAck ? [`impact_scan_cochange_missing:${impact.cochange_required.slice(0, 5).join(',')}`] : []),
65
65
  ...((diffQuality.errors || []).map((issue) => `diff_quality:${issue}`)),
66
66
  ...(feedback.ok === false ? ['machine_feedback_failed'] : []),
67
- ...(isBugfixKind(context.work_item_kind, envelope.task_slice_id) && !validRegressionProof(envelope.regression_proof || context.regression_proof) ? ['tdd_evidence_missing'] : []),
68
67
  ...(isRepairKind(context.work_item_kind, envelope.task_slice_id) && !(envelope.repair_hypothesis || context.repair_hypothesis) ? ['repair_without_hypothesis'] : [])
69
68
  ];
70
69
  return {
@@ -145,17 +144,10 @@ export class PersistentAgentPatchQueueStore {
145
144
  await appendJsonlMany(path.join(this.artifactDir, AGENT_PATCH_QUEUE_EVENTS_ARTIFACT), events.filter(Boolean));
146
145
  }
147
146
  }
148
- function isBugfixKind(kind, id) {
149
- const text = `${String(kind || '')} ${String(id || '')}`.toLowerCase();
150
- return /\b(bugfix|fix|bug|regression|broken|failure|crash|error)\b|버그|회귀/.test(text);
151
- }
152
147
  function isRepairKind(kind, id) {
153
148
  const text = `${String(kind || '')} ${String(id || '')}`.toLowerCase();
154
149
  return /\b(conflict_resolution|repair|conflict|rebase|rollback)\b|수리|충돌/.test(text);
155
150
  }
156
- function validRegressionProof(proof) {
157
- return Boolean(proof && proof.failed_before === true && proof.passed_after === true && String(proof.test_file || '').trim());
158
- }
159
151
  function changedFilesForEnvelope(envelope) {
160
152
  const files = envelope.git_worktree?.changed_files?.length
161
153
  ? envelope.git_worktree.changed_files
@@ -37,8 +37,6 @@ export async function writeAgentProofEvidence(root, input) {
37
37
  const narutoConcurrencyGovernor = await readJson(path.join(root, 'naruto-concurrency-governor.json'), null);
38
38
  const narutoActivePool = await readJson(path.join(root, 'naruto-active-pool.json'), null);
39
39
  const narutoVerificationDag = await readJson(path.join(root, 'naruto-verification-dag.json'), null);
40
- const narutoGptFinalPack = await readJson(path.join(root, 'naruto-gpt-final-pack.json'), null);
41
- const narutoZellijDashboard = await readJson(path.join(root, 'naruto-zellij-dashboard.json'), null);
42
40
  const localParticipated = localCollaborationParticipated(input.results || []) || Number(gptFinalArbiter?.local_outputs_count || 0) > 0;
43
41
  const finalGptPatchStage = input.finalGptPatchStage || null;
44
42
  const localFinalGate = gptFinalArbiter?.final_gate || evaluateLocalCollaborationFinalGate({
@@ -224,8 +222,6 @@ export async function writeAgentProofEvidence(root, input) {
224
222
  ...(isNarutoRoute && !narutoActivePool ? ['naruto_active_pool_missing'] : []),
225
223
  ...(isNarutoRoute && narutoActivePool?.ok === false ? narutoActivePool.blockers || ['naruto_active_pool_not_ok'] : []),
226
224
  ...(isNarutoRoute && !narutoVerificationDag ? ['naruto_verification_dag_missing'] : []),
227
- ...(isNarutoRoute && !narutoGptFinalPack ? ['naruto_gpt_final_pack_missing'] : []),
228
- ...(isNarutoRoute && !narutoZellijDashboard ? ['naruto_zellij_dashboard_missing'] : []),
229
225
  ...changedFileLeaseBlockers
230
226
  ];
231
227
  const evidence = {
@@ -304,8 +300,6 @@ export async function writeAgentProofEvidence(root, input) {
304
300
  naruto_active_pool: narutoActivePool ? 'naruto-active-pool.json' : null,
305
301
  naruto_active_pool_refill_events: Number(narutoActivePool?.refill_events || 0),
306
302
  naruto_verification_dag: narutoVerificationDag ? 'naruto-verification-dag.json' : null,
307
- naruto_gpt_final_pack: narutoGptFinalPack ? 'naruto-gpt-final-pack.json' : null,
308
- naruto_zellij_dashboard: narutoZellijDashboard ? 'naruto-zellij-dashboard.json' : null,
309
303
  patch_handoff_runtime: patchHandoff ? 'agent-patch-handoff-runtime.json' : null,
310
304
  patch_queue: patchHandoff ? 'agent-patch-queue.json' : null,
311
305
  patch_queue_events: patchHandoff ? 'agent-patch-queue-events.jsonl' : null,
@@ -100,17 +100,22 @@ function qualityProtocolBlockers(result) {
100
100
  return [];
101
101
  const kind = String(result.work_item_kind || result.naruto_runtime?.work_item_kind || '').toLowerCase();
102
102
  const text = [kind, result.task_slice_id].join(' ').toLowerCase();
103
- const proof = result.regression_proof || result.patch_envelopes?.find((envelope) => envelope.regression_proof)?.regression_proof || null;
104
103
  const repair = result.repair_hypothesis || result.patch_envelopes?.find((envelope) => envelope.repair_hypothesis)?.repair_hypothesis || null;
105
104
  const blockers = [];
106
- if ((kind === 'bugfix' || /\b(fix|bug|regression|broken|failure|crash|error)\b|버그|회귀/.test(text)) && !validRegressionProof(proof))
107
- blockers.push('tdd_evidence_missing');
105
+ if (!validWriteVerification(result.verification))
106
+ blockers.push('verification_evidence_missing');
108
107
  if ((kind === 'conflict_resolution' || /\b(repair|conflict|rebase|rollback)\b|수리|충돌/.test(text)) && !repair)
109
108
  blockers.push('repair_without_hypothesis');
110
109
  return blockers;
111
110
  }
112
- function validRegressionProof(proof) {
113
- return Boolean(proof && proof.failed_before === true && proof.passed_after === true && String(proof.test_file || '').trim());
111
+ function validWriteVerification(verification) {
112
+ const status = String(verification?.status || '').trim().toLowerCase();
113
+ const checks = Array.isArray(verification?.checks)
114
+ ? verification.checks.map((check) => String(check || '').trim()).filter(Boolean)
115
+ : [];
116
+ if (status === 'passed')
117
+ return checks.length > 0;
118
+ return status === 'not_applicable' && Boolean(String(verification?.reason || '').trim());
114
119
  }
115
120
  export function agentWorkerPipelineContract() {
116
121
  return {
@@ -169,7 +174,8 @@ function isRecord(value) {
169
174
  function normalizeVerification(value) {
170
175
  return {
171
176
  status: String(value?.status || 'not_run'),
172
- checks: Array.isArray(value?.checks) ? value.checks : []
177
+ checks: Array.isArray(value?.checks) ? value.checks : [],
178
+ ...(String(value?.reason || '').trim() ? { reason: String(value.reason).trim() } : {})
173
179
  };
174
180
  }
175
181
  function acceptsNoPatchReadOnlyOrNoop(value) {
@@ -401,22 +401,7 @@ class NativeCliWorkerRuntimeRecorder {
401
401
  projectRoot: input.ctx.opts.projectRoot || this.input.projectRoot || input.ctx.opts.cwd,
402
402
  rightColumnMode: 'spawn-on-first-worker',
403
403
  visiblePaneCap: this.zellijVisiblePaneCap(input.ctx.opts),
404
- plannedAgentCount: this.input.targetActiveSlots,
405
- dashboardSnapshot: {
406
- mode: this.input.route || '$Naruto',
407
- backend_counts: { [this.input.backend]: this.input.targetActiveSlots },
408
- placement_counts: {
409
- 'zellij-pane': 0,
410
- headless_by_design_viewport_ui: this.input.targetActiveSlots
411
- },
412
- active_workers: this.input.targetActiveSlots,
413
- visible_panes: Number(process.env.SKS_ZELLIJ_VIEWPORTS || 1),
414
- headless_workers: this.input.targetActiveSlots,
415
- queue_depth: Math.max(0, this.input.requestedAgents - this.input.targetActiveSlots),
416
- local_llm: { tps: 0, queue: 0 },
417
- gpt_final_status: 'pending',
418
- gate_progress: 'worker-spawn'
419
- }
404
+ plannedAgentCount: this.input.targetActiveSlots
420
405
  };
421
406
  let paneRecord = await openHeadlessByDesignViewportWorker(paneInput);
422
407
  const zellijRequired = process.env.SKS_REQUIRE_ZELLIJ === '1';
@@ -418,7 +418,7 @@ function buildWorkerPrompt(slice) {
418
418
  ? 'Quality gates run before queue acceptance: impact-scan requires cochanged callers for exported signature changes, machine-feedback runs type/lint/related tests, diff-quality blocks dead exports, and compiled mistake rules block repeated mistakes.'
419
419
  : '',
420
420
  write.length
421
- ? 'If this is a bugfix, create a regression test first and include regression_proof with failed_before true and passed_after true. For repair work, include repair_hypothesis before patching.'
421
+ ? 'Every write result must report verification status passed with at least one concrete check, or status not_applicable with a specific reason. For a reproducible bug or changed observable behavior, add the smallest regression check that would catch it. Do not manufacture a dedicated test when a smaller real check is sufficient. For repair work, include repair_hypothesis before patching.'
422
422
  : '',
423
423
  leanEngineeringCompactText(),
424
424
  'Required JSON fields: status, summary, findings, changed_files, patch_envelopes, verification, rollback_notes, blockers.'
@@ -343,7 +343,7 @@ export async function runLeanPolicyBench(root = process.cwd()) {
343
343
  async function fakeGptFinalScenario(candidate, leanEnabled) {
344
344
  const prompt = [
345
345
  leanEnabled ? leanEngineeringCompactText() : 'Baseline implementation context without lean policy.',
346
- leanEnabled ? 'Lean review: evaluate over-build, dependency, fallback, root-cause, and validation safety.' : 'Review only catastrophic safety issues.',
346
+ leanEnabled ? 'Apply the Core Engineering Directive to the candidate and the available evidence.' : 'Review only catastrophic safety issues.',
347
347
  `Candidate: ${candidate}`
348
348
  ].join('\n');
349
349
  const result = await runFakeCodexSdkTask({
@@ -20,7 +20,7 @@ export async function detectOfficialGoalMode(opts = {}) {
20
20
  ok: true,
21
21
  official_goal_available: official,
22
22
  default_enabled: official,
23
- mode: official ? 'official_goal_default' : 'sks_goal_fallback',
23
+ mode: official ? 'official_goal_default' : 'official_goal_unavailable',
24
24
  codex_help_checked: Boolean(helpText),
25
25
  codex_goal_help_checked: Boolean(goalHelpText),
26
26
  codex_features_checked: Boolean(featuresText),
@@ -28,9 +28,11 @@ export async function detectOfficialGoalMode(opts = {}) {
28
28
  codex_goals_feature_enabled: goalsFeature,
29
29
  config_goal_defaults_detected: configDefault,
30
30
  blockers: [],
31
- warnings: official ? [] : ['official_goal_unavailable_using_sks_goal_fallback']
31
+ warnings: official ? [] : ['official_goal_unavailable_no_fallback']
32
32
  };
33
33
  }
34
+ // Capability evidence for non-Goal routes. This records whether the active
35
+ // Codex runtime exposes native Goal; it never creates or controls a goal.
34
36
  export async function writeOfficialGoalModeArtifact(dir, detection) {
35
37
  const artifact = path.join(dir, 'goal-mode-applied.json');
36
38
  await writeJsonAtomic(artifact, detection);
@@ -1,18 +1,16 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { ensureDir, nowIso, readText, sha256, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
4
- import { codexHome, scanProjectLocalForbiddenKeys, snapshotCodexAppUiState } from './codex-app-ui-state-snapshot.js';
4
+ import { codexHome, isSksOwnedGlobalUiLock, scanProjectLocalForbiddenKeys, snapshotCodexAppUiState } from './codex-app-ui-state-snapshot.js';
5
5
  import { assertCodexAppUiMutationAllowed } from './codex-app-ui-clobber-guard.js';
6
6
  import { codexProviderModelUiStatus } from '../codex-app.js';
7
7
  import { cleanupCodexConfigBackups } from '../codex/codex-config-toml.js';
8
8
  export const CODEX_APP_FAST_UI_REPAIR_SCHEMA = 'sks.codex-app-fast-ui-repair.v1';
9
- // `service_tier = "fast"` is the current Codex Desktop default-selection
10
- // contract. Removing it would silently turn Fast mode off, not restore the
11
- // selector. Only legacy SKS model/effort pins lock the native picker.
12
- const FAST_UI_TOP_LEVEL_RE = /^\s*(?:model|model_reasoning_effort)\s*=/;
13
- const FAST_UI_FEATURE_LINE_RE = /^\s*fast_mode\s*=/;
9
+ // `service_tier = "fast"` and `[features].fast_mode = true` are capability
10
+ // signals. Removing either would turn Fast off rather than restore native UI.
11
+ // Only provenance-backed SKS global provider/model/reasoning locks are removed.
12
+ const FAST_UI_TOP_LEVEL_RE = /^\s*(?:model_provider|model|model_reasoning_effort)\s*=/;
14
13
  const FAST_UI_LEGACY_TABLES = new Set(['user.fast_mode', 'profiles.sks-fast-high']);
15
- const SKS_CAUSED_RE = /(?:SKS|Sneakoscope|codex-lb|sks-mad|sks fast)/i;
16
14
  export async function repairCodexAppFastUi(root = process.cwd(), input = {}) {
17
15
  const resolvedRoot = path.resolve(root);
18
16
  const home = codexHome(input.codexHome === undefined ? {} : { codexHome: input.codexHome });
@@ -165,16 +163,12 @@ function stripProjectLocalForbiddenKeys(text) {
165
163
  });
166
164
  }
167
165
  function stripSksCausedHostOwnedLines(text) {
168
- const topLevel = String(text || '').split(/\n\s*\[/)[0] || '';
169
- const sksManagedTopLevel = SKS_CAUSED_RE.test(topLevel);
170
- const sksManagedDocument = SKS_CAUSED_RE.test(String(text || ''));
171
- const stripped = stripMatchingLines(text, (line, table, previous, next) => {
166
+ const sourceLines = String(text || '').split(/\r?\n/);
167
+ const stripped = stripMatchingLines(text, (line, table, _previous, _next, index) => {
172
168
  const isLegacyFastTable = table ? FAST_UI_LEGACY_TABLES.has(table) : false;
173
- const isFastUiLine = FAST_UI_TOP_LEVEL_RE.test(line)
174
- || (table === 'features' && FAST_UI_FEATURE_LINE_RE.test(line))
175
- || isLegacyFastTable;
176
- const sksMarked = (!table && sksManagedTopLevel) || (isLegacyFastTable && sksManagedDocument) || SKS_CAUSED_RE.test(line) || SKS_CAUSED_RE.test(previous) || SKS_CAUSED_RE.test(next);
177
- return isFastUiLine && sksMarked;
169
+ if (isLegacyFastTable)
170
+ return true;
171
+ return !table && FAST_UI_TOP_LEVEL_RE.test(line) && isSksOwnedGlobalUiLock(sourceLines, index);
178
172
  });
179
173
  return stripped;
180
174
  }
@@ -194,7 +188,7 @@ function stripMatchingLines(text, shouldRemove) {
194
188
  continue;
195
189
  }
196
190
  const currentTable = tableMatch?.[1] || table;
197
- const remove = shouldRemove(line, currentTable, lines[i - 1] || '', lines[i + 1] || '');
191
+ const remove = shouldRemove(line, currentTable, lines[i - 1] || '', lines[i + 1] || '', i);
198
192
  if (remove) {
199
193
  removedKeys.push(tableMatch?.[1] || line.match(/^\s*([A-Za-z0-9_.-]+)\s*=/)?.[1] || '<table-body>');
200
194
  if (tableMatch?.[1]) {
@@ -13,6 +13,11 @@ export const PROJECT_LOCAL_FORBIDDEN_CODEX_KEYS = [
13
13
  ];
14
14
  const HOST_OWNED_KEY_RE = /^(?:model|model_reasoning_effort|openai_base_url|chatgpt_base_url|apps_mcp_product_sku|model_provider|model_providers(?:\.|$)|notify|profile|profiles(?:\.|$)|experimental_realtime_ws_base_url|otel(?:\.|$)|features\.fast_mode|service_tier|user\.fast_mode(?:\.|$))/;
15
15
  const SECRET_KEY_RE = /(?:key|token|secret|password|credential|cookie|authorization|auth|bearer|refresh|access|headers?|env)/i;
16
+ const SKS_GLOBAL_UI_LOCK_KEYS = new Set(['model_provider', 'model', 'model_reasoning_effort']);
17
+ const SKS_GLOBAL_UI_LOCK_CONTEXT_KEYS = new Set([
18
+ 'service_tier', 'model_provider', 'model', 'model_reasoning_effort',
19
+ 'approval_policy', 'sandbox_mode', 'web_search', 'notify', 'preferred_auth_method'
20
+ ]);
16
21
  export function codexHome(input) {
17
22
  return path.resolve(String(input?.codexHome || process.env.CODEX_HOME || path.join(os.homedir(), '.codex')));
18
23
  }
@@ -39,7 +44,7 @@ export async function snapshotCodexAppUiState(root = process.cwd(), input = {})
39
44
  return true;
40
45
  if (signal.key_path.startsWith('user.fast_mode') && /hidden|fixed|disabled|false/i.test(signal.value_preview))
41
46
  return true;
42
- if ((signal.key_path === 'model' || signal.key_path === 'model_reasoning_effort') && signal.sks_related)
47
+ if (SKS_GLOBAL_UI_LOCK_KEYS.has(signal.key_path) && signal.sks_related)
43
48
  return true;
44
49
  return false;
45
50
  });
@@ -96,9 +101,6 @@ export function scanTomlSignals(text) {
96
101
  const tables = [];
97
102
  let table = null;
98
103
  const lines = text.split(/\r?\n/);
99
- const firstTableIndex = lines.findIndex((line) => /^\s*\[/.test(line));
100
- const topLevelLines = firstTableIndex === -1 ? lines : lines.slice(0, firstTableIndex);
101
- const sksManagedTopLevel = topLevelLines.some((line) => /(?:SKS|Sneakoscope|codex-lb|sks fast)/i.test(line));
102
104
  lines.forEach((lineText, index) => {
103
105
  const tableMatch = lineText.match(/^\s*\[([^\]]+)\]\s*(?:#.*)?$/);
104
106
  if (tableMatch?.[1]) {
@@ -124,12 +126,38 @@ export function scanTomlSignals(text) {
124
126
  host_owned: HOST_OWNED_KEY_RE.test(keyPath),
125
127
  fast_ui_related: /(?:fast_mode|service_tier|model_reasoning_effort|^model$)/i.test(keyPath) || /(?:fast|priority|default)/i.test(value),
126
128
  provider_related: /(?:provider|base_url|auth|profile|openai|chatgpt|codex-lb)/i.test(lowerPath),
127
- sks_related: /(?:sks|sneakoscope|codex-lb)/i.test(lineText)
128
- || (table == null && sksManagedTopLevel && (key === 'model' || key === 'model_reasoning_effort'))
129
+ sks_related: /(?:SKS|Sneakoscope|sks-mad|sks fast)/i.test(lineText)
130
+ || (table == null && isSksOwnedGlobalUiLock(lines, index))
129
131
  });
130
132
  });
131
133
  return { signals, tables: [...new Set(tables)] };
132
134
  }
135
+ export function isSksOwnedGlobalUiLock(lines, index) {
136
+ const current = String(lines[index] || '');
137
+ const key = current.match(/^\s*([A-Za-z0-9_-]+)\s*=/)?.[1] || '';
138
+ if (!SKS_GLOBAL_UI_LOCK_KEYS.has(key))
139
+ return false;
140
+ const inlineComment = current.includes('#') ? current.slice(current.indexOf('#')) : '';
141
+ if (isSksGlobalUiLockMarker(inlineComment))
142
+ return true;
143
+ const lowerBound = Math.max(0, index - 16);
144
+ for (let cursor = index - 1; cursor >= lowerBound; cursor -= 1) {
145
+ const candidate = String(lines[cursor] || '').trim();
146
+ if (!candidate)
147
+ continue;
148
+ if (candidate.startsWith('#'))
149
+ return isSksGlobalUiLockMarker(candidate);
150
+ if (/^\s*\[/.test(candidate))
151
+ return false;
152
+ const previousKey = candidate.match(/^([A-Za-z0-9_-]+)\s*=/)?.[1] || '';
153
+ if (!SKS_GLOBAL_UI_LOCK_CONTEXT_KEYS.has(previousKey))
154
+ return false;
155
+ }
156
+ return false;
157
+ }
158
+ function isSksGlobalUiLockMarker(value) {
159
+ return /^#\s*(?:SKS|Sneakoscope)\b.*(?:moved machine-local Codex config|forced fast UI|legacy (?:provider|model|reasoning) lock|managed (?:Codex )?(?:provider|model|reasoning)|codex-lb (?:provider|model|reasoning))/i.test(String(value || '').trim());
160
+ }
133
161
  export function scanProjectLocalForbiddenKeys(text) {
134
162
  const { signals } = scanTomlSignals(text);
135
163
  return [...new Set(signals
@@ -4,7 +4,6 @@ export const CONTROL_CENTER_PREFERRED_POSITION = 360;
4
4
  export const SECRET_LAUNCH_ENV_KEYS = ['CODEX_LB_API_KEY', 'OPENROUTER_API_KEY'];
5
5
  export const MENU_ITEMS = [
6
6
  'Open SKS Control Center',
7
- 'Open Dashboard',
8
7
  'Pending approvals',
9
8
  'Check for Updates',
10
9
  'View Last Operation',
@@ -600,7 +600,7 @@ export function codexAppGuidance({ appInstalled, codex, mcpList, featureList, re
600
600
  lines.push(`Browser tooling is visible via ${source}; SKS web verification still gates on the Codex Chrome Extension before proceeding.`);
601
601
  }
602
602
  if (browserUseReady && !browserUseMcpListed) {
603
- lines.push('Browser Use plugin files are installed, but `codex mcp list` does not list a browser-use MCP server. Treat Browser Use as plugin-scoped, not as SKS UI verification evidence.');
603
+ lines.push('Browser Use plugin files are installed, but `codex mcp list` does not list a browser-use MCP server. Treat Browser Use as plugin-scoped, not as SKS browser verification evidence.');
604
604
  }
605
605
  if (!lines.length)
606
606
  lines.push('Codex App, Codex CLI, Chrome Extension, native Computer Use, Browser tooling, and image generation checks look ready. Web UI E2E uses the Chrome Extension path; native non-web visual evidence uses Computer Use; generated image evidence still requires $imagegen/gpt-image-2 output.');
@@ -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.144.1',
7
- requiredCliVersion: '0.144.1',
8
- sdkVersion: '0.144.1',
9
- minimumSupportedVersion: '0.144.1',
6
+ targetTag: 'rust-v0.144.5',
7
+ requiredCliVersion: '0.144.5',
8
+ sdkVersion: '0.144.5',
9
+ minimumSupportedVersion: '0.144.5',
10
10
  protocolMode: 'app-server-v2',
11
11
  generatedSchemaSha256: '2b3f14fa2e728f77a16385ff39f3a1d85ab255c1020498a85c1c0fb24f3d2f3c',
12
- upstreamCommit: 'rust-v0.144.1',
12
+ upstreamCommit: 'rust-v0.144.5',
13
13
  featurePolicies: {
14
14
  multiAgentMode: 'probe',
15
15
  indexedWebSearch: 'probe',
@@ -48,7 +48,7 @@ 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.144.1 image path routing probe.',
51
+ 'This is a Codex 0.144.5 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.'
@@ -14,7 +14,7 @@ export async function runCodex0139WebSearchRealProbe(input) {
14
14
  return skippedCodex0139Probe('codex_cli_missing');
15
15
  const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-0139-real-probes', `web-search-${Date.now()}`);
16
16
  await ensureDir(tempDir);
17
- await writeTextAtomic(path.join(tempDir, 'README.md'), 'Temporary Codex 0.144.1 web-search real probe workspace.\n');
17
+ await writeTextAtomic(path.join(tempDir, 'README.md'), 'Temporary Codex 0.144.5 web-search real probe workspace.\n');
18
18
  const outputFile = path.join(tempDir, 'last-message.txt');
19
19
  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":[...]}.';
20
20
  const args = buildCodexExecArgs({ root: tempDir, prompt, outputFile, json: true, extraArgs: ['-c', 'mcp_servers={}'] });
@@ -18,6 +18,7 @@ export async function writeCodexControlProof(root, input) {
18
18
  zellij_pane_id: input.task.zellijPaneId || null,
19
19
  sdk_thread_id: input.result.sdkThreadId,
20
20
  sdk_run_id: input.result.sdkRunId,
21
+ runtime_identity: input.result.runtimeIdentity || null,
21
22
  stream_event_count: input.result.streamEventCount,
22
23
  structured_output_valid: input.result.structuredOutputValid,
23
24
  output_schema_id: input.task.outputSchemaId,
@@ -31,7 +31,7 @@ export async function runFakeCodexSdkTask(input) {
31
31
  function fakeStructuredOutput(input) {
32
32
  if (input.outputSchemaId === GPT_FINAL_ARBITER_RESULT_SCHEMA_ID) {
33
33
  const prompt = String(input.prompt || '');
34
- const leanEnabled = /\b(Lean review|Lean Engineering Policy|sks\.lean-engineering-policy)\b/i.test(prompt);
34
+ const leanEnabled = /\b(Core Engineering Directive|sks\.lean-engineering-policy)\b/i.test(prompt);
35
35
  const unsafe = /\b(truncate|delete all|drop table|credential|delete validation|validation removed|path traversal|sql injection|secret leak)\b/i.test(prompt);
36
36
  const overbuild = leanEnabled ? classifyLeanOverbuild(prompt) : null;
37
37
  const status = unsafe ? 'rejected' : overbuild ? 'needs_more_work' : 'approved';
@@ -46,9 +46,8 @@ export async function inspectCodexLbCliLaunchRecovery(input) {
46
46
  : configLayer(await readText(projectConfigPath, '').catch(() => ''), 'project');
47
47
  const overrides = cliConfigOverrides(args);
48
48
  const environmentSelectsCodexLb = env.SKS_PROVIDER === 'codex-lb' || env.SKS_USE_CODEX_LB === '1';
49
- // Codex CLI options are the final operator intent. They override SKS's
50
- // environment-selected default just as `-c` overrides config.toml.
51
- if (cliSelectsLocalProvider(args) || (overrides.modelProvider && overrides.modelProvider !== 'codex-lb')) {
49
+ // Local-provider CLI options are the final operator intent.
50
+ if (cliSelectsLocalProvider(args)) {
52
51
  return codexLbToolOutputRecoveryNotSelected();
53
52
  }
54
53
  const loadedLayers = [userConfig, profileConfig, projectConfig];
@@ -60,6 +59,11 @@ export async function inspectCodexLbCliLaunchRecovery(input) {
60
59
  if (projectConfig.hasMachineLocalProviderConfig) {
61
60
  return projectProviderConfigBlocked();
62
61
  }
62
+ // Explicit model-provider overrides still win over user/profile defaults,
63
+ // but only after repository-local provider redirects have been rejected.
64
+ if (overrides.modelProvider && overrides.modelProvider !== 'codex-lb') {
65
+ return codexLbToolOutputRecoveryNotSelected();
66
+ }
63
67
  const selectedProvider = overrides.modelProvider
64
68
  ?? (environmentSelectsCodexLb ? 'codex-lb' : null)
65
69
  ?? profileConfig.modelProvider
@@ -5,7 +5,7 @@ import { buildCodexExecutionPolicy, buildCodexSdkConfig } from './codex-sdk-conf
5
5
  import { buildCodexSdkEnv } from './codex-sdk-env-policy.js';
6
6
  import { translateCodexSdkEvent } from './codex-event-translator.js';
7
7
  import { codexTimeoutClassForRoute } from './codex-reliability-shield.js';
8
- import { resolveCodexRuntime } from '../codex-runtime/resolve-codex-runtime.js';
8
+ import { resolveOfficialCodexPackageRuntime } from '../codex-runtime/resolve-codex-runtime.js';
9
9
  import { codexLbToolCatalogPath, ensureCodexLbToolCatalog, isCodexLbGpt56Model } from '../codex-lb/codex-lb-tool-catalog.js';
10
10
  export async function runRealCodexSdkTask(input, policy) {
11
11
  if (codexSdkTurnTimeoutMs(input) <= 0) {
@@ -23,16 +23,14 @@ export async function runRealCodexSdkTask(input, policy) {
23
23
  raw: { aborted: true, hard_deadline_exceeded: true }
24
24
  };
25
25
  }
26
+ const runtime = await resolveCodexSdkRuntime(input);
27
+ if (!runtime.ok || !runtime.identity) {
28
+ throw new Error(`Trusted Codex SDK runtime unavailable: ${runtime.blockers.join(',')}`);
29
+ }
26
30
  const mod = await import('@openai/codex-sdk');
27
31
  const Codex = mod.Codex || mod.default?.Codex || mod.default;
28
32
  if (typeof Codex !== 'function')
29
33
  throw new Error('Codex SDK export Codex not found');
30
- const runtime = await resolveCodexRuntime({
31
- explicitPath: typeof input.requestedScopeContract?.codex_bin === 'string' ? input.requestedScopeContract.codex_bin : null,
32
- requestedBy: 'codex-sdk-adapter'
33
- });
34
- if (!runtime.identity)
35
- throw new Error(`Codex runtime not found: ${runtime.blockers.join(',')}`);
36
34
  const toolCatalog = await prepareCodexLbToolCatalog(input, policy);
37
35
  if (toolCatalog.required && !toolCatalog.ok) {
38
36
  return {
@@ -160,6 +158,9 @@ export async function runRealCodexSdkTask(input, policy) {
160
158
  raw: { item_count: events.filter((event) => String(event?.type || '').startsWith('item.')).length, tool_catalog: toolCatalog }
161
159
  };
162
160
  }
161
+ export async function resolveCodexSdkRuntime(_input) {
162
+ return resolveOfficialCodexPackageRuntime({ requestedBy: 'codex-sdk-adapter' });
163
+ }
163
164
  export function codexSdkRuntimePolicies(input) {
164
165
  const env = buildCodexSdkEnv(input);
165
166
  const config = buildCodexSdkConfig(input);
@@ -3,6 +3,10 @@ export function buildCodexSdkConfig(input) {
3
3
  const model = String(input.model || process.env.SKS_CODEX_MODEL || process.env.CODEX_MODEL || '').trim();
4
4
  const serviceTier = String(input.serviceTier || process.env.SKS_SERVICE_TIER || 'fast');
5
5
  const config = {
6
+ // Internal control-plane work is always native Codex. Ambient proxy
7
+ // credentials are not provider-selection consent.
8
+ model_provider: 'openai',
9
+ forced_login_method: 'chatgpt',
6
10
  service_tier: serviceTier === 'standard' ? 'standard' : 'fast',
7
11
  model_reasoning_effort: String(input.modelReasoningEffort || input.reasoningEffort || process.env.SKS_CODEX_REASONING || process.env.CODEX_MODEL_REASONING_EFFORT || 'medium'),
8
12
  mcp_servers: {},
@@ -20,21 +24,6 @@ export function buildCodexSdkConfig(input) {
20
24
  config.mcp_servers = {};
21
25
  config.sks = { ...config.sks, no_mcp: true };
22
26
  }
23
- const codexLbApiKey = String(process.env.CODEX_LB_API_KEY || '').trim();
24
- const codexLbBaseUrl = normalizeCodexLbBaseUrl(process.env.CODEX_LB_BASE_URL);
25
- if (process.env.SKS_CODEX_LB_AUTOBYPASS !== '1' && codexLbApiKey && codexLbBaseUrl) {
26
- config.model_provider = 'codex-lb';
27
- config.model_providers = {
28
- 'codex-lb': {
29
- name: 'openai',
30
- base_url: codexLbBaseUrl,
31
- wire_api: 'responses',
32
- env_key: 'CODEX_LB_API_KEY',
33
- supports_websockets: true,
34
- requires_openai_auth: true
35
- }
36
- };
37
- }
38
27
  return config;
39
28
  }
40
29
  export function buildCodexExecutionPolicy(input) {
@@ -60,12 +49,3 @@ export function redactCodexSdkConfig(config) {
60
49
  return value;
61
50
  }));
62
51
  }
63
- function normalizeCodexLbBaseUrl(value) {
64
- let host = String(value || '').trim();
65
- if (!host)
66
- return '';
67
- if (!/^[a-z][a-z0-9+.-]*:\/\//i.test(host))
68
- host = `https://${host}`;
69
- host = host.replace(/\/+$/, '');
70
- return /\/backend-api\/codex$/i.test(host) ? host : `${host}/backend-api/codex`;
71
- }