sneakoscope 2.0.7 → 2.0.9

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 (78) hide show
  1. package/README.md +1 -1
  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 +44 -8
  8. package/dist/commands/zellij.js +144 -1
  9. package/dist/core/agents/agent-command-surface.js +4 -2
  10. package/dist/core/agents/agent-orchestrator.js +5 -2
  11. package/dist/core/agents/agent-patch-schema.js +4 -2
  12. package/dist/core/agents/native-cli-session-swarm.js +81 -9
  13. package/dist/core/commands/mad-sks-command.js +17 -1
  14. package/dist/core/commands/naruto-command.js +99 -7
  15. package/dist/core/fsx.js +1 -1
  16. package/dist/core/git/git-repo-detection.js +7 -0
  17. package/dist/core/git/git-worktree-cleanup.js +14 -3
  18. package/dist/core/git/git-worktree-diff.js +7 -2
  19. package/dist/core/git/git-worktree-manager.js +9 -2
  20. package/dist/core/git/git-worktree-patch-envelope.js +5 -5
  21. package/dist/core/naruto/naruto-active-pool.js +108 -0
  22. package/dist/core/naruto/naruto-concurrency-governor.js +16 -1
  23. package/dist/core/naruto/naruto-work-graph.js +2 -1
  24. package/dist/core/release/release-gate-cache-v2.js +117 -0
  25. package/dist/core/release/release-gate-dag.js +190 -0
  26. package/dist/core/release/release-gate-hermetic-env.js +32 -0
  27. package/dist/core/release/release-gate-node.js +62 -0
  28. package/dist/core/release/release-gate-report.js +11 -0
  29. package/dist/core/release/release-gate-resource-governor.js +54 -0
  30. package/dist/core/release/release-gate-scheduler.js +15 -0
  31. package/dist/core/version.js +1 -1
  32. package/dist/core/zellij/zellij-dashboard-pane.js +71 -0
  33. package/dist/core/zellij/zellij-dashboard-renderer.js +58 -0
  34. package/dist/core/zellij/zellij-launcher.js +3 -3
  35. package/dist/core/zellij/zellij-layout-builder.js +1 -1
  36. package/dist/core/zellij/zellij-right-column-layout-proof.js +42 -0
  37. package/dist/core/zellij/zellij-right-column-manager.js +245 -0
  38. package/dist/core/zellij/zellij-worker-pane-manager.js +180 -15
  39. package/dist/scripts/codex-sdk-release-review-pipeline-check.js +5 -5
  40. package/dist/scripts/doctor-fix-proves-codex-read-check.js +26 -5
  41. package/dist/scripts/git-worktree-diff-envelope-check.js +17 -0
  42. package/dist/scripts/git-worktree-dirty-lock-check.js +17 -0
  43. package/dist/scripts/git-worktree-dirty-main-detection-check.js +14 -0
  44. package/dist/scripts/git-worktree-integration-primary-check.js +22 -0
  45. package/dist/scripts/git-worktree-manifest-append-check.js +18 -0
  46. package/dist/scripts/git-worktree-untracked-diff-check.js +18 -0
  47. package/dist/scripts/lib/codex-sdk-gate-lib.js +4 -0
  48. package/dist/scripts/mad-sks-zellij-default-pane-worker-check.js +2 -2
  49. package/dist/scripts/naruto-concurrency-governor-check.js +2 -1
  50. package/dist/scripts/naruto-extreme-parallelism-check.js +22 -0
  51. package/dist/scripts/naruto-real-active-pool-check.js +38 -0
  52. package/dist/scripts/naruto-work-graph-check.js +1 -1
  53. package/dist/scripts/naruto-worktree-coding-blackbox.js +29 -0
  54. package/dist/scripts/naruto-zellij-dynamic-right-column-check.js +21 -0
  55. package/dist/scripts/product-design-auto-install-check.js +3 -3
  56. package/dist/scripts/product-design-plugin-routing-check.js +3 -3
  57. package/dist/scripts/release-cache-glob-hashing-check.js +42 -0
  58. package/dist/scripts/release-dag-full-coverage-check.js +35 -0
  59. package/dist/scripts/release-gate-dag-runner-check.js +17 -0
  60. package/dist/scripts/release-gate-dag-runner.js +32 -0
  61. package/dist/scripts/release-gate-worker.js +10 -0
  62. package/dist/scripts/release-metadata-1-19-check.js +8 -2
  63. package/dist/scripts/release-parallel-speed-budget-check.js +79 -0
  64. package/dist/scripts/release-readiness-report.js +1 -1
  65. package/dist/scripts/release-stability-report-check.js +99 -0
  66. package/dist/scripts/zellij-dashboard-pane-check.js +70 -0
  67. package/dist/scripts/zellij-dashboard-watch.js +41 -0
  68. package/dist/scripts/zellij-developer-controls-check.js +20 -0
  69. package/dist/scripts/zellij-dynamic-pane-lifecycle-check.js +21 -0
  70. package/dist/scripts/zellij-initial-main-only-blackbox.js +28 -0
  71. package/dist/scripts/zellij-right-column-geometry-proof.js +29 -0
  72. package/dist/scripts/zellij-right-column-manager-check.js +22 -0
  73. package/dist/scripts/zellij-worker-pane-manager-check.js +2 -1
  74. package/dist/scripts/zellij-worker-pane-manager-single-owner-check.js +7 -6
  75. package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +185 -0
  76. package/package.json +32 -5
  77. package/schemas/release/release-gate-node.schema.json +52 -0
  78. package/schemas/zellij/zellij-right-column-state.schema.json +41 -0
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const naruto = fs.readFileSync(path.join(root, 'src/core/commands/naruto-command.ts'), 'utf8');
7
+ const worker = fs.readFileSync(path.join(root, 'src/core/zellij/zellij-worker-pane-manager.ts'), 'utf8');
8
+ const swarm = fs.readFileSync(path.join(root, 'src/core/agents/native-cli-session-swarm.ts'), 'utf8');
9
+ const report = {
10
+ schema: 'sks.naruto-zellij-dynamic-right-column-check.v1',
11
+ ok: true,
12
+ initial_main_only: /slotCount:\s*0/.test(naruto),
13
+ passes_session_name: naruto.includes('zellijSessionName: liveZellij?.session_name'),
14
+ passes_worker_placement: naruto.includes("workerPlacement: parsed.json || parsed.noOpenZellij ? 'process' : 'zellij-pane'"),
15
+ 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'")
17
+ };
18
+ report.ok = report.initial_main_only && report.passes_session_name && report.passes_worker_placement && report.passes_visible_cap && report.worker_uses_right_column;
19
+ assertGate(report.ok, 'Naruto must use dynamic right-column worker panes in interactive mode', report);
20
+ emitGate('naruto:zellij-dynamic-right-column', report);
21
+ //# sourceMappingURL=naruto-zellij-dynamic-right-column-check.js.map
@@ -2,7 +2,7 @@
2
2
  // @ts-nocheck
