sneakoscope 2.0.2 → 2.0.5
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 +12 -8
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/.sks-build-stamp.json +4 -4
- package/dist/bin/sks.js +1 -1
- package/dist/build-manifest.json +86 -8
- package/dist/commands/doctor.js +14 -0
- package/dist/core/agents/agent-orchestrator.js +70 -4
- package/dist/core/agents/agent-patch-proof.js +5 -0
- package/dist/core/agents/agent-proof-evidence.js +61 -0
- package/dist/core/agents/agent-roster.js +35 -6
- package/dist/core/agents/agent-schema.js +1 -1
- package/dist/core/agents/native-worker-backend-router.js +31 -9
- package/dist/core/agents/ollama-worker-config.js +164 -15
- package/dist/core/codex/codex-0-137-compat.js +119 -0
- package/dist/core/codex-control/codex-control-proof.js +4 -1
- package/dist/core/codex-control/codex-fake-sdk-adapter.js +20 -0
- package/dist/core/codex-control/codex-output-schemas.js +5 -1
- package/dist/core/codex-control/codex-sdk-capability.js +1 -1
- package/dist/core/codex-control/codex-task-runner.js +329 -5
- package/dist/core/codex-control/gpt-final-arbiter.js +160 -0
- package/dist/core/codex-control/gpt-final-context-compressor.js +17 -0
- package/dist/core/codex-control/gpt-final-proof-pack.js +120 -0
- package/dist/core/codex-control/gpt-final-review-schema.js +71 -0
- package/dist/core/codex-control/python-codex-sdk-adapter.js +197 -0
- package/dist/core/codex-control/python-codex-sdk-event-translator.js +14 -0
- package/dist/core/commands/local-model-command.js +79 -18
- package/dist/core/commands/naruto-command.js +195 -12
- package/dist/core/commands/run-command.js +6 -2
- package/dist/core/doctor/doctor-readiness-matrix.js +34 -0
- package/dist/core/feature-fixtures.js +4 -0
- package/dist/core/fsx.js +1 -1
- package/dist/core/git-simple.js +143 -4
- package/dist/core/local-llm/local-collaboration-policy.js +93 -0
- package/dist/core/local-llm/local-llm-backpressure.js +20 -0
- package/dist/core/local-llm/local-llm-capability.js +29 -0
- package/dist/core/local-llm/local-llm-client.js +100 -0
- package/dist/core/local-llm/local-llm-config.js +20 -0
- package/dist/core/local-llm/local-llm-context-cache.js +21 -0
- package/dist/core/local-llm/local-llm-control-adapter.js +101 -0
- package/dist/core/local-llm/local-llm-json-repair.js +52 -0
- package/dist/core/local-llm/local-llm-metrics.js +42 -0
- package/dist/core/local-llm/local-llm-ollama-client.js +67 -0
- package/dist/core/local-llm/local-llm-openai-compatible-client.js +30 -0
- package/dist/core/local-llm/local-llm-prompt-cache.js +12 -0
- package/dist/core/local-llm/local-llm-scheduler.js +29 -0
- package/dist/core/local-llm/local-llm-schema-enforcer.js +15 -0
- package/dist/core/local-llm/local-llm-smoke.js +83 -0
- package/dist/core/local-llm/local-llm-warmup.js +20 -0
- package/dist/core/local-llm/local-worker-eligibility.js +27 -0
- package/dist/core/naruto/hardware-capacity-probe.js +36 -0
- package/dist/core/naruto/naruto-active-pool.js +118 -0
- package/dist/core/naruto/naruto-backpressure.js +13 -0
- package/dist/core/naruto/naruto-concurrency-governor.js +65 -0
- package/dist/core/naruto/naruto-finalizer.js +18 -0
- package/dist/core/naruto/naruto-generation-scheduler.js +18 -0
- package/dist/core/naruto/naruto-gpt-final-pack.js +49 -0
- package/dist/core/naruto/naruto-parallel-patch-apply.js +95 -0
- package/dist/core/naruto/naruto-patch-transaction-batch.js +42 -0
- package/dist/core/naruto/naruto-role-policy.js +107 -0
- package/dist/core/naruto/naruto-verification-dag.js +42 -0
- package/dist/core/naruto/naruto-verification-pool.js +18 -0
- package/dist/core/naruto/naruto-work-graph.js +198 -0
- package/dist/core/naruto/naruto-work-item.js +40 -0
- package/dist/core/naruto/naruto-work-stealing.js +11 -0
- package/dist/core/naruto/resource-pressure-monitor.js +32 -0
- package/dist/core/pipeline/final-gpt-patch-stage.js +31 -0
- package/dist/core/pipeline/final-gpt-review-stage.js +5 -0
- package/dist/core/pipeline/finalize-pipeline-result.js +58 -0
- package/dist/core/pipeline/gpt-final-required.js +12 -0
- package/dist/core/prompt/prompt-placeholder-guard.js +30 -0
- package/dist/core/router/capability-card.js +13 -0
- package/dist/core/router/route-cache.js +3 -0
- package/dist/core/router/ultra-router.js +2 -1
- package/dist/core/routes.js +4 -4
- package/dist/core/safety/mutation-guard.js +2 -0
- package/dist/core/update-check.js +60 -25
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-lane-runtime.js +2 -2
- package/dist/core/zellij/zellij-naruto-dashboard.js +36 -0
- package/dist/core/zellij/zellij-worker-pane-manager.js +4 -4
- package/dist/scripts/blackbox-command-import-smoke.js +10 -1
- package/dist/scripts/check-package-boundary.js +12 -3
- package/dist/scripts/codex-0-137-compat-check.js +27 -0
- package/dist/scripts/codex-environment-scoped-approvals-check.js +10 -0
- package/dist/scripts/codex-plugin-list-json-check.js +8 -0
- package/dist/scripts/codex-sdk-team-naruto-agent-pipeline-check.js +2 -1
- package/dist/scripts/codex-thread-runtime-choice-check.js +10 -0
- package/dist/scripts/gpt-final-arbiter-check.js +63 -0
- package/dist/scripts/gpt-final-arbiter-performance-check.js +36 -0
- package/dist/scripts/local-collab-all-pipelines-final-gpt-check.js +21 -0
- package/dist/scripts/local-collab-gpt-final-availability-check.js +58 -0
- package/dist/scripts/local-collab-no-local-only-final-check.js +27 -0
- package/dist/scripts/local-collab-policy-check.js +17 -0
- package/dist/scripts/local-llm-all-pipelines-check.js +11 -0
- package/dist/scripts/local-llm-cache-performance-check.js +10 -0
- package/dist/scripts/local-llm-capability-check.js +14 -0
- package/dist/scripts/local-llm-smoke-check.js +23 -0
- package/dist/scripts/local-llm-structured-output-check.js +11 -0
- package/dist/scripts/local-llm-throughput-check.js +10 -0
- package/dist/scripts/local-llm-tool-call-repair-check.js +10 -0
- package/dist/scripts/local-llm-warmup-check.js +11 -0
- package/dist/scripts/naruto-active-pool-check.js +27 -0
- package/dist/scripts/naruto-concurrency-governor-check.js +52 -0
- package/dist/scripts/naruto-gpt-final-pack-check.js +34 -0
- package/dist/scripts/naruto-parallel-patch-apply-check.js +41 -0
- package/dist/scripts/naruto-real-local-gpt-final-smoke.js +16 -0
- package/dist/scripts/naruto-role-distribution-check.js +23 -0
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +6 -0
- package/dist/scripts/naruto-verification-pool-check.js +36 -0
- package/dist/scripts/naruto-work-graph-check.js +24 -0
- package/dist/scripts/naruto-zellij-massive-ui-check.js +23 -0
- package/dist/scripts/prompt-placeholder-guard-check.js +33 -0
- package/dist/scripts/python-codex-sdk-all-pipelines-check.js +47 -0
- package/dist/scripts/python-codex-sdk-capability-check.js +75 -0
- package/dist/scripts/python-codex-sdk-sandbox-policy-check.js +10 -0
- package/dist/scripts/python-codex-sdk-stream-bridge-check.js +12 -0
- package/dist/scripts/release-parallel-check.js +1 -1
- package/dist/scripts/release-real-check.js +5 -0
- package/dist/scripts/zellij-worker-pane-manager-check.js +1 -1
- package/package.json +38 -4
- package/schemas/local-llm/local-collaboration-policy.schema.json +57 -0
- package/schemas/local-llm/local-model-config.schema.json +74 -0
- package/schemas/naruto/naruto-concurrency-governor.schema.json +21 -0
- package/schemas/naruto/naruto-work-graph.schema.json +22 -0
|
@@ -162,6 +162,8 @@ export async function guardedProcessKill(ctx, pid, opts = {}) {
|
|
|
162
162
|
export async function guardedPackageInstall(ctx, spec, opts) {
|
|
163
163
|
return guard(ctx, 'package_install', spec, opts, async () => {
|
|
164
164
|
const runOpts = { timeoutMs: opts.timeoutMs ?? 600000 };
|
|
165
|
+
if (opts.cwd !== undefined)
|
|
166
|
+
runOpts.cwd = opts.cwd;
|
|
165
167
|
if (opts.env !== undefined)
|
|
166
168
|
runOpts.env = opts.env;
|
|
167
169
|
if (opts.maxOutputBytes !== undefined)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { PACKAGE_VERSION, packageRoot, readJson, runProcess, which } from './fsx.js';
|
|
4
|
+
import { createRequestedScopeContract } from './safety/requested-scope-contract.js';
|
|
5
|
+
import { guardedPackageInstall, guardContextForRoute } from './safety/mutation-guard.js';
|
|
4
6
|
const DEFAULT_REGISTRY = 'https://registry.npmjs.org/';
|
|
5
7
|
export async function runSksUpdateCheck(options = {}) {
|
|
6
8
|
const packageName = options.packageName || 'sneakoscope';
|
|
@@ -17,9 +19,21 @@ export async function runSksUpdateCheck(options = {}) {
|
|
|
17
19
|
effectiveOptions.timeoutMs = options.timeoutMs;
|
|
18
20
|
if (options.maxOutputBytes !== undefined)
|
|
19
21
|
effectiveOptions.maxOutputBytes = options.maxOutputBytes;
|
|
20
|
-
const effective = await detectEffectiveSksVersion(effectiveOptions);
|
|
21
|
-
const current = effective.current;
|
|
22
22
|
const override = env[versionOverrideEnvName(packageName)];
|
|
23
|
+
const effectivePromise = detectEffectiveSksVersion(effectiveOptions);
|
|
24
|
+
const latestPromise = !override && npmBin
|
|
25
|
+
? runProcess(npmBin, ['view', packageName, 'version', '--silent', '--registry', registry], {
|
|
26
|
+
env,
|
|
27
|
+
timeoutMs: options.timeoutMs ?? 5000,
|
|
28
|
+
maxOutputBytes: options.maxOutputBytes ?? 4096
|
|
29
|
+
}).catch((err) => ({
|
|
30
|
+
code: 1,
|
|
31
|
+
stdout: '',
|
|
32
|
+
stderr: err instanceof Error ? err.message : String(err)
|
|
33
|
+
}))
|
|
34
|
+
: Promise.resolve(null);
|
|
35
|
+
const effective = await effectivePromise;
|
|
36
|
+
const current = effective.current;
|
|
23
37
|
if (override)
|
|
24
38
|
return buildResult({ packageName, current, effective, latest: override, registry, npmBin });
|
|
25
39
|
if (!npmBin) {
|
|
@@ -33,16 +47,18 @@ export async function runSksUpdateCheck(options = {}) {
|
|
|
33
47
|
error: 'npm not found on PATH'
|
|
34
48
|
});
|
|
35
49
|
}
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
const result = await latestPromise;
|
|
51
|
+
if (!result) {
|
|
52
|
+
return buildResult({
|
|
53
|
+
packageName,
|
|
54
|
+
current,
|
|
55
|
+
effective,
|
|
56
|
+
latest: null,
|
|
57
|
+
registry,
|
|
58
|
+
npmBin,
|
|
59
|
+
error: 'npm view failed'
|
|
60
|
+
});
|
|
61
|
+
}
|
|
46
62
|
if (result.code !== 0) {
|
|
47
63
|
return buildResult({
|
|
48
64
|
packageName,
|
|
@@ -157,7 +173,17 @@ export async function runSksUpdateNow(options = {}) {
|
|
|
157
173
|
error: null
|
|
158
174
|
});
|
|
159
175
|
}
|
|
160
|
-
const
|
|
176
|
+
const mutationLedgerRoot = env.SKS_MUTATION_LEDGER_ROOT || packageRoot();
|
|
177
|
+
const installContract = createRequestedScopeContract({
|
|
178
|
+
route: 'update',
|
|
179
|
+
userRequest: command || `npm global install ${packageName}`,
|
|
180
|
+
projectRoot: mutationLedgerRoot,
|
|
181
|
+
overrides: { package_install: true }
|
|
182
|
+
});
|
|
183
|
+
const install = await guardedPackageInstall(guardContextForRoute(mutationLedgerRoot, installContract, command || `npm global install ${packageName}`), `${packageName}@${installVersion}`, {
|
|
184
|
+
confirmed: true,
|
|
185
|
+
command: npmBin,
|
|
186
|
+
args: npmArgs,
|
|
161
187
|
cwd,
|
|
162
188
|
env,
|
|
163
189
|
timeoutMs: options.timeoutMs ?? 10 * 60 * 1000,
|
|
@@ -202,25 +228,34 @@ export async function detectEffectiveSksVersion(options = {}) {
|
|
|
202
228
|
};
|
|
203
229
|
add(options.currentVersion || PACKAGE_VERSION, 'runtime');
|
|
204
230
|
add(env.SKS_INSTALLED_SKS_VERSION, 'env:SKS_INSTALLED_SKS_VERSION');
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
231
|
+
const packageRootPromise = readJson(path.join(packageRoot(), 'package.json'), {}).catch(() => ({}));
|
|
232
|
+
const pathSksPromise = which('sks')
|
|
233
|
+
.then(async (sks) => {
|
|
234
|
+
if (!sks)
|
|
235
|
+
return null;
|
|
209
236
|
const result = await runProcess(sks, ['--version'], {
|
|
210
237
|
timeoutMs: 2000,
|
|
211
238
|
maxOutputBytes: 4096,
|
|
212
239
|
env: { ...env, SKS_DISABLE_UPDATE_CHECK: '1' }
|
|
213
240
|
}).catch((err) => ({ code: 1, stdout: '', stderr: err?.message || String(err) }));
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (npmBin) {
|
|
220
|
-
const npmGlobal = await detectNpmGlobalPackageVersion(npmBin, packageName, env, {
|
|
241
|
+
return { sks, result };
|
|
242
|
+
})
|
|
243
|
+
.catch(() => null);
|
|
244
|
+
const npmGlobalPromise = npmBin
|
|
245
|
+
? detectNpmGlobalPackageVersion(npmBin, packageName, env, {
|
|
221
246
|
timeoutMs: options.timeoutMs ?? 2500,
|
|
222
247
|
maxOutputBytes: options.maxOutputBytes ?? 8192
|
|
223
|
-
}).catch((err) => ({ version: null, error: err?.message || String(err) }))
|
|
248
|
+
}).catch((err) => ({ version: null, error: err?.message || String(err) }))
|
|
249
|
+
: Promise.resolve(null);
|
|
250
|
+
const [pkg, pathSks, npmGlobal] = await Promise.all([packageRootPromise, pathSksPromise, npmGlobalPromise]);
|
|
251
|
+
add(pkg?.version, 'packageRoot:package.json');
|
|
252
|
+
if (pathSks?.sks) {
|
|
253
|
+
if (pathSks.result.code === 0)
|
|
254
|
+
add(pathSks.result.stdout, `PATH:${pathSks.sks}`);
|
|
255
|
+
else
|
|
256
|
+
errors.push(`path_sks_version:${String(pathSks.result.stderr || pathSks.result.stdout || 'failed').trim()}`);
|
|
257
|
+
}
|
|
258
|
+
if (npmGlobal) {
|
|
224
259
|
add(npmGlobal.version, `npm-global:${packageName}`);
|
|
225
260
|
if (npmGlobal.error)
|
|
226
261
|
errors.push(`npm_global_version:${npmGlobal.error}`);
|
package/dist/core/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const PACKAGE_VERSION = '2.0.
|
|
1
|
+
export const PACKAGE_VERSION = '2.0.5';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -176,10 +176,10 @@ export function extractZellijPaneIdFromOutput(text) {
|
|
|
176
176
|
}
|
|
177
177
|
const lines = raw.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
178
178
|
for (const line of lines.slice().reverse()) {
|
|
179
|
-
const direct = line.match(/^(?:pane[_ -]?id[:=]\s*)?([0-9]+)$/i);
|
|
179
|
+
const direct = line.match(/^(?:pane[_ -]?id[:=]\s*)?([0-9]+|terminal_[0-9]+)$/i);
|
|
180
180
|
if (direct?.[1])
|
|
181
181
|
return direct[1];
|
|
182
|
-
const embedded = line.match(/\bpane[_ -]?id[:=]\s*([0-9]+)\b/i);
|
|
182
|
+
const embedded = line.match(/\bpane[_ -]?id[:=]\s*([0-9]+|terminal_[0-9]+)\b/i);
|
|
183
183
|
if (embedded?.[1])
|
|
184
184
|
return embedded[1];
|
|
185
185
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function planNarutoZellijDashboard(input) {
|
|
2
|
+
const targetActiveWorkers = Math.max(1, Math.floor(Number(input.targetActiveWorkers || 1)));
|
|
3
|
+
const visiblePaneCap = Math.max(1, Math.floor(Number(input.visiblePaneCap || 12)));
|
|
4
|
+
const visibleWorkerPanes = Math.min(targetActiveWorkers, visiblePaneCap);
|
|
5
|
+
const headlessWorkers = Math.max(0, targetActiveWorkers - visibleWorkerPanes);
|
|
6
|
+
const backend = input.backend || 'codex-sdk';
|
|
7
|
+
const roles = input.roles && input.roles.length ? input.roles : ['implementer', 'modifier', 'verifier', 'test_writer'];
|
|
8
|
+
const paneTitles = Array.from({ length: visibleWorkerPanes }, (_, index) => {
|
|
9
|
+
const slot = `slot-${String(index + 1).padStart(3, '0')}`;
|
|
10
|
+
const role = roles[index % roles.length] || 'worker';
|
|
11
|
+
return `${slot}/gen-1 · ${role} · ${backend} · active`;
|
|
12
|
+
});
|
|
13
|
+
const blockers = [
|
|
14
|
+
...(visibleWorkerPanes > visiblePaneCap ? ['naruto_zellij_visible_panes_exceed_cap'] : []),
|
|
15
|
+
...(headlessWorkers < 0 ? ['naruto_zellij_headless_negative'] : [])
|
|
16
|
+
];
|
|
17
|
+
return {
|
|
18
|
+
schema: 'sks.zellij-naruto-dashboard.v1',
|
|
19
|
+
target_active_workers: targetActiveWorkers,
|
|
20
|
+
visible_pane_cap: visiblePaneCap,
|
|
21
|
+
visible_worker_panes: visibleWorkerPanes,
|
|
22
|
+
headless_workers: headlessWorkers,
|
|
23
|
+
dashboard: {
|
|
24
|
+
active: targetActiveWorkers,
|
|
25
|
+
visible: visibleWorkerPanes,
|
|
26
|
+
headless: headlessWorkers,
|
|
27
|
+
completed: Math.max(0, Math.floor(Number(input.completed || 0))),
|
|
28
|
+
failed: Math.max(0, Math.floor(Number(input.failed || 0))),
|
|
29
|
+
backpressure: input.backpressure || 'normal'
|
|
30
|
+
},
|
|
31
|
+
pane_titles: paneTitles,
|
|
32
|
+
ok: blockers.length === 0,
|
|
33
|
+
blockers
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=zellij-naruto-dashboard.js.map
|
|
@@ -9,10 +9,10 @@ export const ZELLIJ_WORKER_PANE_EVENT_SCHEMA = 'sks.zellij-worker-pane-event.v1'
|
|
|
9
9
|
export function buildWorkerPaneName(slotId, generationIndex) {
|
|
10
10
|
return `${slotId}/gen-${Math.max(1, Math.floor(Number(generationIndex) || 1))}`;
|
|
11
11
|
}
|
|
12
|
-
export function buildWorkerPaneTitle(slotId, generationIndex, context, serviceTier) {
|
|
12
|
+
export function buildWorkerPaneTitle(slotId, generationIndex, context, serviceTier, backend, status) {
|
|
13
13
|
const base = buildWorkerPaneName(slotId, generationIndex);
|
|
14
14
|
const normalized = normalizePaneProviderContext(context, serviceTier);
|
|
15
|
-
return `${base} · codex-sdk · ${providerPaneLabel(normalized)}`;
|
|
15
|
+
return `${base} · ${backend || 'codex-sdk'} · ${providerPaneLabel(normalized)} · ${status || 'launching'}`;
|
|
16
16
|
}
|
|
17
17
|
export function isRealZellijWorkerPaneIdSource(value) {
|
|
18
18
|
return value === 'zellij_worker_new_pane_stdout' || value === 'zellij_worker_list_panes';
|
|
@@ -22,7 +22,7 @@ export function buildWorkerPaneArtifact(input) {
|
|
|
22
22
|
const paneIdSource = input.paneIdSource || 'zellij_worker_pane_launch_failed';
|
|
23
23
|
const blockers = input.blockers || [];
|
|
24
24
|
const providerContext = normalizePaneProviderContext(input.providerContext, input.serviceTier);
|
|
25
|
-
const paneTitle = buildWorkerPaneTitle(input.slotId, input.generationIndex, providerContext, input.serviceTier);
|
|
25
|
+
const paneTitle = buildWorkerPaneTitle(input.slotId, input.generationIndex, providerContext, input.serviceTier, input.backend, input.status || input.statusLabel);
|
|
26
26
|
return {
|
|
27
27
|
schema: ZELLIJ_WORKER_PANE_SCHEMA,
|
|
28
28
|
generated_at: now,
|
|
@@ -82,7 +82,7 @@ export async function openWorkerPane(input) {
|
|
|
82
82
|
timeoutMs: 5000,
|
|
83
83
|
optional: false
|
|
84
84
|
});
|
|
85
|
-
const paneName = buildWorkerPaneTitle(input.slotId, input.generationIndex, providerContext, input.serviceTier);
|
|
85
|
+
const paneName = buildWorkerPaneTitle(input.slotId, input.generationIndex, providerContext, input.serviceTier, input.backend, input.statusLabel || 'running');
|
|
86
86
|
let launch = createSession.ok
|
|
87
87
|
? await runZellij(['--session', input.sessionName, 'action', 'new-pane', '--direction', 'right', '--name', paneName, '--', 'sh', '-lc', input.workerCommand], {
|
|
88
88
|
cwd,
|
|
@@ -5,6 +5,7 @@ import os from 'node:os';
|
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { spawnSync } from 'node:child_process';
|
|
7
7
|
import { pathToFileURL } from 'node:url';
|
|
8
|
+
import { currentDistFreshness } from './lib/ensure-dist-fresh.js';
|
|
8
9
|
const root = process.cwd();
|
|
9
10
|
const npmBin = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
10
11
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-command-import-smoke-'));
|
|
@@ -16,7 +17,15 @@ const rows = [];
|
|
|
16
17
|
fs.mkdirSync(consumer, { recursive: true });
|
|
17
18
|
fs.writeFileSync(path.join(consumer, 'package.json'), `${JSON.stringify({ name: 'sks-command-smoke-consumer', private: true }, null, 2)}\n`);
|
|
18
19
|
try {
|
|
19
|
-
|
|
20
|
+
if (process.env.SKS_ENSURE_DIST_NO_REBUILD === '1' || process.env.SKS_RELEASE_DIST_FRESHNESS_NO_REBUILD === '1') {
|
|
21
|
+
const freshness = currentDistFreshness();
|
|
22
|
+
rows.push({ label: 'dist_freshness', ok: freshness.ok, status: freshness.ok ? 0 : 1, issues: freshness.issues });
|
|
23
|
+
if (!freshness.ok)
|
|
24
|
+
failures.push(`dist_not_fresh:${freshness.issues.join(',')}`);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
run('build', npmBin, ['run', 'build'], { cwd: root });
|
|
28
|
+
}
|
|
20
29
|
const pack = run('npm_pack', npmBin, ['pack', '--json', '--ignore-scripts', '--pack-destination', tmp, '--registry', 'https://registry.npmjs.org/'], { cwd: root });
|
|
21
30
|
const info = pack.ok ? JSON.parse(pack.stdout || '[]')[0] : null;
|
|
22
31
|
const tarball = info ? path.join(tmp, info.filename) : null;
|
|
@@ -5,12 +5,21 @@ import os from 'node:os';
|
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { spawnSync } from 'node:child_process';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { currentDistFreshness } from './lib/ensure-dist-fresh.js';
|
|
8
9
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
9
10
|
const npmBin = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
10
11
|
const issues = [];
|
|
11
|
-
const
|
|
12
|
-
if (
|
|
13
|
-
|
|
12
|
+
const noRebuild = process.env.SKS_ENSURE_DIST_NO_REBUILD === '1' || process.env.SKS_RELEASE_DIST_FRESHNESS_NO_REBUILD === '1';
|
|
13
|
+
if (noRebuild) {
|
|
14
|
+
const freshness = currentDistFreshness();
|
|
15
|
+
if (!freshness.ok)
|
|
16
|
+
issues.push(`dist_not_fresh:${freshness.issues.join(',')}`);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
const build = spawnSync(npmBin, ['run', 'build'], { cwd: root, encoding: 'utf8', stdio: 'pipe' });
|
|
20
|
+
if (build.status !== 0)
|
|
21
|
+
issues.push(`build_failed:${tail(build.stderr || build.stdout)}`);
|
|
22
|
+
}
|
|
14
23
|
const pack = spawnSync(npmBin, ['pack', '--dry-run', '--json', '--ignore-scripts'], {
|
|
15
24
|
cwd: root,
|
|
16
25
|
encoding: 'utf8',
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { pathToFileURL } from 'node:url';
|
|
6
|
+
import { ensureDistFresh, root } from './lib/ensure-dist-fresh.js';
|
|
7
|
+
const freshness = ensureDistFresh({ rebuild: true });
|
|
8
|
+
if (!freshness.ok)
|
|
9
|
+
fail('dist_not_fresh', { freshness });
|
|
10
|
+
const mod = await import(pathToFileURL(path.join(root, 'dist', 'core', 'codex', 'codex-0-137-compat.js')).href);
|
|
11
|
+
const evidence = await mod.collectCodex0137LocalEvidence();
|
|
12
|
+
const matrix = mod.codex0137Matrix({
|
|
13
|
+
version: evidence.versionText,
|
|
14
|
+
available: evidence.available,
|
|
15
|
+
pluginListText: evidence.pluginListText,
|
|
16
|
+
debugModelsText: evidence.debugModelsText,
|
|
17
|
+
doctorText: evidence.doctorText,
|
|
18
|
+
requireReal: process.argv.includes('--require-real') || process.env.SKS_REQUIRE_CODEX_0137 === '1'
|
|
19
|
+
});
|
|
20
|
+
const report = { ...matrix, local_evidence: evidence };
|
|
21
|
+
await fs.mkdir(path.join(root, '.sneakoscope', 'reports'), { recursive: true });
|
|
22
|
+
await fs.writeFile(path.join(root, '.sneakoscope', 'reports', 'codex-0.137-compat.json'), `${JSON.stringify(report, null, 2)}\n`);
|
|
23
|
+
emit(report);
|
|
24
|
+
function emit(report) { console.log(JSON.stringify(report, null, 2)); if (!report.ok)
|
|
25
|
+
process.exitCode = 1; }
|
|
26
|
+
function fail(blocker, detail) { emit({ schema: 'sks.codex-0.137-compat-check.v1', ok: false, blockers: [blocker], detail }); process.exit(1); }
|
|
27
|
+
//# sourceMappingURL=codex-0-137-compat-check.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { assertGate, emitGate, readText } from './lib/codex-sdk-gate-lib.js';
|
|
4
|
+
const proof = readText('src/core/codex-control/codex-control-proof.ts');
|
|
5
|
+
const sandbox = readText('src/core/codex-control/codex-sdk-sandbox-policy.ts');
|
|
6
|
+
assertGate(proof.includes('sandbox:'), 'Codex control proof must include sandbox scope');
|
|
7
|
+
assertGate(proof.includes('env:'), 'Codex control proof must include environment proof');
|
|
8
|
+
assertGate(sandbox.includes('mad_sks_authorized') || sandbox.includes('user_confirmed_full_access'), 'Sandbox policy must include scoped authorization signals');
|
|
9
|
+
emitGate('codex:environment-scoped-approvals', { proof: ['sandbox', 'env', 'scoped_authorization'] });
|
|
10
|
+
//# sourceMappingURL=codex-environment-scoped-approvals-check.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { assertGate, emitGate, readText } from './lib/codex-sdk-gate-lib.js';
|
|
4
|
+
const source = readText('src/core/codex/codex-0-137-compat.ts');
|
|
5
|
+
assertGate(source.includes("run(['plugin', 'list', '--json'])"), '0.137 evidence must run codex plugin list --json');
|
|
6
|
+
assertGate(source.includes('looksLikeJson'), '0.137 plugin list JSON parser missing');
|
|
7
|
+
emitGate('codex:plugin-list-json', { detector: 'codex plugin list --json' });
|
|
8
|
+
//# sourceMappingURL=codex-plugin-list-json-check.js.map
|
|
@@ -6,6 +6,7 @@ const naruto = readText('src/core/commands/naruto-command.ts');
|
|
|
6
6
|
const agent = readText('src/core/agents/agent-command-surface.ts');
|
|
7
7
|
assertGate(team.includes("backend: mock ? 'fake' : 'codex-sdk'"), 'Team must default to codex-sdk');
|
|
8
8
|
assertGate(naruto.includes("backend: 'codex-sdk'"), 'Naruto help/defaults must expose codex-sdk');
|
|
9
|
-
assertGate(agent.includes("
|
|
9
|
+
assertGate(agent.includes("useOllama && !noOllama ? 'ollama' : 'codex-sdk'"), 'Agent command surface must default to codex-sdk unless local model is explicit');
|
|
10
|
+
assertGate(agent.includes('backendExplicit'), 'Agent command surface must preserve explicit backend/local-model intent');
|
|
10
11
|
emitGate('codex-sdk:team-naruto-agent-pipeline', { routes: ['$Team', '$Naruto', '$Agent'] });
|
|
11
12
|
//# sourceMappingURL=codex-sdk-team-naruto-agent-pipeline-check.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { assertGate, emitGate, readText } from './lib/codex-sdk-gate-lib.js';
|
|
4
|
+
const runner = readText('src/core/codex-control/codex-task-runner.ts');
|
|
5
|
+
const registry = readText('src/core/codex-control/codex-thread-registry.ts');
|
|
6
|
+
assertGate(runner.includes('backendPreference'), 'Codex task runner must carry backend/runtime preference');
|
|
7
|
+
assertGate(runner.includes('backend_family'), 'Codex task runner must persist backend family');
|
|
8
|
+
assertGate(registry.includes('recordCodexThread'), 'Codex thread registry missing');
|
|
9
|
+
emitGate('codex:thread-runtime-choice', { runtime_choice: 'backendPreference/backend_family' });
|
|
10
|
+
//# sourceMappingURL=codex-thread-runtime-choice-check.js.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { assertGate, emitGate, importDist, readJsonFile, root } from './lib/codex-sdk-gate-lib.js';
|
|
7
|
+
const mod = await importDist('core/codex-control/gpt-final-arbiter.js');
|
|
8
|
+
const old = snapshotEnv();
|
|
9
|
+
process.env.NODE_ENV = 'test';
|
|
10
|
+
process.env.SKS_CODEX_SDK_FAKE = '1';
|
|
11
|
+
delete process.env.SKS_GPT_FINAL_ARBITER_UNAVAILABLE;
|
|
12
|
+
try {
|
|
13
|
+
const tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-gpt-final-arbiter-'));
|
|
14
|
+
const approved = await mod.runGptFinalArbiter(fixtureInput('approved'), { cwd: root, mutationLedgerRoot: tmp });
|
|
15
|
+
assertGate(approved.ok === true, 'GPT final arbiter fixture must approve safe candidate', approved);
|
|
16
|
+
assertGate(approved.backend === 'codex-sdk', 'GPT final arbiter backend must be codex-sdk');
|
|
17
|
+
assertGate(approved.result.status === 'approved', 'safe candidate must return approved');
|
|
18
|
+
assertGate(approved.final_gate.ok === true, 'approved arbiter result must pass final gate');
|
|
19
|
+
const artifact = await readJsonFile(path.join(tmp, 'gpt-final-arbiter.json'));
|
|
20
|
+
assertGate(artifact.result.schema === 'sks.gpt-final-arbiter-result.v1', 'arbiter artifact must contain schema-valid result');
|
|
21
|
+
const unsafeTmp = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-gpt-final-arbiter-unsafe-'));
|
|
22
|
+
const rejected = await mod.runGptFinalArbiter({ ...fixtureInput('unsafe'), candidate_diff: 'unsafe delete all credential patch' }, { cwd: root, mutationLedgerRoot: unsafeTmp });
|
|
23
|
+
assertGate(rejected.ok === false, 'unsafe candidate must not pass final arbiter');
|
|
24
|
+
assertGate(rejected.result.status === 'rejected', 'unsafe candidate must be rejected');
|
|
25
|
+
assertGate(rejected.blockers.includes('unsafe_candidate_patch'), 'unsafe rejection blocker must be preserved');
|
|
26
|
+
emitGate('local-collab:gpt-final-arbiter', { approved: approved.result.status, rejected: rejected.result.status });
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
restoreEnv(old);
|
|
30
|
+
}
|
|
31
|
+
function fixtureInput(label) {
|
|
32
|
+
return {
|
|
33
|
+
schema: 'sks.gpt-final-arbiter-input.v1',
|
|
34
|
+
route: '$Naruto',
|
|
35
|
+
mission_id: `M-${label}`,
|
|
36
|
+
local_mode: 'local-parallel-gpt-final',
|
|
37
|
+
local_outputs: [
|
|
38
|
+
{ worker_id: 'slot-001/gen-1', backend: 'local-llm', summary: 'candidate patch drafted', patch_envelopes: [], proof: 'local draft' }
|
|
39
|
+
],
|
|
40
|
+
candidate_diff: 'diff --git a/example.ts b/example.ts',
|
|
41
|
+
candidate_patch_envelopes: [],
|
|
42
|
+
verification_results: [{ ok: true, status: 'passed' }],
|
|
43
|
+
side_effect_report: { ok: true },
|
|
44
|
+
mutation_ledger: { ok: true },
|
|
45
|
+
rollback_plan: { ok: true }
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function snapshotEnv() {
|
|
49
|
+
return {
|
|
50
|
+
NODE_ENV: process.env.NODE_ENV,
|
|
51
|
+
SKS_CODEX_SDK_FAKE: process.env.SKS_CODEX_SDK_FAKE,
|
|
52
|
+
SKS_GPT_FINAL_ARBITER_UNAVAILABLE: process.env.SKS_GPT_FINAL_ARBITER_UNAVAILABLE
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function restoreEnv(old) {
|
|
56
|
+
for (const [key, value] of Object.entries(old)) {
|
|
57
|
+
if (value === undefined)
|
|
58
|
+
delete process.env[key];
|
|
59
|
+
else
|
|
60
|
+
process.env[key] = value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=gpt-final-arbiter-check.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { assertGate, emitGate, importDist } from './lib/codex-sdk-gate-lib.js';
|
|
4
|
+
const compressor = await importDist('core/codex-control/gpt-final-context-compressor.js');
|
|
5
|
+
const local_outputs = Array.from({ length: 20 }, (_, index) => ({
|
|
6
|
+
worker_id: `slot-${String(index + 1).padStart(3, '0')}/gen-1`,
|
|
7
|
+
backend: 'local-llm',
|
|
8
|
+
status: 'done',
|
|
9
|
+
summary: `worker ${index + 1} summarized a bounded shard`,
|
|
10
|
+
changed_files: [`src/example-${index + 1}.ts`],
|
|
11
|
+
blockers: []
|
|
12
|
+
}));
|
|
13
|
+
const candidate_patch_envelopes = local_outputs.map((output, index) => ({
|
|
14
|
+
id: `patch-${index + 1}`,
|
|
15
|
+
agent_id: output.worker_id,
|
|
16
|
+
source: 'model_authored',
|
|
17
|
+
lease_id: `lease-${index + 1}`,
|
|
18
|
+
rollback_hint: { ok: true },
|
|
19
|
+
operations: [{ op: 'replace', path: output.changed_files[0], search: 'before', replace: 'after' }]
|
|
20
|
+
}));
|
|
21
|
+
const report = compressor.compressGptFinalContext({
|
|
22
|
+
route: '$Naruto',
|
|
23
|
+
mission_id: 'M-20-local-workers',
|
|
24
|
+
local_mode: 'local-parallel-gpt-final',
|
|
25
|
+
local_outputs,
|
|
26
|
+
candidate_patch_envelopes,
|
|
27
|
+
verification_results: [{ ok: true, status: 'passed' }],
|
|
28
|
+
side_effect_report: { ok: true },
|
|
29
|
+
mutation_ledger: { ok: true },
|
|
30
|
+
rollback_plan: { ok: true }
|
|
31
|
+
});
|
|
32
|
+
assertGate(report.proof_pack.worker_count === 20, 'proof pack must include 20 worker summaries');
|
|
33
|
+
assertGate(report.proof_pack.token_budget_estimate < 8000, '20-worker proof pack must stay under token budget', report.proof_pack);
|
|
34
|
+
assertGate(report.latency_budget.ok === true, 'GPT final latency budget report must pass');
|
|
35
|
+
emitGate('local-collab:gpt-final-performance', { workers: report.proof_pack.worker_count, token_budget_estimate: report.proof_pack.token_budget_estimate });
|
|
36
|
+
//# sourceMappingURL=gpt-final-arbiter-performance-check.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { assertGate, emitGate, importDist } from './lib/codex-sdk-gate-lib.js';
|
|
4
|
+
const finalizer = await importDist('core/pipeline/finalize-pipeline-result.js');
|
|
5
|
+
const blocked = await finalizer.finalizePipelineResult({
|
|
6
|
+
route: '$Team',
|
|
7
|
+
missionId: 'M-local-final-gpt',
|
|
8
|
+
localParticipated: true,
|
|
9
|
+
candidateResults: [{ backend: 'local-llm', summary: 'draft' }],
|
|
10
|
+
candidatePatchEnvelopes: [],
|
|
11
|
+
verificationResults: [],
|
|
12
|
+
sideEffectReport: {},
|
|
13
|
+
mutationLedger: {},
|
|
14
|
+
rollbackPlan: {},
|
|
15
|
+
applyPatches: true,
|
|
16
|
+
forceGptFinalUnavailable: true
|
|
17
|
+
});
|
|
18
|
+
assertGate(blocked.ok === false, 'local participation without GPT final must block finalization');
|
|
19
|
+
assertGate(blocked.blockers.includes('gpt_final_arbiter_required_not_passed'), 'missing GPT final blocker required');
|
|
20
|
+
emitGate('local-collab:all-pipelines-final-gpt', { final_status: blocked.final_status, blockers: blocked.blockers.length });
|
|
21
|
+
//# sourceMappingURL=local-collab-all-pipelines-final-gpt-check.js.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { assertGate, emitGate, importDist, root } from './lib/codex-sdk-gate-lib.js';
|
|
7
|
+
const arbiterMod = await importDist('core/codex-control/gpt-final-arbiter.js');
|
|
8
|
+
const doctorMod = await importDist('core/doctor/doctor-readiness-matrix.js');
|
|
9
|
+
const old = snapshotEnv();
|
|
10
|
+
try {
|
|
11
|
+
process.env.SKS_GPT_FINAL_ARBITER_UNAVAILABLE = '1';
|
|
12
|
+
const unavailable = await arbiterMod.runGptFinalArbiter(input('unavailable'), { writeArtifact: false, forceUnavailable: true });
|
|
13
|
+
assertGate(unavailable.ok === false, 'GPT unavailable fixture must block final apply');
|
|
14
|
+
assertGate(unavailable.blockers.includes('gpt_final_arbiter_unavailable'), 'GPT unavailable blocker must be present');
|
|
15
|
+
const doctor = doctorMod.buildDoctorReadinessMatrix({
|
|
16
|
+
codex: { available: false },
|
|
17
|
+
codex_config: { ok: true, checks: [] },
|
|
18
|
+
local_collaboration: { mode: 'local-parallel-gpt-final', gpt_final_arbiter_available: false }
|
|
19
|
+
});
|
|
20
|
+
assertGate(doctor.blockers.includes('gpt_final_arbiter_unavailable'), 'doctor must report gpt_final_arbiter_unavailable');
|
|
21
|
+
delete process.env.SKS_GPT_FINAL_ARBITER_UNAVAILABLE;
|
|
22
|
+
process.env.NODE_ENV = 'test';
|
|
23
|
+
process.env.SKS_CODEX_SDK_FAKE = '1';
|
|
24
|
+
const tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-gpt-final-available-'));
|
|
25
|
+
const available = await arbiterMod.runGptFinalArbiter(input('available'), { cwd: root, mutationLedgerRoot: tmp });
|
|
26
|
+
assertGate(available.ok === true, 'GPT available fixture must pass final arbiter');
|
|
27
|
+
emitGate('local-collab:gpt-final-availability', { unavailable: unavailable.result.status, available: available.result.status });
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
restoreEnv(old);
|
|
31
|
+
}
|
|
32
|
+
function input(label) {
|
|
33
|
+
return {
|
|
34
|
+
schema: 'sks.gpt-final-arbiter-input.v1',
|
|
35
|
+
route: '$Team',
|
|
36
|
+
mission_id: `M-${label}`,
|
|
37
|
+
local_mode: 'local-parallel-gpt-final',
|
|
38
|
+
local_outputs: [{ worker_id: 'local', backend: 'local-llm', summary: 'candidate' }],
|
|
39
|
+
candidate_patch_envelopes: [],
|
|
40
|
+
verification_results: []
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function snapshotEnv() {
|
|
44
|
+
return {
|
|
45
|
+
NODE_ENV: process.env.NODE_ENV,
|
|
46
|
+
SKS_CODEX_SDK_FAKE: process.env.SKS_CODEX_SDK_FAKE,
|
|
47
|
+
SKS_GPT_FINAL_ARBITER_UNAVAILABLE: process.env.SKS_GPT_FINAL_ARBITER_UNAVAILABLE
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function restoreEnv(old) {
|
|
51
|
+
for (const [key, value] of Object.entries(old)) {
|
|
52
|
+
if (value === undefined)
|
|
53
|
+
delete process.env[key];
|
|
54
|
+
else
|
|
55
|
+
process.env[key] = value;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=local-collab-gpt-final-availability-check.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { assertGate, emitGate, importDist } from './lib/codex-sdk-gate-lib.js';
|
|
4
|
+
const policyMod = await importDist('core/local-llm/local-collaboration-policy.js');
|
|
5
|
+
const arbiterMod = await importDist('core/codex-control/gpt-final-arbiter.js');
|
|
6
|
+
const gate = policyMod.evaluateLocalCollaborationFinalGate({
|
|
7
|
+
mode: 'local-only-draft',
|
|
8
|
+
localParticipated: true,
|
|
9
|
+
gptFinalStatus: null,
|
|
10
|
+
gptFinalAvailable: false,
|
|
11
|
+
applyPatches: true
|
|
12
|
+
});
|
|
13
|
+
assertGate(gate.ok === false, 'local-only-draft must not be final accepted');
|
|
14
|
+
assertGate(gate.final_status === 'draft_only', 'local-only-draft must end as draft_only');
|
|
15
|
+
assertGate(gate.apply_allowed === false, 'local-only-draft must block apply');
|
|
16
|
+
const result = await arbiterMod.runGptFinalArbiter({
|
|
17
|
+
schema: 'sks.gpt-final-arbiter-input.v1',
|
|
18
|
+
route: '$DFix',
|
|
19
|
+
mission_id: 'M-local-only-draft',
|
|
20
|
+
local_mode: 'local-only-draft',
|
|
21
|
+
local_outputs: [{ worker_id: 'local', backend: 'local-llm', summary: 'draft only' }],
|
|
22
|
+
candidate_patch_envelopes: []
|
|
23
|
+
}, { writeArtifact: false });
|
|
24
|
+
assertGate(result.ok === false, 'local-only-draft arbiter result must not pass');
|
|
25
|
+
assertGate(result.blockers.includes('needs_gpt_final_review'), 'local-only-draft arbiter must include needs_gpt_final_review');
|
|
26
|
+
emitGate('local-collab:no-local-only-final', { final_status: gate.final_status, blockers: result.blockers.length });
|
|
27
|
+
//# sourceMappingURL=local-collab-no-local-only-final-check.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { assertGate, emitGate, importDist, readText } from './lib/codex-sdk-gate-lib.js';
|
|
4
|
+
const policyMod = await importDist('core/local-llm/local-collaboration-policy.js');
|
|
5
|
+
const schemaText = readText('schemas/local-llm/local-collaboration-policy.schema.json');
|
|
6
|
+
const policy = policyMod.resolveLocalCollaborationPolicy({ env: {} });
|
|
7
|
+
assertGate(policy.mode === 'local-parallel-gpt-final', 'default local collaboration mode must be local-parallel-gpt-final');
|
|
8
|
+
assertGate(policy.gpt_final_required === true, 'default local collaboration mode must require GPT final');
|
|
9
|
+
assertGate(policy.final_patch_source_when_enabled === 'gpt_final_arbiter', 'final patch source must be GPT final arbiter');
|
|
10
|
+
assertGate(schemaText.includes('local-only-draft'), 'policy schema must include local-only-draft mode');
|
|
11
|
+
const draft = policyMod.resolveLocalCollaborationPolicy({ mode: 'local-only-draft' });
|
|
12
|
+
const draftGate = policyMod.evaluateLocalCollaborationFinalGate({ policy: draft, localParticipated: true, applyPatches: true });
|
|
13
|
+
assertGate(draftGate.ok === false, 'local-only-draft must not pass final gate');
|
|
14
|
+
assertGate(draftGate.blockers.includes('needs_gpt_final_review'), 'local-only-draft must carry needs_gpt_final_review');
|
|
15
|
+
assertGate(draftGate.blockers.includes('local_only_draft_apply_blocked'), 'local-only-draft must block apply');
|
|
16
|
+
emitGate('local-collab:policy', { default_mode: policy.mode, draft_blockers: draftGate.blockers.length });
|
|
17
|
+
//# sourceMappingURL=local-collab-policy-check.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { assertGate, emitGate, readText } from './lib/codex-sdk-gate-lib.js';
|
|
4
|
+
const router = readText('src/core/agents/native-worker-backend-router.ts');
|
|
5
|
+
const control = readText('src/core/codex-control/codex-task-runner.ts');
|
|
6
|
+
const policy = readText('src/core/local-llm/local-worker-eligibility.ts');
|
|
7
|
+
assertGate(router.includes("backend === 'local-llm'"), 'native worker router must support local-llm backend');
|
|
8
|
+
assertGate(control.includes('runLocalLlmTask'), 'Codex Control Plane must call local LLM task adapter');
|
|
9
|
+
assertGate(policy.includes('requires_gpt_final'), 'local worker eligibility must require GPT final');
|
|
10
|
+
emitGate('local-llm:all-pipelines', { local_backend: 'local-llm', requires_gpt_final: true });
|
|
11
|
+
//# sourceMappingURL=local-llm-all-pipelines-check.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { assertGate, emitGate, importDist } from './lib/codex-sdk-gate-lib.js';
|
|
4
|
+
const cache = await importDist('core/local-llm/local-llm-prompt-cache.js');
|
|
5
|
+
const a = cache.buildLocalLlmPromptCacheRecord({ routeSystemEnvelopeHash: 'a', localWorkerPolicyHash: 'b', coreSkillSnapshotHash: 'c', triwikiContextPackHash: 'd', repoSummaryHash: 'e', capabilityCardHash: 'f' });
|
|
6
|
+
const b = cache.buildLocalLlmPromptCacheRecord({ routeSystemEnvelopeHash: 'a', localWorkerPolicyHash: 'b', coreSkillSnapshotHash: 'c', triwikiContextPackHash: 'd2', repoSummaryHash: 'e', capabilityCardHash: 'f' });
|
|
7
|
+
assertGate(a.cacheable === true, 'prompt cache record should be cacheable when hashes exist');
|
|
8
|
+
assertGate(a.cache_key !== b.cache_key, 'source hash change must invalidate cache');
|
|
9
|
+
emitGate('local-llm:cache-performance', { cacheable: a.cacheable, invalidates_on_hash_change: true });
|
|
10
|
+
//# sourceMappingURL=local-llm-cache-performance-check.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { assertGate, emitGate, importDist, readText } from './lib/codex-sdk-gate-lib.js';
|
|
4
|
+
const mod = await importDist('core/agents/ollama-worker-config.js');
|
|
5
|
+
const schemaText = readText('schemas/local-llm/local-model-config.schema.json');
|
|
6
|
+
const config = mod.normalizeLocalModelConfig({ enabled: true, status: 'enabled_unverified' });
|
|
7
|
+
const mlx = mod.normalizeLocalModelConfig({ enabled: true, provider: 'mlx-lm', model: 'mlx-community/Qwen3.6-35B-A3B-4bit', base_url: 'http://127.0.0.1:8080' });
|
|
8
|
+
assertGate(config.schema === 'sks.local-model-config.v2', 'local model config must use v2 schema');
|
|
9
|
+
assertGate(config.status === 'enabled_unverified', 'enabled without smoke must be enabled_unverified');
|
|
10
|
+
assertGate(mlx.provider === 'mlx-lm' && mlx.base_url === 'http://127.0.0.1:8080', 'local model config must preserve MLX LM provider settings');
|
|
11
|
+
assertGate(schemaText.includes('verified'), 'local model schema must include verified status');
|
|
12
|
+
assertGate(schemaText.includes('mlx-lm'), 'local model schema must allow MLX LM provider');
|
|
13
|
+
emitGate('local-llm:capability', { status: config.status, schema: config.schema, mlx_provider: mlx.provider });
|
|
14
|
+
//# sourceMappingURL=local-llm-capability-check.js.map
|