sneakoscope 2.0.9 → 2.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +8 -4
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/crates/sks-core/src/main.rs +1 -1
  5. package/dist/.sks-build-stamp.json +4 -4
  6. package/dist/bin/sks.js +1 -1
  7. package/dist/build-manifest.json +21 -8
  8. package/dist/cli/command-registry.js +1 -0
  9. package/dist/commands/doctor.js +18 -1
  10. package/dist/commands/zellij-slot-pane.js +26 -0
  11. package/dist/core/agents/agent-orchestrator.js +198 -7
  12. package/dist/core/agents/agent-role-config.js +92 -0
  13. package/dist/core/agents/native-cli-session-swarm.js +186 -71
  14. package/dist/core/commands/naruto-command.js +59 -4
  15. package/dist/core/doctor/doctor-readiness-matrix.js +6 -0
  16. package/dist/core/fsx.js +1 -1
  17. package/dist/core/hooks-runtime.js +4 -0
  18. package/dist/core/init.js +1 -0
  19. package/dist/core/naruto/naruto-active-pool.js +35 -2
  20. package/dist/core/naruto/naruto-concurrency-governor.js +1 -1
  21. package/dist/core/naruto/naruto-real-worker-child.js +35 -0
  22. package/dist/core/naruto/naruto-real-worker-runtime.js +121 -0
  23. package/dist/core/version.js +1 -1
  24. package/dist/core/zellij/zellij-right-column-manager.js +66 -7
  25. package/dist/core/zellij/zellij-slot-pane-renderer.js +82 -0
  26. package/dist/core/zellij/zellij-ui-mode.js +16 -0
  27. package/dist/core/zellij/zellij-worker-pane-manager.js +38 -8
  28. package/dist/scripts/agent-role-config-repair-check.js +33 -0
  29. package/dist/scripts/git-worktree-integration-primary-check.js +4 -2
  30. package/dist/scripts/git-worktree-integration-primary-runtime-check.js +20 -0
  31. package/dist/scripts/mutation-callsite-coverage-check.js +2 -1
  32. package/dist/scripts/naruto-extreme-parallelism-check.js +1 -1
  33. package/dist/scripts/naruto-extreme-parallelism-real-check.js +42 -0
  34. package/dist/scripts/naruto-real-active-pool-check.js +3 -2
  35. package/dist/scripts/naruto-real-active-pool-runtime-check.js +53 -0
  36. package/dist/scripts/naruto-zellij-dynamic-right-column-check.js +29 -2
  37. package/dist/scripts/readme-architecture-imagegen-official-check.js +4 -3
  38. package/dist/scripts/release-check-dynamic-execute.js +27 -1
  39. package/dist/scripts/release-check-dynamic.js +38 -11
  40. package/dist/scripts/release-check-stamp.js +7 -2
  41. package/dist/scripts/release-dynamic-performance-check.js +31 -1
  42. package/dist/scripts/release-gate-existence-audit.js +29 -33
  43. package/dist/scripts/release-readiness-report.js +13 -2
  44. package/dist/scripts/zellij-right-column-geometry-proof.js +155 -22
  45. package/dist/scripts/zellij-right-column-headless-overflow-check.js +22 -0
  46. package/dist/scripts/zellij-right-column-manager-check.js +4 -4
  47. package/dist/scripts/zellij-slot-only-ui-check.js +22 -0
  48. package/dist/scripts/zellij-slot-pane-renderer-check.js +38 -0
  49. package/package.json +12 -4
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
7
+ import { buildNarutoWorkGraph } from '../core/naruto/naruto-work-graph.js';
8
+ import { decideNarutoConcurrency } from '../core/naruto/naruto-concurrency-governor.js';
9
+ import { runNarutoRealActivePool } from '../core/naruto/naruto-active-pool.js';
10
+ import { collectActualNarutoWorker, spawnActualNarutoWorker } from '../core/naruto/naruto-real-worker-runtime.js';
11
+ const graph = buildNarutoWorkGraph({ requestedClones: 12, totalWorkItems: 24, writeCapable: false, maxActiveWorkers: 6 });
12
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-naruto-real-runtime-'));
13
+ const missionId = `M-naruto-real-runtime-${process.pid}`;
14
+ const governor = decideNarutoConcurrency({
15
+ requestedClones: 12,
16
+ totalWorkItems: graph.total_work_items,
17
+ pendingWorkQueueSize: graph.total_work_items,
18
+ backend: 'codex-sdk',
19
+ hardware: { cores: 8, freeMemoryBytes: 32 * 1024 * 1024 * 1024, totalMemoryBytes: 64 * 1024 * 1024 * 1024, fileDescriptorLimit: 4096, processCount: 100, terminalRows: 40, remoteApiRateLimitBudget: 8 }
20
+ });
21
+ let spawned = 0;
22
+ let collected = 0;
23
+ const target = { ...governor, safe_active_workers: Math.min(6, governor.safe_active_workers), safe_zellij_visible_panes: 3 };
24
+ const report = await runNarutoRealActivePool({
25
+ graph,
26
+ governor: target,
27
+ spawnWorker: async (item, placement) => {
28
+ spawned += 1;
29
+ return spawnActualNarutoWorker({
30
+ root: tempRoot,
31
+ missionId,
32
+ item,
33
+ placement,
34
+ backend: 'codex-sdk',
35
+ visiblePaneCap: target.safe_zellij_visible_panes,
36
+ zellijSessionName: `sks-${missionId}`
37
+ });
38
+ },
39
+ collectWorker: async (handle) => {
40
+ collected += 1;
41
+ return collectActualNarutoWorker(handle);
42
+ },
43
+ enqueueVerification: async () => undefined,
44
+ updateDashboard: async () => undefined
45
+ });
46
+ const processEvidence = report.worker_lifecycle.every((row) => row.pid && row.worker_artifact_dir);
47
+ const artifactEvidence = report.worker_lifecycle.every((row) => row.worker_artifact_dir
48
+ && fs.existsSync(path.join(row.worker_artifact_dir, 'worker-heartbeat.jsonl'))
49
+ && fs.existsSync(path.join(row.worker_artifact_dir, 'worker-result.json')));
50
+ const ok = report.ok && spawned === graph.total_work_items && collected === graph.total_work_items && report.max_observed_active_workers >= target.safe_active_workers && report.active_pool_utilization >= 0.8 && processEvidence && artifactEvidence;
51
+ assertGate(ok, 'Naruto real active pool runtime must include actual child process, heartbeat, and result evidence', { report, spawned, collected, processEvidence, artifactEvidence, tempRoot });
52
+ emitGate('naruto:real-active-pool-runtime', report);
53
+ //# sourceMappingURL=naruto-real-active-pool-runtime-check.js.map
@@ -2,20 +2,47 @@
2
2
  // @ts-nocheck
