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.
- package/README.md +26 -34
- package/config/codex-releases/{rust-v0.144.1.json → rust-v0.144.5.json} +5 -5
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/install.js +1 -1
- package/dist/cli/command-manifest-lite.js +2 -3
- package/dist/cli/command-registry.js +6 -4
- package/dist/cli/help-fast.js +0 -1
- package/dist/cli/router.js +24 -3
- package/dist/commands/zellij.js +18 -29
- package/dist/config/skills-manifest.json +62 -62
- package/dist/core/agent-bridge/agent-manifest.js +22 -1
- package/dist/core/agents/agent-codex-cockpit.js +1 -81
- package/dist/core/agents/agent-effort-policy.js +13 -7
- package/dist/core/agents/agent-orchestrator.js +0 -6
- package/dist/core/agents/agent-output-validator.js +2 -1
- package/dist/core/agents/agent-patch-queue-store.js +0 -8
- package/dist/core/agents/agent-proof-evidence.js +0 -6
- package/dist/core/agents/agent-worker-pipeline.js +12 -6
- package/dist/core/agents/native-cli-worker-runtime.js +1 -16
- package/dist/core/agents/native-worker-backend-router.js +1 -1
- package/dist/core/bench.js +1 -1
- package/dist/core/codex/official-goal-mode.js +4 -2
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +11 -17
- package/dist/core/codex-app/codex-app-ui-state-snapshot.js +34 -6
- package/dist/core/codex-app/menubar/constants.js +0 -1
- package/dist/core/codex-app.js +1 -1
- package/dist/core/codex-compat/codex-release-manifest.js +5 -5
- package/dist/core/codex-control/codex-0139-image-path-real-probe.js +1 -1
- package/dist/core/codex-control/codex-0139-web-search-probe.js +1 -1
- package/dist/core/codex-control/codex-control-proof.js +1 -0
- package/dist/core/codex-control/codex-fake-sdk-adapter.js +1 -1
- package/dist/core/codex-control/codex-lb-launch-recovery.js +7 -3
- package/dist/core/codex-control/codex-sdk-adapter.js +8 -7
- package/dist/core/codex-control/codex-sdk-config-policy.js +4 -24
- package/dist/core/codex-control/codex-sdk-env-policy.js +396 -11
- package/dist/core/codex-control/codex-task-runner.js +112 -57
- package/dist/core/codex-control/gpt-final-arbiter.js +1 -2
- package/dist/core/codex-control/python-codex-sdk-adapter.js +38 -15
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +3 -3
- package/dist/core/codex-native/core-skill-manifest.js +4 -7
- package/dist/core/codex-runtime/resolve-codex-runtime.js +199 -0
- package/dist/core/commands/agent-bridge-command.js +46 -15
- package/dist/core/commands/basic-cli.js +1 -1
- package/dist/core/commands/command-utils.js +2 -2
- package/dist/core/commands/eval-command.js +19 -2
- package/dist/core/commands/goal-command.js +37 -86
- package/dist/core/commands/mad-sks-command.js +0 -2
- package/dist/core/commands/naruto-command.js +236 -176
- package/dist/core/doctor/current-project-guidance.js +1 -1
- package/dist/core/doctor/doctor-dirty-planner.js +1 -1
- package/dist/core/doctor/retired-managed-residue-missions.js +26 -11
- package/dist/core/doctor/retired-managed-residue-private.js +1 -1
- package/dist/core/doctor/retired-managed-residue-runtime.js +12 -2
- package/dist/core/doctor/retired-managed-residue-state.js +7 -7
- package/dist/core/evaluation.js +83 -21
- package/dist/core/feature-fixtures.js +4 -7
- package/dist/core/feature-registry.js +0 -1
- package/dist/core/fsx.js +169 -14
- package/dist/core/goal-workflow.js +71 -140
- package/dist/core/hooks-runtime/hook-io.js +2 -2
- package/dist/core/hooks-runtime.js +228 -50
- package/dist/core/init/skills.js +7 -6
- package/dist/core/init.js +52 -33
- package/dist/core/install/installed-package-smoke.js +1 -1
- package/dist/core/lean-engineering-policy.js +25 -23
- package/dist/core/locks/file-lock.js +74 -21
- package/dist/core/managed-assets/managed-assets-manifest.js +1 -1
- package/dist/core/mcp-config/health-check.js +7 -2
- package/dist/core/mission.js +99 -3
- package/dist/core/ops/upgrade-migration-fixtures.js +30 -2
- package/dist/core/pipeline-internals/runtime-core.js +67 -95
- package/dist/core/pipeline-internals/runtime-gates.js +25 -6
- package/dist/core/proof/fake-real-proof-policy.js +32 -9
- package/dist/core/proof/route-proof-gate.js +49 -1
- package/dist/core/provider/model-router.js +2 -0
- package/dist/core/questions.js +31 -5
- package/dist/core/recallpulse.js +2 -2
- package/dist/core/release/canonical-test-proof.js +135 -0
- package/dist/core/release/release-closure-contract.js +1 -0
- package/dist/core/release/release-closure-validation.js +25 -12
- package/dist/core/release/release-closure.js +34 -5
- package/dist/core/release/release-gate-contract.js +4 -3
- package/dist/core/release/release-gate-dag.js +4 -2
- package/dist/core/release/release-pack-content-scanner.js +7 -6
- package/dist/core/release/release-pack-receipt.js +33 -12
- package/dist/core/release/release-real-contract.js +41 -2
- package/dist/core/retention.js +95 -16
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes/dollar-manifest-lite.js +1 -1
- package/dist/core/routes.js +18 -20
- package/dist/core/safety/command-contract/contracts.js +33 -0
- package/dist/core/safety/command-contract/types.js +1 -1
- package/dist/core/safety/ssot-guard.js +1 -54
- package/dist/core/stop-gate/stop-gate-check.js +0 -14
- package/dist/core/stop-gate/stop-gate-writer.js +0 -4
- package/dist/core/strategy/adhd-orchestrating-gate.js +2 -2
- package/dist/core/subagents/agent-catalog.js +28 -5
- package/dist/core/subagents/model-policy.js +52 -11
- package/dist/core/subagents/naruto-help-contract.js +2 -1
- package/dist/core/subagents/naruto-proof-projection.js +449 -0
- package/dist/core/subagents/official-subagent-preparation.js +641 -51
- package/dist/core/subagents/official-subagent-prompt.js +16 -6
- package/dist/core/subagents/official-subagent-runner.js +132 -12
- package/dist/core/subagents/subagent-evidence.js +44 -8
- package/dist/core/subagents/wave-lifecycle.js +238 -0
- package/dist/core/update-check.js +13 -4
- package/dist/core/verification/machine-feedback.js +39 -19
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-lane-renderer.js +19 -19
- package/dist/core/zellij/zellij-official-subagent-activity.js +2 -0
- package/dist/core/zellij/zellij-right-column-manager.js +6 -55
- package/dist/core/zellij/zellij-slot-column-anchor.js +4 -5
- package/dist/core/zellij/zellij-slot-pane-renderer.js +1 -1
- package/dist/core/zellij/zellij-ui-mode.js +0 -7
- package/dist/core/zellij/zellij-worker-pane-manager.js +3 -11
- package/dist/native/sks-menubar/Sources/AppDelegate.swift +0 -1
- package/dist/native/sks-menubar/Sources/NotificationCoordinator.swift +1 -3
- package/dist/native/sks-menubar/Sources/OverviewViewController.swift +194 -24
- package/dist/native/sks-menubar/Sources/ProcessClient.swift +49 -4
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +38 -10
- package/dist/native/sks-menubar/Sources/StatusItemController.swift +73 -11
- package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +27 -2
- package/dist/scripts/architecture-guard-check.js +1 -9
- package/dist/scripts/canonical-test-runner.js +51 -8
- package/dist/scripts/check-architecture.js +11 -1
- package/dist/scripts/cli-output-consistency-check.js +0 -2
- package/dist/scripts/codex-0144-app-server-v2-check.js +4 -4
- package/dist/scripts/codex-0144-binary-identity-check.js +10 -4
- package/dist/scripts/codex-0144-capability-check.js +5 -5
- package/dist/scripts/codex-0144-policy-check.js +4 -0
- package/dist/scripts/codex-control-all-pipelines-check.js +2 -1
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +3 -3
- package/dist/scripts/codex-sdk-all-pipelines-check.js +2 -1
- package/dist/scripts/codex-sdk-real-smoke-check.js +20 -2
- package/dist/scripts/current-command-surface-check.js +5 -3
- package/dist/scripts/current-surface-update-e2e-check.js +2 -2
- package/dist/scripts/docs-truthfulness-check.js +8 -6
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +3 -2
- package/dist/scripts/gate-policy-audit-check.js +7 -1
- package/dist/scripts/harness-benchmark-check.js +4 -4
- package/dist/scripts/hook-latency-quantum-check.js +2 -2
- package/dist/scripts/legacy-gate-purge-check.js +4 -2
- package/dist/scripts/loop-directive-check-lib.js +14 -13
- package/dist/scripts/naruto-codex-e2e-check.js +2 -2
- package/dist/scripts/naruto-ssot-gate-aliases-check.js +9 -0
- package/dist/scripts/naruto-ssot-pipeline-default-check.js +10 -0
- package/dist/scripts/naruto-ssot-route-normalization-check.js +8 -0
- package/dist/scripts/naruto-ssot-routing-check.js +12 -0
- package/dist/scripts/product-design-plugin-routing-check.js +4 -9
- package/dist/scripts/release-affected-selector-check.js +7 -1
- package/dist/scripts/release-check-stamp.js +151 -18
- package/dist/scripts/release-dynamic-presets-check.js +5 -2
- package/dist/scripts/release-metadata-1-19-check.js +4 -0
- package/dist/scripts/release-real-check.js +21 -3
- package/dist/scripts/sks-menubar-install-check.js +5 -5
- package/dist/scripts/upgrade-migration-matrix-check.js +278 -5
- package/dist/scripts/zellij-developer-controls-check.js +3 -5
- package/dist/scripts/zellij-initial-main-only-blackbox.js +3 -8
- package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +1 -2
- package/dist/scripts/zellij-right-column-headless-overflow-check.js +1 -1
- package/dist/scripts/zellij-right-column-manager-check.js +3 -4
- package/dist/scripts/zellij-slot-only-ui-check.js +2 -2
- package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +1 -2
- package/docs/demo.tape +1 -1
- package/infra-harness-gates.json +0 -27
- package/package.json +11 -6
- package/release-gates.v2.json +150 -22
- package/schemas/codex/agent-result.schema.json +4 -0
- package/schemas/codex/app-server-0.144/codex_app_server_protocol.v2.schemas.json +1 -18812
- package/schemas/codex/codex-0139-real-probe-result.schema.json +2 -2
- package/schemas/zellij/zellij-right-column-state.schema.json +0 -1
- package/dist/core/commands/ui-command.js +0 -198
- package/dist/core/loops/goal-to-loop-compat.js +0 -22
- package/dist/core/naruto/naruto-allocation-policy.js +0 -98
- package/dist/core/naruto/naruto-finalizer.js +0 -22
- package/dist/core/naruto/naruto-gpt-final-pack.js +0 -50
- package/dist/core/naruto/naruto-real-worker-child.js +0 -209
- package/dist/core/naruto/naruto-real-worker-runtime.js +0 -178
- package/dist/core/naruto/naruto-rebalance-policy.js +0 -47
- package/dist/core/naruto/naruto-verification-pool.js +0 -17
- package/dist/core/ui/dashboard-html.js +0 -110
- package/dist/core/zellij/zellij-dashboard-pane.js +0 -70
- package/dist/core/zellij/zellij-dashboard-renderer.js +0 -59
- package/dist/core/zellij/zellij-naruto-dashboard.js +0 -44
- package/dist/scripts/zellij-dashboard-pane-check.js +0 -69
- 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
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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,
|
|
110
|
-
'
|
|
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 (
|
|
107
|
-
blockers.push('
|
|
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
|
|
113
|
-
|
|
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
|
-
? '
|
|
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.'
|
package/dist/core/bench.js
CHANGED
|
@@ -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 ? '
|
|
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' : '
|
|
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 ? [] : ['
|
|
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"`
|
|
10
|
-
//
|
|
11
|
-
//
|
|
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
|
|
169
|
-
const
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
|
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: /(?:
|
|
128
|
-
|| (table == null &&
|
|
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',
|
package/dist/core/codex-app.js
CHANGED
|
@@ -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
|
|
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.
|
|
7
|
-
requiredCliVersion: '0.144.
|
|
8
|
-
sdkVersion: '0.144.
|
|
9
|
-
minimumSupportedVersion: '0.144.
|
|
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.
|
|
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.
|
|
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.
|
|
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(
|
|
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
|
-
//
|
|
50
|
-
|
|
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 {
|
|
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
|
-
}
|