sneakoscope 6.0.0 → 6.0.2
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 +2 -1
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +0 -40
- package/dist/bin/sks-dispatch.js +0 -16
- package/dist/cli/codex-app-command.js +1 -2
- package/dist/cli/help-fast.js +2 -2
- package/dist/cli/install-helpers.js +26 -21
- package/dist/config/skills-manifest.json +57 -57
- package/dist/core/agents/agent-effort-policy.js +19 -38
- package/dist/core/agents/agent-orchestrator.js +2 -2
- package/dist/core/agents/agent-role-config.js +17 -10
- package/dist/core/agents/agent-roster.js +19 -39
- package/dist/core/agents/agent-scheduler.js +6 -5
- package/dist/core/agents/agent-schema.js +4 -5
- package/dist/core/agents/agent-task-graph.js +1 -1
- package/dist/core/agents/agent-work-partition.js +2 -1
- package/dist/core/agents/native-worker-backend-router.js +1 -1
- package/dist/core/agents/route-collaboration-ledger.js +2 -2
- package/dist/core/auto-review.js +1 -4
- package/dist/core/codex/codex-config-guard.js +11 -9
- package/dist/core/codex-adapter.js +2 -2
- package/dist/core/codex-app/codex-agent-role-sync.js +0 -1
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +7 -4
- package/dist/core/codex-app/codex-app-ui-state-snapshot.js +1 -7
- package/dist/core/codex-app.js +0 -2
- package/dist/core/codex-control/codex-model-capabilities.js +1 -2
- package/dist/core/codex-control/codex-model-metadata.js +13 -6
- package/dist/core/codex-control/codex-sdk-config-policy.js +3 -3
- package/dist/core/codex-control/codex-task-runner.js +2 -3
- package/dist/core/codex-model-guard.js +24 -89
- package/dist/core/commands/basic-cli.js +6 -0
- package/dist/core/commands/loop-command.js +2 -2
- package/dist/core/commands/mad-db-command.js +1 -1
- package/dist/core/commands/naruto-command.js +11 -11
- package/dist/core/commands/profile-command.js +14 -5
- package/dist/core/commands/qa-loop-command.js +2 -2
- package/dist/core/commands/research-command.js +2 -2
- package/dist/core/doctor/doctor-codex-startup-repair.js +0 -3
- package/dist/core/evaluation.js +1 -1
- package/dist/core/feature-fixtures.js +2 -2
- package/dist/core/feature-registry.js +1 -1
- package/dist/core/hooks-runtime.js +7 -45
- package/dist/core/image-ux-review/imagegen-adapter.js +17 -2
- package/dist/core/init/skills.js +6 -7
- package/dist/core/init.js +7 -20
- package/dist/core/loops/loop-concurrency-budget.js +6 -4
- package/dist/core/loops/loop-planner.js +1 -1
- package/dist/core/loops/loop-runtime.js +2 -2
- package/dist/core/loops/loop-scheduler.js +7 -7
- package/dist/core/managed-assets/managed-assets-manifest.js +1 -4
- package/dist/core/naruto/naruto-concurrency-governor.js +20 -17
- package/dist/core/naruto/naruto-loop-mesh.js +3 -3
- package/dist/core/naruto/resource-pressure-monitor.js +5 -2
- package/dist/core/provider/model-router.js +15 -35
- package/dist/core/release/release-gate-batch-runner.js +2 -1
- package/dist/core/release/release-gate-resource-governor.js +12 -12
- package/dist/core/release/resource-class-budget.js +5 -5
- package/dist/core/routes/constants.js +3 -4
- package/dist/core/routes.js +1 -1
- package/dist/core/structured-output-adapter.js +15 -1
- package/dist/core/update/update-migration-state.js +3 -16
- package/dist/core/version.js +1 -1
- package/dist/scripts/agent-backfill-replenishment-check.js +1 -1
- package/dist/scripts/agent-dynamic-pool-check.js +3 -3
- package/dist/scripts/agent-dynamic-pool-fixture.js +1 -1
- package/dist/scripts/agent-goal-mode-propagation-check.js +1 -1
- package/dist/scripts/agent-patch-swarm-gate-lib.js +2 -2
- package/dist/scripts/agent-role-config-repair-check.js +9 -5
- package/dist/scripts/agent-scheduler-proof-check.js +1 -1
- package/dist/scripts/agent-scheduler-proof-hardening-check.js +1 -1
- package/dist/scripts/agent-source-intelligence-propagation-check.js +1 -1
- package/dist/scripts/agent-strategy-to-lease-wiring-check.js +2 -2
- package/dist/scripts/agent-zellij-dynamic-backfill-panes-check.js +1 -1
- package/dist/scripts/codex-app-fast-ui-preservation-check.js +2 -2
- package/dist/scripts/codex-app-ui-preservation-check.js +6 -5
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +4 -4
- package/dist/scripts/codex-lb-gpt55-fast-profile-check.js +3 -2
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +6 -6
- package/dist/scripts/install-update-preserves-config-check.js +3 -3
- package/dist/scripts/loop-hardening-check-lib.js +1 -1
- package/dist/scripts/naruto-parallelism-mode-check.js +2 -1
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +25 -32
- package/dist/scripts/npm-publish-performance-check.js +1 -1
- package/dist/scripts/release-aggressive-resource-governor-check.js +2 -2
- package/dist/scripts/release-parallel-check.js +1 -2
- package/dist/scripts/release-real-check.js +1 -1
- package/dist/scripts/sizecheck.js +3 -3
- package/package.json +3 -2
|
@@ -5,7 +5,6 @@ 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 { REQUIRED_CODEX_MODEL } from '../core/codex-model-guard.js';
|
|
9
8
|
const tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-codex-lb-gpt55-fast-'));
|
|
10
9
|
const home = path.join(tmp, 'home');
|
|
11
10
|
const root = path.join(tmp, 'project');
|
|
@@ -46,7 +45,7 @@ await fs.writeFile(projectConfig, [
|
|
|
46
45
|
'enabled = true',
|
|
47
46
|
'',
|
|
48
47
|
'[profiles.sks-fast-high]',
|
|
49
|
-
|
|
48
|
+
'model = "future-codex-model"',
|
|
50
49
|
'service_tier = "fast"',
|
|
51
50
|
''
|
|
52
51
|
].join('\n'));
|
|
@@ -87,6 +86,7 @@ function assertFastProfile(text, label) {
|
|
|
87
86
|
...(parsed.default_profile === undefined ? [] : ['default_profile_legacy_key_present']),
|
|
88
87
|
...(parsed.user?.fast_mode === undefined ? [] : ['user_fast_mode_legacy_table_present']),
|
|
89
88
|
...(parsed.profiles?.['sks-fast-high'] === undefined ? [] : ['sks_fast_high_legacy_profile_present']),
|
|
89
|
+
...(parsed.model === undefined ? [] : ['codex_app_model_was_injected']),
|
|
90
90
|
...(provider.requires_openai_auth === true ? [] : ['codex_lb_requires_openai_auth_not_true']),
|
|
91
91
|
...(provider.wire_api === 'responses' ? [] : ['codex_lb_wire_api_not_responses']),
|
|
92
92
|
...(desktop.on ? [] : ['desktop_fast_status_off'])
|
|
@@ -95,6 +95,7 @@ function assertFastProfile(text, label) {
|
|
|
95
95
|
label,
|
|
96
96
|
ok: blockers.length === 0,
|
|
97
97
|
default_profile: parsed.default_profile || null,
|
|
98
|
+
model: parsed.model || null,
|
|
98
99
|
legacy_keys: validation.legacy_keys,
|
|
99
100
|
service_tier: parsed.service_tier || null,
|
|
100
101
|
provider_wire_api: provider.wire_api || null,
|
|
@@ -7,8 +7,8 @@ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-doctor-fast-ui-'));
|
|
|
7
7
|
const codexHome = path.join(root, 'home', '.codex');
|
|
8
8
|
await fs.mkdir(path.join(root, '.codex'), { recursive: true });
|
|
9
9
|
await fs.mkdir(codexHome, { recursive: true });
|
|
10
|
-
await fs.writeFile(path.join(root, '.codex', 'config.toml'), 'model = "
|
|
11
|
-
await fs.writeFile(path.join(codexHome, 'config.toml'), '# SKS forced fast UI during legacy install\nmodel = "
|
|
10
|
+
await fs.writeFile(path.join(root, '.codex', 'config.toml'), 'model = "future-codex-model"\nmodel_reasoning_effort = "medium"\nmodel_provider = "codex-lb"\n');
|
|
11
|
+
await fs.writeFile(path.join(codexHome, 'config.toml'), '# SKS forced fast UI during legacy install\nmodel = "legacy-sks-model"\nmodel_reasoning_effort = "xhigh"\nmodel_provider = "codex-lb"\nservice_tier = "fast"\n[features]\nfast_mode = false # user disabled, must remain untouched\n\n[profiles.sks-fast-high]\nmodel = "legacy-profile-model"\nservice_tier = "fast"\n\n[model_providers.codex-lb]\nname = "openai"\nbase_url = "https://lb.example.test/backend-api/codex"\nwire_api = "responses"\nenv_key = "CODEX_LB_API_KEY"\nsupports_websockets = true\nrequires_openai_auth = true\n');
|
|
12
12
|
const plan = await repairCodexAppFastUi(root, { codexHome, apply: false });
|
|
13
13
|
const repaired = await repairCodexAppFastUi(root, { codexHome, apply: true });
|
|
14
14
|
const projectAfter = await fs.readFile(path.join(root, '.codex', 'config.toml'), 'utf8');
|
|
@@ -29,12 +29,12 @@ const ok = plan.fast_selector === 'manual_action_required'
|
|
|
29
29
|
&& repaired.fast_selector === 'repaired'
|
|
30
30
|
&& repaired.provider_selector === 'manual_action_required'
|
|
31
31
|
&& repaired.safe_auto_apply === true
|
|
32
|
-
&& backups.length >=
|
|
33
|
-
&&
|
|
34
|
-
&&
|
|
32
|
+
&& backups.length >= 1
|
|
33
|
+
&& /^model\s*=\s*"future-codex-model"$/m.test(projectAfter.split(/\n\s*\[/)[0] || '')
|
|
34
|
+
&& /^model_reasoning_effort\s*=\s*"medium"$/m.test(projectAfter.split(/\n\s*\[/)[0] || '')
|
|
35
35
|
&& !/^model\s*=/m.test(homeTopLevel)
|
|
36
36
|
&& !/^model_reasoning_effort\s*=/m.test(homeTopLevel)
|
|
37
|
-
&&
|
|
37
|
+
&& /model_provider\s*=\s*"codex-lb"/.test(projectAfter)
|
|
38
38
|
&& !/service_tier\s*=/.test(homeTopLevel)
|
|
39
39
|
&& /fast_mode = false/.test(homeAfter)
|
|
40
40
|
&& /model_provider = "codex-lb"/.test(homeAfter)
|
|
@@ -23,7 +23,7 @@ const results = [];
|
|
|
23
23
|
const cfg = path.join(codexDir, 'config.toml');
|
|
24
24
|
const userConfig = [
|
|
25
25
|
'# my hand-tuned Codex config',
|
|
26
|
-
'model = "
|
|
26
|
+
'model = "future-codex-model"',
|
|
27
27
|
'service_tier = "standard"',
|
|
28
28
|
'model_reasoning_effort = "high"',
|
|
29
29
|
'',
|
|
@@ -36,7 +36,7 @@ const results = [];
|
|
|
36
36
|
const after = await fs.readFile(cfg, 'utf8');
|
|
37
37
|
const backups = (await fs.readdir(codexDir)).filter((f) => f.startsWith('config.toml.sks-'));
|
|
38
38
|
const ok = res.status === 'updated' &&
|
|
39
|
-
/^model = "
|
|
39
|
+
/^model = "future-codex-model"/m.test(after) && // arbitrary user model preserved
|
|
40
40
|
/^service_tier = "standard"/m.test(after) && // user tier preserved
|
|
41
41
|
/^model_reasoning_effort = "high"/m.test(after) && // user effort NOT stripped
|
|
42
42
|
/# my hand-tuned Codex config/.test(after) && // user comment preserved
|
|
@@ -45,7 +45,7 @@ const results = [];
|
|
|
45
45
|
!/\[user\.fast_mode\]/.test(after) && // legacy fast UI table stripped
|
|
46
46
|
backups.length >= 1 && // backup created
|
|
47
47
|
Boolean(res.backup_path);
|
|
48
|
-
results.push({ case: 'preserves_user_config', ok, status: res.status, backups, model_preserved: /
|
|
48
|
+
results.push({ case: 'preserves_user_config', ok, status: res.status, backups, model_preserved: /future-codex-model/.test(after) });
|
|
49
49
|
}
|
|
50
50
|
// --- Case 2: fresh/empty config gets SKS defaults without forcing fast service tier ---
|
|
51
51
|
{
|
|
@@ -146,7 +146,7 @@ export async function runLoopHardeningCheck(id) {
|
|
|
146
146
|
else if (id === 'loop:concurrency-budget' || id === 'loop:concurrency-budget-runtime' || id === 'loop:concurrency-oversubscription-blackbox') {
|
|
147
147
|
const plan = samplePlan('M-check-budget', Array.from({ length: 10 }, (_, i) => sampleNode(`loop-${i}`, 'M-check-budget', 8, 8)));
|
|
148
148
|
const budget = computeLoopConcurrencyBudget({ plan, parallelism: 'extreme', env: { SKS_LOOP_MAX_ACTIVE_WORKERS: '16', SKS_LOOP_MAX_ACTIVE_LOOPS: '4', SKS_LOOP_MAX_MODEL_CALLS: '8' } });
|
|
149
|
-
assert(budget.max_active_workers ===
|
|
149
|
+
assert(budget.max_active_workers === 4 && budget.max_active_loops === 4, 'env concurrency requests cannot raise the desktop-safe loop budget', budget);
|
|
150
150
|
assert(budget.per_loop_worker_budget.reduce((sum, row) => sum + row.maker_workers + row.checker_workers, 0) <= 16, 'per-loop worker budget does not oversubscribe');
|
|
151
151
|
}
|
|
152
152
|
else if (id === 'loop:mesh-production-e2e-blackbox') {
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
import { decideNarutoConcurrency } from '../core/naruto/naruto-concurrency-governor.js';
|
|
4
4
|
import { DEFAULT_NARUTO_CLONES } from '../core/agents/agent-schema.js';
|
|
5
5
|
import { assertGate, emitGate, readText } from './sks-1-18-gate-lib.js';
|
|
6
|
-
assertGate(DEFAULT_NARUTO_CLONES ===
|
|
6
|
+
assertGate(DEFAULT_NARUTO_CLONES === 8, 'default Naruto clone roster must be 8');
|
|
7
7
|
const extreme = decideNarutoConcurrency({ requestedClones: 32, totalWorkItems: 64, backend: 'fake', parallelismMode: 'extreme' });
|
|
8
8
|
const safe = decideNarutoConcurrency({ requestedClones: 32, totalWorkItems: 64, backend: 'fake', parallelismMode: 'safe' });
|
|
9
9
|
assertGate(extreme.parallelism_mode === 'extreme' && safe.parallelism_mode === 'safe', 'governor must record parallelism mode', { extreme, safe });
|
|
10
|
+
assertGate(extreme.safe_active_workers <= 4 && safe.safe_active_workers <= extreme.safe_active_workers, 'all modes must honor the desktop-safe active-worker cap', { extreme, safe });
|
|
10
11
|
assertGate(readText('src/core/commands/naruto-command.ts').includes('--parallelism'), 'Naruto CLI must parse --parallelism');
|
|
11
12
|
emitGate('naruto:parallelism-mode', { extreme, safe });
|
|
12
13
|
//# sourceMappingURL=naruto-parallelism-mode-check.js.map
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// @ts-nocheck
|
|
3
3
|
// $Naruto Shadow Clone Swarm gate.
|
|
4
|
-
// Proves
|
|
5
|
-
//
|
|
6
|
-
// schedules >20 concurrent clone sessions to completion with proof.
|
|
4
|
+
// Proves Naruto can queue a 100-clone roster while active work stays bounded by
|
|
5
|
+
// the desktop-safe resource governor.
|
|
7
6
|
import { spawnSync } from 'node:child_process';
|
|
8
7
|
import fs from 'node:fs';
|
|
9
8
|
import os from 'node:os';
|
|
@@ -16,11 +15,11 @@ const effortPolicy = await importDist('core/agents/agent-effort-policy.js');
|
|
|
16
15
|
// 1) Naruto ceiling exists and is 100; standard ceiling untouched at 20.
|
|
17
16
|
assertGate(schema.MAX_NARUTO_AGENT_COUNT === 100, 'MAX_NARUTO_AGENT_COUNT must be 100', { value: schema.MAX_NARUTO_AGENT_COUNT });
|
|
18
17
|
assertGate(schema.MAX_AGENT_COUNT === 20, 'MAX_AGENT_COUNT must remain 20 (standard ceiling)', { value: schema.MAX_AGENT_COUNT });
|
|
19
|
-
// 2)
|
|
18
|
+
// 2) Roster size can reach 100, but every scheduler caller stays desktop-safe.
|
|
20
19
|
const narutoSlots = scheduler.normalizeTargetActiveSlots(100, schema.MAX_NARUTO_AGENT_COUNT);
|
|
21
20
|
const defaultSlots = scheduler.normalizeTargetActiveSlots(100);
|
|
22
|
-
assertGate(narutoSlots ===
|
|
23
|
-
assertGate(defaultSlots ===
|
|
21
|
+
assertGate(narutoSlots === 4, 'normalizeTargetActiveSlots(100, naruto-max) must retain the desktop-safe cap', { narutoSlots });
|
|
22
|
+
assertGate(defaultSlots === 4, 'normalizeTargetActiveSlots(100) must stay desktop-safe', { defaultSlots });
|
|
24
23
|
// 3) A 100-clone roster builds 100 unique clones (no unique-persona ceiling).
|
|
25
24
|
const fullRoster = roster.buildNarutoCloneRoster({ clones: 100, maxAgentCount: schema.MAX_NARUTO_AGENT_COUNT });
|
|
26
25
|
const uniqueIds = new Set(fullRoster.roster.map((row) => row.id)).size;
|
|
@@ -40,9 +39,9 @@ const tiers = new Set(effortRoster.roster.map((row) => row.service_tier));
|
|
|
40
39
|
const fastFlags = new Set(effortRoster.roster.map((row) => row.fast_mode));
|
|
41
40
|
assertGate([...efforts].every((e) => e === 'low' || e === 'medium'), 'naruto clone efforts must be only low/medium (never high/xhigh)', { efforts: [...efforts] });
|
|
42
41
|
assertGate(efforts.has('low') && efforts.has('medium'), 'naruto effort must be dynamic: a no-tool prompt must yield both low and medium clones', { efforts: [...efforts] });
|
|
43
|
-
assertGate([...modelTiers].every((tier) => tier === '
|
|
44
|
-
assertGate(modelTiers.has('
|
|
45
|
-
assertGate([...modelEfforts].
|
|
42
|
+
assertGate([...modelTiers].every((tier) => tier === 'codex-selected-low' || tier === 'codex-selected-medium'), 'Naruto must inherit the Codex-selected model and vary only reasoning effort', { modelTiers: [...modelTiers] });
|
|
43
|
+
assertGate(modelTiers.has('codex-selected-low') && modelTiers.has('codex-selected-medium'), 'Naruto effort allocation must dynamically mix low and medium without changing model IDs', { modelTiers: [...modelTiers] });
|
|
44
|
+
assertGate([...modelEfforts].every((effort) => effort === 'low' || effort === 'medium'), 'ordinary Naruto clone model reasoning must stay low/medium', { modelEfforts: [...modelEfforts] });
|
|
46
45
|
assertGate([...tiers].length === 1 && tiers.has('fast'), 'every naruto clone must be fast service tier', { tiers: [...tiers] });
|
|
47
46
|
assertGate([...fastFlags].length === 1 && fastFlags.has(true), 'every naruto clone must have fast_mode=true', { fastFlags: [...fastFlags] });
|
|
48
47
|
// 4c) Unit rule: no tool use -> low; any tool use -> medium; always fast.
|
|
@@ -51,9 +50,9 @@ const toolWrite = effortPolicy.decideNarutoCloneEffort({ readonly: false, prompt
|
|
|
51
50
|
const toolReadCmd = effortPolicy.decideNarutoCloneEffort({ readonly: true, prompt: 'run the build and apply the migration' });
|
|
52
51
|
const simpleWrite = effortPolicy.decideNarutoCloneEffort({ readonly: false, prompt: 'simple one-line typo fix' });
|
|
53
52
|
assertGate(simple.reasoning_effort === 'low' && simple.service_tier === 'fast', 'no-tool read-only work must be low + fast', { simple });
|
|
54
|
-
assertGate(simple.model === '
|
|
55
|
-
assertGate(toolWrite.reasoning_effort === 'medium' && toolWrite.service_tier === 'fast' && toolWrite.model === '
|
|
56
|
-
assertGate(simpleWrite.model === '
|
|
53
|
+
assertGate(simple.model === '' && simple.model_reasoning_effort === 'low', 'no-tool read-only work must inherit the Codex model at low effort', { simple });
|
|
54
|
+
assertGate(toolWrite.reasoning_effort === 'medium' && toolWrite.service_tier === 'fast' && toolWrite.model === '' && toolWrite.model_reasoning_effort === 'medium', 'writing clone must inherit the Codex model at medium effort', { toolWrite });
|
|
55
|
+
assertGate(simpleWrite.model === '' && simpleWrite.model_reasoning_effort === 'low', 'simple write work must inherit the Codex model at low effort', { simpleWrite });
|
|
57
56
|
assertGate(toolReadCmd.reasoning_effort === 'medium' && toolReadCmd.service_tier === 'fast' && toolReadCmd.model_reasoning_effort === 'high', 'risky read-only command/migration work must escalate model reasoning to high', { toolReadCmd });
|
|
58
57
|
// 5) System-safe concurrency: never spawn the whole count at once; throttle to host capacity.
|
|
59
58
|
const fakeSafe = roster.systemSafeNarutoConcurrency({ backend: 'fake' });
|
|
@@ -64,22 +63,18 @@ const lowFreeButCapable = roster.systemSafeNarutoConcurrency({
|
|
|
64
63
|
freeBytes: 512 * 1024 * 1024,
|
|
65
64
|
totalBytes: 16 * 1024 * 1024 * 1024
|
|
66
65
|
});
|
|
67
|
-
assertGate(fakeSafe.cap >= 1 && fakeSafe.cap <=
|
|
68
|
-
|
|
69
|
-
// so concurrency is bounded by MEMORY + the 100-clone ceiling, NOT by CPU cores: a
|
|
70
|
-
// capable host may run up to MAX_NARUTO_AGENT_COUNT in parallel.
|
|
71
|
-
assertGate(heavySafe.cap >= 1 && heavySafe.cap <= schema.MAX_NARUTO_AGENT_COUNT, 'heavy-backend concurrency cap must be in [1, 100]', { heavySafe });
|
|
66
|
+
assertGate(fakeSafe.cap >= 1 && fakeSafe.cap <= 4, 'fake-backend active concurrency cap must stay in [1, 4]', { fakeSafe });
|
|
67
|
+
assertGate(heavySafe.cap >= 1 && heavySafe.cap <= 4, 'heavy-backend active concurrency cap must stay in [1, 4]', { heavySafe });
|
|
72
68
|
assertGate(heavySafe.cap <= fakeSafe.cap, 'heavy backend must throttle no looser than the light backend', { heavySafe, fakeSafe });
|
|
73
69
|
assertGate(heavySafe.cores >= 1, 'must detect at least one core', { cores: heavySafe.cores });
|
|
74
|
-
assertGate(lowFreeButCapable.cap
|
|
75
|
-
// A big-memory host is NOT throttled by core count: simulate 64 GB and assert the
|
|
76
|
-
// heavy backend scales well past the old 16-core-derived ceiling toward 100.
|
|
70
|
+
assertGate(lowFreeButCapable.cap === 1, 'low free memory must collapse active Codex concurrency to one worker', { lowFreeButCapable });
|
|
77
71
|
const bigMemoryHost = roster.systemSafeNarutoConcurrency({ backend: 'codex-sdk', cores: 4, freeBytes: 48 * 1024 * 1024 * 1024, totalBytes: 64 * 1024 * 1024 * 1024 });
|
|
78
|
-
assertGate(bigMemoryHost.cap >=
|
|
79
|
-
// 6)
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
const
|
|
72
|
+
assertGate(bigMemoryHost.cap >= 1 && bigMemoryHost.cap <= 4, 'large memory must not bypass the interactive CPU cap', { bigMemoryHost });
|
|
73
|
+
// 6) A small end-to-end run proves the same queue/drain path. The direct roster
|
|
74
|
+
// assertions above cover the 100-clone ceiling without making this release
|
|
75
|
+
// gate create dozens of unnecessary worker processes.
|
|
76
|
+
const proofClones = 6;
|
|
77
|
+
const proofConcurrency = 4;
|
|
83
78
|
const cli = path.join(root, 'dist', 'bin', 'sks.js');
|
|
84
79
|
const isolatedWorktreeRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-naruto-shadow-wt-'));
|
|
85
80
|
const childEnv = { ...process.env, SKS_WORKTREE_ROOT: isolatedWorktreeRoot, SKS_DISABLE_GIT_WORKTREE: '1' };
|
|
@@ -101,13 +96,13 @@ const parsed = parseJson(run.stdout);
|
|
|
101
96
|
assertGate(parsed !== null, 'sks naruto run must emit JSON', { stdout: tail(run.stdout) });
|
|
102
97
|
assertGate(parsed.ok === true, 'naruto run must be ok', { ok: parsed.ok });
|
|
103
98
|
assertGate(parsed.mode === 'NARUTO' && parsed.jutsu === 'kage_bunshin_no_jutsu', 'naruto run must report NARUTO mode', { mode: parsed.mode, jutsu: parsed.jutsu });
|
|
104
|
-
assertGate(parsed.clones === proofClones, 'clone fan-out must use the requested count
|
|
99
|
+
assertGate(parsed.clones === proofClones, 'clone fan-out must use the requested queued count', { clones: parsed.clones });
|
|
105
100
|
assertGate(parsed.max_clones === 100, 'naruto run must advertise the 100 ceiling', { max_clones: parsed.max_clones });
|
|
106
101
|
assertGate(parsed.proof === 'passed', 'naruto run proof must pass', { proof: parsed.proof });
|
|
107
102
|
// Throttle invariant: active concurrency never exceeds the requested count nor the host cap.
|
|
108
103
|
assertGate(parsed.target_active_slots >= 1 && parsed.target_active_slots <= proofClones, 'active slots must be in [1, clones]', { target_active_slots: parsed.target_active_slots });
|
|
109
104
|
assertGate(parsed.target_active_slots <= fakeSafe.cap, 'active slots must be throttled to the system-safe cap', { target_active_slots: parsed.target_active_slots, cap: fakeSafe.cap });
|
|
110
|
-
assertGate(parsed.target_active_slots
|
|
105
|
+
assertGate(parsed.target_active_slots <= proofConcurrency && parsed.target_active_slots <= 4, 'release proof must keep Naruto live slots desktop-safe while queued fan-out remains larger', { target_active_slots: parsed.target_active_slots, proofConcurrency });
|
|
111
106
|
// Task 9.1: fan-out (clones) and live concurrency (target_active_slots) are reported
|
|
112
107
|
// distinctly, and concurrency_capped truthfully reflects "N clones, running M at a time".
|
|
113
108
|
assertGate(typeof parsed.concurrency_capped === 'boolean', 'naruto run must report concurrency_capped', { concurrency_capped: parsed.concurrency_capped });
|
|
@@ -124,13 +119,11 @@ assertGate(new Set(writePaths).size > 1, 'naruto command default patch-envelope
|
|
|
124
119
|
assertGate(commandGraph.active_waves.some((wave) => wave.write_paths.length > 1), 'naruto command graph must contain a parallel write wave when route-local patch envelopes do not overlap', { waves: commandGraph.active_waves.slice(0, 3) });
|
|
125
120
|
const state = parsed.run?.scheduler?.state || parsed.run?.scheduler || {};
|
|
126
121
|
assertGate(Number(state.completed_count) === Number(parsed.work_graph?.total_work_items || 0) && Number(state.completed_count) >= proofClones, 'all clone work items must complete despite throttling', { completed_count: state.completed_count, total_work_items: parsed.work_graph?.total_work_items, proofClones });
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
assertGate(explicitConcurrency.status === 0 && explicitParsed?.target_active_slots === 6, 'explicit --concurrency must let Naruto use the requested parallel slot count', { status: explicitConcurrency.status, target_active_slots: explicitParsed?.target_active_slots });
|
|
130
|
-
// 7) A small request is NOT throttled below what was asked (cap only ever reduces, never inflates).
|
|
122
|
+
assertGate(parsed.target_active_slots <= 4, 'explicit --concurrency cannot bypass the desktop-safe cap', { target_active_slots: parsed.target_active_slots });
|
|
123
|
+
// 7) A small request is never inflated; live pressure may still reduce it.
|
|
131
124
|
const small = spawnSync(process.execPath, [cli, 'naruto', 'run', 'tiny', '--clones', '2', '--backend', 'fake', '--work-items', '2', '--json', '--no-open-zellij'], { cwd: root, env: childEnv, encoding: 'utf8', timeout: 600000, maxBuffer: 4 * 1024 * 1024 });
|
|
132
125
|
const smallParsed = parseJson(small.stdout);
|
|
133
|
-
assertGate(small.status === 0 && smallParsed?.target_active_slots
|
|
126
|
+
assertGate(small.status === 0 && smallParsed?.target_active_slots >= 1 && smallParsed?.target_active_slots <= 2, 'a 2-clone run must stay within [1, 2] active workers', { status: small.status, target_active_slots: smallParsed?.target_active_slots });
|
|
134
127
|
// 8) Naruto clones always run fast. Per-route --no-fast / standard-tier requests
|
|
135
128
|
// are intentionally not honored for shadow clones.
|
|
136
129
|
const standardOptOut = spawnSync(process.execPath, [cli, 'naruto', 'run', 'fast opt-out ignored', '--clones', '2', '--backend', 'fake', '--work-items', '2', '--no-fast', '--service-tier', 'standard', '--json', '--no-open-zellij'], { cwd: root, env: childEnv, encoding: 'utf8', timeout: 600000, maxBuffer: 4 * 1024 * 1024 });
|
|
@@ -5,7 +5,7 @@ import path from 'node:path';
|
|
|
5
5
|
import { spawnSync } from 'node:child_process';
|
|
6
6
|
import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
|
|
7
7
|
const MAX_FILES = Number(process.env.SKS_MAX_PACK_FILES || 2100);
|
|
8
|
-
const MAX_PACKED = Number(process.env.SKS_MAX_PACK_BYTES ||
|
|
8
|
+
const MAX_PACKED = Number(process.env.SKS_MAX_PACK_BYTES || 2410 * 1024);
|
|
9
9
|
const BUDGET_MS = Number(process.env.SKS_PACK_BUDGET_MS || 30000);
|
|
10
10
|
function runNpmPack() {
|
|
11
11
|
const npmCli = process.env.npm_execpath; // set when invoked via `npm run`
|
|
@@ -4,8 +4,8 @@ process.env.SKS_RELEASE_MAX_CPU_LIGHT = '7';
|
|
|
4
4
|
process.env.SKS_RELEASE_MAX_TOTAL = '2';
|
|
5
5
|
const governor = await importDist('core/release/release-gate-resource-governor.js');
|
|
6
6
|
const budget = governor.defaultReleaseGateBudget();
|
|
7
|
-
assertGate(budget['cpu-light']
|
|
8
|
-
assertGate(governor.defaultReleaseGateMaxTotal() >=
|
|
7
|
+
assertGate(budget['cpu-light'] >= 1 && budget['cpu-light'] <= 4, 'resource governor env requests must not raise the desktop-safe cpu-light cap', budget);
|
|
8
|
+
assertGate(governor.defaultReleaseGateMaxTotal() >= 1 && governor.defaultReleaseGateMaxTotal() <= 4, 'resource governor default total cap must stay desktop-safe', { max_total: governor.defaultReleaseGateMaxTotal() });
|
|
9
9
|
const gate = (id) => ({ id, resource: ['cpu-light'], deps: [], command: 'true', side_effect: 'hermetic', timeout_ms: 1000, cache: { enabled: false, inputs: [] }, isolation: { report_dir: 'per-gate' }, preset: ['release'] });
|
|
10
10
|
const fsGate = (id) => ({ ...gate(id), resource: ['fs-read'] });
|
|
11
11
|
const timingGate = (id) => ({ ...gate(id), resource: ['timing-sensitive'] });
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from 'node:fs';
|
|
3
|
-
import os from 'node:os';
|
|
4
3
|
import path from 'node:path';
|
|
5
4
|
import { fileURLToPath } from 'node:url';
|
|
6
5
|
import { buildVerificationDag } from '../core/verification/verification-dag.js';
|
|
@@ -298,7 +297,7 @@ tasks.push(task('release:metadata', 'npm run release:metadata --silent', { depen
|
|
|
298
297
|
const dag = buildVerificationDag(tasks);
|
|
299
298
|
const result = await runVerificationDag(dag, {
|
|
300
299
|
cwd: root,
|
|
301
|
-
concurrency: Number(process.env.SKS_VERIFY_CONCURRENCY ||
|
|
300
|
+
concurrency: Math.min(4, Number(process.env.SKS_VERIFY_CONCURRENCY || 2)),
|
|
302
301
|
logDir,
|
|
303
302
|
failFast: false
|
|
304
303
|
});
|
|
@@ -6,7 +6,7 @@ import { writeJsonAtomic } from '../core/fsx.js';
|
|
|
6
6
|
const args = process.argv.slice(2);
|
|
7
7
|
const skipReleaseCheck = args.includes('--skip-release-check') || process.env.SKS_RELEASE_REAL_CHECK_SKIP_RELEASE_CHECK === '1';
|
|
8
8
|
const root = process.cwd();
|
|
9
|
-
const concurrency = Math.max(1, Math.floor(Number(process.env.SKS_RELEASE_REAL_CHECK_CONCURRENCY ||
|
|
9
|
+
const concurrency = Math.max(1, Math.min(4, Math.floor(Number(process.env.SKS_RELEASE_REAL_CHECK_CONCURRENCY || 2))));
|
|
10
10
|
const report = {
|
|
11
11
|
schema: 'sks.release-real-check.v1',
|
|
12
12
|
generated_at: new Date().toISOString(),
|
|
@@ -7,9 +7,9 @@ import path from 'node:path';
|
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
8
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
9
9
|
const limits = {
|
|
10
|
-
packedBytes: Number(process.env.SKS_MAX_PACK_BYTES ||
|
|
11
|
-
unpackedBytes: Number(process.env.SKS_MAX_UNPACKED_BYTES ||
|
|
12
|
-
packFiles: Number(process.env.SKS_MAX_PACK_FILES ||
|
|
10
|
+
packedBytes: Number(process.env.SKS_MAX_PACK_BYTES || 2410 * 1024),
|
|
11
|
+
unpackedBytes: Number(process.env.SKS_MAX_UNPACKED_BYTES || 10 * 1024 * 1024),
|
|
12
|
+
packFiles: Number(process.env.SKS_MAX_PACK_FILES || 2100),
|
|
13
13
|
trackedFileBytes: Number(process.env.SKS_MAX_TRACKED_FILE_BYTES || 384 * 1024)
|
|
14
14
|
};
|
|
15
15
|
const trackedFileSizeAllowlist = new Set([
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sneakoscope",
|
|
3
3
|
"displayName": "ㅅㅋㅅ",
|
|
4
|
-
"version": "6.0.
|
|
4
|
+
"version": "6.0.2",
|
|
5
5
|
"description": "Proof-first Codex trust layer for bounded agent workflows, search visibility evidence, and release integrity gates.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
|
|
@@ -139,7 +139,8 @@
|
|
|
139
139
|
"release:check:full": "npm run build:clean --silent && node ./dist/bin/sks.js doctor --fix --yes --json >/tmp/sks-release-check-full-doctor.json && node ./dist/scripts/release-gate-dag-runner.js --preset release --full && node ./dist/scripts/release-gate-dag-runner.js --preset bench --full && node ./dist/scripts/release-check-stamp.js write",
|
|
140
140
|
"publish:packlist-performance": "node ./dist/scripts/packlist-performance-check.js",
|
|
141
141
|
"publish:dry": "npm run publish:prep-ignore-scripts && npm publish --dry-run --ignore-scripts --json",
|
|
142
|
-
"publish:
|
|
142
|
+
"publish:verify-ignore-scripts": "npm run build:clean --silent && npm run typecheck --silent && npm test --silent && npm run release:version-truth --silent && npm run release:dist-freshness --silent && npm run publish:packlist-performance --silent && node ./dist/scripts/package-published-contract-check.js && npm run publish-tag:check --silent && npm pack --dry-run --ignore-scripts --json",
|
|
143
|
+
"publish:prep-ignore-scripts": "npm run publish:verify-ignore-scripts --silent && node ./dist/scripts/release-registry-check.js --require-unpublished --require-publish-auth",
|
|
143
144
|
"publish:ignore-scripts": "npm run publish:prep-ignore-scripts && npm publish --ignore-scripts",
|
|
144
145
|
"gates:run": "node ./dist/scripts/release-gate-dag-runner.js",
|
|
145
146
|
"policy:gate-audit": "node ./dist/scripts/gate-policy-audit-check.js",
|