3
3
  import fs from 'node:fs';
4
4
  import path from 'node:path';
5
+ import { spawnSync } from 'node:child_process';
5
6
  import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
7
+ const requireReal = process.argv.includes('--require-real') || process.env.SKS_REQUIRE_ZELLIJ === '1';
6
8
  const naruto = fs.readFileSync(path.join(root, 'src/core/commands/naruto-command.ts'), 'utf8');
7
9
  const worker = fs.readFileSync(path.join(root, 'src/core/zellij/zellij-worker-pane-manager.ts'), 'utf8');
8
10
  const swarm = fs.readFileSync(path.join(root, 'src/core/agents/native-cli-session-swarm.ts'), 'utf8');
11
+ const realGeometryProof = requireReal ? runRealGeometryProof() : null;
9
12
  const report = {
10
13
  schema: 'sks.naruto-zellij-dynamic-right-column-check.v1',
11
14
  ok: true,
15
+ require_real: requireReal,
12
16
  initial_main_only: /slotCount:\s*0/.test(naruto),
13
17
  passes_session_name: naruto.includes('zellijSessionName: liveZellij?.session_name'),
14
18
  passes_worker_placement: naruto.includes("workerPlacement: parsed.json || parsed.noOpenZellij ? 'process' : 'zellij-pane'"),
15
19
  passes_visible_cap: naruto.includes('zellijVisiblePaneCap: zellijVisiblePanes'),
16
- worker_uses_right_column: worker.includes("rightColumnMode: 'spawn-on-first-worker'") || swarm.includes("rightColumnMode: 'spawn-on-first-worker'")
20
+ worker_uses_right_column: worker.includes("rightColumnMode: 'spawn-on-first-worker'") || swarm.includes("rightColumnMode: 'spawn-on-first-worker'"),
21
+ real_geometry_proof: realGeometryProof
17
22
  };
