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
@@ -4,6 +4,7 @@ import { providerPaneLabel } from '../provider/provider-badge.js';
4
4
  import { resolveProviderContext } from '../provider/provider-context.js';
5
5
  import { runZellij } from './zellij-command.js';
6
6
  import { extractZellijPaneIdFromOutput } from './zellij-lane-runtime.js';
7
+ import { closeWorkerInRightColumn, prepareWorkerInRightColumn, recordWorkerPaneInRightColumn } from './zellij-right-column-manager.js';
7
8
  export const ZELLIJ_WORKER_PANE_SCHEMA = 'sks.zellij-worker-pane.v1';
8
9
  export const ZELLIJ_WORKER_PANE_EVENT_SCHEMA = 'sks.zellij-worker-pane-event.v1';
9
10
  export function buildWorkerPaneName(slotId, generationIndex) {
@@ -23,7 +24,7 @@ export function buildWorkerPaneArtifact(input) {
23
24
  const paneIdSource = input.paneIdSource || 'zellij_worker_pane_launch_failed';
24
25
  const blockers = input.blockers || [];
25
26
  const providerContext = normalizePaneProviderContext(input.providerContext, input.serviceTier);
26
- const paneTitle = buildWorkerPaneTitle(input.slotId, input.generationIndex, providerContext, input.serviceTier, input.backend, input.status || input.statusLabel, input.worktree || null);
27
+ const paneTitle = buildWorkerPaneTitle(input.slotId, input.generationIndex, providerContext, input.serviceTier, input.backend, input.statusLabel || input.status, input.worktree || null);
27
28
  return {
28
29
  schema: ZELLIJ_WORKER_PANE_SCHEMA,
29
30
  generated_at: now,
@@ -59,8 +60,9 @@ export function buildWorkerPaneArtifact(input) {
59
60
  opened_at: now,
60
61
  closed_at: null,
61
62
  close: null,
62
- direction_requested: 'right',
63
+ direction_requested: input.directionRequested || 'right',
63
64
  direction_applied: input.directionApplied || 'not_applied',
65
+ right_column: input.rightColumn || null,
64
66
  sdk_thread_id: input.sdkThreadId || null,
65
67
  sdk_run_id: input.sdkRunId || null,
66
68
  stream_event_count: Number(input.streamEventCount || 0),
@@ -79,34 +81,61 @@ export async function openWorkerPane(input) {
79
81
  const workerDir = path.join(root, input.workerArtifactDir);
80
82
  await ensureDir(workerDir);
81
83
  await appendWorkerPaneEvent(root, 'session_launch_started', input, {});
82
- const createSession = await runZellij(['attach', '--create-background', input.sessionName], {
84
+ const createSessionRaw = await runZellij(['attach', '--create-background', input.sessionName], {
83
85
  cwd,
84
86
  timeoutMs: 5000,
85
87
  optional: false
86
88
  });
89
+ const createSession = normalizeExistingZellijSession(input.sessionName, createSessionRaw);
90
+ const rightColumn = input.rightColumnMode === 'spawn-on-first-worker'
91
+ ? await prepareWorkerInRightColumn({
92
+ root,
93
+ ...(input.projectRoot ? { projectRoot: input.projectRoot } : {}),
94
+ missionId: input.missionId,
95
+ sessionName: input.sessionName,
96
+ cwd,
97
+ worker: { slotId: input.slotId, generationIndex: input.generationIndex },
98
+ visiblePaneCap: input.visiblePaneCap || 1,
99
+ dashboardSnapshot: {
100
+ ...(input.dashboardSnapshot || {}),
101
+ mode: String(input.dashboardSnapshot?.mode || 'naruto'),
102
+ active_workers: Number(input.dashboardSnapshot?.active_workers || input.visiblePaneCap || 1),
103
+ visible_panes: Number(input.dashboardSnapshot?.visible_panes || input.visiblePaneCap || 1)
104
+ }
105
+ })
106
+ : null;
87
107
  const paneName = buildWorkerPaneTitle(input.slotId, input.generationIndex, providerContext, input.serviceTier, input.backend, input.statusLabel || 'running', input.worktree || null);
108
+ const directionRequested = rightColumn ? 'down' : 'right';
109
+ const focus = rightColumn?.focusPaneId
110
+ ? await focusZellijPaneById(input.sessionName, rightColumn.focusPaneId, cwd)
111
+ : null;
112
+ const newPaneArgs = ['--session', input.sessionName, 'action', 'new-pane', '--direction', directionRequested, ...(rightColumn ? ['--near-current-pane'] : []), '--name', paneName, '--', 'sh', '-lc', input.workerCommand];
88
113
  let launch = createSession.ok
89
- ? await runZellij(['--session', input.sessionName, 'action', 'new-pane', '--direction', 'right', '--name', paneName, '--', 'sh', '-lc', input.workerCommand], {
114
+ ? await runZellij(newPaneArgs, {
90
115
  cwd,
91
116
  timeoutMs: 5000,
92
117
  optional: false
93
118
  })
94
119
  : null;
95
- let directionApplied = launch?.ok ? 'right' : 'not_applied';
120
+ let directionApplied = launch?.ok ? directionRequested : 'not_applied';
96
121
  if (createSession.ok && launch && !launch.ok) {
97
- const fallback = await runZellij(['--session', input.sessionName, 'action', 'new-pane', '--name', paneName, '--', 'sh', '-lc', input.workerCommand], {
122
+ const fallbackArgs = rightColumn
123
+ ? ['--session', input.sessionName, 'action', 'new-pane', '--direction', 'down', '--name', paneName, '--', 'sh', '-lc', input.workerCommand]
124
+ : ['--session', input.sessionName, 'action', 'new-pane', '--name', paneName, '--', 'sh', '-lc', input.workerCommand];
125
+ const fallback = await runZellij(fallbackArgs, {
98
126
  cwd,
99
127
  timeoutMs: 5000,
100
128
  optional: false
101
129
  });
102
130
  if (fallback.ok) {
103
131
  launch = fallback;
104
- directionApplied = 'unknown';
132
+ directionApplied = rightColumn ? 'down' : 'unknown';
105
133
  }
106
134
  }
107
135
  const stdoutPaneId = launch?.ok ? extractZellijPaneIdFromOutput(launch.stdout_tail) : null;
108
136
  const reconciledPane = stdoutPaneId ? null : launch?.ok ? await reconcileZellijWorkerPaneId(input.sessionName, paneName, path.join(root, input.resultPath), cwd) : null;
109
137
  const paneId = stdoutPaneId || reconciledPane?.pane_id || null;
138
+ const renamePane = paneId ? await renameZellijPaneById(input.sessionName, paneId, paneName, cwd) : null;
110
139
  const paneIdSource = stdoutPaneId
111
140
  ? 'zellij_worker_new_pane_stdout'
112
141
  : reconciledPane?.pane_id
@@ -116,6 +145,7 @@ export async function openWorkerPane(input) {
116
145
  : 'zellij_worker_pane_launch_failed';
117
146
  const blockers = [
118
147
  ...(createSession.ok ? [] : createSession.blockers.map((blocker) => `zellij_worker_session_${blocker}`)),
148
+ ...(rightColumn && rightColumn.placement !== 'zellij-pane' ? [`zellij_worker_right_column_${rightColumn.placement}`] : []),
119
149
  ...(launch && !launch.ok ? launch.blockers.map((blocker) => `zellij_worker_pane_${blocker}`) : []),
120
150
  ...(launch?.ok && !isRealZellijWorkerPaneIdSource(paneIdSource) ? ['zellij_worker_pane_id_real_source_missing'] : [])
121
151
  ];
@@ -125,14 +155,30 @@ export async function openWorkerPane(input) {
125
155
  paneIdSource,
126
156
  createSession,
127
157
  launch,
128
- paneReconciliation: reconciledPane,
158
+ paneReconciliation: {
159
+ ...(reconciledPane || {}),
160
+ focus_pane: focus,
161
+ focus_degraded: focus ? focus.ok !== true : false,
162
+ rename_pane: renamePane
163
+ },
164
+ directionRequested,
129
165
  directionApplied,
166
+ rightColumn: rightColumn ? { mode: 'spawn-on-first-worker', focus_pane_id: rightColumn.focusPaneId, y_order: rightColumn.yOrder } : null,
130
167
  status: blockers.length ? 'failed' : 'running',
131
168
  providerContext,
132
169
  serviceTier: input.serviceTier || providerContext.service_tier,
133
170
  blockers
134
171
  });
135
172
  await writeWorkerPaneArtifact(root, record);
173
+ if (rightColumn) {
174
+ await recordWorkerPaneInRightColumn({
175
+ root,
176
+ ...(input.projectRoot ? { projectRoot: input.projectRoot } : {}),
177
+ missionId: input.missionId,
178
+ record,
179
+ yOrder: rightColumn.yOrder
180
+ });
181
+ }
136
182
  await appendWorkerPaneEvent(root, 'zellij_worker_pane_created', input, {
137
183
  ok: record.ok,
138
184
  pane_id: record.pane_id,
@@ -172,12 +218,16 @@ export async function openWorkerPane(input) {
172
218
  }
173
219
  export async function closeWorkerPane(input) {
174
220
  const root = path.resolve(input.root);
175
- const close = process.env.SKS_ZELLIJ_CLOSE_WORKER_PANE === '1' && input.paneRecord.pane_id
176
- ? await runZellij(['--session', input.paneRecord.session_name, 'action', 'close-pane', '--pane-id', input.paneRecord.pane_id], {
177
- cwd: input.cwd || packageRoot(),
178
- timeoutMs: 5000,
179
- optional: true
180
- })
221
+ const success = (input.status || 'closed') === 'closed' && !(input.blockers || []).length;
222
+ const closeSuccess = process.env.SKS_ZELLIJ_CLOSE_WORKER_PANE !== '0';
223
+ const closeFailed = process.env.SKS_ZELLIJ_CLOSE_FAILED_PANE === '1' || process.env.SKS_ZELLIJ_KEEP_FAILED_PANE === '0';
224
+ const paneId = input.paneRecord.pane_id;
225
+ const shouldClose = Boolean(paneId) && (success ? closeSuccess : closeFailed);
226
+ const close = shouldClose
227
+ ? await closeZellijPaneById(input.paneRecord.session_name, paneId || '', input.cwd || packageRoot())
228
+ : null;
229
+ const rename = !shouldClose && paneId
230
+ ? await renameZellijPaneById(input.paneRecord.session_name, paneId, `${input.paneRecord.pane_title} · ${success ? 'drained' : 'failed'}`, input.cwd || packageRoot())
181
231
  : null;
182
232
  const next = {
183
233
  ...input.paneRecord,
@@ -191,9 +241,25 @@ export async function closeWorkerPane(input) {
191
241
  stream_event_count: Number(input.streamEventCount || input.paneRecord.stream_event_count || 0),
192
242
  structured_output_valid: input.structuredOutputValid === true || input.paneRecord.structured_output_valid === true,
193
243
  worker_result_path: input.workerResultPath || input.paneRecord.worker_result_path,
194
- blockers: [...input.paneRecord.blockers, ...(input.blockers || []), ...(close && !close.ok ? close.blockers.map((blocker) => `zellij_worker_close_${blocker}`) : [])]
244
+ blockers: [
245
+ ...input.paneRecord.blockers,
246
+ ...(input.blockers || []),
247
+ ...(close && !close.ok ? close.blockers.map((blocker) => `zellij_worker_close_${blocker}`) : []),
248
+ ...(rename && !rename.ok ? rename.blockers.map((blocker) => `zellij_worker_rename_${blocker}`) : [])
249
+ ]
195
250
  };
196
251
  await writeWorkerPaneArtifact(root, next);
252
+ if (next.right_column?.mode === 'spawn-on-first-worker') {
253
+ await closeWorkerInRightColumn({
254
+ root,
255
+ ...(input.projectRoot ? { projectRoot: input.projectRoot } : {}),
256
+ missionId: next.mission_id,
257
+ slotId: next.slot_id,
258
+ generationIndex: next.generation_index,
259
+ paneId: next.pane_id,
260
+ status: next.status === 'failed' ? 'failed' : close?.ok ? 'closed' : 'draining'
261
+ });
262
+ }
197
263
  await appendWorkerPaneEvent(root, 'pane_closed', {
198
264
  root,
199
265
  missionId: next.mission_id,
@@ -262,6 +328,11 @@ async function reconcileZellijWorkerPaneId(sessionName, paneName, resultPath, cw
262
328
  timeoutMs: 5000,
263
329
  optional: true
264
330
  });
331
+ const screen = await runZellij(['--session', sessionName, 'action', 'dump-screen'], {
332
+ cwd,
333
+ timeoutMs: 5000,
334
+ optional: true
335
+ });
265
336
  const rows = parsePaneRows(listed.stdout_tail);
266
337
  const pane = rows.find((row) => {
267
338
  const title = String(row.title || row.name || row.pane_name || '');
@@ -280,6 +351,7 @@ async function reconcileZellijWorkerPaneId(sessionName, paneName, resultPath, cw
280
351
  pane_id: paneId == null ? null : String(paneId),
281
352
  listed_count: rows.length,
282
353
  command: listed,
354
+ dump_screen: screen,
283
355
  blockers: paneId == null ? ['zellij_worker_pane_id_not_reconciled'] : []
284
356
  };
285
357
  }
@@ -330,4 +402,97 @@ function parsePaneRows(text) {
330
402
  return [];
331
403
  }
332
404
  }
405
+ async function renameZellijPaneById(sessionName, paneId, paneName, cwd) {
406
+ const numeric = Number.parseInt(paneId.replace(/^terminal_/, ''), 10);
407
+ const numericCandidates = Number.isFinite(numeric)
408
+ ? [numeric, numeric + 1, numeric - 1].filter((value) => value >= 0).map(String)
409
+ : [];
410
+ const candidates = [...new Set([paneId, paneId.replace(/^terminal_/, ''), ...numericCandidates].filter(Boolean))];
411
+ let last = null;
412
+ for (let attempt = 0; attempt < 3; attempt += 1) {
413
+ if (attempt > 0)
414
+ await sleep(200 * attempt);
415
+ for (const candidate of candidates) {
416
+ last = await runZellij(['--session', sessionName, 'action', 'rename-pane', '--pane-id', candidate, paneName], {
417
+ cwd,
418
+ timeoutMs: 5000,
419
+ optional: true
420
+ });
421
+ if (last.ok)
422
+ return last;
423
+ const focus = await runZellij(['--session', sessionName, 'action', 'focus-pane-id', candidate], {
424
+ cwd,
425
+ timeoutMs: 5000,
426
+ optional: true
427
+ });
428
+ if (focus.ok) {
429
+ last = await runZellij(['--session', sessionName, 'action', 'rename-pane', paneName], {
430
+ cwd,
431
+ timeoutMs: 5000,
432
+ optional: true
433
+ });
434
+ if (last.ok)
435
+ return last;
436
+ }
437
+ }
438
+ }
439
+ return last;
440
+ }
441
+ async function focusZellijPaneById(sessionName, paneId, cwd) {
442
+ const candidates = zellijPaneIdCandidates(paneId);
443
+ let last = null;
444
+ for (const candidate of candidates) {
445
+ const focus = await runZellij(['--session', sessionName, 'action', 'focus-pane-id', candidate], {
446
+ cwd,
447
+ timeoutMs: 5000,
448
+ optional: true
449
+ });
450
+ last = focus;
451
+ if (focus.ok)
452
+ return focus;
453
+ }
454
+ return last;
455
+ }
456
+ async function closeZellijPaneById(sessionName, paneId, cwd) {
457
+ const candidates = zellijPaneIdCandidates(paneId);
458
+ let last = null;
459
+ for (const candidate of candidates) {
460
+ const close = await runZellij(['--session', sessionName, 'action', 'close-pane', '--pane-id', candidate], {
461
+ cwd,
462
+ timeoutMs: 5000,
463
+ optional: true
464
+ });
465
+ last = close;
466
+ if (close.ok)
467
+ return close;
468
+ }
469
+ return last;
470
+ }
471
+ function zellijPaneIdCandidates(paneId) {
472
+ const raw = String(paneId || '').trim();
473
+ const numeric = raw.replace(/^terminal_/, '');
474
+ const parsed = Number.parseInt(numeric, 10);
475
+ return [...new Set([
476
+ raw,
477
+ numeric,
478
+ Number.isFinite(parsed) ? String(parsed) : '',
479
+ Number.isFinite(parsed) ? `terminal_${parsed}` : ''
480
+ ].filter(Boolean))];
481
+ }
482
+ function sleep(ms) {
483
+ return new Promise((resolve) => setTimeout(resolve, ms));
484
+ }
485
+ function normalizeExistingZellijSession(sessionName, result) {
486
+ if (result.ok)
487
+ return result;
488
+ if (/Session already exists/i.test(result.stderr_tail || '')) {
489
+ return {
490
+ ...result,
491
+ ok: true,
492
+ blockers: [],
493
+ warnings: [...result.warnings, `zellij_session_already_exists:${sessionName}`]
494
+ };
495
+ }
496
+ return result;
497
+ }
333
498
  //# sourceMappingURL=zellij-worker-pane-manager.js.map
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  // @ts-nocheck
3
- import { assertGate, emitGate, packageScripts, readText } from './lib/codex-sdk-gate-lib.js';
3
+ import { assertGate, emitGate, packageScripts, readText, releaseGateIds } from './lib/codex-sdk-gate-lib.js';
4
4
  const scripts = packageScripts();
5
- const releaseCheck = String(scripts['release:check'] || '');
6
5
  const releaseRealCheck = String(scripts['release:real-check'] || '');
7
- assertGate(releaseCheck.includes('codex-sdk:capability'), 'release:check must include Codex SDK capability gate');
8
- assertGate(releaseCheck.includes('codex-sdk:all-pipelines'), 'release:check must include Codex SDK all-pipelines gate');
6
+ const releaseGates = releaseGateIds();
7
+ assertGate(releaseGates.has('codex-sdk:capability'), 'release gate DAG must include Codex SDK capability gate');
8
+ assertGate(releaseGates.has('codex-sdk:all-pipelines'), 'release gate DAG must include Codex SDK all-pipelines gate');
9
9
  assertGate(releaseRealCheck.includes('codex-sdk:real-smoke'), 'release:real-check must include Codex SDK real smoke');
10
10
  assertGate(readText('src/core/agents/agent-orchestrator.ts').includes('legacy_codex_exec_runtime_removed'), 'orchestrator must block legacy codex-exec requests');
11
- emitGate('codex-sdk:release-review-pipeline', { release_check_contains_sdk: true });
11
+ emitGate('codex-sdk:release-review-pipeline', { release_gate_dag_contains_sdk: true });
12
12
  //# sourceMappingURL=codex-sdk-release-review-pipeline-check.js.map
@@ -25,19 +25,40 @@ const run = spawnSync(process.execPath, [
25
25
  SKS_DISABLE_UPDATE_CHECK: '1'
26
26
  },
27
27
  encoding: 'utf8',
28
- timeout: 60000
28
+ timeout: 180000
29
29
  });
30
30
  const parsed = parseLastJson(run.stdout || '{}');
31
31
  const ok = run.status !== 0
32
32
  && parsed.ready?.ready === false
33
33
  && parsed.ready?.blockers?.includes('codex_cli_config_eperm')
34
34
  && parsed.ready?.next_actions?.length > 0;
35
- console.log(JSON.stringify({ schema: 'sks.doctor-fix-proves-codex-read-check.v1', ok, status: run.status, parsed }, null, 2));
35
+ console.log(JSON.stringify({
36
+ schema: 'sks.doctor-fix-proves-codex-read-check.v1',
37
+ ok,
38
+ status: run.status,
39
+ signal: run.signal,
40
+ error: run.error ? String(run.error.message || run.error) : null,
41
+ parsed,
42
+ stdout_tail: String(run.stdout || '').slice(-1000),
43
+ stderr_tail: String(run.stderr || '').slice(-1000)
44
+ }, null, 2));
36
45
  if (!ok)
37
46
  process.exitCode = 1;
38
47
  function parseLastJson(text) {
39
- const index = String(text).lastIndexOf('\n{');
40
- const jsonText = index >= 0 ? String(text).slice(index + 1) : String(text).slice(String(text).indexOf('{'));
41
- return JSON.parse(jsonText || '{}');
48
+ const source = String(text || '').trim();
49
+ if (!source)
50
+ return {};
51
+ const starts = [];
52
+ for (let index = source.indexOf('{'); index >= 0; index = source.indexOf('{', index + 1))
53
+ starts.push(index);
54
+ for (let i = starts.length - 1; i >= 0; i -= 1) {
55
+ try {
56
+ return JSON.parse(source.slice(starts[i]));
57
+ }
58
+ catch {
59
+ // Continue searching for the outer JSON object; pretty JSON may contain nested objects.
60
+ }
61
+ }
62
+ return {};
42
63
  }
43
64
  //# sourceMappingURL=doctor-fix-proves-codex-read-check.js.map
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, emitGate, importDist } from './sks-1-18-gate-lib.js';
4
+ const envelopeMod = await importDist('core/git/git-worktree-patch-envelope.js');
5
+ const schemaMod = await importDist('core/agents/agent-patch-schema.js');
6
+ const envelope = envelopeMod.buildGitWorktreePatchEnvelope({
7
+ diff: { schema: 'sks.git-worktree-diff.v1', mission_id: 'M-env', worker_id: 'worker-1', main_repo_root: '.', worktree_path: '.', branch: null, base_head: null, worktree_head: null, changed_files: ['a.txt', 'b.txt'], diff_bytes: 12, diff: 'diff --git a/a.txt b/a.txt\n', clean: false },
8
+ agentId: 'agent-1',
9
+ sessionId: 'session-1',
10
+ slotId: 'slot-001',
11
+ generationIndex: 1
12
+ });
13
+ const validation = schemaMod.validateAgentPatchEnvelope(schemaMod.normalizeAgentPatchEnvelope(envelope));
14
+ assertGate(envelope.operations.length === 1 && envelope.operations[0].op === 'git_apply_patch', 'git worktree envelope must use one git_apply_patch operation', envelope);
15
+ assertGate(validation.ok === true, 'git_apply_patch envelope must validate', validation);
16
+ emitGate('git:worktree-diff-envelope', { operations: envelope.operations.length, op: envelope.operations[0].op });
17
+ //# sourceMappingURL=git-worktree-diff-envelope-check.js.map
@@ -0,0 +1,17 @@
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, importDist } from './sks-1-18-gate-lib.js';
7
+ import { makeGitFixture } from './lib/git-worktree-fixture.js';
8
+ const managerMod = await importDist('core/git/git-worktree-manager.js');
9
+ const cleanupMod = await importDist('core/git/git-worktree-cleanup.js');
10
+ const repo = makeGitFixture('dirty-lock');
11
+ process.env.SKS_WORKTREE_ROOT = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-wt-lock-'));
12
+ const allocation = await managerMod.allocateWorkerWorktree({ repoRoot: repo, missionId: 'M-lock', workerId: 'worker-1', slotId: 'slot-001' });
13
+ fs.writeFileSync(path.join(allocation.worktree_path, 'a.txt'), 'dirty\n');
14
+ const cleanup = await cleanupMod.cleanupGitWorktree({ repoRoot: repo, worktreePath: allocation.worktree_path, branch: allocation.branch });
15
+ assertGate(cleanup.action === 'retained_dirty' && cleanup.git_locked === true, 'dirty retained worktree must be git locked', cleanup);
16
+ emitGate('git:worktree-dirty-lock', { git_locked: cleanup.git_locked, unlock_command: cleanup.unlock_command });
17
+ //# sourceMappingURL=git-worktree-dirty-lock-check.js.map
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, importDist } from './sks-1-18-gate-lib.js';
6
+ import { makeGitFixture } from './lib/git-worktree-fixture.js';
7
+ const detectionMod = await importDist('core/git/git-repo-detection.js');
8
+ const repo = makeGitFixture('dirty-main-detection');
9
+ fs.writeFileSync(path.join(repo, 'dirty.txt'), 'dirty\n');
10
+ const detection = await detectionMod.detectGitRepo(repo);
11
+ assertGate(detection.main_worktree_dirty === true, 'dirty main worktree must be detected', detection);
12
+ assertGate(String(detection.status_porcelain).includes('dirty.txt'), 'status_porcelain must include dirty file', detection);
13
+ emitGate('git:worktree-dirty-main-detection', { dirty: detection.main_worktree_dirty });
14
+ //# sourceMappingURL=git-worktree-dirty-main-detection-check.js.map
@@ -0,0 +1,22 @@
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, importDist } from './sks-1-18-gate-lib.js';
7
+ import { makeGitFixture } from './lib/git-worktree-fixture.js';
8
+ const managerMod = await importDist('core/git/git-worktree-manager.js');
9
+ const diffMod = await importDist('core/git/git-worktree-diff.js');
10
+ const mergeMod = await importDist('core/git/git-worktree-merge-queue.js');
11
+ const repo = makeGitFixture('integration-primary');
12
+ process.env.SKS_WORKTREE_ROOT = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-wt-integration-'));
13
+ const allocation = await managerMod.allocateWorkerWorktree({ repoRoot: repo, missionId: 'M-integrate', workerId: 'worker-1', slotId: 'slot-001' });
14
+ fs.writeFileSync(path.join(allocation.worktree_path, 'a.txt'), 'alpha\nintegrated\n');
15
+ const diff = await diffMod.exportGitWorktreeDiff({ mainRepoRoot: repo, worktreePath: allocation.worktree_path, missionId: 'M-integrate', workerId: 'worker-1' });
16
+ const integrationPath = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-integration-'));
17
+ fs.rmSync(integrationPath, { recursive: true, force: true });
18
+ const integration = await managerMod.allocateWorkerWorktree({ repoRoot: repo, missionId: 'M-integrate', workerId: 'integration', slotId: 'integration' });
19
+ const report = await mergeMod.applyGitWorktreeMergeQueue({ integrationWorktreePath: integration.worktree_path, diffs: [diff] });
20
+ assertGate(report.ok === true && report.applied_count === 1, 'git-worktree-diff must apply through merge queue', report);
21
+ emitGate('git:worktree-integration-primary', { applied_count: report.applied_count });
22
+ //# sourceMappingURL=git-worktree-integration-primary-check.js.map
@@ -0,0 +1,18 @@
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, importDist } from './sks-1-18-gate-lib.js';
7
+ import { makeGitFixture } from './lib/git-worktree-fixture.js';
8
+ const managerMod = await importDist('core/git/git-worktree-manager.js');
9
+ const repo = makeGitFixture('worktree-manifest-append');
10
+ process.env.SKS_WORKTREE_ROOT = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-wt-manifest-'));
11
+ const allocations = [];
12
+ for (let index = 0; index < 4; index += 1) {
13
+ allocations.push(await managerMod.allocateWorkerWorktree({ repoRoot: repo, missionId: 'M-manifest', workerId: `worker-${index}`, slotId: `slot-${index}` }));
14
+ }
15
+ const manifest = JSON.parse(fs.readFileSync(allocations[0].manifest_path, 'utf8'));
16
+ assertGate(manifest.allocations.length >= allocations.length, 'manifest append must preserve allocations', manifest);
17
+ emitGate('git:worktree-manifest-append', { allocations: manifest.allocations.length });
18
+ //# sourceMappingURL=git-worktree-manifest-append-check.js.map
@@ -0,0 +1,18 @@
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, importDist } from './sks-1-18-gate-lib.js';
7
+ import { makeGitFixture } from './lib/git-worktree-fixture.js';
8
+ const managerMod = await importDist('core/git/git-worktree-manager.js');
9
+ const diffMod = await importDist('core/git/git-worktree-diff.js');
10
+ const repo = makeGitFixture('untracked-diff');
11
+ process.env.SKS_WORKTREE_ROOT = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-wt-untracked-'));
12
+ const allocation = await managerMod.allocateWorkerWorktree({ repoRoot: repo, missionId: 'M-untracked', workerId: 'worker-1', slotId: 'slot-001' });
13
+ fs.writeFileSync(path.join(allocation.worktree_path, 'new-file.txt'), 'new content\n');
14
+ const diff = await diffMod.exportGitWorktreeDiff({ mainRepoRoot: repo, worktreePath: allocation.worktree_path, missionId: 'M-untracked', workerId: 'worker-1' });
15
+ assertGate(diff.changed_files.includes('new-file.txt'), 'changed files must include untracked file', diff);
16
+ assertGate(diff.diff.includes('new file mode') && diff.diff.includes('+new content'), 'git diff must include untracked file content', { diff: diff.diff });
17
+ emitGate('git:worktree-untracked-diff', { changed_files: diff.changed_files });
18
+ //# sourceMappingURL=git-worktree-untracked-diff-check.js.map
@@ -59,6 +59,10 @@ export async function runFakeCodexSdkTaskFixture(label = 'fixture', extra = {})
59
59
  export function packageScripts() {
60
60
  return readJson('package.json').scripts || {};
61
61
  }
62
+ export function releaseGateIds() {
63
+ const manifest = readJson('release-gates.v2.json');
64
+ return new Set((manifest.gates || []).map((gate) => gate.id));
65
+ }
62
66
  export function assertSourceIncludes(file, tokens) {
63
67
  const text = readText(file);
64
68
  for (const token of tokens)
@@ -17,10 +17,10 @@ const checks = {
17
17
  zellij_session_before_swarm: launchIndex >= 0 && swarmIndex >= 0 && launchIndex < swarmIndex,
18
18
  main_only_session: mad.includes('slotCount: 0'),
19
19
  zellij_default_backend: /return 'zellij'/.test(mad) && mad.includes("list.includes('--json')") && mad.includes("list.includes('--no-attach')"),
20
- worker_command_real_zellij: mad.includes("command.push('--real')") && mad.includes("command.push('--zellij-session-name'") && mad.includes("command.push('--zellij-pane-worker')"),
20
+ worker_command_real_zellij: mad.includes("command.push('--real')") && mad.includes("command.push('--zellij-session-name'") && mad.includes("command.push('--zellij-pane-worker')") && mad.includes("command.push('--worker-placement'"),
21
21
  parser_accepts_worker_flags: parser.includes('--zellij-session-name') && parser.includes('--zellij-pane-worker') && parser.includes('--no-zellij-pane-worker'),
22
22
  native_worker_pane_path: swarm.includes("this.input.backend === 'zellij'") && swarm.includes('ctx.opts.zellijPaneWorker !== false') && swarm.includes('openWorkerPane({'),
23
- right_pane_requested: manager.includes("'--direction', 'right'")
23
+ right_pane_requested: manager.includes("'--direction', directionRequested") && manager.includes("'--near-current-pane'")
24
24
  };
25
25
  const ok = Object.values(checks).every(Boolean);
26
26
  emit({
@@ -10,6 +10,7 @@ const normal = governorMod.decideNarutoConcurrency({
10
10
  zellijVisiblePaneCap: 12,
11
11
  hardware: {
12
12
  cores: 32,
13
+ loadAverage: [0, 0, 0],
13
14
  freeMemoryBytes: 48 * 1024 * 1024 * 1024,
14
15
  totalMemoryBytes: 64 * 1024 * 1024 * 1024,
15
16
  fileDescriptorLimit: 4096,
@@ -37,7 +38,7 @@ const pressure = governorMod.decideNarutoConcurrency({
37
38
  diskIoPressure: 0.9
38
39
  }
39
40
  });
40
- assertGate(normal.safe_active_workers <= 32, 'requested_clones=200 fixture must cap active workers safely', { normal });
41
+ assertGate(normal.safe_active_workers >= 32 && normal.safe_active_workers <= 100, 'requested_clones=200 fixture must cap active workers safely while allowing aggressive process-pool fanout', { normal });
41
42
  assertGate(normal.safe_zellij_visible_panes === 12 && normal.headless_workers === normal.safe_active_workers - 12, 'zellij visible panes must stay within UI cap', { normal });
42
43
  assertGate(normal.local_llm_parallel <= 4, 'local LLM active requests must respect max_parallel_requests=4', { normal });
43
44
  assertGate(pressure.safe_active_workers < normal.safe_active_workers, 'memory/load pressure fixture must decrease active workers', { normal: normal.safe_active_workers, pressure: pressure.safe_active_workers });
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
4
+ import { buildNarutoWorkGraph } from '../core/naruto/naruto-work-graph.js';
5
+ import { decideNarutoConcurrency } from '../core/naruto/naruto-concurrency-governor.js';
6
+ const graph = buildNarutoWorkGraph({ requestedClones: 100, writeCapable: true, maxActiveWorkers: 32 });
7
+ const governor = decideNarutoConcurrency({
8
+ requestedClones: 100,
9
+ totalWorkItems: graph.total_work_items,
10
+ pendingWorkQueueSize: graph.total_work_items,
11
+ backend: 'codex-sdk',
12
+ hardware: { cores: 16, loadAverage: [1, 1, 1], freeMemoryBytes: 64 * 1024 * 1024 * 1024, totalMemoryBytes: 128 * 1024 * 1024 * 1024, fileDescriptorLimit: 8192, processCount: 100, terminalRows: 48, remoteApiRateLimitBudget: 32, localLlmMaxParallelRequests: 8 }
13
+ });
14
+ const report = {
15
+ schema: 'sks.naruto-extreme-parallelism-check.v1',
16
+ ok: graph.total_work_items >= 200 && governor.safe_active_workers >= 16 && governor.safe_zellij_visible_panes <= governor.safe_active_workers && graph.mixed_work_kinds.length >= 6,
17
+ graph: { total_work_items: graph.total_work_items, mixed_work_kinds: graph.mixed_work_kinds, write_allowed_count: graph.write_allowed_count },
18
+ governor
19
+ };
20
+ assertGate(report.ok, 'Naruto extreme parallelism must fan out >=2x clones and keep a high safe active pool', report);
21
+ emitGate('naruto:extreme-parallelism', report);
22
+ //# sourceMappingURL=naruto-extreme-parallelism-check.js.map
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
4
+ import { buildNarutoWorkGraph } from '../core/naruto/naruto-work-graph.js';
5
+ import { decideNarutoConcurrency } from '../core/naruto/naruto-concurrency-governor.js';
6
+ import { runNarutoRealActivePool } from '../core/naruto/naruto-active-pool.js';
7
+ const graph = buildNarutoWorkGraph({ requestedClones: 12, totalWorkItems: 24, writeCapable: true, maxActiveWorkers: 6 });
8
+ const governor = decideNarutoConcurrency({
9
+ requestedClones: 12,
10
+ totalWorkItems: graph.total_work_items,
11
+ pendingWorkQueueSize: graph.total_work_items,
12
+ backend: 'codex-sdk',
13
+ hardware: { cpuCoreCount: 8, freeMemoryBytes: 32 * 1024 * 1024 * 1024, totalMemoryBytes: 64 * 1024 * 1024 * 1024, fileDescriptorLimit: 4096, processCount: 100, terminalRows: 40, remoteApiRateLimitBudget: 8 }
14
+ });
15
+ const target = { ...governor, safe_active_workers: Math.min(6, governor.safe_active_workers), safe_zellij_visible_panes: 3 };
16
+ let spawned = 0;
17
+ let collected = 0;
18
+ let dashboardEvents = 0;
19
+ const report = await runNarutoRealActivePool({
20
+ graph,
21
+ governor: target,
22
+ spawnWorker: async (item, placement) => {
23
+ spawned += 1;
24
+ return { id: item.id, item, placement, started_at: Date.now() };
25
+ },
26
+ collectWorker: async (handle) => {
27
+ collected += 1;
28
+ return { id: handle.id, ok: true, item: handle.item, placement: handle.placement, completed_at: Date.now() };
29
+ },
30
+ enqueueVerification: async () => undefined,
31
+ updateDashboard: async () => {
32
+ dashboardEvents += 1;
33
+ }
34
+ });
35
+ const ok = report.ok && spawned === graph.total_work_items && collected === graph.total_work_items && report.max_observed_active_workers >= target.safe_active_workers && dashboardEvents > graph.total_work_items;
36
+ assertGate(ok, 'Naruto real active pool must run spawn/collect lifecycle and refill to cap', { report, spawned, collected, dashboardEvents, target });
37
+ emitGate('naruto:real-active-pool', { spawned, collected, max_observed_active_workers: report.max_observed_active_workers, refill_latency_ms_p95: report.refill_latency_ms_p95 });
38
+ //# sourceMappingURL=naruto-real-active-pool-check.js.map
@@ -11,7 +11,7 @@ const graph = workGraph.buildNarutoWorkGraph({
11
11
  });
12
12
  const validation = workGraph.validateNarutoWorkGraph(graph);
13
13
  assertGate(graph.ok === true && validation.ok === true, 'Naruto work graph must validate', { graph_blockers: graph.blockers, validation });
14
- assertGate(graph.total_work_items >= graph.requested_clones, 'work graph must create at least requested clone count', { total: graph.total_work_items, requested: graph.requested_clones });
14
+ assertGate(graph.total_work_items >= graph.requested_clones * 2, 'write-capable work graph must create at least 2x requested clone count', { total: graph.total_work_items, requested: graph.requested_clones });
15
15
  assertGate(graph.mixed_work_kinds.length > 4, 'work graph must contain mixed work kinds, not only verification', { kinds: graph.mixed_work_kinds });
16
16
  assertGate(graph.write_allowed_count > 0, 'write-capable Naruto graph must include write_allowed work items', { write_allowed_count: graph.write_allowed_count });
17
17
  assertGate(graph.active_waves.every((wave) => wave.conflict_count === 0), 'active waves must not overlap write leases', { waves: graph.active_waves });
@@ -0,0 +1,29 @@
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, importDist } from './sks-1-18-gate-lib.js';
7
+ import { makeGitFixture, run } from './lib/git-worktree-fixture.js';
8
+ const managerMod = await importDist('core/git/git-worktree-manager.js');
9
+ const diffMod = await importDist('core/git/git-worktree-diff.js');
10
+ const mergeMod = await importDist('core/git/git-worktree-merge-queue.js');
11
+ const repo = makeGitFixture('naruto-worktree-blackbox');
12
+ process.env.SKS_WORKTREE_ROOT = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-naruto-blackbox-'));
13
+ const allocations = [];
14
+ for (const file of ['a.txt', 'b.txt']) {
15
+ const allocation = await managerMod.allocateWorkerWorktree({ repoRoot: repo, missionId: 'M-naruto-blackbox', workerId: file.replace('.txt', ''), slotId: file.replace('.txt', '') });
16
+ fs.writeFileSync(path.join(allocation.worktree_path, file), `${file}\nworker-change\n`);
17
+ allocations.push(allocation);
18
+ }
19
+ assertGate(run('git', ['status', '--porcelain=v1'], repo).trim() === '', 'main worktree must remain unchanged before integration');
20
+ const diffs = [];
21
+ for (const allocation of allocations) {
22
+ diffs.push(await diffMod.exportGitWorktreeDiff({ mainRepoRoot: repo, worktreePath: allocation.worktree_path, missionId: 'M-naruto-blackbox', workerId: allocation.worker_id }));
23
+ }
24
+ const integration = await managerMod.allocateWorkerWorktree({ repoRoot: repo, missionId: 'M-naruto-blackbox', workerId: 'integration', slotId: 'integration' });
25
+ const report = await mergeMod.applyGitWorktreeMergeQueue({ integrationWorktreePath: integration.worktree_path, diffs });
26
+ assertGate(report.ok === true && report.applied_count === 2, 'integration worktree merge report must apply worker diffs', report);
27
+ assertGate(run('git', ['status', '--porcelain=v1'], repo).trim() === '', 'main worktree must remain unchanged after integration queue');
28
+ emitGate('naruto:worktree-coding:blackbox', { allocations: allocations.length, applied_count: report.applied_count });
29
+ //# sourceMappingURL=naruto-worktree-coding-blackbox.js.map