sneakoscope 6.1.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -11
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +18 -9
- package/dist/bin/sks-dispatch.js +2 -2
- package/dist/cli/args.js +2 -0
- package/dist/cli/command-manifest-lite.js +2 -3
- package/dist/cli/command-registry.js +3 -4
- package/dist/cli/help-fast.js +1 -1
- package/dist/cli/install-helpers.js +116 -306
- package/dist/cli/install-tool-helpers.js +287 -0
- package/dist/cli/router.js +40 -4
- package/dist/commands/codex-lb.js +51 -20
- package/dist/commands/codex.js +39 -1
- package/dist/commands/doctor.js +242 -20
- package/dist/commands/tmux.js +5 -1
- package/dist/commands/zellij-monitor-pane.js +2 -0
- package/dist/commands/zellij-viewport-pane.js +3 -1
- package/dist/commands/zellij.js +1 -1
- package/dist/config/skills-manifest.json +59 -59
- package/dist/core/agent-bridge/agent-manifest.js +48 -0
- package/dist/core/agents/agent-command-surface.js +2 -1
- package/dist/core/agents/agent-effort-policy.js +38 -35
- package/dist/core/agents/agent-plan.js +100 -21
- package/dist/core/agents/agent-role-config.js +43 -46
- package/dist/core/agents/agent-runner-codex-exec.js +16 -3
- package/dist/core/agents/agent-schema.js +3 -2
- package/dist/core/agents/native-cli-session-swarm.js +1 -1
- package/dist/core/agents/zellij-right-lane-cockpit.js +2 -2
- package/dist/core/codex/agent-config-file-repair.js +94 -193
- package/dist/core/codex/codex-cli-update.js +723 -0
- package/dist/core/codex/codex-config-guard.js +185 -9
- package/dist/core/codex/codex-config-readability.js +21 -8
- package/dist/core/codex/codex-config-toml.js +14 -11
- package/dist/core/codex/codex-project-config-policy.js +3 -6
- package/dist/core/codex/codex-startup-config-postcheck.js +52 -42
- package/dist/core/codex-adapter.js +35 -22
- package/dist/core/codex-app/codex-agent-role-sync.js +13 -54
- package/dist/core/codex-app/codex-app-launcher.js +48 -17
- package/dist/core/codex-app/codex-app-restart.js +23 -2
- package/dist/core/codex-app/mcp-manager.js +679 -0
- package/dist/core/codex-app/sks-menubar.js +533 -8
- package/dist/core/codex-control/codex-0139-image-path-real-probe.js +15 -4
- package/dist/core/codex-control/codex-0139-web-search-probe.js +17 -6
- package/dist/core/codex-control/codex-lb-launch-recovery.js +293 -0
- package/dist/core/codex-control/codex-reliability-shield.js +89 -29
- package/dist/core/codex-control/codex-sdk-adapter.js +44 -8
- package/dist/core/codex-control/codex-task-runner.js +62 -9
- package/dist/core/codex-control/python-codex-sdk-adapter.js +30 -3
- package/dist/core/codex-exec-output-schema.js +35 -6
- package/dist/core/codex-lb/codex-lb-env.js +1 -1
- package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +291 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +9 -16
- package/dist/core/codex-native/codex-native-repair-transaction.js +1 -1
- package/dist/core/codex-native/core-skill-manifest.js +8 -4
- package/dist/core/codex-runtime/codex-desktop-config-policy.js +2 -3
- package/dist/core/commands/agent-bridge-command.js +23 -2
- package/dist/core/commands/agent-command.js +19 -5
- package/dist/core/commands/basic-cli.js +47 -6
- package/dist/core/commands/command-utils.js +1 -1
- package/dist/core/commands/mad-sks-command.js +76 -10
- package/dist/core/commands/menubar-command.js +94 -0
- package/dist/core/commands/naruto-command.js +645 -1156
- package/dist/core/commands/research-command.js +293 -231
- package/dist/core/commands/run-command.js +100 -23
- package/dist/core/commands/team-command.js +2 -3
- package/dist/core/commands/team-legacy-observe-command.js +94 -359
- package/dist/core/commands/wiki-command.js +11 -5
- package/dist/core/db-safety.js +2 -2
- package/dist/core/decision-lattice.js +6 -6
- package/dist/core/doctor/codex-startup-config-repair.js +8 -3
- package/dist/core/doctor/doctor-codex-startup-repair.js +6 -141
- package/dist/core/feature-fixture-executor.js +71 -7
- package/dist/core/feature-fixture-runner.js +53 -12
- package/dist/core/feature-fixtures.js +47 -14
- package/dist/core/feature-registry.js +28 -27
- package/dist/core/fsx.js +1 -0
- package/dist/core/harness-conflicts.js +18 -9
- package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +14 -8
- package/dist/core/hooks-runtime/hook-io.js +8 -4
- package/dist/core/hooks-runtime/light-turn.js +70 -0
- package/dist/core/hooks-runtime/naruto-decision-gate.js +184 -0
- package/dist/core/hooks-runtime/payload-signals.js +270 -0
- package/dist/core/hooks-runtime/stop-repeat-guard.js +89 -0
- package/dist/core/hooks-runtime/team-digest.js +0 -1
- package/dist/core/hooks-runtime/tool-output-quarantine.js +93 -0
- package/dist/core/hooks-runtime.js +438 -354
- package/dist/core/init/skills.js +16 -30
- package/dist/core/init.js +144 -36
- package/dist/core/managed-assets/managed-assets-manifest.js +566 -10
- package/dist/core/mission.js +24 -1
- package/dist/core/pipeline-internals/runtime-core.js +570 -177
- package/dist/core/pipeline-internals/runtime-gates.js +174 -48
- package/dist/core/preflight/parallel-preflight-engine.js +66 -4
- package/dist/core/proof/route-adapter.js +1 -1
- package/dist/core/proof/route-proof-gate.js +7 -2
- package/dist/core/proof/selftest-proof-fixtures.js +3 -5
- package/dist/core/proof-field.js +1 -1
- package/dist/core/provider/model-router.js +42 -31
- package/dist/core/recallpulse/policy.js +12 -28
- package/dist/core/recallpulse.js +11 -6
- package/dist/core/release/npm-pack-proof.js +247 -0
- package/dist/core/release/package-dist-snapshot.js +151 -0
- package/dist/core/release/package-size-budget.js +4 -1
- package/dist/core/release/release-authorization-snapshot.js +115 -0
- package/dist/core/release/release-gate-affected-selector.js +14 -2
- package/dist/core/release/release-gate-cache-v2.js +30 -0
- package/dist/core/release/release-gate-contract.js +161 -0
- package/dist/core/release/release-gate-dag.js +1 -0
- package/dist/core/release/release-real-contract.js +90 -10
- package/dist/core/release-parallel-full-coverage.js +31 -143
- package/dist/core/research/claim-evidence-matrix.js +41 -6
- package/dist/core/research/experiment-plan.js +14 -10
- package/dist/core/research/falsification.js +9 -2
- package/dist/core/research/implementation-blueprint-densifier.js +82 -60
- package/dist/core/research/implementation-blueprint.js +32 -26
- package/dist/core/research/mock-result.js +122 -11
- package/dist/core/research/replication-pack.js +15 -8
- package/dist/core/research/research-adversarial-review.js +1068 -0
- package/dist/core/research/research-claim-builder.js +69 -17
- package/dist/core/research/research-claim-synthesizer.js +343 -0
- package/dist/core/research/research-cycle-runner.js +53 -3
- package/dist/core/research/research-falsification-runner.js +176 -0
- package/dist/core/research/research-final-reviewer.js +44 -125
- package/dist/core/research/research-plan-markdown.js +123 -0
- package/dist/core/research/research-realistic-report.js +14 -6
- package/dist/core/research/research-review-artifact-digest.js +66 -0
- package/dist/core/research/research-source-evidence.js +144 -0
- package/dist/core/research/research-source-layer-catalog.js +68 -0
- package/dist/core/research/research-source-ledger-merge.js +250 -12
- package/dist/core/research/research-source-shards.js +26 -70
- package/dist/core/research/research-stage-runner.js +237 -247
- package/dist/core/research/research-super-search.js +188 -0
- package/dist/core/research/research-synthesis-prompt.js +20 -1
- package/dist/core/research/research-synthesis-writer.js +86 -5
- package/dist/core/research/research-work-graph.js +25 -18
- package/dist/core/research/source-quality-report.js +21 -0
- package/dist/core/research.js +424 -390
- package/dist/core/retention.js +70 -2
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes/dollar-manifest-lite.js +11 -11
- package/dist/core/routes.js +149 -69
- package/dist/core/runtime/task-profile.js +66 -0
- package/dist/core/runtime/verification-budget.js +12 -0
- package/dist/core/security/high-risk-contracts.js +6 -6
- package/dist/core/stop-gate/stop-gate-check.js +49 -12
- package/dist/core/subagents/agent-catalog.js +287 -0
- package/dist/core/subagents/model-policy.js +259 -0
- package/dist/core/subagents/naruto-help-contract.js +47 -0
- package/dist/core/subagents/official-subagent-config.js +488 -0
- package/dist/core/subagents/official-subagent-preparation.js +297 -0
- package/dist/core/subagents/official-subagent-prompt.js +159 -0
- package/dist/core/subagents/official-subagent-runner.js +129 -0
- package/dist/core/subagents/subagent-evidence.js +663 -0
- package/dist/core/subagents/terminology.js +16 -0
- package/dist/core/subagents/thread-budget.js +21 -0
- package/dist/core/subagents/triwiki-attention.js +168 -0
- package/dist/core/super-search/runtime-helpers.js +173 -19
- package/dist/core/super-search/runtime.js +140 -15
- package/dist/core/super-search/source-records.js +49 -8
- package/dist/core/team-review-policy.js +15 -0
- package/dist/core/triwiki/code-pack-head-freshness.js +291 -0
- package/dist/core/triwiki/triwiki-module-card.js +1 -1
- package/dist/core/triwiki-wrongness/wrongness-ledger.js +9 -2
- package/dist/core/version-manager.js +51 -1
- package/dist/core/version.js +1 -1
- package/dist/core/work-order-ledger.js +40 -1
- package/dist/core/zellij/zellij-fake-adapter.js +3 -1
- package/dist/core/zellij/zellij-launcher.js +49 -10
- package/dist/core/zellij/zellij-layout-builder.js +14 -5
- package/dist/core/zellij/zellij-official-subagent-activity.js +477 -0
- package/dist/core/zellij/zellij-official-subagent-telemetry.js +264 -0
- package/dist/core/zellij/zellij-pane-proof.js +9 -1
- package/dist/core/zellij/zellij-slot-pane-renderer.js +17 -5
- package/dist/core/zellij/zellij-slot-telemetry.js +15 -3
- package/dist/core/zellij/zellij-ui-mode.js +1 -1
- package/dist/core/zellij/zellij-update.js +14 -1
- package/dist/core/zellij/zellij-viewport-binder.js +3 -0
- package/dist/scripts/agent-role-config-repair-check.js +14 -16
- package/dist/scripts/architecture-guard-check.js +8 -1
- package/dist/scripts/canonical-test-runner.js +7 -1
- package/dist/scripts/check-route-modularity.js +0 -1
- package/dist/scripts/check-ts-contracts.js +1 -1
- package/dist/scripts/codex-control-all-pipelines-check.js +7 -3
- package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +27 -0
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +11 -1
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +9 -2
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +13 -2
- package/dist/scripts/codex-native-agent-role-content-check.js +27 -7
- package/dist/scripts/codex-native-repair-transaction-check.js +3 -1
- package/dist/scripts/codex-sdk-all-pipelines-check.js +7 -4
- package/dist/scripts/codex-sdk-backend-router-check.js +2 -0
- package/dist/scripts/codex-sdk-research-pipeline-check.js +30 -8
- package/dist/scripts/db-route-materialization-check.js +33 -0
- package/dist/scripts/docs-truthfulness-check.js +3 -1
- package/dist/scripts/doctor-codex-startup-repair-check.js +12 -15
- package/dist/scripts/doctor-fix-production-blackbox.js +12 -2
- package/dist/scripts/doctor-startup-config-repair-blackbox.js +8 -2
- package/dist/scripts/doctor-startup-config-repair-check.js +12 -2
- package/dist/scripts/install-update-preserves-config-check.js +6 -1
- package/dist/scripts/lib/codex-sdk-gate-lib.js +4 -0
- package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +0 -1
- package/dist/scripts/managed-role-manifest-parity-check.js +5 -4
- package/dist/scripts/naruto-codex-e2e-check.js +14 -7
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +4 -201
- package/dist/scripts/npm-publish-performance-check.js +20 -12
- package/dist/scripts/official-subagent-workflow-check.js +145 -0
- package/dist/scripts/package-published-contract-check.js +6 -29
- package/dist/scripts/packlist-performance-check.js +18 -21
- package/dist/scripts/parallel-verification-engine-check.js +2 -2
- package/dist/scripts/prepublish-release-check-or-fast.js +23 -86
- package/dist/scripts/python-codex-sdk-all-pipelines-check.js +8 -0
- package/dist/scripts/release-affected-selector-check.js +74 -1
- package/dist/scripts/release-check-stamp.js +153 -248
- package/dist/scripts/release-dag-full-coverage-check.js +7 -15
- package/dist/scripts/release-dynamic-presets-check.js +2 -1
- package/dist/scripts/release-gate-dag-runner-check.js +0 -1
- package/dist/scripts/release-gate-dag-runner.js +12 -1
- package/dist/scripts/release-gate-existence-audit.js +1 -2
- package/dist/scripts/release-parallel-full-coverage-check.js +12 -6
- package/dist/scripts/release-parallel-speed-budget-check.js +18 -2
- package/dist/scripts/release-real-check.js +26 -4
- package/dist/scripts/release-registry-check.js +61 -16
- package/dist/scripts/research-blueprint-densifier-check.js +2 -2
- package/dist/scripts/research-real-cycle-no-legacy-final-md-check.js +11 -7
- package/dist/scripts/sizecheck.js +2 -2
- package/dist/scripts/sks-3-1-4-directive-check-lib.js +8 -2
- package/dist/scripts/sks-3-1-5-directive-check-lib.js +3 -2
- package/dist/scripts/sks-3-1-6-directive-check-lib.js +5 -3
- package/dist/scripts/sks-menubar-install-check.js +14 -1
- package/dist/scripts/super-search-provider-interface-check.js +31 -18
- package/dist/scripts/trust-fixture-check.js +32 -10
- package/dist/scripts/wrongness-fixture-check.js +1 -1
- package/dist/scripts/zellij-layout-valid-check.js +5 -5
- package/dist/scripts/zellij-spawn-on-demand-layout-check.js +3 -3
- package/docs/demo.tape +1 -1
- package/infra-harness-gates.json +1486 -0
- package/package.json +15 -10
- package/release-gates.v2.json +4060 -0
- package/runtime-required-scripts.json +9 -0
- package/dist/commands/db.js +0 -6
- package/dist/core/commands/db-command.js +0 -146
- package/dist/core/research/prompt.js +0 -15
- package/dist/scripts/codex-0139-feature-probes-check.js +0 -30
- package/dist/scripts/codex-0139-marketplace-source-check.js +0 -13
- package/dist/scripts/codex-control-tool-call-sequence-repair-check.js +0 -14
|
@@ -3,6 +3,7 @@ import fs from 'node:fs/promises';
|
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { run } from '../commands/codex-lb.js';
|
|
6
|
+
import { CODEX_LB_TOOL_OUTPUT_RECOVERY_MIN_VERSION } from '../core/codex-lb/codex-lb-tool-output-recovery.js';
|
|
6
7
|
const calls = [];
|
|
7
8
|
const home = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-codex-lb-fast-truth-'));
|
|
8
9
|
await fs.mkdir(path.join(home, '.codex'), { recursive: true });
|
|
@@ -58,7 +59,16 @@ async function runFastCheck(env) {
|
|
|
58
59
|
try {
|
|
59
60
|
Object.assign(process.env, env);
|
|
60
61
|
process.exitCode = 0;
|
|
61
|
-
globalThis.fetch = async (
|
|
62
|
+
globalThis.fetch = async (url, init = {}) => {
|
|
63
|
+
if (new URL(String(url)).pathname === '/health') {
|
|
64
|
+
return new Response('{}', {
|
|
65
|
+
status: 200,
|
|
66
|
+
headers: {
|
|
67
|
+
'content-type': 'application/json',
|
|
68
|
+
'x-app-version': CODEX_LB_TOOL_OUTPUT_RECOVERY_MIN_VERSION
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
62
72
|
const body = JSON.parse(String(init.body || '{}'));
|
|
63
73
|
calls.push({ body });
|
|
64
74
|
const id = calls.length % 2 === 1 ? 'resp_fast_1' : 'resp_fast_2';
|
|
@@ -41,8 +41,15 @@ await fs.writeFile(configPath, [
|
|
|
41
41
|
].join('\n'));
|
|
42
42
|
await fs.writeFile(envPath, 'export CODEX_LB_BASE_URL="https://lb.example.test/backend-api/codex"\nexport CODEX_LB_API_KEY="sk-test-fast-ui"\n');
|
|
43
43
|
await fs.writeFile(authPath, `${oauthAuth}\n`);
|
|
44
|
+
const toolOutputRecoveryFetch = async () => new Response('{}', {
|
|
45
|
+
status: 200,
|
|
46
|
+
headers: {
|
|
47
|
+
'content-type': 'application/json',
|
|
48
|
+
'x-app-version': '1.21.0-beta.3'
|
|
49
|
+
}
|
|
50
|
+
});
|
|
44
51
|
const install = await ensureGlobalCodexFastModeDuringInstall({ home, configPath, forceFastMode: true });
|
|
45
|
-
const firstRepair = await repairCodexLbAuth({ home, configPath, envPath, forceCodexLbApiKeyAuth: true, forceFastMode: true, authMode: 'codex-lb' });
|
|
52
|
+
const firstRepair = await repairCodexLbAuth({ home, configPath, envPath, forceCodexLbApiKeyAuth: true, forceFastMode: true, authMode: 'codex-lb', toolOutputRecoveryFetch });
|
|
46
53
|
const firstConfig = await fs.readFile(configPath, 'utf8');
|
|
47
54
|
const firstAssert = assertConfig(firstConfig, 'first_use_codex_lb');
|
|
48
55
|
const release = await releaseCodexLbAuthHold({ home, configPath, authPath, backupPath: oauthBackupPath });
|
|
@@ -55,7 +62,7 @@ const releaseAssert = {
|
|
|
55
62
|
...(hasLegacyFastModeTables(releasedConfig) ? ['legacy_fast_mode_tables_survived_use_oauth'] : [])
|
|
56
63
|
]
|
|
57
64
|
};
|
|
58
|
-
const secondRepair = await repairCodexLbAuth({ home, configPath, envPath, forceCodexLbApiKeyAuth: true, forceFastMode: true, authMode: 'codex-lb' });
|
|
65
|
+
const secondRepair = await repairCodexLbAuth({ home, configPath, envPath, forceCodexLbApiKeyAuth: true, forceFastMode: true, authMode: 'codex-lb', toolOutputRecoveryFetch });
|
|
59
66
|
const secondConfig = await fs.readFile(configPath, 'utf8');
|
|
60
67
|
const secondAssert = assertConfig(secondConfig, 'second_use_codex_lb');
|
|
61
68
|
const report = {
|
|
@@ -5,6 +5,7 @@ import path from 'node:path';
|
|
|
5
5
|
import { codexFastModeDesktopStatus, codexLbConfigPath, configureCodexLb, ensureGlobalCodexFastModeDuringInstall, releaseCodexLbAuthHold, repairCodexLbAuth } from '../cli/install-helpers.js';
|
|
6
6
|
import { repairCodexConfigStructure, splitCodexProjectConfigPolicy } from '../core/codex/codex-project-config-policy.js';
|
|
7
7
|
import { parseCodexConfigToml, validateCodexConfigRoundTrip } from '../core/codex/codex-config-toml.js';
|
|
8
|
+
import { CODEX_LB_TOOL_OUTPUT_RECOVERY_MIN_VERSION } from '../core/codex-lb/codex-lb-tool-output-recovery.js';
|
|
8
9
|
import { normalizeCodexLbToolCatalog } from '../core/codex-lb/codex-lb-tool-catalog.js';
|
|
9
10
|
const tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-codex-lb-gpt56-fast-'));
|
|
10
11
|
const home = path.join(tmp, 'home');
|
|
@@ -29,13 +30,14 @@ const setup = await configureCodexLb({
|
|
|
29
30
|
forceFastMode: true,
|
|
30
31
|
forceCodexLbApiKeyAuth: true,
|
|
31
32
|
authMode: 'codex-lb',
|
|
32
|
-
shellProfile: 'skip'
|
|
33
|
+
shellProfile: 'skip',
|
|
34
|
+
toolOutputRecoveryFetch
|
|
33
35
|
});
|
|
34
36
|
const fastOn = await ensureGlobalCodexFastModeDuringInstall({ home, configPath, forceFastMode: true });
|
|
35
37
|
const first = assertFastProfile(await fs.readFile(configPath, 'utf8'), 'setup_fast_on');
|
|
36
38
|
const release = await releaseCodexLbAuthHold({ home, configPath, authPath, backupPath: oauthBackupPath });
|
|
37
39
|
const afterOauth = assertFastProfile(await fs.readFile(configPath, 'utf8'), 'use_oauth_roundtrip');
|
|
38
|
-
const repair = await repairCodexLbAuth({ home, configPath, envPath, forceCodexLbApiKeyAuth: true, forceFastMode: true, authMode: 'codex-lb' });
|
|
40
|
+
const repair = await repairCodexLbAuth({ home, configPath, envPath, forceCodexLbApiKeyAuth: true, forceFastMode: true, authMode: 'codex-lb', toolOutputRecoveryFetch });
|
|
39
41
|
await fs.writeFile(projectConfig, [
|
|
40
42
|
'# SKS managed fixture',
|
|
41
43
|
'default_profile = "sks-fast-high"',
|
|
@@ -154,4 +156,13 @@ function codex0144Model(slug) {
|
|
|
154
156
|
minimal_client_version: '0.144.1'
|
|
155
157
|
};
|
|
156
158
|
}
|
|
159
|
+
async function toolOutputRecoveryFetch() {
|
|
160
|
+
return new Response('{}', {
|
|
161
|
+
status: 200,
|
|
162
|
+
headers: {
|
|
163
|
+
'content-type': 'application/json',
|
|
164
|
+
'x-app-version': CODEX_LB_TOOL_OUTPUT_RECOVERY_MIN_VERSION
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
157
168
|
//# sourceMappingURL=codex-lb-gpt56-fast-profile-check.js.map
|
|
@@ -2,18 +2,38 @@
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import os from 'node:os';
|
|
5
|
+
import { parse } from 'smol-toml';
|
|
5
6
|
import { syncCodexAgentRoles } from '../core/codex-app/codex-agent-role-sync.js';
|
|
7
|
+
import { MANAGED_OFFICIAL_SUBAGENT_ROLES } from '../core/managed-assets/managed-assets-manifest.js';
|
|
6
8
|
const root = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'sks-agent-role-content-'));
|
|
7
9
|
const codexHome = path.join(root, 'codex-home');
|
|
8
10
|
const report = await syncCodexAgentRoles({ root, codexHome, apply: true, agentTypeSupported: true });
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const expert = await fs.promises.readFile(path.join(root, '.codex', 'agents', 'expert.toml'), 'utf8');
|
|
12
|
+
const worker = await fs.promises.readFile(path.join(root, '.codex', 'agents', 'worker.toml'), 'utf8');
|
|
13
|
+
const implementation = await fs.promises.readFile(path.join(root, '.codex', 'agents', 'implementation-specialist.toml'), 'utf8');
|
|
14
|
+
const browser = await fs.promises.readFile(path.join(root, '.codex', 'agents', 'browser-use-operator.toml'), 'utf8');
|
|
15
|
+
assertGate(expert.includes('model = "gpt-5.6-sol"') && expert.includes('model_reasoning_effort = "max"'), 'expert role must use Sol Max');
|
|
16
|
+
assertGate(worker.includes('model = "gpt-5.6-luna"') && worker.includes('model_reasoning_effort = "max"'), 'worker role must use Luna Max');
|
|
17
|
+
assertGate(implementation.includes('model = "gpt-5.6-sol"') && implementation.includes('model_reasoning_effort = "high"'), 'implementation role must use Sol High');
|
|
18
|
+
assertGate(browser.includes('model = "gpt-5.6-terra"') && browser.includes('model_reasoning_effort = "medium"'), 'browser role must use Terra Medium');
|
|
19
|
+
assertGate(expert.includes('Do not spawn another subagent.') && worker.includes('Do not redesign the task, expand scope, or spawn another subagent.'), 'official roles must prohibit nested delegation');
|
|
20
|
+
for (const role of MANAGED_OFFICIAL_SUBAGENT_ROLES) {
|
|
21
|
+
const text = await fs.promises.readFile(path.join(root, '.codex', 'agents', role.filename), 'utf8');
|
|
22
|
+
const doc = parse(text);
|
|
23
|
+
assertGate(doc.name === role.codex_name && doc.model === role.model && doc.model_reasoning_effort === role.model_reasoning_effort, `official role policy mismatch:${role.codex_name}`);
|
|
24
|
+
assertGate(Object.hasOwn(doc, 'sandbox_mode') === (role.sandbox === 'read-only'), `official role sandbox inheritance mismatch:${role.codex_name}`);
|
|
25
|
+
assertGate(doc.sandbox_mode === role.sandbox, `official role sandbox value mismatch:${role.codex_name}`);
|
|
13
26
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
assertGate(
|
|
27
|
+
const distribution = Object.fromEntries(['luna_max_mechanical', 'sol_high_implementation', 'sol_max_judgment', 'terra_medium_context_tools']
|
|
28
|
+
.map((policy) => [policy, MANAGED_OFFICIAL_SUBAGENT_ROLES.filter((role) => role.model_policy === policy).length]));
|
|
29
|
+
assertGate(JSON.stringify(distribution) === JSON.stringify({
|
|
30
|
+
luna_max_mechanical: 1,
|
|
31
|
+
sol_high_implementation: 3,
|
|
32
|
+
sol_max_judgment: 15,
|
|
33
|
+
terra_medium_context_tools: 6
|
|
34
|
+
}), 'official role policy distribution mismatch');
|
|
35
|
+
assertGate(!fs.existsSync(path.join(codexHome, 'agents')), 'agent role sync must not create global directive roles');
|
|
36
|
+
assertGate(report.strategy === 'agent_type' && report.probe_artifact_path && report.clobbered_user_roles === false && report.official_roles.length === MANAGED_OFFICIAL_SUBAGENT_ROLES.length, 'agent role report strategy/probe/catalog/no-clobber fields missing');
|
|
17
37
|
emitGate('codex-native:agent-role-content');
|
|
18
38
|
function assertGate(condition, message) {
|
|
19
39
|
if (condition)
|
|
@@ -11,11 +11,13 @@ process.env.CODEX_HOME = path.join(root, 'codex-home');
|
|
|
11
11
|
try {
|
|
12
12
|
const denied = await repairCodexNativeManagedAssets({ root, requestedBy: 'manual' });
|
|
13
13
|
assertGate(denied.ok === false && denied.blockers.includes('repair_transaction_requires_yes'), 'repair transaction must require --yes before mutation', denied);
|
|
14
|
-
assertGate(!(await exists(path.join(root, 'codex-home', 'skills'))) && !(await exists(path.join(root, 'codex-home', 'agents'))), 'no-yes repair created managed assets', denied);
|
|
14
|
+
assertGate(!(await exists(path.join(root, 'codex-home', 'skills'))) && !(await exists(path.join(root, 'codex-home', 'agents'))) && !(await exists(path.join(root, '.codex', 'agents'))), 'no-yes repair created managed assets', denied);
|
|
15
15
|
const report = await repairCodexNativeManagedAssets({ root, requestedBy: 'manual', yes: true });
|
|
16
16
|
assertGate(report.schema === 'sks.codex-native-repair-transaction.v1' && report.repaired.length === 4, 'repair transaction report incomplete', report);
|
|
17
17
|
assertGate(report.confirmed === true && typeof report.mutation_ledger_path === 'string', 'repair transaction missing confirmation/ledger proof', report);
|
|
18
18
|
assertGate(report.repaired.every((row) => row.artifact_path && Array.isArray(row.blockers)), 'repair rows missing artifact/blocker contract', report);
|
|
19
|
+
assertGate(await exists(path.join(root, '.codex', 'agents', 'worker.toml')) && await exists(path.join(root, '.codex', 'agents', 'expert.toml')), 'repair transaction did not create official project agent roles', report);
|
|
20
|
+
assertGate(!(await exists(path.join(root, 'codex-home', 'agents'))), 'repair transaction created legacy global agent roles', report);
|
|
19
21
|
}
|
|
20
22
|
finally {
|
|
21
23
|
if (previous === undefined)
|
|
@@ -16,12 +16,15 @@ const sources = {
|
|
|
16
16
|
coreSkill: readText('src/core/skills/core-skill-types.ts')
|
|
17
17
|
};
|
|
18
18
|
const teamCreateRedirectsToNaruto = sources.team.includes('redirectTeamCreateToNaruto') && sources.team.includes('narutoCommand');
|
|
19
|
-
assertGate(teamCreateRedirectsToNaruto, 'Team create must route through Naruto
|
|
19
|
+
assertGate(teamCreateRedirectsToNaruto, 'Team create must route through the Naruto official-subagent SSOT');
|
|
20
20
|
assertGate(sources.qa.includes("mock ? 'fake' : 'codex-sdk'"), 'QA must route native agents through codex-sdk');
|
|
21
|
-
assertGate(sources.research.includes("mock ? '
|
|
22
|
-
|
|
21
|
+
assertGate(sources.research.includes("backend: mock ? 'mock' : 'codex-sdk'")
|
|
22
|
+
&& sources.research.includes("reviewer_workflow: 'official_codex_subagent'"), 'Research must use the Codex SDK stage backend plus the official subagent reviewer workflow');
|
|
23
|
+
assertGate(sources.naruto.includes('runOfficialSubagentWorkflow'), 'Naruto must invoke the official Codex subagent runner');
|
|
24
|
+
assertGate(sources.naruto.includes("workflow: 'official_codex_subagent'"), 'Naruto must persist the official subagent workflow contract');
|
|
25
|
+
assertGate(!sources.naruto.includes("backend: 'codex-sdk'"), 'Naruto must not select the legacy codex-sdk backend');
|
|
23
26
|
assertGate(sources.coreSkill.includes("'codex-sdk'"), 'Core skill backend type must include codex-sdk');
|
|
24
27
|
const fixture = await runFakeCodexSdkTaskFixture('all-pipelines');
|
|
25
28
|
assertGate(fixture.result.ok === true, 'all pipeline SDK fixture must pass', fixture.result);
|
|
26
|
-
emitGate('codex-sdk:all-pipelines', { gates: required.length, sdk_thread_id: fixture.result.sdkThreadId });
|
|
29
|
+
emitGate('codex-sdk:all-pipelines', { gates: required.length, naruto_workflow: 'official_codex_subagent', sdk_thread_id: fixture.result.sdkThreadId });
|
|
27
30
|
//# sourceMappingURL=codex-sdk-all-pipelines-check.js.map
|
|
@@ -9,6 +9,7 @@ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-codex-sdk-router-'));
|
|
|
9
9
|
const old = snapshotEnv();
|
|
10
10
|
process.env.NODE_ENV = 'test';
|
|
11
11
|
process.env.SKS_CODEX_SDK_FAKE = '1';
|
|
12
|
+
process.env.SKS_CODEX_LB_AUTOBYPASS = '1';
|
|
12
13
|
process.env.SKS_DISABLE_ROUTE_RECURSION = '1';
|
|
13
14
|
process.env.SKS_AGENT_WORKER = '1';
|
|
14
15
|
process.env.SKS_FAST_MODE = '1';
|
|
@@ -48,6 +49,7 @@ function snapshotEnv() {
|
|
|
48
49
|
return {
|
|
49
50
|
NODE_ENV: process.env.NODE_ENV,
|
|
50
51
|
SKS_CODEX_SDK_FAKE: process.env.SKS_CODEX_SDK_FAKE,
|
|
52
|
+
SKS_CODEX_LB_AUTOBYPASS: process.env.SKS_CODEX_LB_AUTOBYPASS,
|
|
51
53
|
SKS_DISABLE_ROUTE_RECURSION: process.env.SKS_DISABLE_ROUTE_RECURSION,
|
|
52
54
|
SKS_AGENT_WORKER: process.env.SKS_AGENT_WORKER,
|
|
53
55
|
SKS_FAST_MODE: process.env.SKS_FAST_MODE,
|
|
@@ -5,21 +5,29 @@ import os from 'node:os';
|
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { assertGate, emitGate, importDist, readText } from './lib/codex-sdk-gate-lib.js';
|
|
7
7
|
const researchCommand = readText('src/core/commands/research-command.ts');
|
|
8
|
-
assertGate(researchCommand.includes("backend: mock ? '
|
|
9
|
-
assertGate(researchCommand.includes("
|
|
10
|
-
assertGate(researchCommand.includes(
|
|
11
|
-
assertGate(researchCommand.includes('readonly: true'), 'Research pipeline must force read-only native orchestration');
|
|
8
|
+
assertGate(researchCommand.includes("backend: mock ? 'mock' : 'codex-sdk'"), 'Research stage cycle must use the Codex SDK only as a bounded source/synthesis adapter');
|
|
9
|
+
assertGate(researchCommand.includes("source_acquisition: 'super-search'"), 'Research must route source acquisition through Super Search');
|
|
10
|
+
assertGate(researchCommand.includes("reviewer_workflow: 'official_codex_subagent'"), 'Research must use the official Codex subagent reviewer workflow');
|
|
12
11
|
assertGate(researchCommand.includes('quality_metrics'), 'Research pipeline JSON output must include quality metrics');
|
|
13
12
|
assertGate(researchCommand.includes('const cycleResult = await runResearchCycle({'), 'Research default path must use runResearchCycle');
|
|
14
|
-
|
|
13
|
+
for (const removed of ['runNativeAgentOrchestrator', 'SKS_RESEARCH_LEGACY_CYCLE', 'runCodexExec({']) {
|
|
14
|
+
assertGate(!researchCommand.includes(removed), `Research legacy runtime token must be removed: ${removed}`);
|
|
15
|
+
}
|
|
16
|
+
assertGate(researchCommand.includes('REMOVED_RESEARCH_RUNTIME_FLAGS')
|
|
17
|
+
&& researchCommand.includes('Unsupported legacy Research runtime option:'), 'Research must fail closed on removed runtime options');
|
|
18
|
+
for (const removedFlag of ['--legacy-research-cycle', '--native-proof-only']) {
|
|
19
|
+
assertGate(researchCommand.includes(removedFlag), `Research removed-option blocker must include ${removedFlag}`);
|
|
20
|
+
}
|
|
15
21
|
const researchCore = readText('src/core/research.ts');
|
|
16
22
|
assertGate(researchCore.includes('readResearchQualityContract'), 'Research gate must read research-quality-contract.json');
|
|
17
23
|
assertGate(researchCore.includes('claim_evidence_matrix_missing'), 'Research gate must require claim-evidence-matrix.json');
|
|
18
24
|
assertGate(researchCore.includes('research_final_review_not_approved'), 'Research gate must require final reviewer approval');
|
|
19
25
|
for (const [file, tokens] of Object.entries({
|
|
20
|
-
'src/core/research/research-work-graph.ts': ['buildResearchWorkGraph', '
|
|
26
|
+
'src/core/research/research-work-graph.ts': ['buildResearchWorkGraph', 'REQUIRED_SOURCE_SHARD_IDS', 'source_shard_${layer.id}'],
|
|
21
27
|
'src/core/research/research-cycle-runner.ts': ['runResearchCycle', 'Promise.race'],
|
|
22
|
-
'src/core/research/research-final-reviewer.ts': ['runResearchCodexFinalReviewer'],
|
|
28
|
+
'src/core/research/research-final-reviewer.ts': ['runResearchCodexFinalReviewer', 'research_final_reviewer_static_plus_official_subagents'],
|
|
29
|
+
'src/core/research/research-adversarial-review.ts': ['runResearchAdversarialReviewLoop', 'official_codex_subagent', 'critical_objections_unresolved'],
|
|
30
|
+
'src/core/research/research-super-search.ts': ['runResearchSuperSearchShard', 'runSuperSearch'],
|
|
23
31
|
'src/core/research/claim-evidence-matrix.ts': ['claim-evidence-matrix'],
|
|
24
32
|
'src/core/research/implementation-blueprint.ts': ['implementation-blueprint'],
|
|
25
33
|
'src/core/research/research-quality-contract.ts': ['research-quality-contract']
|
|
@@ -30,6 +38,8 @@ for (const [file, tokens] of Object.entries({
|
|
|
30
38
|
}
|
|
31
39
|
const research = await importDist('core/research.js');
|
|
32
40
|
const fsx = await importDist('core/fsx.js');
|
|
41
|
+
const adversarial = await importDist('core/research/research-adversarial-review.js');
|
|
42
|
+
const finalReviewer = await importDist('core/research/research-final-reviewer.js');
|
|
33
43
|
const dirShort = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-codex-research-short-'));
|
|
34
44
|
const planShort = await research.writeResearchPlan(dirShort, 'codex sdk short rejection fixture', { missionId: 'M-CODEX-SHORT' });
|
|
35
45
|
await fsx.writeTextAtomic(path.join(dirShort, 'research-report.md'), `# Short Report\n\n${Array.from({ length: 300 }, (_unused, index) => `word${index}`).join(' ')}\n`);
|
|
@@ -40,7 +50,19 @@ assertGate(shortGate.passed === false, 'codex-sdk research pipeline must reject
|
|
|
40
50
|
assertGate((shortGate.reasons || []).includes('research_report_too_short'), 'short rejection must include report length reason', shortGate);
|
|
41
51
|
const dirComplete = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-codex-research-complete-'));
|
|
42
52
|
const planComplete = await research.writeResearchPlan(dirComplete, 'codex sdk complete package fixture', { missionId: 'M-CODEX-COMPLETE' });
|
|
43
|
-
|
|
53
|
+
await research.writeMockResearchResult(dirComplete, planComplete);
|
|
54
|
+
const adversarialResult = await adversarial.runResearchAdversarialReviewLoop({
|
|
55
|
+
root: process.cwd(),
|
|
56
|
+
dir: dirComplete,
|
|
57
|
+
plan: planComplete,
|
|
58
|
+
timeoutMs: 1_000,
|
|
59
|
+
maxCycles: 1,
|
|
60
|
+
maxThreads: 5,
|
|
61
|
+
mock: true
|
|
62
|
+
});
|
|
63
|
+
assertGate(adversarialResult.ok === true, 'mock complete package must pass official-subagent adversarial contract', adversarialResult);
|
|
64
|
+
await finalReviewer.runResearchFinalReviewer(dirComplete, { plan: planComplete, root: process.cwd(), mock: true });
|
|
65
|
+
const completeGate = await research.evaluateResearchGate(dirComplete);
|
|
44
66
|
assertGate(completeGate.passed === true, 'codex-sdk research pipeline must pass complete package fixture', completeGate);
|
|
45
67
|
assertGate(completeGate.metrics?.final_review_approved === true, 'complete package must include approved final review', completeGate.metrics);
|
|
46
68
|
emitGate('codex-sdk:research-pipeline', { route: '$Research', short_dir: dirShort, complete_dir: dirComplete });
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fsp from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { prepareRoute } from '../core/pipeline-internals/runtime-core.js';
|
|
6
|
+
const root = await fsp.mkdtemp(path.join(os.tmpdir(), 'sks-db-route-materialization-'));
|
|
7
|
+
try {
|
|
8
|
+
await fsp.writeFile(path.join(root, 'package.json'), `${JSON.stringify({ name: 'sks-db-route-fixture', private: true }, null, 2)}\n`);
|
|
9
|
+
const prepared = await prepareRoute(root, '$DB inspect the local migration safely', {});
|
|
10
|
+
const missionId = String(prepared?.mission_id || '');
|
|
11
|
+
if (!missionId || prepared?.route?.id !== 'DB')
|
|
12
|
+
throw new Error('DB route did not materialize a mission');
|
|
13
|
+
const dir = path.join(root, '.sneakoscope', 'missions', missionId);
|
|
14
|
+
const scan = JSON.parse(await fsp.readFile(path.join(dir, 'db-safety-scan.json'), 'utf8'));
|
|
15
|
+
const review = JSON.parse(await fsp.readFile(path.join(dir, 'db-review.json'), 'utf8'));
|
|
16
|
+
if (typeof scan?.ok !== 'boolean')
|
|
17
|
+
throw new Error('db-safety-scan.json is missing an ok decision');
|
|
18
|
+
if (typeof review?.scan_ok !== 'boolean' || review?.destructive_operation_zero !== true) {
|
|
19
|
+
throw new Error('db-review.json is missing the fail-closed safety baseline');
|
|
20
|
+
}
|
|
21
|
+
console.log(JSON.stringify({
|
|
22
|
+
schema: 'sks.db-route-materialization-check.v1',
|
|
23
|
+
ok: true,
|
|
24
|
+
route: '$DB',
|
|
25
|
+
mission_id: missionId,
|
|
26
|
+
artifacts: ['db-safety-scan.json', 'db-review.json'],
|
|
27
|
+
legacy_cli_registered: false
|
|
28
|
+
}, null, 2));
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
await fsp.rm(root, { recursive: true, force: true });
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=db-route-materialization-check.js.map
|
|
@@ -12,6 +12,7 @@ const files = [
|
|
|
12
12
|
'docs/codex-0.136-compat.md',
|
|
13
13
|
'docs/codex-0.135-compat.md',
|
|
14
14
|
'docs/codex-cli-compat.md',
|
|
15
|
+
'docs/codex-app.md',
|
|
15
16
|
'docs/official-docs-compat.md',
|
|
16
17
|
'docs/hooks-pat.md',
|
|
17
18
|
'docs/known-gaps.md',
|
|
@@ -24,7 +25,8 @@ const required = {
|
|
|
24
25
|
'docs/codex-lb.md': ['durable_env_file', 'durable_keychain', 'shell_profile', 'process_only_ephemeral', 'base URL only'],
|
|
25
26
|
'docs/codex-0.136-compat.md': ['rust-v0.136.0', 'codex:0.136-compat', 'codex archive', 'codex app-server --stdio', 'CODEX_API_KEY', 'server tokens'],
|
|
26
27
|
'docs/codex-0.135-compat.md': ['rust-v0.135.0', 'codex:0.135-compat', 'named permission profiles'],
|
|
27
|
-
'docs/codex-cli-compat.md': ['rust-v0.
|
|
28
|
+
'docs/codex-cli-compat.md': ['rust-v0.144.1', 'sks codex 0.144', 'Inherited Codex 0.136 Capabilities', 'session_archive_restore', 'profile_primary_selector', 'managed_network_proxy_env', 'goals_default_enabled', 'permission_profiles_requirements', 'SubagentStart', 'sks_zero_warning_disallowed', 'strict subset'],
|
|
29
|
+
'docs/codex-app.md': ['rust-v0.144.1', 'sks codex 0.144', 'App Server v2', 'Codex Chrome Extension', 'gpt-image-2'],
|
|
28
30
|
'docs/official-docs-compat.md': ['official-docs-compat-report.js', 'rust-v0.144.1', 'gpt-image-2', 'input_fidelity', 'additionalProperties:false'],
|
|
29
31
|
'docs/hooks-pat.md': ['SubagentStop', 'strict subset', 'zero-warning'],
|
|
30
32
|
'docs/known-gaps.md': ['No P0', 'P1'],
|
|
@@ -53,20 +53,19 @@ await writeTextAtomic(path.join(codexHome, 'agents', 'sks-checker.toml'), [
|
|
|
53
53
|
''
|
|
54
54
|
].join('\n'));
|
|
55
55
|
const planned = await mod.runDoctorCodexStartupRepair({ root: tmp, codexHome, fix: false });
|
|
56
|
-
assertGate(planned.configs.every((entry) => entry.warnings.some((warning) => warning.includes('agent_config_file_stale'))), '
|
|
56
|
+
assertGate(planned.configs.every((entry) => !entry.warnings.some((warning) => warning.includes('agent_config_file_stale'))), 'structural startup inspection must ignore preserved legacy agent config_file paths', planned);
|
|
57
57
|
const repaired = await mod.runDoctorCodexStartupRepair({ root: tmp, codexHome, fix: true, includeDefaultNodeReplCandidates: false });
|
|
58
58
|
const projectText = await fs.readFile(path.join(tmp, '.codex', 'config.toml'), 'utf8');
|
|
59
59
|
const globalText = await fs.readFile(path.join(codexHome, 'config.toml'), 'utf8');
|
|
60
60
|
const checkerText = await fs.readFile(path.join(codexHome, 'agents', 'sks-checker.toml'), 'utf8');
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
for (const [scope, text
|
|
64
|
-
['project', projectText
|
|
65
|
-
['global', globalText
|
|
61
|
+
const projectScoutPresent = await fs.stat(path.join(tmp, '.codex', 'agents', 'analysis-scout.toml')).then(() => true).catch(() => false);
|
|
62
|
+
const globalScoutPresent = await fs.stat(path.join(codexHome, 'agents', 'analysis-scout.toml')).then(() => true).catch(() => false);
|
|
63
|
+
for (const [scope, text] of [
|
|
64
|
+
['project', projectText],
|
|
65
|
+
['global', globalText]
|
|
66
66
|
]) {
|
|
67
|
-
assertGate(
|
|
68
|
-
assertGate(text.includes(
|
|
69
|
-
assertGate(text.includes('description = "SKS scout with bounded write capability."'), `${scope} managed agent description must be write-capable`, text);
|
|
67
|
+
assertGate(text.includes('/Users/alfredo/.codex/agents/analysis-scout.toml'), `${scope} legacy config_file must be preserved`, text);
|
|
68
|
+
assertGate(text.includes('description = "Read-only SKS scout."'), `${scope} legacy agent description must be preserved`, text);
|
|
70
69
|
assertGate(!text.includes('[mcp_servers.node_repl]'), `${scope} stale node_repl MCP block must be removed`, text);
|
|
71
70
|
assertGate(!text.includes('[mcp_servers.node_repl.env]'), `${scope} stale node_repl child MCP block must be removed`, text);
|
|
72
71
|
assertGate((text.match(/\[mcp_servers\.context7\]/g) || []).length === 1, `${scope} duplicate context7 MCP block must be deduped`, text);
|
|
@@ -74,14 +73,12 @@ for (const [scope, text, expectedDir] of [
|
|
|
74
73
|
assertGate(text.includes('[mcp_servers.supabase_sauron]'), `${scope} optional sauron MCP block must be preserved`, text);
|
|
75
74
|
assertGate(text.includes('[features]') && text.includes('hooks = true'), `${scope} unrelated tables must be preserved`, text);
|
|
76
75
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
assertGate(!text.includes('Do not edit files.'), `${scope} agent role file must not preserve stale read-only instruction`, text);
|
|
80
|
-
}
|
|
81
|
-
assertGate(!checkerText.includes('message_role_prefix'), 'managed directive agent role must remove unsupported message_role_prefix', checkerText);
|
|
76
|
+
assertGate(projectScoutPresent === false && globalScoutPresent === false, 'structural startup repair must not synthesize legacy role TOMLs', { projectScoutPresent, globalScoutPresent });
|
|
77
|
+
assertGate(checkerText.includes('message_role_prefix'), 'legacy directive role TOMLs must be preserved byte-for-byte', checkerText);
|
|
82
78
|
assertGate(repaired.ok === true, 'startup repair must pass when only optional sauron remains', repaired);
|
|
83
79
|
assertGate(repaired.configs.every((entry) => entry.changed === true && entry.backup_path), 'startup repair must back up changed configs', repaired);
|
|
84
|
-
assertGate(repaired.agent_role_files.created.length
|
|
80
|
+
assertGate(repaired.agent_role_files.created.length === 0 && repaired.agent_role_files.sanitized.length === 0, 'startup repair must leave project/global agent role files untouched', repaired);
|
|
81
|
+
assertGate(repaired.configs.every((entry) => entry.agent_config_files_repaired.length === 0), 'startup repair must not rewrite legacy agent config_file references', repaired);
|
|
85
82
|
assertGate(repaired.configs.every((entry) => !entry.warnings.some((warning) => warning.includes('agent_config_file_stale'))), 'startup repair must not keep stale agent config warnings after repair', repaired);
|
|
86
83
|
assertGate(repaired.configs.every((entry) => entry.duplicate_toml_blocks_removed.length === 0), 'valid startup repair fixture must not claim duplicate-invalid TOML repair', repaired);
|
|
87
84
|
const tmpInvalid = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-codex-startup-invalid-'));
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
2
3
|
import path from 'node:path';
|
|
4
|
+
import { parse } from 'smol-toml';
|
|
3
5
|
import { assertGate, emitGate, makeTempRoot, writeText } from './sks-3-1-8-check-lib.js';
|
|
4
6
|
import { repairCodexStartupConfig } from '../core/doctor/codex-startup-config-repair.js';
|
|
5
7
|
import { repairContext7Mcp } from '../core/doctor/context7-mcp-repair.js';
|
|
@@ -7,8 +9,16 @@ import { repairSupabaseMcp } from '../core/doctor/supabase-mcp-repair.js';
|
|
|
7
9
|
import { runDoctorFixTransaction } from '../core/doctor/doctor-transaction.js';
|
|
8
10
|
import { doctorRepairPostcheck } from '../core/doctor/doctor-repair-postcheck.js';
|
|
9
11
|
const root = await makeTempRoot('sks-doctor-production-');
|
|
10
|
-
await writeText(path.join(root, '.codex', 'config.toml'), '[mcp_servers.context7]\ncommand = "npx"\n\n[mcp_servers.supabase]\nurl = "https://supabase.example/mcp"\nread_only = true\n\n[agents.analysis_scout]\nconfig_file = ".codex/agents/stale.toml"\nmessage_role_prefix = "legacy"\n');
|
|
11
|
-
const startup = await repairCodexStartupConfig({ root, apply: true });
|
|
12
|
+
await writeText(path.join(root, '.codex', 'config.toml'), '# SKS-MANAGED-CODEX-CONFIG\n[mcp_servers.context7]\ncommand = "npx"\n\n[mcp_servers.supabase]\nurl = "https://supabase.example/mcp"\nread_only = true\n\n[agents.analysis_scout]\nconfig_file = ".codex/agents/stale.toml"\nmessage_role_prefix = "legacy"\n');
|
|
13
|
+
const startup = await repairCodexStartupConfig({ root, apply: true, home: path.join(root, 'home'), codexHome: path.join(root, 'codex-home') });
|
|
14
|
+
const startupText = await fs.readFile(path.join(root, '.codex', 'config.toml'), 'utf8');
|
|
15
|
+
const startupConfig = parse(startupText);
|
|
16
|
+
const startupAgents = startupConfig.agents || {};
|
|
17
|
+
const startupAgentFiles = (await fs.readdir(path.join(root, '.codex', 'agents'))).sort();
|
|
18
|
+
assertGate(startup.ok === true, 'doctor production startup repair must pass', startup);
|
|
19
|
+
assertGate(startupAgents.max_threads === 12 && startupAgents.max_depth === 1 && startupAgents.job_max_runtime_seconds === 1200 && startupAgents.interrupt_message === true, 'doctor production startup repair must write official config defaults', startupAgents);
|
|
20
|
+
assertGate(startupAgentFiles.join(',') === 'expert.toml,worker.toml', 'doctor production startup repair must create only official worker/expert TOMLs', startupAgentFiles);
|
|
21
|
+
assertGate(startupText.includes('[agents.analysis_scout]') && startupText.includes('config_file = ".codex/agents/stale.toml"'), 'doctor production startup repair must preserve legacy config tables', startupText);
|
|
12
22
|
const context7 = await repairContext7Mcp({ root, apply: true });
|
|
13
23
|
const supabase = await repairSupabaseMcp({ root, apply: true });
|
|
14
24
|
const tx = await runDoctorFixTransaction({ root, phases: [
|
|
@@ -3,11 +3,17 @@ import fs from 'node:fs/promises';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { assertGate, emitGate, makeTempRoot, writeText } from './sks-3-1-8-check-lib.js';
|
|
5
5
|
import { repairCodexStartupConfig } from '../core/doctor/codex-startup-config-repair.js';
|
|
6
|
+
import { parse } from 'smol-toml';
|
|
6
7
|
const root = await makeTempRoot('sks-startup-config-blackbox-');
|
|
7
8
|
await writeText(path.join(root, '.codex', 'config.toml'), '# SKS managed Codex config fixture\n[agents.analysis_scout]\nconfig_file = ".codex/agents/stale.toml"\nmessage_role_prefix = "legacy"\n');
|
|
8
|
-
const report = await repairCodexStartupConfig({ root, apply: true });
|
|
9
|
+
const report = await repairCodexStartupConfig({ root, apply: true, home: path.join(root, 'home'), codexHome: path.join(root, 'codex-home') });
|
|
9
10
|
const text = await fs.readFile(path.join(root, '.codex', 'config.toml'), 'utf8');
|
|
11
|
+
const parsed = parse(text);
|
|
12
|
+
const agents = parsed.agents || {};
|
|
13
|
+
const files = (await fs.readdir(path.join(root, '.codex', 'agents'))).sort();
|
|
10
14
|
assertGate(report.ok === true, 'startup config blackbox must pass postcheck', report);
|
|
11
|
-
assertGate(
|
|
15
|
+
assertGate(agents.max_threads === 12 && agents.max_depth === 1 && agents.job_max_runtime_seconds === 1200 && agents.interrupt_message === true, 'startup config blackbox must persist official settings', agents);
|
|
16
|
+
assertGate(files.join(',') === 'expert.toml,worker.toml', 'startup config blackbox must create only official worker/expert TOMLs', files);
|
|
17
|
+
assertGate(text.includes('config_file = ".codex/agents/stale.toml"') && text.includes('message_role_prefix = "legacy"'), 'startup config blackbox must preserve legacy compatibility tables', { text });
|
|
12
18
|
emitGate('doctor:startup-config-repair-blackbox');
|
|
13
19
|
//# sourceMappingURL=doctor-startup-config-repair-blackbox.js.map
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { assertGate, emitGate, makeTempRoot, writeText } from './sks-3-1-8-check-lib.js';
|
|
3
3
|
import { repairCodexStartupConfig } from '../core/doctor/codex-startup-config-repair.js';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
4
5
|
import path from 'node:path';
|
|
6
|
+
import { parse } from 'smol-toml';
|
|
5
7
|
const root = await makeTempRoot('sks-startup-config-');
|
|
6
8
|
await writeText(path.join(root, '.codex', 'config.toml'), '# SKS managed Codex config fixture\n[agents.analysis_scout]\nconfig_file = ".codex/agents/missing.toml"\nmessage_role_prefix = "legacy"\n');
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
+
const codexHome = path.join(root, 'codex-home');
|
|
10
|
+
const report = await repairCodexStartupConfig({ root, apply: true, home: path.join(root, 'home'), codexHome });
|
|
11
|
+
const text = await fs.readFile(path.join(root, '.codex', 'config.toml'), 'utf8');
|
|
12
|
+
const parsed = parse(text);
|
|
13
|
+
const agents = parsed.agents || {};
|
|
14
|
+
const files = (await fs.readdir(path.join(root, '.codex', 'agents'))).sort();
|
|
15
|
+
assertGate(report.ok === true, 'startup config repair must install the official project config and agent files', report);
|
|
16
|
+
assertGate(agents.max_threads === 12 && agents.max_depth === 1 && agents.job_max_runtime_seconds === 1200 && agents.interrupt_message === true, 'startup config repair must write official [agents] defaults', agents);
|
|
17
|
+
assertGate(files.length === 2 && files[0] === 'expert.toml' && files[1] === 'worker.toml', 'startup config repair must create only worker/expert TOMLs', files);
|
|
18
|
+
assertGate(text.includes('[agents.analysis_scout]') && text.includes('config_file = ".codex/agents/missing.toml"') && text.includes('message_role_prefix = "legacy"'), 'legacy agent config must be preserved without synthesizing its TOML', text);
|
|
9
19
|
emitGate('doctor:startup-config-repair');
|
|
10
20
|
//# sourceMappingURL=doctor-startup-config-repair-check.js.map
|
|
@@ -29,6 +29,9 @@ const results = [];
|
|
|
29
29
|
'',
|
|
30
30
|
'[mcp_servers.custom]',
|
|
31
31
|
'command = "npx"',
|
|
32
|
+
'',
|
|
33
|
+
'[agents]',
|
|
34
|
+
'max_threads = 20',
|
|
32
35
|
''
|
|
33
36
|
].join('\n');
|
|
34
37
|
await fs.writeFile(cfg, userConfig);
|
|
@@ -41,6 +44,7 @@ const results = [];
|
|
|
41
44
|
/^model_reasoning_effort = "high"/m.test(after) && // user effort NOT stripped
|
|
42
45
|
/# my hand-tuned Codex config/.test(after) && // user comment preserved
|
|
43
46
|
/\[mcp_servers\.custom\]/.test(after) && // user table preserved
|
|
47
|
+
/\[agents\][\s\S]*max_threads = 20/.test(after) && // user concurrency preserved
|
|
44
48
|
!/\[profiles\.sks-fast-high\]/.test(after) && // legacy profile table stripped
|
|
45
49
|
!/\[user\.fast_mode\]/.test(after) && // legacy fast UI table stripped
|
|
46
50
|
backups.length >= 1 && // backup created
|
|
@@ -59,7 +63,8 @@ const results = [];
|
|
|
59
63
|
&& !/^model\s*=/m.test(topLevel)
|
|
60
64
|
&& !/^model_reasoning_effort\s*=/m.test(topLevel)
|
|
61
65
|
&& !/^service_tier = "fast"/m.test(topLevel)
|
|
62
|
-
&& /\[features\]/.test(after)
|
|
66
|
+
&& /\[features\]/.test(after)
|
|
67
|
+
&& !/^max_threads\s*=/m.test(after);
|
|
63
68
|
results.push({ case: 'fresh_config_seeds_defaults', ok, status: res.status });
|
|
64
69
|
}
|
|
65
70
|
// --- Case 3: unparseable config is preserved + backed up, NOT overwritten ---
|
|
@@ -17,6 +17,9 @@ export async function runFakeCodexSdkTaskFixture(label = 'fixture', extra = {})
|
|
|
17
17
|
const old = snapshotEnv();
|
|
18
18
|
process.env.NODE_ENV = 'test';
|
|
19
19
|
process.env.SKS_CODEX_SDK_FAKE = '1';
|
|
20
|
+
// Hermetic fixture runs must not inherit an operator's live codex-lb
|
|
21
|
+
// selection. The fake adapter exercises control-plane contracts only.
|
|
22
|
+
process.env.SKS_CODEX_LB_AUTOBYPASS = '1';
|
|
20
23
|
try {
|
|
21
24
|
const result = await mod.runCodexTask({
|
|
22
25
|
route: extra.route || '$Agent',
|
|
@@ -78,6 +81,7 @@ function snapshotEnv() {
|
|
|
78
81
|
return {
|
|
79
82
|
NODE_ENV: process.env.NODE_ENV,
|
|
80
83
|
SKS_CODEX_SDK_FAKE: process.env.SKS_CODEX_SDK_FAKE,
|
|
84
|
+
SKS_CODEX_LB_AUTOBYPASS: process.env.SKS_CODEX_LB_AUTOBYPASS,
|
|
81
85
|
SKS_CODEX_SDK_FIXTURE: process.env.SKS_CODEX_SDK_FIXTURE
|
|
82
86
|
};
|
|
83
87
|
}
|
|
@@ -144,7 +144,6 @@ async function cleanupOwnedSession(sessionName, socketDir, cwd) {
|
|
|
144
144
|
const blockers = [
|
|
145
145
|
...(!sessionRemoved ? ['mad_ui_check_zellij_session_still_present'] : []),
|
|
146
146
|
...(!socketExclusive ? ['mad_ui_check_zellij_socket_not_exclusive'] : []),
|
|
147
|
-
...(!ownedProcessTree.server_found ? ['mad_ui_check_zellij_server_not_observed'] : []),
|
|
148
147
|
...(!processExit.ok ? ['mad_ui_check_owned_processes_still_alive'] : []),
|
|
149
148
|
...(!socketDirRemoved ? ['mad_ui_check_zellij_socket_dir_not_removed'] : [])
|
|
150
149
|
];
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
import { assertGate, emitGate, importDist } from './sks-1-18-gate-lib.js';
|
|
4
4
|
const manifest = await importDist('core/managed-assets/managed-assets-manifest.js');
|
|
5
5
|
const agentConfig = await importDist('core/agents/agent-role-config.js');
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
6
|
+
const allRoles = [...manifest.MANAGED_OFFICIAL_SUBAGENT_ROLES, ...manifest.MANAGED_AGENT_ROLES];
|
|
7
|
+
const roles = allRoles.map((role) => role.id);
|
|
8
|
+
const files = allRoles.map((role) => role.filename);
|
|
9
|
+
const generated = allRoles.every((role) => agentConfig.managedAgentRoleConfigForRole(role.id)?.file === role.filename);
|
|
9
10
|
const uniqueIds = new Set(roles).size === roles.length;
|
|
10
11
|
const uniqueFiles = new Set(files).size === files.length;
|
|
11
12
|
manifest.assertUniqueManagedAgentRoleFilenames();
|
|
@@ -18,6 +19,6 @@ const report = {
|
|
|
18
19
|
unique_files: uniqueFiles,
|
|
19
20
|
generated
|
|
20
21
|
};
|
|
21
|
-
assertGate(uniqueIds && uniqueFiles && generated && roles.includes('sks-checker') && roles.includes('sks-codex-probe-verifier'), 'managed agent role manifest must be the shared generation/inventory source with unique physical files', report);
|
|
22
|
+
assertGate(uniqueIds && uniqueFiles && generated && roles.includes('sks-official-worker') && roles.includes('sks-official-expert') && roles.includes('sks-checker') && roles.includes('sks-codex-probe-verifier'), 'managed agent role manifest must be the shared generation/inventory source with unique physical files', report);
|
|
22
23
|
emitGate('managed-assets:role-manifest-parity', report);
|
|
23
24
|
//# sourceMappingURL=managed-role-manifest-parity-check.js.map
|
|
@@ -30,12 +30,10 @@ const args = [
|
|
|
30
30
|
realMode ? 'real Codex E2E readonly smoke' : 'hermetic Naruto E2E readonly smoke',
|
|
31
31
|
'--json',
|
|
32
32
|
'--readonly',
|
|
33
|
-
'--
|
|
34
|
-
'--clones',
|
|
33
|
+
'--agents',
|
|
35
34
|
realMode ? '2' : '3',
|
|
36
|
-
'--
|
|
37
|
-
realMode ? '2' : '3'
|
|
38
|
-
...(realMode ? ['--real'] : ['--mock'])
|
|
35
|
+
'--max-threads',
|
|
36
|
+
realMode ? '2' : '3'
|
|
39
37
|
];
|
|
40
38
|
const run = await runProcess(process.execPath, args, {
|
|
41
39
|
cwd: tempRoot,
|
|
@@ -46,11 +44,19 @@ const run = await runProcess(process.execPath, args, {
|
|
|
46
44
|
SKS_CODEX_ALLOW_NON_GIT: realMode ? '1' : process.env.SKS_CODEX_ALLOW_NON_GIT || '',
|
|
47
45
|
SKS_DISABLE_NETWORK: realMode ? process.env.SKS_DISABLE_NETWORK || '' : '1',
|
|
48
46
|
SKS_DISABLE_UPDATE_CHECK: '1',
|
|
49
|
-
|
|
47
|
+
SKS_NARUTO_STANDALONE_CLI: realMode ? '1' : '0',
|
|
48
|
+
SKS_NARUTO_APP_SESSION: realMode ? '0' : '1',
|
|
49
|
+
CODEX_THREAD_ID: realMode ? process.env.CODEX_THREAD_ID || '' : `naruto-e2e-${path.basename(tempRoot)}`
|
|
50
50
|
}
|
|
51
51
|
});
|
|
52
52
|
const parsed = parseJsonObjectFromStdout(run.stdout);
|
|
53
|
-
const ok =
|
|
53
|
+
const ok = realMode
|
|
54
|
+
? run.code === 0 && parsed?.ok === true && parsed?.route === '$Naruto' && parsed?.status === 'completed'
|
|
55
|
+
: run.code === 0
|
|
56
|
+
&& parsed?.ok === false
|
|
57
|
+
&& parsed?.route === '$Naruto'
|
|
58
|
+
&& parsed?.status === 'delegation_context_ready'
|
|
59
|
+
&& parsed?.app_session === true;
|
|
54
60
|
assertGate(ok || (realMode && !requireReal), `${mode} Naruto E2E failed`, {
|
|
55
61
|
code: run.code,
|
|
56
62
|
parsed,
|
|
@@ -63,6 +69,7 @@ emitGate(realMode ? 'naruto:e2e-real-codex' : 'naruto:e2e-hermetic', {
|
|
|
63
69
|
temp_root: tempRoot,
|
|
64
70
|
mission_id: parsed?.mission_id || null,
|
|
65
71
|
readonly: true,
|
|
72
|
+
preparation_only: !realMode,
|
|
66
73
|
real_required: requireReal
|
|
67
74
|
});
|
|
68
75
|
function readOption(args, name, fallback = null) {
|