18
- report.ok = report.initial_main_only && report.passes_session_name && report.passes_worker_placement && report.passes_visible_cap && report.worker_uses_right_column;
23
+ report.ok = report.initial_main_only
24
+ && report.passes_session_name
25
+ && report.passes_worker_placement
26
+ && report.passes_visible_cap
27
+ && report.worker_uses_right_column
28
+ && (!requireReal || realGeometryProof?.ok === true);
19
29
  assertGate(report.ok, 'Naruto must use dynamic right-column worker panes in interactive mode', report);
20
30
  emitGate('naruto:zellij-dynamic-right-column', report);
31
+ function runRealGeometryProof() {
32
+ const res = spawnSync('npm', ['run', 'zellij:right-column-real-geometry', '--silent', '--', '--require-real'], {
33
+ cwd: root,
34
+ env: { ...process.env, SKS_REQUIRE_ZELLIJ: '1' },
35
+ encoding: 'utf8',
36
+ maxBuffer: 20 * 1024 * 1024
37
+ });
38
+ return {
39
+ ok: res.status === 0,
40
+ exit_code: res.status,
41
+ stdout_tail: tail(res.stdout),
42
+ stderr_tail: tail(res.stderr)
43
+ };
44
+ }
45
+ function tail(text) {
46
+ return String(text || '').split('\n').slice(-30).join('\n');
47
+ }
21
48
  //# sourceMappingURL=naruto-zellij-dynamic-right-column-check.js.map
@@ -5,6 +5,7 @@ import os from 'node:os';
5
5
  import path from 'node:path';
6
6
  import { createHash } from 'node:crypto';
7
7
  import { execFileSync } from 'node:child_process';
8
+ import { writeTextAtomic } from '../core/fsx.js';
8
9
  const root = process.cwd();
9
10
  const args = process.argv.slice(2);
10
11
  const reportPath = path.join(root, '.sneakoscope', 'reports', 'readme-architecture-imagegen-attempt-1.18.8.json');
@@ -139,12 +140,12 @@ else {
139
140
  }
140
141
  async function ensurePromptContract() {
141
142
  if (!promptExistedBeforeRun) {
142
- await fs.promises.writeFile(promptPath, prompt);
143
+ await writeTextAtomic(promptPath, prompt);
143
144
  return { changed: true, reason: 'created' };
144
145
  }
145
146
  const existing = await fs.promises.readFile(promptPath, 'utf8').catch(() => null);
146
147
  if (existing !== prompt) {
147
- await fs.promises.writeFile(promptPath, prompt);
148
+ await writeTextAtomic(promptPath, prompt);
148
149
  return { changed: true, reason: 'refreshed_prompt_changed' };
149
150
  }
150
151
  return { changed: false, reason: 'unchanged' };
@@ -334,7 +335,7 @@ async function textArtifactMeta(file, promptWrite = null) {
334
335
  };
335
336
  }
336
337
  async function writeReport(report) {
337
- await fs.promises.writeFile(reportPath, `${JSON.stringify(report, null, 2)}\n`);
338
+ await writeTextAtomic(reportPath, `${JSON.stringify(report, null, 2)}\n`);
338
339
  }