3
3
  import { ensureProductDesignPluginInstalledWithRequest, findProductDesignPluginSummaryFromMarketplaces, productDesignAutoInstallRequested } from '../core/product-design-app-server.js';
4
4
  import { PRODUCT_DESIGN_PLUGIN, PRODUCT_DESIGN_REQUIRED_SKILLS } from '../core/product-design-plugin.js';
5
- import { assertGate, emitGate, readText } from './lib/codex-sdk-gate-lib.js';
5
+ import { assertGate, emitGate, readText, releaseGateIds } from './lib/codex-sdk-gate-lib.js';
6
6
  function pluginReadResponse({ installed, enabled }) {
7
7
  return {
8
8
  plugin: {
@@ -92,7 +92,7 @@ const codexAppSource = readText('src/core/codex-app.ts');
92
92
  const commandSource = readText('src/commands/codex-app.ts');
93
93
  const appServerSource = readText('src/core/product-design-app-server.ts');
94
94
  const pkg = JSON.parse(readText('package.json'));
95
- const releaseCheck = String(pkg.scripts?.['release:check'] || '');
95
+ const releaseGates = releaseGateIds();
96
96
  for (const token of [
97
97
  'ensureProductDesignPluginInstalled',
98
98
  'PRODUCT_DESIGN_AUTO_INSTALL_ENV',
@@ -109,7 +109,7 @@ for (const token of [
109
109
  assertGate(commandSource.includes(token), `sks codex-app command missing Product Design token: ${token}`);
110
110
  }
111
111
  assertGate(Boolean(pkg.scripts?.['codex:product-design-auto-install']), 'package script missing codex:product-design-auto-install');
112
- assertGate(releaseCheck.includes('codex:product-design-auto-install'), 'release:check must include Product Design auto-install gate');
112
+ assertGate(releaseGates.has('codex:product-design-auto-install'), 'release gate DAG must include Product Design auto-install gate');
113
113
  emitGate('codex:product-design-auto-install', {
114
114
  install_calls: installCalls.map((call) => call.method),
115
115
  dry_calls: dryCalls.map((call) => call.method),
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // @ts-nocheck
3
3
  import { PRODUCT_DESIGN_PIPELINE_STAGES, PRODUCT_DESIGN_PLUGIN, PRODUCT_DESIGN_REQUIRED_SKILLS, normalizeProductDesignPluginEvidence, productDesignPluginVisibilityFromCodexPluginList } from '../core/product-design-plugin.js';
4
- import { assertGate, emitGate, readText } from './lib/codex-sdk-gate-lib.js';
4
+ import { assertGate, emitGate, readText, releaseGateIds } from './lib/codex-sdk-gate-lib.js';
5
5
  const routesSource = readText('src/core/routes.ts');
6
6
  const productDesignSource = readText('src/core/product-design-plugin.ts');
7
7
  const runtimeSource = readText('src/core/pipeline-internals/runtime-core.ts');
@@ -9,7 +9,7 @@ const pptSource = readText('src/core/ppt.ts');
9
9
  const codexAppSource = readText('src/core/codex-app.ts');
10
10
  const initSource = readText('src/core/init.ts');
11
11
  const pkg = JSON.parse(readText('package.json'));
12
- const releaseCheck = String(pkg.scripts?.['release:check'] || '');
12
+ const releaseGates = releaseGateIds();
13
13
  assertGate(PRODUCT_DESIGN_PLUGIN.id === 'product-design@openai-curated-remote', 'Product Design plugin id must use the remote marketplace');
14
14
  assertGate(PRODUCT_DESIGN_PLUGIN.marketplace === 'openai-curated-remote', 'Product Design marketplace must be openai-curated-remote');
15
15
  assertGate(PRODUCT_DESIGN_PLUGIN.marketplace_kind === 'vertical', 'Product Design marketplace kind must be vertical');
@@ -90,7 +90,7 @@ for (const token of [
90
90
  assertGate(codexAppSource.includes(token), `codex-app.ts missing Product Design readiness token: ${token}`);
91
91
  }
92
92
  assertGate(Boolean(pkg.scripts?.['codex:product-design-plugin-routing']), 'package script missing codex:product-design-plugin-routing');
93
- assertGate(releaseCheck.includes('codex:product-design-plugin-routing'), 'release:check must include Product Design routing gate');
93
+ assertGate(releaseGates.has('codex:product-design-plugin-routing'), 'release gate DAG must include Product Design routing gate');
94
94
  emitGate('codex:product-design-plugin-routing', {
95
95
  plugin_id: PRODUCT_DESIGN_PLUGIN.id,
96
96
  remote_plugin_id: PRODUCT_DESIGN_PLUGIN.remote_plugin_id,
@@ -0,0 +1,42 @@
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 { expandGlob, releaseGateCacheKey } from '../core/release/release-gate-cache-v2.js';
8
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-cache-glob-'));
9
+ fs.mkdirSync(path.join(tmp, 'src/core/release'), { recursive: true });
10
+ fs.writeFileSync(path.join(tmp, 'package.json'), JSON.stringify({ version: '0.0.0' }));
11
+ fs.writeFileSync(path.join(tmp, 'release-gates.v2.json'), JSON.stringify({ schema: 'sks.release-gates.v2', gates: [] }));
12
+ fs.writeFileSync(path.join(tmp, 'src/core/release/a.ts'), 'a');
13
+ const gate = {
14
+ id: 'release:cache-glob-hashing-fixture',
15
+ command: 'node fixture',
16
+ deps: [],
17
+ resource: ['cpu-light'],
18
+ side_effect: 'hermetic',
19
+ timeout_ms: 1000,
20
+ cache: { enabled: true, inputs: ['src/core/release/**'] },
21
+ isolation: { home: 'temp', codex_home: 'temp', report_dir: 'per-gate' },
22
+ preset: ['release']
23
+ };
24
+ const before = releaseGateCacheKey(tmp, gate);
25
+ const expandedBefore = expandGlob(tmp, 'src/core/release/**');
26
+ fs.writeFileSync(path.join(tmp, 'src/core/release/b.ts'), 'b');
27
+ const afterAdd = releaseGateCacheKey(tmp, gate);
28
+ fs.writeFileSync(path.join(tmp, 'src/core/release/a.ts'), 'changed');
29
+ const afterChange = releaseGateCacheKey(tmp, gate);
30
+ const expandedAfter = expandGlob(tmp, 'src/core/release/**');
31
+ const report = {
32
+ schema: 'sks.release-cache-glob-hashing-check.v1',
33
+ ok: expandedBefore.length === 1 && expandedAfter.length === 2 && before !== afterAdd && afterAdd !== afterChange,
34
+ expanded_before: expandedBefore.map((file) => path.basename(file)),
35
+ expanded_after: expandedAfter.map((file) => path.basename(file)),
36
+ before,
37
+ after_add: afterAdd,
38
+ after_change: afterChange
39
+ };
40
+ assertGate(report.ok, 'release cache key must hash recursive glob file paths and contents', report);
41
+ emitGate('release:cache-glob-hashing', report);
42
+ //# sourceMappingURL=release-cache-glob-hashing-check.js.map
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
7
+ const manifest = JSON.parse(fs.readFileSync(path.join(root, 'release-gates.v2.json'), 'utf8'));
8
+ const legacy = String(pkg.scripts['release:check:legacy'] || '');
9
+ const legacyIds = [...new Set([...legacy.matchAll(/npm run ([^\s&]+)/g)].map((match) => match[1]).filter((id) => pkg.scripts[id]))];
10
+ const allowlist = new Map([
11
+ ['release:check:parallel', 'legacy aggregate superseded by release-gates.v2 DAG'],
12
+ ['codex-app:fast-ui-preservation', 'Codex App UI real-environment preservation gate'],
13
+ ['codex-control:keepalive-no-cot-leak', 'long-running remote keepalive/debug gate'],
14
+ ['zellij:real-session-heartbeat', 'real Zellij heartbeat covered by release:real-check'],
15
+ ['publish:packlist-performance', 'publish/package performance gate'],
16
+ ['release:dynamic-performance', 'performance budget gate covered by release:parallel-speed-budget']
17
+ ]);
18
+ const gateIds = new Set(manifest.gates.map((gate) => gate.id));
19
+ const missing = legacyIds.filter((id) => !gateIds.has(id) && !allowlist.has(id));
20
+ const allowed = legacyIds.filter((id) => allowlist.has(id)).map((id) => ({ id, reason: allowlist.get(id) }));
21
+ const coverage = legacyIds.length ? (legacyIds.length - missing.length) / legacyIds.length : 1;
22
+ const schemaComplete = manifest.gates.every((gate) => gate.id && gate.command && Array.isArray(gate.deps) && Array.isArray(gate.resource) && gate.side_effect && gate.timeout_ms && gate.cache && gate.isolation && Array.isArray(gate.preset));
23
+ const report = {
24
+ schema: 'sks.release-dag-full-coverage-check.v1',
25
+ ok: missing.length === 0 && coverage >= 0.95 && schemaComplete,
26
+ legacy_gate_count: legacyIds.length,
27
+ v2_gate_count: manifest.gates.length,
28
+ coverage,
29
+ missing,
30
+ allowed,
31
+ schema_complete: schemaComplete
32
+ };
33
+ assertGate(report.ok, 'release-gates.v2 must cover legacy hermetic release gates', report);
34
+ emitGate('release:dag-full-coverage', report);
35
+ //# sourceMappingURL=release-dag-full-coverage-check.js.map
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, emitGate, readJson, readText } from './sks-1-18-gate-lib.js';
4
+ const pkg = readJson('package.json');
5
+ const manifest = readJson('release-gates.v2.json');
6
+ const runner = readText('src/core/release/release-gate-dag.ts');
7
+ const scheduler = readText('src/core/release/release-gate-scheduler.ts');
8
+ const cache = readText('src/core/release/release-gate-cache-v2.ts');
9
+ assertGate(pkg.scripts['release:check'].includes('release-gate-dag-runner.js'), 'release:check must execute DAG runner', pkg.scripts['release:check']);
10
+ assertGate(!/&&\s*npm run\s+\w/.test(pkg.scripts['release:check'].replace('npm run build --silent &&', '')), 'release:check must not be a giant npm-run chain', pkg.scripts['release:check']);
11
+ assertGate(pkg.scripts['release:check:legacy'], 'release:check:legacy must exist for explicit debugging');
12
+ assertGate(manifest.schema === 'sks.release-gates.v2' && manifest.gates.length >= 10, 'release-gates.v2 manifest must exist with nodes', manifest);
13
+ assertGate(runner.includes('Promise.race') && scheduler.includes('pickLaunchableReleaseGates'), 'DAG runner must schedule independent gates concurrently');
14
+ assertGate(runner.includes('readReleaseGateCacheHit') && cache.includes('RELEASE_GATE_CACHE_V2_SCHEMA'), 'DAG runner must use release gate cache v2 module');
15
+ assertGate(runner.includes('cpu_time_saved_ms') && runner.includes('peak_running') && runner.includes('budget_snapshot'), 'DAG summary must include CPU time saved, peak running gates, and resource budget proof');
16
+ emitGate('release:dag-runner', { gates: manifest.gates.length, default_script: pkg.scripts['release:check'] });
17
+ //# sourceMappingURL=release-gate-dag-runner-check.js.map
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { runReleaseGateDag } from '../core/release/release-gate-dag.js';
5
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
6
+ const args = process.argv.slice(2);
7
+ const presetIndex = args.indexOf('--preset');
8
+ const preset = presetIndex >= 0 ? args[presetIndex + 1] : 'release';
9
+ const result = await runReleaseGateDag({
10
+ root,
11
+ ...(preset === undefined ? {} : { preset }),
12
+ explain: args.includes('--explain'),
13
+ noCache: args.includes('--no-cache'),
14
+ failFast: args.includes('--fail-fast')
15
+ });
16
+ console.log(`SKS Release DAG
17
+ gates: ${result.total_gates} total, ${result.selected_gates} selected, ${result.cached} cached
18
+ concurrency: ${result.budget_summary}
19
+ peak_running: ${result.peak_running}
20
+ completed: ${result.completed} pass, ${result.failed} fail
21
+ wall: ${(result.wall_ms / 1000).toFixed(1)}s
22
+ parallelism_gain: ${result.parallelism_gain}
23
+ cpu_time_saved: ${(result.cpu_time_saved_ms / 1000).toFixed(1)}s
24
+ critical_path: ${(result.critical_path_ms / 1000).toFixed(1)}s
25
+ report: ${result.report_dir}`);
26
+ if (!result.ok) {
27
+ for (const failure of result.failures) {
28
+ console.error(`[fail] ${failure.id} exit=${failure.exit_code}\n${failure.stderr_tail}`);
29
+ }
30
+ process.exit(1);
31
+ }
32
+ //# sourceMappingURL=release-gate-dag-runner.js.map
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from 'node:child_process';
3
+ const command = process.argv.slice(2).join(' ');
4
+ if (!command) {
5
+ console.error('usage: release-gate-worker <command>');
6
+ process.exit(2);
7
+ }
8
+ const result = spawnSync(command, { shell: true, stdio: 'inherit', env: process.env });
9
+ process.exit(result.status ?? 1);
10
+ //# sourceMappingURL=release-gate-worker.js.map
@@ -10,6 +10,11 @@ const distManifestPath = path.join(root, 'dist/build-manifest.json');
10
10
  const distManifest = fs.existsSync(distManifestPath) ? JSON.parse(fs.readFileSync(distManifestPath, 'utf8')) : null;
11
11
  const parallelCheckPath = path.join(root, 'src/scripts/release-parallel-check.ts');
12
12
  const parallelCheckSource = fs.existsSync(parallelCheckPath) ? fs.readFileSync(parallelCheckPath, 'utf8') : '';
13
+ const releaseCheckScriptSource = [
14
+ String(pkg.scripts?.['release:check'] || ''),
15
+ String(pkg.scripts?.['release:check:legacy'] || ''),
16
+ parallelCheckSource
17
+ ].join('\n');
13
18
  const releaseRealCheckPath = path.join(root, 'src/scripts/release-real-check.ts');
14
19
  const releaseRealCheckSource = fs.existsSync(releaseRealCheckPath) ? fs.readFileSync(releaseRealCheckPath, 'utf8') : '';
15
20
  const requiredDocs = [
@@ -304,13 +309,14 @@ assertGate(distManifest?.version === RELEASE_VERSION, `dist/build-manifest versi
304
309
  assertGate(distManifest?.package_version === RELEASE_VERSION, `dist/build-manifest package_version must be ${RELEASE_VERSION}`, { package_version: distManifest?.package_version || null });
305
310
  assertGate(typeof distManifest?.source_digest === 'string' && distManifest.source_digest.length >= 32, 'dist/build-manifest must include source_digest', { source_digest: distManifest?.source_digest || null });
306
311
  assertGate(pkg.scripts?.['release:metadata']?.includes('dist/scripts/release-metadata-check.js'), 'release:metadata must point to the generic release metadata check');
307
- assertGate(String(pkg.scripts?.['release:check'] || '').startsWith('npm run release:check:parallel'), 'release:check must use release:check:parallel');
312
+ const releaseCheckScript = String(pkg.scripts?.['release:check'] || '');
313
+ assertGate(releaseCheckScript.startsWith('npm run release:check:parallel') || releaseCheckScript.includes('release-gate-dag-runner.js --preset release'), 'release:check must use release:check:parallel or the release gate DAG runner');
308
314
  for (const script of requiredScripts)
309
315
  assertGate(Boolean(pkg.scripts?.[script]), `missing package script: ${script}`);
310
316
  for (const script of requiredRealScripts)
311
317
  assertGate(Boolean(pkg.scripts?.[script]), `missing package real script: ${script}`);
312
318
  for (const script of requiredScripts.filter((name) => name !== 'release:check:parallel')) {
313
- assertGate(parallelCheckSource.includes(`npm run ${script}`) || String(pkg.scripts?.['release:check'] || '').includes(`npm run ${script}`) || ['release:metadata', 'release:readiness'].includes(script), `release:check DAG missing ${script}`);
319
+ assertGate(releaseCheckScriptSource.includes(`npm run ${script}`) || ['release:metadata', 'release:readiness'].includes(script), `release check coverage missing ${script}`);
314
320
  }
315
321
  for (const script of requiredRealScripts) {
316
322
  assertGate(String(pkg.scripts?.['release:real-check'] || '').includes(`npm run ${script}`) || releaseRealCheckSource.includes(`'${script}'`) || releaseRealCheckSource.includes(`"${script}"`), `release:real-check missing ${script}`);
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const latest = latestDagSummary();
7
+ assertGate(Boolean(latest), 'release speed budget requires an actual DAG summary', {
8
+ expected: '.sneakoscope/reports/release-gates/<latest>/summary.json',
9
+ hint: 'run npm run release:check:dag first'
10
+ });
11
+ const summary = JSON.parse(fs.readFileSync(latest.summaryPath, 'utf8'));
12
+ const slowest = slowestGateResults(latest.dir);
13
+ const warnOnly = process.env.SKS_RELEASE_SPEED_BUDGET_WARN_ONLY === '1';
14
+ const budgetMs = Number(process.env.SKS_RELEASE_SPEED_BUDGET_MS || 20 * 60 * 1000);
15
+ const cachedBudgetMs = 3 * 60 * 1000;
16
+ const cachedRatio = Number(summary.cached || 0) / Math.max(1, Number(summary.completed || summary.selected_gates || 1));
17
+ const cachedRun = cachedRatio >= 0.5;
18
+ const parallelismOk = cachedRun || summary.parallelism_gain >= 2;
19
+ const wallOk = cachedRun ? summary.wall_ms <= cachedBudgetMs : summary.wall_ms <= budgetMs;
20
+ const summaryOk = Number(summary.failed || 0) === 0;
21
+ const report = {
22
+ schema: 'sks.release-speed.v1',
23
+ ok: summaryOk && parallelismOk && (wallOk || warnOnly),
24
+ summary_path: path.relative(root, latest.summaryPath),
25
+ run_id: summary.run_id,
26
+ mode: cachedRun ? 'cached' : 'full',
27
+ total_gates: summary.total_gates,
28
+ selected_gates: summary.selected_gates,
29
+ completed: summary.completed,
30
+ failed: summary.failed,
31
+ cached: summary.cached,
32
+ cached_ratio: Number(cachedRatio.toFixed(4)),
33
+ wall_ms: summary.wall_ms,
34
+ sum_gate_ms: summary.sum_gate_ms,
35
+ critical_path_ms: summary.critical_path_ms,
36
+ slowest_gates: slowest,
37
+ target_full_wall_ms: budgetMs,
38
+ target_cached_wall_ms: cachedBudgetMs,
39
+ target_changed_file_wall_ms: 90 * 1000,
40
+ parallelism_gain: summary.parallelism_gain,
41
+ warn_only: warnOnly,
42
+ blockers: [
43
+ ...(summaryOk ? [] : ['release_summary_has_failures']),
44
+ ...(parallelismOk ? [] : ['parallelism_gain_below_2']),
45
+ ...(wallOk || warnOnly ? [] : [cachedRun ? 'cached_release_wall_budget_exceeded' : 'release_wall_budget_exceeded']),
46
+ ...(Number.isFinite(Number(summary.critical_path_ms)) ? [] : ['critical_path_ms_missing']),
47
+ ...(Array.isArray(slowest) && slowest.length ? [] : ['slowest_gates_missing'])
48
+ ]
49
+ };
50
+ assertGate(report.blockers.length === 0, 'release DAG speed budget must use and pass actual run summary', report);
51
+ fs.mkdirSync(path.join(root, '.sneakoscope', 'reports'), { recursive: true });
52
+ fs.writeFileSync(path.join(root, '.sneakoscope', 'reports', 'release-parallel-speed-budget.json'), `${JSON.stringify(report, null, 2)}\n`);
53
+ emitGate('release:parallel-speed-budget', report);
54
+ function latestDagSummary() {
55
+ const dir = path.join(root, '.sneakoscope', 'reports', 'release-gates');
56
+ if (!fs.existsSync(dir))
57
+ return null;
58
+ const rows = fs.readdirSync(dir)
59
+ .map((name) => path.join(dir, name))
60
+ .filter((candidate) => fs.existsSync(path.join(candidate, 'summary.json')))
61
+ .map((candidate) => ({ dir: candidate, summaryPath: path.join(candidate, 'summary.json'), mtime: fs.statSync(path.join(candidate, 'summary.json')).mtimeMs }))
62
+ .sort((a, b) => b.mtime - a.mtime);
63
+ return rows[0] || null;
64
+ }
65
+ function slowestGateResults(reportDir) {
66
+ const out = [];
67
+ for (const name of fs.readdirSync(reportDir)) {
68
+ const file = path.join(reportDir, name, 'result.json');
69
+ if (!fs.existsSync(file))
70
+ continue;
71
+ try {
72
+ const result = JSON.parse(fs.readFileSync(file, 'utf8'));
73
+ out.push({ id: result.id || name, duration_ms: Number(result.duration_ms || 0), cached: result.cached === true, ok: result.ok === true });
74
+ }
75
+ catch { }
76
+ }
77
+ return out.sort((a, b) => b.duration_ms - a.duration_ms).slice(0, 10);
78
+ }
79
+ //# sourceMappingURL=release-parallel-speed-budget-check.js.map
@@ -216,7 +216,7 @@ const releaseMetadata = runNodeScript('dist/scripts/release-metadata-check.js');
216
216
  const sideEffectRuntime = runNodeScript('dist/scripts/side-effect-runtime-report-check.js');
217
217
  const releaseProvenance = runNodeScript('dist/scripts/release-provenance-check.js');
218
218
  const imagegenCore = runNodeScript('dist/scripts/imagegen-capability-check.js');
219
- const dynamicReleaseMode = process.env.SKS_RELEASE_DYNAMIC === '1';
219
+ const dynamicReleaseMode = process.env.SKS_RELEASE_DYNAMIC === '1' || Boolean(process.env.SKS_REPORT_DIR);
220
220
  const runtimeReports = {
221
221
  ppt_full_e2e_blackbox: readJson('.sneakoscope/reports/ppt-full-e2e-blackbox.json', null),
222
222
  flagship_proof_graph_v3: readJson('.sneakoscope/reports/flagship-proof-graph-v3.json', null),
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, readJson, root } from './sks-1-18-gate-lib.js';
6
+ const manifest = readJson('release-gates.v2.json');
7
+ const currentRunDir = process.env.SKS_REPORT_DIR ? path.dirname(process.env.SKS_REPORT_DIR) : null;
8
+ const latestReleaseRun = currentRunDir || latestDir(path.join(root, '.sneakoscope', 'reports', 'release-gates'));
9
+ const latestSummary = currentRunDir ? summarizeCurrentRun(currentRunDir) : latestReleaseRun ? readJsonIfExists(path.join(latestReleaseRun, 'summary.json')) : null;
10
+ const zellijReportPath = path.join(root, '.sneakoscope', 'reports', 'zellij-worker-pane-real-ui-blackbox.json');
11
+ const zellij = fs.existsSync(zellijReportPath) ? JSON.parse(fs.readFileSync(zellijReportPath, 'utf8')) : null;
12
+ const requiredGateIds = [
13
+ 'release:dag-runner',
14
+ 'release:parallel-speed-budget',
15
+ 'git:worktree-manifest-append',
16
+ 'git:worktree-dirty-main-detection',
17
+ 'git:worktree-untracked-diff',
18
+ 'git:worktree-diff-envelope',
19
+ 'git:worktree-integration-primary',
20
+ 'git:worktree-dirty-lock',
21
+ 'naruto:worktree-coding:blackbox',
22
+ 'release:version-truth'
23
+ ];
24
+ const manifestIds = new Set(manifest.gates.map((gate) => gate.id));
25
+ const missing = requiredGateIds.filter((id) => !manifestIds.has(id));
26
+ const score = computeScore({ missing, latestSummary, zellij });
27
+ const report = {
28
+ schema: 'sks.release-stability-report.v1',
29
+ ok: score >= 9.5 && missing.length === 0 && latestSummary?.ok === true && zellij?.ok === true,
30
+ target_score: 9.5,
31
+ score,
32
+ manifest_gate_count: manifest.gates.length,
33
+ latest_release_summary: latestSummary ? path.relative(root, path.join(latestReleaseRun, 'summary.json')) : null,
34
+ release_check_ok: latestSummary?.ok === true,
35
+ release_check_passed: latestSummary?.completed || 0,
36
+ release_check_failed: latestSummary?.failed || 0,
37
+ zellij_real_worker_panes_ok: zellij?.ok === true,
38
+ zellij_real_worker_panes: zellij?.real_pane_ids || 0,
39
+ missing_required_gates: missing,
40
+ blockers: []
41
+ };
42
+ if (!report.ok) {
43
+ report.blockers = [
44
+ ...(score >= 9.5 ? [] : ['stability_score_below_target']),
45
+ ...(missing.length ? ['required_release_gate_missing'] : []),
46
+ ...(latestSummary?.ok === true ? [] : ['latest_release_check_not_green']),
47
+ ...(zellij?.ok === true ? [] : ['zellij_real_worker_panes_not_green'])
48
+ ];
49
+ }
50
+ fs.mkdirSync(path.join(root, '.sneakoscope', 'reports'), { recursive: true });
51
+ fs.writeFileSync(path.join(root, '.sneakoscope', 'reports', 'release-stability-report.json'), `${JSON.stringify(report, null, 2)}\n`);
52
+ assertGate(report.ok, 'release stability report must meet 9.5+ target', report);
53
+ emitGate('release:stability-report', report);
54
+ function computeScore({ missing, latestSummary, zellij }) {
55
+ let score = 10;
56
+ score -= missing.length * 0.25;
57
+ if (latestSummary?.ok !== true)
58
+ score -= 1.5;
59
+ if ((latestSummary?.failed || 0) > 0)
60
+ score -= 1;
61
+ if (zellij?.ok !== true)
62
+ score -= 1;
63
+ return Number(Math.max(0, score).toFixed(2));
64
+ }
65
+ function latestDir(dir) {
66
+ if (!fs.existsSync(dir))
67
+ return null;
68
+ const dirs = fs.readdirSync(dir)
69
+ .map((name) => path.join(dir, name))
70
+ .filter((candidate) => fs.statSync(candidate).isDirectory())
71
+ .sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
72
+ return dirs[0] || null;
73
+ }
74
+ function summarizeCurrentRun(runDir) {
75
+ const results = [];
76
+ for (const entry of fs.readdirSync(runDir)) {
77
+ const result = readJsonIfExists(path.join(runDir, entry, 'result.json'));
78
+ if (result && result.id !== 'release:stability-report')
79
+ results.push(result);
80
+ }
81
+ if (!results.length)
82
+ return null;
83
+ const failed = results.filter((result) => result.ok !== true);
84
+ return {
85
+ schema: 'sks.release-gate-current-run-summary.v1',
86
+ ok: failed.length === 0,
87
+ completed: results.filter((result) => result.ok === true).length,
88
+ failed: failed.length
89
+ };
90
+ }
91
+ function readJsonIfExists(file) {
92
+ try {
93
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
94
+ }
95
+ catch {
96
+ return null;
97
+ }
98
+ }
99
+ //# sourceMappingURL=release-stability-report-check.js.map
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import path from 'node:path';
4
+ import { pathToFileURL } from 'node:url';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ import { ensureDistFresh } from './lib/ensure-dist-fresh.js';
7
+ import fs from 'node:fs';
8
+ const requireReal = process.env.SKS_REQUIRE_ZELLIJ === '1' || process.argv.includes('--require-real');
9
+ const freshness = ensureDistFresh({ rebuild: false });
10
+ assertGate(freshness.ok === true, 'dist must be fresh for zellij dashboard pane check', freshness);
11
+ const managerSource = fs.readFileSync(path.join(root, 'src', 'core', 'zellij', 'zellij-right-column-manager.ts'), 'utf8');
12
+ const narutoSource = fs.readFileSync(path.join(root, 'src', 'core', 'commands', 'naruto-command.ts'), 'utf8');
13
+ const madSource = fs.readFileSync(path.join(root, 'src', 'core', 'commands', 'mad-sks-command.ts'), 'utf8');
14
+ assertGate(managerSource.includes('openZellijDashboardPane') && narutoSource.includes("dashboard_created: false") && madSource.includes("dashboard_created: false"), 'Dashboard pane must be created by right-column manager after first worker spawn, not at launch', {
15
+ manager: managerSource.includes('openZellijDashboardPane'),
16
+ naruto_initial_dashboard_false: narutoSource.includes("dashboard_created: false"),
17
+ mad_initial_dashboard_false: madSource.includes("dashboard_created: false")
18
+ });
19
+ const dashboard = await import(pathToFileURL(path.join(root, 'dist', 'core', 'zellij', 'zellij-dashboard-pane.js')).href);
20
+ const command = await import(pathToFileURL(path.join(root, 'dist', 'core', 'zellij', 'zellij-command.js')).href);
21
+ const missionId = `M-zellij-dashboard-${Date.now()}`;
22
+ const sessionName = `sks-dashboard-${process.pid}`;
23
+ if (!requireReal) {
24
+ const snapshotMod = await import(pathToFileURL(path.join(root, 'dist', 'core', 'zellij', 'zellij-dashboard-renderer.js')).href);
25
+ const snapshot = snapshotMod.buildZellijDashboardSnapshot({ mission_id: missionId, active_workers: 4, visible_panes: 2, headless_workers: 2 });
26
+ const text = snapshotMod.renderZellijDashboardText(snapshot);
27
+ assertGate(text.includes('Mission') && text.includes('Backend counts') && text.includes('headless') && text.includes('GPT final status') && text.includes('Patch / verify'), 'dashboard renderer must include required fields', { text });
28
+ assertGate(fs.readFileSync(path.join(root, 'src', 'scripts', 'zellij-dashboard-watch.ts'), 'utf8').includes('--interval-ms')
29
+ && fs.existsSync(path.join(root, 'dist', 'scripts', 'zellij-dashboard-watch.js')), 'dashboard watch script must support interval updates');
30
+ emitGate('zellij:dashboard-pane', { real_required: false, renderer_fields: true });
31
+ process.exit(0);
32
+ }
33
+ await command.runZellij(['kill-session', sessionName], { cwd: root, timeoutMs: 5000, optional: true });
34
+ try {
35
+ const record = await dashboard.openZellijDashboardPane({
36
+ root,
37
+ missionId,
38
+ sessionName,
39
+ cwd: root,
40
+ snapshot: {
41
+ mode: 'naruto',
42
+ backend_counts: { 'codex-sdk': 2, 'local-llm': 1 },
43
+ placement_counts: { 'zellij-pane': 2, headless: 1 },
44
+ active_workers: 3,
45
+ visible_panes: 2,
46
+ headless_workers: 1,
47
+ queue_depth: 7,
48
+ worktrees: { active: 2, completed: 1, retained: 0 },
49
+ local_llm: { tps: 12, queue: 1 },
50
+ gpt_final_status: 'pending',
51
+ gate_progress: 'release: 8/12'
52
+ }
53
+ });
54
+ const ok = record.ok === true && record.pane_kind === 'dashboard' && record.worker_pane === false && record.pane_id
55
+ && String(record.command || '').includes('zellij-dashboard-watch.js')
56
+ && String(record.command || '').includes('--interval-ms 1000');
57
+ assertGate(ok, 'real Zellij dashboard pane must open and not count as worker pane', record);
58
+ emitGate('zellij:dashboard-pane', {
59
+ real_required: true,
60
+ pane_id: record.pane_id,
61
+ pane_kind: record.pane_kind,
62
+ worker_pane: record.worker_pane,
63
+ mission_id: missionId,
64
+ session_name: sessionName
65
+ });
66
+ }
67
+ finally {
68
+ await command.runZellij(['kill-session', sessionName], { cwd: root, timeoutMs: 5000, optional: true });
69
+ }
70
+ //# sourceMappingURL=zellij-dashboard-pane-check.js.map
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { buildZellijDashboardSnapshot, renderZellijDashboardText } from '../core/zellij/zellij-dashboard-renderer.js';
5
+ const args = process.argv.slice(2);
6
+ const snapshotPath = path.resolve(String(readOption(args, '--snapshot', '') || ''));
7
+ const intervalMs = Math.max(250, Number(readOption(args, '--interval-ms', '1000')) || 1000);
8
+ const once = args.includes('--once');
9
+ if (!snapshotPath) {
10
+ console.error('Usage: zellij-dashboard-watch --snapshot <path> [--interval-ms 1000] [--once]');
11
+ process.exit(2);
12
+ }
13
+ render();
14
+ if (!once)
15
+ setInterval(render, intervalMs);
16
+ function render() {
17
+ const snapshot = readSnapshot(snapshotPath);
18
+ const text = renderZellijDashboardText(snapshot);
19
+ process.stdout.write(`\x1b[2J\x1b[H${text}\nUpdated: ${new Date().toISOString()}\n`);
20
+ }
21
+ function readSnapshot(file) {
22
+ try {
23
+ const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
24
+ return buildZellijDashboardSnapshot(parsed);
25
+ }
26
+ catch (err) {
27
+ return buildZellijDashboardSnapshot({
28
+ mission_id: path.basename(path.dirname(file)) || 'unknown',
29
+ mode: 'dashboard-watch',
30
+ latest_blockers: [`snapshot_read_failed:${err?.code || err?.message || String(err)}`]
31
+ });
32
+ }
33
+ }
34
+ function readOption(list, name, fallback) {
35
+ const index = list.indexOf(name);
36
+ if (index >= 0 && list[index + 1])
37
+ return list[index + 1];
38
+ const prefixed = list.find((arg) => arg.startsWith(`${name}=`));
39
+ return prefixed ? prefixed.slice(name.length + 1) : fallback;
40
+ }
41
+ //# sourceMappingURL=zellij-dashboard-watch.js.map
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const zellij = fs.readFileSync(path.join(root, 'src/commands/zellij.ts'), 'utf8');
7
+ const naruto = fs.readFileSync(path.join(root, 'src/core/commands/naruto-command.ts'), 'utf8');
8
+ const report = {
9
+ schema: 'sks.zellij-developer-controls-check.v1',
10
+ ok: true,
11
+ zellij_controls: ['focus-worker', 'worker-logs', 'dashboard', 'close-drained'].every((token) => zellij.includes(token)),
12
+ naruto_controls: ['dashboard', 'workers'].every((token) => naruto.includes(`'${token}'`)),
13
+ dashboard_watch: zellij.includes('--watch') && zellij.includes('renderZellijDashboardText'),
14
+ focus_uses_pane_id: zellij.includes('focus-pane-id'),
15
+ logs_read_swarm: zellij.includes('agent-native-cli-session-swarm.json')
16
+ };
17
+ report.ok = report.zellij_controls && report.naruto_controls && report.dashboard_watch && report.focus_uses_pane_id && report.logs_read_swarm;
18
+ assertGate(report.ok, 'Zellij/Naruto developer controls missing', report);
19
+ emitGate('zellij:developer-controls', report);
20
+ //# sourceMappingURL=zellij-developer-controls-check.js.map
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const worker = fs.readFileSync(path.join(root, 'src/core/zellij/zellij-worker-pane-manager.ts'), 'utf8');
7
+ const manager = fs.readFileSync(path.join(root, 'src/core/zellij/zellij-right-column-manager.ts'), 'utf8');
8
+ const swarm = fs.readFileSync(path.join(root, 'src/core/agents/native-cli-session-swarm.ts'), 'utf8');
9
+ const report = {
10
+ schema: 'sks.zellij-dynamic-pane-lifecycle-check.v1',
11
+ ok: true,
12
+ close_success_default: worker.includes("SKS_ZELLIJ_CLOSE_WORKER_PANE !== '0'"),
13
+ keep_failed_default: worker.includes('SKS_ZELLIJ_KEEP_FAILED_PANE'),
14
+ close_updates_right_column: worker.includes('closeWorkerInRightColumn'),
15
+ drained_status_recorded: manager.includes('worker_pane_drained'),
16
+ overflow_headless_recorded: swarm.includes('recordHeadlessWorkerInRightColumn')
17
+ };
18
+ report.ok = report.close_success_default && report.keep_failed_default && report.close_updates_right_column && report.drained_status_recorded && report.overflow_headless_recorded;
19
+ assertGate(report.ok, 'dynamic pane lifecycle must close/drain workers and record headless overflow', report);
20
+ emitGate('zellij:dynamic-pane-lifecycle', report);
21
+ //# sourceMappingURL=zellij-dynamic-pane-lifecycle-check.js.map
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const mad = fs.readFileSync(path.join(root, 'src/core/commands/mad-sks-command.ts'), 'utf8');
7
+ const naruto = fs.readFileSync(path.join(root, 'src/core/commands/naruto-command.ts'), 'utf8');
8
+ const launcher = fs.readFileSync(path.join(root, 'src/core/zellij/zellij-launcher.ts'), 'utf8');
9
+ const report = {
10
+ schema: 'sks.zellij-initial-main-only-blackbox.v1',
11
+ ok: true,
12
+ mad_slot_zero: /launchMadZellijUi\([\s\S]*slotCount:\s*0/.test(mad),
13
+ mad_no_launch_dashboard: !/launch\.dashboard_pane\s*=\s*await openZellijDashboardPane/.test(mad),
14
+ mad_initial_ui_artifact: mad.includes('zellij-initial-ui.json') && mad.includes("dashboard_created: false"),
15
+ naruto_slot_zero: /launchZellijLayout\([\s\S]*slotCount:\s*0/.test(naruto),
16
+ naruto_no_launch_dashboard: !/liveZellij\.dashboard_pane\s*=\s*await openZellijDashboardPane/.test(naruto),
17
+ naruto_initial_ui_artifact: naruto.includes('zellij-initial-ui.json') && naruto.includes("dashboard_created: false"),
18
+ launcher_allows_zero: launcher.includes('slotCount: opts.slotCount || 1')
19
+ };
20
+ report.ok = report.mad_slot_zero
21
+ && report.mad_no_launch_dashboard
22
+ && report.mad_initial_ui_artifact
23
+ && report.naruto_slot_zero
24
+ && report.naruto_no_launch_dashboard
25
+ && report.naruto_initial_ui_artifact;
26
+ assertGate(report.ok, 'Zellij initial UI must be main-only with no dashboard/worker pane at launch', report);
27
+ emitGate('zellij:initial-main-only-blackbox', report);
28
+ //# sourceMappingURL=zellij-initial-main-only-blackbox.js.map