339
340
  async function sha256File(file) {
340
341
  return new Promise((resolve, reject) => {
@@ -40,7 +40,7 @@ const invariants = {
40
40
  };
41
41
  const distHash = distHashValue();
42
42
  const gitCommit = gitHead();
43
- const manifestHash = fileHash('release-gates.json');
43
+ const manifestHash = fileHash(fs.existsSync(path.join(root, 'release-gates.v2.json')) ? 'release-gates.v2.json' : 'release-gates.json');
44
44
  const packageScriptsHash = sha256(JSON.stringify(pkg.scripts || {}));
45
45
  const nodeVersion = process.version;
46
46
  const npmVersion = npmVersionValue();
@@ -134,6 +134,25 @@ emitGate('release:check:dynamic:execute', {
134
134
  });
135
135
  // ---- helpers ----------------------------------------------------------------
136
136
  function loadManifest() {
137
+ const v2Path = path.join(root, 'release-gates.v2.json');
138
+ if (fs.existsSync(v2Path)) {
139
+ const parsed = JSON.parse(fs.readFileSync(v2Path, 'utf8'));
140
+ const releaseNodes = (Array.isArray(parsed.gates) ? parsed.gates : []).filter((gate) => Array.isArray(gate.preset) && gate.preset.includes('release'));
141
+ const byId = new Map(releaseNodes.map((gate) => [gate.id, gate]));
142
+ const dynamic = buildGateManifest(releaseNodes.map((gate) => gate.id));
143
+ return {
144
+ schema: 'sks.release-gate-manifest.v1.from-v2',
145
+ gates: dynamic.gates.map((entry) => {
146
+ const node = byId.get(entry.id);
147
+ const resource = Array.isArray(node?.resource) ? node.resource.join(',') : '';
148
+ return {
149
+ ...entry,
150
+ affected_by: usefulCacheInputs(node?.cache?.inputs, entry.affected_by),
151
+ cost: node?.side_effect === 'real-env' || resource.includes('real') ? 'real' : entry.cost
152
+ };
153
+ })
154
+ };
155
+ }
137
156
  const p = path.join(root, 'release-gates.json');
138
157
  if (fs.existsSync(p))
139
158
  return JSON.parse(fs.readFileSync(p, 'utf8'));
@@ -143,6 +162,13 @@ function loadManifest() {
143
162
  const ids = [...new Set([...dagIds, ...releaseCheckIds])].filter((id) => id && id !== 'build' && id !== 'release:check:parallel');
144
163
  return buildGateManifest(ids);
145
164
  }
165
+ function usefulCacheInputs(inputs, fallback) {
166
+ if (!Array.isArray(inputs) || !inputs.length)
167
+ return fallback;
168
+ if (inputs.some((input) => ['src/**', 'package.json', 'release-gates.v2.json', 'schemas/**'].includes(input)))
169
+ return fallback;
170
+ return inputs;
171
+ }
146
172
  function hashAffectedFiles(globs) {
147
173
  const regexes = (globs || []).map(globToRegExp);
148
174
  const hashes = [];
@@ -12,17 +12,8 @@ const args = process.argv.slice(2);
12
12
  const publish = args.includes('--publish');
13
13
  const baseArg = readArg(args, '--base');
14
14
  const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
15
- const dagSource = fs.readFileSync(path.join(root, 'src/scripts/release-parallel-check.ts'), 'utf8');
16
- const dagIds = [...dagSource.matchAll(/task\('([^']+)'/g)].map((m) => m[1]);
17
- const releaseCheckIds = [...String(pkg.scripts?.['release:check'] || '').matchAll(/npm run ([^\s&]+)/g)].map((m) => m[1]);
18
- const releaseGateIds = [...new Set([...dagIds, ...releaseCheckIds])].filter((id) => id && id !== 'build' && id !== 'release:check:parallel');
19
- // Prefer the checked-in manifest; rebuild from the live set if absent.
20
- let manifest;
21
- const manifestPath = path.join(root, 'release-gates.json');
22
- if (fs.existsSync(manifestPath))
23
- manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
24
- else
25
- manifest = buildGateManifest(releaseGateIds);
15
+ // Prefer the checked-in v2 DAG manifest and normalize it for the legacy dynamic selector.
16
+ const manifest = loadDynamicManifest();
26
17
  const changedFiles = detectChangedFiles(baseArg);
27
18
  const plan = selectGates(manifest.gates, changedFiles, { publish });
28
19
  // --- Hermetic invariant proofs (independent of the current git state) ---
@@ -57,6 +48,42 @@ function readArg(list, name) {
57
48
  const i = list.indexOf(name);
58
49
  return i >= 0 ? list[i + 1] || null : null;
59
50
  }
51
+ function loadDynamicManifest() {
52
+ const v2Path = path.join(root, 'release-gates.v2.json');
53
+ if (fs.existsSync(v2Path)) {
54
+ const parsed = JSON.parse(fs.readFileSync(v2Path, 'utf8'));
55
+ const releaseNodes = (Array.isArray(parsed.gates) ? parsed.gates : []).filter((gate) => Array.isArray(gate.preset) && gate.preset.includes('release'));
56
+ const byId = new Map(releaseNodes.map((gate) => [gate.id, gate]));
57
+ const dynamic = buildGateManifest(releaseNodes.map((gate) => gate.id));
58
+ return {
59
+ schema: 'sks.release-gate-manifest.v1.from-v2',
60
+ gates: dynamic.gates.map((entry) => {
61
+ const node = byId.get(entry.id);
62
+ const resource = Array.isArray(node?.resource) ? node.resource.join(',') : '';
63
+ return {
64
+ ...entry,
65
+ affected_by: usefulCacheInputs(node?.cache?.inputs, entry.affected_by),
66
+ cost: node?.side_effect === 'real-env' || resource.includes('real') ? 'real' : entry.cost
67
+ };
68
+ })
69
+ };
70
+ }
71
+ const manifestPath = path.join(root, 'release-gates.json');
72
+ if (fs.existsSync(manifestPath))
73
+ return JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
74
+ const legacySource = fs.readFileSync(path.join(root, 'src/scripts/release-parallel-check.ts'), 'utf8');
75
+ const legacyIds = [...legacySource.matchAll(/task\('([^']+)'/g)].map((m) => m[1]);
76
+ const releaseCheckIds = [...String(pkg.scripts?.['release:check'] || '').matchAll(/npm run ([^\s&]+)/g)].map((m) => m[1]);
77
+ const ids = [...new Set([...legacyIds, ...releaseCheckIds])].filter((id) => id && id !== 'build' && id !== 'release:check:parallel');
78
+ return buildGateManifest(ids);
79
+ }
80
+ function usefulCacheInputs(inputs, fallback) {
81
+ if (!Array.isArray(inputs) || !inputs.length)
82
+ return fallback;
83
+ if (inputs.some((input) => ['src/**', 'package.json', 'release-gates.v2.json', 'schemas/**'].includes(input)))
84
+ return fallback;
85
+ return inputs;
86
+ }
60
87
  function detectChangedFiles(base) {
61
88
  try {
62
89
  let ref = base;
@@ -66,8 +66,11 @@ function gitCommit() {
66
66
  return result.status === 0 ? result.stdout.trim() : null;
67
67
  }
68
68
  function releaseGateHash(pkg) {
69
- const gateManifest = fs.existsSync(path.join(root, 'release-gates.json')) ? fs.readFileSync(path.join(root, 'release-gates.json'), 'utf8') : '';
70
- return sha256(`${pkg.scripts?.['release:check'] || ''}\0${pkg.scripts?.['prepublishOnly'] || ''}\0${gateManifest}`);
69
+ const manifests = ['release-gates.v2.json', 'release-gates.json'].map((rel) => {
70
+ const file = path.join(root, rel);
71
+ return fs.existsSync(file) ? `${rel}\0${fs.readFileSync(file, 'utf8')}` : `${rel}\0missing`;
72
+ }).join('\0');
73
+ return sha256(`${pkg.scripts?.['release:check'] || ''}\0${pkg.scripts?.['prepublishOnly'] || ''}\0${manifests}`);
71
74
  }
72
75
  function collectFiles(dir, out) {
73
76
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
@@ -98,6 +101,8 @@ function releaseRelevant(file) {
98
101
  return false;
99
102
  if (/^(package|package-lock)\.json$/.test(file))
100
103
  return true;
104
+ if (/^release-gates(?:\.v2)?\.json$/.test(file))
105
+ return true;
101
106
  if (/^tsconfig.*\.json$/.test(file))
102
107
  return true;
103
108
  if (/^(README|CHANGELOG|LICENSE)(\.md)?$/i.test(file))
@@ -4,7 +4,8 @@ import fs from 'node:fs';
4
4
  import path from 'node:path';
5
5
  import { assertGate, emitGate, importDist, root } from './sks-1-18-gate-lib.js';
6
6
  const { selectGates } = await importDist('core/release/gate-manifest.js');
7
- const manifest = JSON.parse(fs.readFileSync(path.join(root, 'release-gates.json'), 'utf8'));
7
+ const { buildGateManifest } = await importDist('core/release/gate-manifest.js');
8
+ const manifest = loadDynamicManifest();
8
9
  const t0 = Date.now();
9
10
  const docsOnly = summarize(['docs/release-readiness.md']);
10
11
  const zellijOnly = summarize(['src/core/zellij/zellij-capability.ts']);
@@ -70,4 +71,33 @@ function readJson(rel, fallback) {
70
71
  return fallback;
71
72
  }
72
73
  }
74
+ function loadDynamicManifest() {
75
+ const v2Path = path.join(root, 'release-gates.v2.json');
76
+ if (fs.existsSync(v2Path)) {
77
+ const parsed = JSON.parse(fs.readFileSync(v2Path, 'utf8'));
78
+ const releaseNodes = (Array.isArray(parsed.gates) ? parsed.gates : []).filter((gate) => Array.isArray(gate.preset) && gate.preset.includes('release'));
79
+ const byId = new Map(releaseNodes.map((gate) => [gate.id, gate]));
80
+ const dynamic = buildGateManifest(releaseNodes.map((gate) => gate.id));
81
+ return {
82
+ schema: 'sks.release-gate-manifest.v1.from-v2',
83
+ gates: dynamic.gates.map((entry) => {
84
+ const node = byId.get(entry.id);
85
+ const resource = Array.isArray(node?.resource) ? node.resource.join(',') : '';
86
+ return {
87
+ ...entry,
88
+ affected_by: usefulCacheInputs(node?.cache?.inputs, entry.affected_by),
89
+ cost: node?.side_effect === 'real-env' || resource.includes('real') ? 'real' : entry.cost
90
+ };
91
+ })
92
+ };
93
+ }
94
+ return JSON.parse(fs.readFileSync(path.join(root, 'release-gates.json'), 'utf8'));
95
+ }
96
+ function usefulCacheInputs(inputs, fallback) {
97
+ if (!Array.isArray(inputs) || !inputs.length)
98
+ return fallback;
99
+ if (inputs.some((input) => ['src/**', 'package.json', 'release-gates.v2.json', 'schemas/**'].includes(input)))
100
+ return fallback;
101
+ return inputs;
102
+ }
73
103
  //# sourceMappingURL=release-dynamic-performance-check.js.map
@@ -4,8 +4,13 @@ import fs from 'node:fs';
4
4
  import path from 'node:path';
5
5
  import { assertGate, emitGate, packageScripts, root } from './sks-1-18-gate-lib.js';
6
6
  const scripts = packageScripts();
7
- const releaseDagSource = fs.readFileSync(path.join(root, 'src', 'scripts', 'release-parallel-check.ts'), 'utf8');
8
- const dagTasks = new Set([...releaseDagSource.matchAll(/task\('([^']+)'/g)].map((match) => match[1]));
7
+ const releaseManifestPath = path.join(root, 'release-gates.v2.json');
8
+ const releaseManifest = JSON.parse(fs.readFileSync(releaseManifestPath, 'utf8'));
9
+ const releaseGates = Array.isArray(releaseManifest.gates)
10
+ ? releaseManifest.gates.filter((gate) => Array.isArray(gate.preset) && gate.preset.includes('release'))
11
+ : [];
12
+ const dagTasks = new Set(releaseGates.map((gate) => gate.id));
13
+ const manifestTasks = new Set((Array.isArray(releaseManifest.gates) ? releaseManifest.gates : []).map((gate) => gate.id));
9
14
  const removedRuntime = `${'tm'}ux`;
10
15
  const removedLane = `${'warp'}-right-${'lane'}`;
11
16
  const removedRuntimeGateRe = new RegExp(`^${removedRuntime}:|^agent:${removedRuntime}-|real-${removedRuntime}|${removedLane}`, 'i');
@@ -14,18 +19,26 @@ const required = [
14
19
  'terminal:keyboard-enhancement-safety',
15
20
  'terminal:tui-output-stability',
16
21
  'zellij:layout-valid',
17
- 'zellij:pane-proof',
18
- 'zellij:screen-proof',
22
+ 'zellij:initial-main-only-blackbox',
23
+ 'zellij:right-column-geometry-proof',
24
+ 'zellij:dynamic-pane-lifecycle',
19
25
  'zellij:lane-renderer',
20
26
  'zellij:doctor-readiness',
21
27
  'zellij:spawn-on-demand-layout',
22
28
  'zellij:worker-pane-manager',
23
29
  'zellij:worker-pane-manager-single-owner',
30
+ 'zellij:slot-only-ui',
31
+ 'zellij:compact-slot-renderer',
32
+ 'zellij:right-column-headless-overflow',
24
33
  'safety:mutation-callsite-coverage',
25
34
  'mad-sks:zellij-launch',
26
35
  'mad-sks:zellij-default-pane-worker',
27
36
  'agent:zellij-runtime',
37
+ 'agent:slot-pane-binding-proof',
38
+ 'agent:role-config-repair',
28
39
  'agent:worker-pane-communication-contract',
40
+ 'git:worktree-integration-primary',
41
+ 'git:worktree-integration-primary-runtime',
29
42
  'codex:0.136-compat',
30
43
  'codex:0.135-compat',
31
44
  'doctor:codex-doctor-parity',
@@ -34,10 +47,6 @@ const required = [
34
47
  'codex:resume-cwd-truth',
35
48
  'mcp:tool-naming-parity',
36
49
  'responses:retry-policy-centralized',
37
- 'codex:0.134-compat',
38
- 'codex:0.134-official-compat',
39
- 'codex:profile-primary',
40
- 'codex:managed-proxy-env',
41
50
  'codex-app:fast-ui-preservation',
42
51
  'codex-app:ui-clobber-guard',
43
52
  'doctor:fixes-codex-app-fast-ui',
@@ -47,32 +56,11 @@ const required = [
47
56
  'codex-app:provider-badge',
48
57
  'runtime:no-mjs-scripts',
49
58
  'runtime:ts-python-boundary',
50
- 'strategy:adhd-orchestrating-gate',
51
- 'strategy:parallel-modification-plan',
52
- 'strategy:file-ownership-plan',
53
- 'strategy:verification-rollback-dag',
54
- 'appshots:capability',
55
- 'appshots:operator-policy',
56
- 'appshots:evidence',
57
- 'appshots:source-intelligence',
58
- 'appshots:triwiki-voxel',
59
- 'appshots:privacy-safety',
60
- 'mcp:0.134-modernization',
61
- 'mcp:readonly-concurrency',
62
- 'hooks:0.134-context-parity',
63
- 'source-intelligence:codex-history-search',
64
- 'agent:parallel-write-kernel',
65
- 'agent:parallel-write-blackbox',
66
- 'team:parallel-write-blackbox',
67
- 'dfix:parallel-write-blackbox',
68
- 'agent:patch-proof',
69
- 'agent:patch-rollback',
70
59
  'agent:patch-swarm-runtime-truth',
71
60
  'agent:patch-transaction-journal',
72
61
  'agent:patch-conflict-rebase',
73
62
  'agent:strategy-to-patch-strict',
74
63
  'agent:rollback-command',
75
- 'agent:real-codex-patch-envelope-smoke',
76
64
  'agent:native-cli-session-swarm',
77
65
  'agent:native-cli-session-swarm-10',
78
66
  'agent:native-cli-session-swarm-20',
@@ -82,7 +70,12 @@ const required = [
82
70
  'agent:fast-mode-worker-propagation',
83
71
  'codex:fast-mode-profile-propagation',
84
72
  'mad-sks:fast-mode-propagation',
85
- 'release:runtime-truth-matrix',
73
+ 'naruto:active-pool',
74
+ 'naruto:real-active-pool',
75
+ 'naruto:real-active-pool-runtime',
76
+ 'naruto:extreme-parallelism',
77
+ 'naruto:extreme-parallelism-real',
78
+ 'naruto:zellij-dynamic-right-column',
86
79
  'agent:wiki-context-proof',
87
80
  'shared-memory:check',
88
81
  'wrongness:check',
@@ -90,10 +83,13 @@ const required = [
90
83
  'trust:check',
91
84
  'git-collaboration:e2e'
92
85
  ];
86
+ assertGate(releaseManifest.schema === 'sks.release-gates.v2', 'release gate manifest schema mismatch', { schema: releaseManifest.schema });
87
+ assertGate(String(scripts['release:check'] || '').includes('release-gate-dag-runner') && String(scripts['release:check'] || '').includes('--preset release'), 'release:check must use the v2 DAG release preset', { release_check: scripts['release:check'] });
88
+ assertGate(releaseGates.length > 0, 'release v2 manifest must include release preset gates', { gate_count: releaseGates.length });
93
89
  for (const name of required) {
94
90
  assertGate(Boolean(scripts[name]), `missing release gate script: ${name}`, { required });
95
- const inReleaseCheck = dagTasks.has(name) || String(scripts['release:check'] || '').includes(`npm run ${name}`);
96
- assertGate(inReleaseCheck, `critical release gate missing from release DAG: ${name}`, { name, dag_tasks: [...dagTasks].sort() });
91
+ const inReleaseManifest = manifestTasks.has(name);
92
+ assertGate(inReleaseManifest, `critical gate missing from release v2 manifest: ${name}`, { name, release_gates: [...dagTasks].sort(), manifest_gates: [...manifestTasks].sort() });
97
93
  const match = String(scripts[name]).match(/node\s+(\.\/dist\/scripts\/[^ ]+\.js)/);
98
94
  if (match)
99
95
  assertGate(fs.existsSync(path.join(root, match[1])), `script target missing for ${name}`, { command: scripts[name] });
@@ -107,5 +103,5 @@ for (const name of dagTasks) {
107
103
  for (const name of Object.keys(scripts)) {
108
104
  assertGate(!removedRuntimeGateRe.test(name), `tmux package gate remains: ${name}`, { name });
109
105
  }
110
- emitGate('release:gate-existence-audit', { gates: required.length, dag_tasks: dagTasks.size });
106
+ emitGate('release:gate-existence-audit', { gates: required.length, dag_tasks: dagTasks.size, manifest: 'release-gates.v2.json' });
111
107
  //# sourceMappingURL=release-gate-existence-audit.js.map
@@ -10,8 +10,13 @@ const reportDir = path.join(root, '.sneakoscope', 'reports');
10
10
  const RELEASE_VERSION = pkg.version;
11
11
  const jsonPath = path.join(reportDir, `release-readiness-${RELEASE_VERSION}.json`);
12
12
  const mdPath = path.join(reportDir, `release-readiness-${RELEASE_VERSION}.md`);
13
+ const releaseGateManifest = readJson('release-gates.v2.json', { gates: [] });
14
+ const releaseGateIds = new Set((Array.isArray(releaseGateManifest.gates) ? releaseGateManifest.gates : [])
15
+ .filter((gate) => Array.isArray(gate.preset) && gate.preset.includes('release'))
16
+ .map((gate) => gate.id));
13
17
  const releaseParallelCheckSource = readText('src/scripts/release-parallel-check.ts', '');
14
18
  const releaseRealCheckSource = readText('src/scripts/release-real-check.ts', '');
19
+ const hooksRuntimeSource = readText('src/core/hooks-runtime.ts', '');
15
20
  const checks = {
16
21
  runtime_no_src_mjs: scriptContains('release:check:parallel', 'runtime:no-src-mjs'),
17
22
  runtime_ts_source_of_truth: scriptContains('release:check:parallel', 'runtime:ts-source-of-truth'),
@@ -208,7 +213,8 @@ const checks = {
208
213
  official_docs_compat: scriptContains('release:check', 'official-docs:compat'),
209
214
  update_check_function_only: fileContains('src/core/update-check.ts', 'pipeline_required: false')
210
215
  && fileContains('src/core/update-check.ts', "mode: 'function'")
211
- && fileContains('src/core/hooks-runtime.ts', 'runSksUpdateCheck')
216
+ && fileContains('src/core/hooks-runtime.ts', 'UPDATE_CHECK_HOOK_INVOCATION_POLICY')
217
+ && !/\brunSksUpdateCheck\s*\(/.test(stripComments(hooksRuntimeSource))
212
218
  };
213
219
  const docs = runNodeScript('dist/scripts/docs-truthfulness-check.js');
214
220
  const officialDocs = runNodeScriptWithOkReportCache('dist/scripts/official-docs-compat-report.js', `.sneakoscope/reports/official-docs-compat-${RELEASE_VERSION}.json`, ['src/scripts/official-docs-compat-report.ts', 'package.json', 'package-lock.json']);
@@ -1004,13 +1010,18 @@ function scriptContains(name, needle) {
1004
1010
  return String(pkg.scripts?.[name] || '').includes(needle) || releaseParallelCheckSource.includes(needle);
1005
1011
  }
1006
1012
  if (name === 'release:check') {
1007
- return String(pkg.scripts?.[name] || '').includes(needle) || releaseParallelCheckSource.includes(needle);
1013
+ return String(pkg.scripts?.[name] || '').includes(needle) || releaseParallelCheckSource.includes(needle) || releaseGateIds.has(needle);
1008
1014
  }
1009
1015
  if (name === 'release:real-check') {
1010
1016
  return String(pkg.scripts?.[name] || '').includes(needle) || releaseRealCheckSource.includes(needle);
1011
1017
  }
1012
1018
  return String(pkg.scripts?.[name] || '').includes(needle);
1013
1019
  }
1020
+ function stripComments(text) {
1021
+ return String(text || '')
1022
+ .replace(/\/\*[\s\S]*?\*\//g, '')
1023
+ .replace(/(^|[^:])\/\/.*$/gm, '$1');
1024
+ }
1014
1025
  function readText(rel, fallback = '') {
1015
1026
  try {
1016
1027
  return fs.readFileSync(path.join(root, rel), 'utf8');