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,121 @@
1
+ import fs from 'node:fs';
2
+ import { spawn } from 'node:child_process';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { ensureDir, nowIso, readJson, writeJsonAtomic } from '../fsx.js';
6
+ import { allocateWorkerWorktree } from '../git/git-worktree-manager.js';
7
+ import { cleanupGitWorktree } from '../git/git-worktree-cleanup.js';
8
+ export async function spawnActualNarutoWorker(input) {
9
+ const workerDir = path.join(input.root, '.sneakoscope', 'missions', input.missionId, 'agents', 'naruto-real-workers', input.item.id);
10
+ await ensureDir(workerDir);
11
+ let worktree = null;
12
+ if (input.worktreePolicy?.mode === 'git-worktree' && input.item.write_allowed === true) {
13
+ const allocation = await allocateWorkerWorktree({
14
+ repoRoot: input.worktreePolicy.main_repo_root || input.root,
15
+ missionId: input.missionId,
16
+ workerId: input.item.id,
17
+ slotId: input.item.id.replace(/[^A-Za-z0-9_-]/g, '-'),
18
+ generationIndex: 1
19
+ }).catch((err) => ({ ok: false, blockers: [`git_worktree_allocate_exception:${err?.message || String(err)}`] }));
20
+ await writeJsonAtomic(path.join(workerDir, 'git-worktree-allocation.json'), allocation);
21
+ if (allocation.ok)
22
+ worktree = allocation;
23
+ }
24
+ const resultPath = path.join(workerDir, 'worker-result.json');
25
+ const heartbeatPath = path.join(workerDir, 'worker-heartbeat.jsonl');
26
+ const intakePath = path.join(workerDir, 'worker-intake.json');
27
+ await writeJsonAtomic(intakePath, {
28
+ schema: 'sks.naruto-actual-worker-intake.v1',
29
+ generated_at: nowIso(),
30
+ mission_id: input.missionId,
31
+ item: input.item,
32
+ placement: input.placement,
33
+ backend: input.backend,
34
+ result_path: resultPath,
35
+ heartbeat_path: heartbeatPath,
36
+ worktree_path: worktree?.worktree_path || null,
37
+ zellij_session_name: input.zellijSessionName || null,
38
+ visible_pane_cap: input.visiblePaneCap
39
+ });
40
+ const child = spawn(process.execPath, [actualWorkerEntrypoint(), intakePath], {
41
+ cwd: worktree?.worktree_path || input.root,
42
+ stdio: ['ignore', 'ignore', 'ignore']
43
+ });
44
+ const exit = waitForExit(child, 30000);
45
+ return {
46
+ id: input.item.id,
47
+ item: input.item,
48
+ placement: input.placement,
49
+ started_at: Date.now(),
50
+ pid: child.pid || null,
51
+ child,
52
+ worker_artifact_dir: workerDir,
53
+ result_path: resultPath,
54
+ heartbeat_path: heartbeatPath,
55
+ worktree,
56
+ exit
57
+ };
58
+ }
59
+ export async function collectActualNarutoWorker(handle) {
60
+ const exit = await handle.exit;
61
+ const result = await readJson(handle.result_path, null).catch(() => null);
62
+ const blockers = [
63
+ ...(exit.code === 0 ? [] : [`naruto_actual_worker_exit_${exit.code ?? exit.signal ?? 'unknown'}`]),
64
+ ...(result?.ok === false ? result.blockers || ['naruto_actual_worker_result_not_ok'] : []),
65
+ ...(result ? [] : ['naruto_actual_worker_result_missing'])
66
+ ];
67
+ if (handle.worktree?.worktree_path) {
68
+ const cleanup = await cleanupGitWorktree({
69
+ repoRoot: handle.worktree.main_repo_root || handle.worktree.repo_root || handle.worktree.repoRoot || '',
70
+ worktreePath: handle.worktree.worktree_path,
71
+ branch: handle.worktree.branch,
72
+ deleteBranch: true
73
+ }).catch((err) => ({ ok: false, blockers: [`git_worktree_cleanup_exception:${err?.message || String(err)}`] }));
74
+ await writeJsonAtomic(path.join(handle.worker_artifact_dir, 'git-worktree-cleanup.json'), cleanup);
75
+ blockers.push(...(cleanup.blockers || []));
76
+ }
77
+ return {
78
+ id: handle.id,
79
+ ok: blockers.length === 0,
80
+ item: handle.item,
81
+ placement: handle.placement,
82
+ completed_at: Date.now(),
83
+ pid: handle.pid,
84
+ worker_artifact_dir: handle.worker_artifact_dir,
85
+ blockers
86
+ };
87
+ }
88
+ function actualWorkerEntrypoint() {
89
+ return fileURLToPath(new URL('./naruto-real-worker-child.js', import.meta.url));
90
+ }
91
+ function waitForExit(child, timeoutMs) {
92
+ return new Promise((resolve) => {
93
+ let settled = false;
94
+ let killTimer = null;
95
+ const finish = (code, signal) => {
96
+ if (settled)
97
+ return;
98
+ settled = true;
99
+ clearTimeout(timer);
100
+ if (killTimer)
101
+ clearTimeout(killTimer);
102
+ resolve({ code, signal });
103
+ };
104
+ const timer = setTimeout(() => {
105
+ if (!child.killed)
106
+ child.kill();
107
+ killTimer = setTimeout(() => {
108
+ if (!settled)
109
+ child.kill('SIGKILL');
110
+ finish(null, 'SIGKILL');
111
+ }, 5000);
112
+ }, Math.max(1000, timeoutMs));
113
+ child.on('close', (code, signal) => {
114
+ finish(code, signal);
115
+ });
116
+ child.on('error', () => {
117
+ finish(1, null);
118
+ });
119
+ });
120
+ }
121
+ //# sourceMappingURL=naruto-real-worker-runtime.js.map
@@ -1,2 +1,2 @@
1
- export const PACKAGE_VERSION = '2.0.9';
1
+ export const PACKAGE_VERSION = '2.0.10';
2
2
  //# sourceMappingURL=version.js.map
@@ -1,13 +1,20 @@
1
1
  import path from 'node:path';
2
2
  import { appendJsonl, ensureDir, nowIso, readJson, writeJsonAtomic } from '../fsx.js';
3
3
  import { openZellijDashboardPane } from './zellij-dashboard-pane.js';
4
+ import { zellijUiModeCreatesDashboard } from './zellij-ui-mode.js';
4
5
  export const ZELLIJ_RIGHT_COLUMN_STATE_SCHEMA = 'sks.zellij-right-column-state.v1';
5
6
  export async function ensureRightColumn(input) {
6
7
  const paths = resolveRightColumnPaths(input.root, input.missionId, input.projectRoot);
7
8
  await ensureDir(paths.missionDir);
9
+ const uiMode = input.uiMode || 'compact-slots';
10
+ const createDashboard = input.createDashboard ?? zellijUiModeCreatesDashboard(uiMode);
8
11
  const existing = await readRightColumnState(input.root, input.missionId, input.projectRoot);
9
- if (existing?.status === 'active' && existing.dashboard_pane_id) {
10
- return writeRightColumnState(paths.statePath, { ...existing, updated_at: nowIso() });
12
+ if (existing?.status === 'active') {
13
+ return writeRightColumnState(paths.statePath, {
14
+ ...existing,
15
+ updated_at: nowIso(),
16
+ ui_mode: existing.ui_mode || uiMode
17
+ });
11
18
  }
12
19
  const creating = await writeRightColumnState(paths.statePath, {
13
20
  schema: ZELLIJ_RIGHT_COLUMN_STATE_SCHEMA,
@@ -18,11 +25,29 @@ export async function ensureRightColumn(input) {
18
25
  status: 'creating',
19
26
  dashboard_pane_id: null,
20
27
  right_anchor_pane_id: null,
28
+ ui_mode: uiMode,
21
29
  visible_worker_panes: [],
22
30
  headless_workers: [],
23
31
  blockers: []
24
32
  });
25
33
  await appendRightColumnEvent(paths.eventsPath, 'right_column_creating', creating, {});
34
+ if (!createDashboard) {
35
+ const active = await writeRightColumnState(paths.statePath, {
36
+ ...creating,
37
+ updated_at: nowIso(),
38
+ status: 'active',
39
+ dashboard_pane_id: null,
40
+ right_anchor_pane_id: null,
41
+ ui_mode: uiMode,
42
+ blockers: []
43
+ });
44
+ await appendRightColumnEvent(paths.eventsPath, 'right_column_created', active, {
45
+ ok: true,
46
+ dashboard_created: false,
47
+ ui_mode: uiMode
48
+ });
49
+ return active;
50
+ }
26
51
  const dashboard = await openZellijDashboardPane({
27
52
  root: paths.projectRoot,
28
53
  missionId: input.missionId,
@@ -45,6 +70,7 @@ export async function ensureRightColumn(input) {
45
70
  status: blockers.length ? 'creating' : 'active',
46
71
  dashboard_pane_id: dashboard.pane_id ? String(dashboard.pane_id) : null,
47
72
  right_anchor_pane_id: dashboard.pane_id ? String(dashboard.pane_id) : null,
73
+ ui_mode: uiMode,
48
74
  blockers
49
75
  });
50
76
  await appendRightColumnEvent(paths.eventsPath, 'right_column_created', active, { ok: active.status === 'active' });
@@ -52,6 +78,9 @@ export async function ensureRightColumn(input) {
52
78
  return active;
53
79
  }
54
80
  export async function prepareWorkerInRightColumn(input) {
81
+ return withRightColumnLock(input.root, input.missionId, async () => prepareWorkerInRightColumnUnlocked(input));
82
+ }
83
+ async function prepareWorkerInRightColumnUnlocked(input) {
55
84
  const paths = resolveRightColumnPaths(input.root, input.missionId, input.projectRoot);
56
85
  const state = await ensureRightColumn({
57
86
  root: input.root,
@@ -59,12 +88,13 @@ export async function prepareWorkerInRightColumn(input) {
59
88
  missionId: input.missionId,
60
89
  sessionName: input.sessionName,
61
90
  cwd: input.cwd,
62
- dashboardSnapshot: input.dashboardSnapshot
91
+ dashboardSnapshot: input.dashboardSnapshot,
92
+ uiMode: input.uiMode || 'compact-slots'
63
93
  });
64
94
  const activeVisible = state.visible_worker_panes.filter((pane) => pane.status === 'launching' || pane.status === 'running');
65
95
  const cap = Math.max(1, Math.floor(Number(input.visiblePaneCap || 1)));
66
96
  if (activeVisible.length >= cap) {
67
- const next = await recordHeadlessWorkerInRightColumn({
97
+ const next = await recordHeadlessWorkerInRightColumnUnlocked({
68
98
  root: input.root,
69
99
  ...(input.projectRoot ? { projectRoot: input.projectRoot } : {}),
70
100
  missionId: input.missionId,
@@ -134,6 +164,9 @@ export async function recordWorkerPaneInRightColumn(input) {
134
164
  return next;
135
165
  }
136
166
  export async function recordHeadlessWorkerInRightColumn(input) {
167
+ return withRightColumnLock(input.root, input.missionId, async () => recordHeadlessWorkerInRightColumnUnlocked(input));
168
+ }
169
+ async function recordHeadlessWorkerInRightColumnUnlocked(input) {
137
170
  const paths = resolveRightColumnPaths(input.root, input.missionId, input.projectRoot);
138
171
  const state = await readRightColumnState(input.root, input.missionId, input.projectRoot) || {
139
172
  schema: ZELLIJ_RIGHT_COLUMN_STATE_SCHEMA,
@@ -144,13 +177,14 @@ export async function recordHeadlessWorkerInRightColumn(input) {
144
177
  status: 'absent',
145
178
  dashboard_pane_id: null,
146
179
  right_anchor_pane_id: null,
180
+ ui_mode: 'compact-slots',
147
181
  visible_worker_panes: [],
148
182
  headless_workers: [],
149
183
  blockers: []
150
184
  };
151
185
  const headless = [
152
186
  ...state.headless_workers.filter((row) => !(row.slot_id === input.slotId && row.generation_index === input.generationIndex)),
153
- { slot_id: input.slotId, generation_index: input.generationIndex, reason: input.reason }
187
+ { slot_id: input.slotId, generation_index: input.generationIndex, reason: input.reason, status: 'running', closed_at: null }
154
188
  ];
155
189
  const next = await writeRightColumnState(paths.statePath, { ...state, updated_at: nowIso(), headless_workers: headless });
156
190
  await appendRightColumnEvent(paths.eventsPath, 'worker_headless_overflow', next, {
@@ -169,13 +203,19 @@ export async function closeWorkerInRightColumn(input) {
169
203
  const same = pane.slot_id === input.slotId && pane.generation_index === input.generationIndex;
170
204
  return same ? { ...pane, pane_id: input.paneId || pane.pane_id, status: input.status } : pane;
171
205
  });
206
+ const headless = state.headless_workers.map((row) => {
207
+ const same = row.slot_id === input.slotId && row.generation_index === input.generationIndex;
208
+ return same ? { ...row, status: input.status === 'draining' ? 'closed' : input.status, closed_at: nowIso() } : row;
209
+ });
172
210
  const visibleStillActive = panes.filter((pane) => pane.status === 'launching' || pane.status === 'running');
211
+ const headlessStillActive = headless.filter((row) => !row.status || row.status === 'running');
173
212
  const next = await writeRightColumnState(paths.statePath, {
174
213
  ...state,
175
214
  updated_at: nowIso(),
176
- status: visibleStillActive.length || state.headless_workers.length ? 'active' : 'draining',
215
+ status: visibleStillActive.length || headlessStillActive.length ? 'active' : 'draining',
177
216
  right_anchor_pane_id: visibleStillActive[visibleStillActive.length - 1]?.pane_id || state.dashboard_pane_id,
178
- visible_worker_panes: panes
217
+ visible_worker_panes: panes,
218
+ headless_workers: headless
179
219
  });
180
220
  await appendRightColumnEvent(paths.eventsPath, 'worker_pane_drained', next, {
181
221
  slot_id: input.slotId,
@@ -242,4 +282,23 @@ function inferProjectRoot(root, missionId) {
242
282
  }
243
283
  return root;
244
284
  }
285
+ const rightColumnLocks = new Map();
286
+ async function withRightColumnLock(root, missionId, fn) {
287
+ const key = `${path.resolve(root)}:${missionId}`;
288
+ const previous = rightColumnLocks.get(key) || Promise.resolve();
289
+ let release;
290
+ const current = new Promise((resolve) => {
291
+ release = resolve;
292
+ });
293
+ rightColumnLocks.set(key, previous.then(() => current, () => current));
294
+ await previous.catch(() => undefined);
295
+ try {
296
+ return await fn();
297
+ }
298
+ finally {
299
+ release();
300
+ if (rightColumnLocks.get(key) === current)
301
+ rightColumnLocks.delete(key);
302
+ }
303
+ }
245
304
  //# sourceMappingURL=zellij-right-column-manager.js.map
@@ -0,0 +1,82 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ export function renderZellijSlotPane(input) {
4
+ const mode = input.mode || 'compact-slots';
5
+ const maxLines = mode === 'compact-slots' ? 5 : mode === 'dashboard-plus-slots' ? 8 : 20;
6
+ const task = trimInline(input.currentFile || input.currentTask || '-', 56);
7
+ const heartbeat = input.heartbeatAgeMs == null
8
+ ? 'unknown'
9
+ : input.heartbeatAgeMs < 1000
10
+ ? 'now'
11
+ : `${Math.max(1, Math.round(input.heartbeatAgeMs / 1000))}s ago`;
12
+ const rows = [
13
+ `${input.slotId} gen-${Math.max(1, Math.floor(Number(input.generationIndex) || 1))}`,
14
+ `${trimInline(input.role || 'worker', 18)} - ${trimInline(input.backend || 'codex-sdk', 18)} - ${trimInline(input.worktreeId || '-', 18)}`,
15
+ `status: ${trimInline(input.status || 'running', 14)} ${task}`,
16
+ `patch: ${trimInline(input.patchStatus || 'queued', 18)} verify: ${trimInline(input.verifyStatus || 'queued', 18)}`,
17
+ `heartbeat: ${heartbeat}`
18
+ ];
19
+ return rows.slice(0, maxLines).join('\n');
20
+ }
21
+ export async function renderZellijSlotPaneFromArtifacts(input) {
22
+ const artifactDir = path.resolve(input.artifactDir);
23
+ const result = await readJson(path.join(artifactDir, 'worker-result.json'));
24
+ const heartbeatPath = path.join(artifactDir, 'worker-heartbeat.jsonl');
25
+ const heartbeatMtime = await statMtimeMs(heartbeatPath);
26
+ const now = Date.now();
27
+ return renderZellijSlotPane({
28
+ slotId: input.slotId,
29
+ generationIndex: input.generationIndex,
30
+ role: input.role || result?.persona_id || result?.agent_id || null,
31
+ backend: input.backend || result?.backend || null,
32
+ status: result?.status || (heartbeatMtime ? 'running' : 'launching'),
33
+ currentTask: result?.summary || null,
34
+ currentFile: Array.isArray(result?.changed_files) ? result.changed_files[0] : null,
35
+ patchStatus: Array.isArray(result?.patch_envelopes) && result.patch_envelopes.length ? 'candidate' : 'queued',
36
+ verifyStatus: result?.verification?.status || 'queued',
37
+ heartbeatAgeMs: heartbeatMtime ? now - heartbeatMtime : null,
38
+ worktreeId: result?.worktree?.id || null,
39
+ mode: input.mode || 'compact-slots'
40
+ });
41
+ }
42
+ export function buildZellijSlotPaneCommand(input) {
43
+ const args = [
44
+ input.cliPath,
45
+ 'zellij-slot-pane',
46
+ '--mission', input.missionId,
47
+ '--slot', input.slotId,
48
+ '--generation', String(Math.max(1, Math.floor(Number(input.generationIndex) || 1))),
49
+ '--artifact-dir', input.artifactDir,
50
+ '--mode', input.mode || 'compact-slots',
51
+ ...(input.backend ? ['--backend', input.backend] : []),
52
+ ...(input.role ? ['--role', input.role] : []),
53
+ ...(input.watch ? ['--watch'] : [])
54
+ ];
55
+ return [input.nodePath || process.execPath, ...args].map(shellQuote).join(' ');
56
+ }
57
+ async function readJson(file) {
58
+ try {
59
+ return JSON.parse(await fs.promises.readFile(file, 'utf8'));
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ }
65
+ async function statMtimeMs(file) {
66
+ try {
67
+ return (await fs.promises.stat(file)).mtimeMs;
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ }
73
+ function trimInline(value, max) {
74
+ const text = String(value || '').replace(/\s+/g, ' ').trim();
75
+ if (text.length <= max)
76
+ return text;
77
+ return text.slice(0, Math.max(1, max - 3)) + '...';
78
+ }
79
+ function shellQuote(value) {
80
+ return `'${String(value).replace(/'/g, `'\\''`)}'`;
81
+ }
82
+ //# sourceMappingURL=zellij-slot-pane-renderer.js.map
@@ -0,0 +1,16 @@
1
+ export function resolveZellijUiMode(args = [], env = process.env) {
2
+ const fromEnv = String(env.SKS_ZELLIJ_UI_MODE || '').trim();
3
+ if (fromEnv === 'full-debug')
4
+ return 'full-debug';
5
+ if (fromEnv === 'dashboard-plus-slots')
6
+ return 'dashboard-plus-slots';
7
+ if (args.includes('--zellij-dashboard'))
8
+ return 'dashboard-plus-slots';
9
+ if (args.includes('--zellij-full-debug'))
10
+ return 'full-debug';
11
+ return 'compact-slots';
12
+ }
13
+ export function zellijUiModeCreatesDashboard(mode) {
14
+ return mode !== 'compact-slots';
15
+ }
16
+ //# sourceMappingURL=zellij-ui-mode.js.map
@@ -29,7 +29,7 @@ export function buildWorkerPaneArtifact(input) {
29
29
  schema: ZELLIJ_WORKER_PANE_SCHEMA,
30
30
  generated_at: now,
31
31
  updated_at: now,
32
- ok: blockers.length === 0 && isRealZellijWorkerPaneIdSource(paneIdSource) && Boolean(input.paneId),
32
+ ok: blockers.length === 0 && (paneIdSource === 'zellij_worker_headless_overflow' || (isRealZellijWorkerPaneIdSource(paneIdSource) && Boolean(input.paneId))),
33
33
  status: input.status || 'launching',
34
34
  mission_id: input.missionId,
35
35
  session_name: input.sessionName,
@@ -52,8 +52,8 @@ export function buildWorkerPaneArtifact(input) {
52
52
  stdout_log: input.stdoutLog,
53
53
  stderr_log: input.stderrLog,
54
54
  parent_child_transport: 'worker-result-json-and-heartbeat',
55
- scaling_primitive: 'native_cli_process_in_zellij_worker_pane',
56
- command: '<native-cli-worker-command>',
55
+ scaling_primitive: input.scalingPrimitive || 'native_cli_process_in_zellij_worker_pane',
56
+ command: String(input.workerCommand || '').includes('zellij-slot-pane') ? '<zellij-slot-pane-renderer-command>' : '<native-cli-worker-command>',
57
57
  create_session: input.createSession || null,
58
58
  launch: input.launch || null,
59
59
  pane_reconciliation: input.paneReconciliation || null,
@@ -96,6 +96,7 @@ export async function openWorkerPane(input) {
96
96
  cwd,
97
97
  worker: { slotId: input.slotId, generationIndex: input.generationIndex },
98
98
  visiblePaneCap: input.visiblePaneCap || 1,
99
+ uiMode: input.uiMode || 'compact-slots',
99
100
  dashboardSnapshot: {
100
101
  ...(input.dashboardSnapshot || {}),
101
102
  mode: String(input.dashboardSnapshot?.mode || 'naruto'),
@@ -104,12 +105,41 @@ export async function openWorkerPane(input) {
104
105
  }
105
106
  })
106
107
  : null;
108
+ if (rightColumn?.placement === 'headless') {
109
+ const record = buildWorkerPaneArtifact({
110
+ ...input,
111
+ paneId: null,
112
+ paneIdSource: 'zellij_worker_headless_overflow',
113
+ createSession,
114
+ launch: null,
115
+ paneReconciliation: null,
116
+ directionRequested: 'right',
117
+ directionApplied: 'not_applied',
118
+ rightColumn: {
119
+ mode: 'spawn-on-first-worker',
120
+ focus_pane_id: null,
121
+ y_order: null
122
+ },
123
+ status: 'running',
124
+ providerContext,
125
+ serviceTier: input.serviceTier || providerContext.service_tier,
126
+ scalingPrimitive: 'native_cli_process_headless_with_slot_dashboard',
127
+ blockers: []
128
+ });
129
+ await writeWorkerPaneArtifact(root, record);
130
+ await appendWorkerPaneEvent(root, 'worker_headless_overflow', input, {
131
+ slot_id: input.slotId,
132
+ generation_index: input.generationIndex,
133
+ reason: `visible_pane_cap:${input.visiblePaneCap || 1}`
134
+ });
135
+ return record;
136
+ }
107
137
  const paneName = buildWorkerPaneTitle(input.slotId, input.generationIndex, providerContext, input.serviceTier, input.backend, input.statusLabel || 'running', input.worktree || null);
108
- const directionRequested = rightColumn ? 'down' : 'right';
138
+ const directionRequested = rightColumn?.focusPaneId ? 'down' : 'right';
109
139
  const focus = rightColumn?.focusPaneId
110
140
  ? await focusZellijPaneById(input.sessionName, rightColumn.focusPaneId, cwd)
111
141
  : null;
112
- const newPaneArgs = ['--session', input.sessionName, 'action', 'new-pane', '--direction', directionRequested, ...(rightColumn ? ['--near-current-pane'] : []), '--name', paneName, '--', 'sh', '-lc', input.workerCommand];
142
+ const newPaneArgs = ['--session', input.sessionName, 'action', 'new-pane', '--direction', directionRequested, ...(directionRequested === 'down' ? ['--near-current-pane'] : []), '--name', paneName, '--', 'sh', '-lc', input.workerCommand];
113
143
  let launch = createSession.ok
114
144
  ? await runZellij(newPaneArgs, {
115
145
  cwd,
@@ -119,9 +149,9 @@ export async function openWorkerPane(input) {
119
149
  : null;
120
150
  let directionApplied = launch?.ok ? directionRequested : 'not_applied';
121
151
  if (createSession.ok && launch && !launch.ok) {
122
- const fallbackArgs = rightColumn
152
+ const fallbackArgs = rightColumn && directionRequested === 'down'
123
153
  ? ['--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];
154
+ : ['--session', input.sessionName, 'action', 'new-pane', '--direction', directionRequested, '--name', paneName, '--', 'sh', '-lc', input.workerCommand];
125
155
  const fallback = await runZellij(fallbackArgs, {
126
156
  cwd,
127
157
  timeoutMs: 5000,
@@ -204,7 +234,7 @@ export async function openWorkerPane(input) {
204
234
  provider_context: record.provider_context,
205
235
  direction_requested: record.direction_requested,
206
236
  direction_applied: record.direction_applied,
207
- command: '<native-cli-worker-command>',
237
+ command: record.command,
208
238
  worker_artifact_dir: input.workerArtifactDir,
209
239
  worker_result_path: input.resultPath,
210
240
  heartbeat_path: input.heartbeatPath,
@@ -0,0 +1,33 @@
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
+ const mod = await importDist('core/agents/agent-role-config.js');
8
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-role-repair-'));
9
+ fs.mkdirSync(path.join(root, '.sneakoscope', 'reports'), { recursive: true });
10
+ const plan = await mod.repairAgentRoleConfigs({ root, apply: false, codexHome: path.join(root, 'codex-home') });
11
+ const repair = await mod.repairAgentRoleConfigs({ root, apply: true, codexHome: path.join(root, 'codex-home'), reportPath: path.join(root, '.sneakoscope', 'reports', 'agent-role-config-repair.json') });
12
+ const analysisScout = path.join(root, '.codex', 'agents', 'analysis-scout.toml');
13
+ const staleRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-role-stale-'));
14
+ fs.mkdirSync(path.join(staleRoot, '.codex', 'agents'), { recursive: true });
15
+ fs.writeFileSync(path.join(staleRoot, '.codex', 'agents', 'analysis-scout.toml'), 'model = "gpt-5-codex"\nsandbox_mode = "read-only"\n');
16
+ const stalePlan = await mod.repairAgentRoleConfigs({ root: staleRoot, apply: false, codexHome: path.join(staleRoot, 'codex-home') });
17
+ const staleRepair = await mod.repairAgentRoleConfigs({ root: staleRoot, apply: true, codexHome: path.join(staleRoot, 'codex-home') });
18
+ const repairedText = fs.readFileSync(path.join(staleRoot, '.codex', 'agents', 'analysis-scout.toml'), 'utf8');
19
+ const report = {
20
+ schema: 'sks.agent-role-config-repair-check.v1',
21
+ plan_ok: plan.ok === true && plan.missing.includes('analysis-scout.toml'),
22
+ repair_ok: repair.ok === true,
23
+ analysis_scout_created: fs.existsSync(analysisScout),
24
+ created_matches_model: fs.readFileSync(analysisScout, 'utf8').includes('model = "gpt-5.5"'),
25
+ stale_detected: stalePlan.stale.includes('analysis-scout.toml'),
26
+ stale_repaired: staleRepair.repaired.includes('.codex/agents/analysis-scout.toml') && repairedText.includes('name = "analysis_scout"') && repairedText.includes('model = "gpt-5.5"'),
27
+ warnings_suppressed: repair.warnings_suppressed === true,
28
+ artifact_written: fs.existsSync(path.join(root, '.sneakoscope', 'reports', 'agent-role-config-repair.json'))
29
+ };
30
+ const ok = report.plan_ok && report.repair_ok && report.analysis_scout_created && report.created_matches_model && report.stale_detected && report.stale_repaired && report.warnings_suppressed && report.artifact_written;
31
+ assertGate(ok, 'doctor --fix must repair missing SKS-owned agent role configs', report);
32
+ emitGate('agent:role-config-repair', report);
33
+ //# sourceMappingURL=agent-role-config-repair-check.js.map
@@ -17,6 +17,8 @@ const integrationPath = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-integration-'
17
17
  fs.rmSync(integrationPath, { recursive: true, force: true });
18
18
  const integration = await managerMod.allocateWorkerWorktree({ repoRoot: repo, missionId: 'M-integrate', workerId: 'integration', slotId: 'integration' });
19
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 });
20
+ const mainReport = await mergeMod.applyGitWorktreeMergeQueue({ integrationWorktreePath: repo, diffs: [diff] });
21
+ const mainContent = fs.readFileSync(path.join(repo, 'a.txt'), 'utf8');
22
+ assertGate(report.ok === true && report.applied_count === 1 && mainReport.ok === true && mainReport.applied_count === 1 && mainContent.includes('integrated'), 'git-worktree-diff must prevalidate in integration worktree and apply to main repo', { report, mainReport, mainContent });
23
+ emitGate('git:worktree-integration-primary', { applied_count: report.applied_count, main_applied_count: mainReport.applied_count });
22
24
  //# sourceMappingURL=git-worktree-integration-primary-check.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 orchestrator = fs.readFileSync(path.join(root, 'src/core/agents/agent-orchestrator.ts'), 'utf8');
7
+ const report = {
8
+ schema: 'sks.git-worktree-integration-primary-runtime-check.v1',
9
+ splits_worktree_entries: orchestrator.includes("entry.envelope?.source === 'git-worktree-diff'"),
10
+ uses_integration_worktree: orchestrator.includes('createGitIntegrationWorktree'),
11
+ uses_merge_queue: orchestrator.includes('applyGitWorktreeMergeQueue'),
12
+ applies_to_main_repo: orchestrator.includes('main_repo_apply') && orchestrator.includes('integrationWorktreePath: repoRoot'),
13
+ rollback_evidence: orchestrator.includes('rollback_evidence') && orchestrator.includes('captureGitWorktreeRollbackPlan') && orchestrator.includes('completeGitWorktreeRollbackPlan'),
14
+ bypasses_normal_apply: orchestrator.includes('const normalEntries') && orchestrator.includes('applyAgentPatchQueueEntry(root, entry') && orchestrator.includes('parallelEntries = disjointEntries'),
15
+ writes_report: orchestrator.includes('git-worktree-merge-queue-report.json')
16
+ };
17
+ const ok = report.splits_worktree_entries && report.uses_integration_worktree && report.uses_merge_queue && report.applies_to_main_repo && report.rollback_evidence && report.bypasses_normal_apply && report.writes_report;
18
+ assertGate(ok, 'git-worktree-diff entries must use integration merge queue primary path', report);
19
+ emitGate('git:worktree-integration-primary-runtime', report);
20
+ //# sourceMappingURL=git-worktree-integration-primary-runtime-check.js.map
@@ -17,6 +17,7 @@ const uncovered = [];
17
17
  const GUARD_CALL = /\bguarded(WriteFile|Rm|Rename|Chmod|Xattr|Chflags|GlobalCodexConfigWrite|ProcessKill|PackageInstall|SkillSnapshotPromotion|Apply)\(/;
18
18
  const RISKY = [
19
19
  { kind: 'write_file', token: 'fs.writeFile', re: /\bfs\.writeFile\(/ },
20
+ { kind: 'write_file', token: 'fs.promises.writeFile', re: /\bfs\.promises\.writeFile\(/ },
20
21
  { kind: 'write_file', token: 'fsp.writeFile', re: /\bfsp\.writeFile\(/ },
21
22
  { kind: 'write_file', token: 'writeFileSync', re: /\b(?:fs\.)?writeFileSync\(/ },
22
23
  { kind: 'rm', token: 'fs.rm', re: /\bfs\.rm\(/ },
@@ -167,7 +168,7 @@ function processKillIsLivenessProbe(line) {
167
168
  return /\bprocess\.kill\([^,\n]+,\s*0\s*\)/.test(line);
168
169
  }
169
170
  function codexHomeMutationOnLine(line) {
170
- return /\b(?:writeTextAtomic|writeJsonAtomic|writeFileSync|fs\.writeFile|fsp\.writeFile|fs\.rm|fsp\.rm|fs\.rename|fsp\.rename|fs\.chmod|fsp\.chmod|copyFile|open)\b/.test(line)
171
+ return /\b(?:writeTextAtomic|writeJsonAtomic|writeFileSync|fs\.writeFile|fs\.promises\.writeFile|fsp\.writeFile|fs\.rm|fsp\.rm|fs\.rename|fsp\.rename|fs\.chmod|fsp\.chmod|copyFile|open)\b/.test(line)
171
172
  && /(?:~\/\.codex|CODEX_HOME|codexHome|codexLbHome|auth\.json|config\.toml)/.test(line);
172
173
  }
173
174
  function snippet(line) {
@@ -13,7 +13,7 @@ const governor = decideNarutoConcurrency({
13
13
  });
14
14
  const report = {
15
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,
16
+ ok: graph.total_work_items >= 200 && governor.safe_active_workers >= 16 && governor.safe_zellij_visible_panes <= governor.safe_active_workers && governor.safe_zellij_visible_panes <= 8 && graph.mixed_work_kinds.length >= 6,
17
17
  graph: { total_work_items: graph.total_work_items, mixed_work_kinds: graph.mixed_work_kinds, write_allowed_count: graph.write_allowed_count },
18
18
  governor
19
19
  };
@@ -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 { 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: 100, totalWorkItems: 200, writeCapable: true, maxActiveWorkers: 32 });
12
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-naruto-extreme-real-'));
13
+ const missionId = `M-naruto-extreme-real-${process.pid}`;
14
+ const governor = decideNarutoConcurrency({
15
+ requestedClones: 100,
16
+ totalWorkItems: graph.total_work_items,
17
+ pendingWorkQueueSize: graph.total_work_items,
18
+ backend: 'codex-sdk',
19
+ 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 }
20
+ });
21
+ const target = { ...governor, safe_active_workers: Math.min(32, governor.safe_active_workers), safe_zellij_visible_panes: Math.min(8, governor.safe_zellij_visible_panes) };
22
+ const report = await runNarutoRealActivePool({
23
+ graph,
24
+ governor: target,
25
+ spawnWorker: async (item, placement) => spawnActualNarutoWorker({
26
+ root: tempRoot,
27
+ missionId,
28
+ item,
29
+ placement,
30
+ backend: 'codex-sdk',
31
+ visiblePaneCap: target.safe_zellij_visible_panes,
32
+ zellijSessionName: `sks-${missionId}`
33
+ }),
34
+ collectWorker: async (handle) => collectActualNarutoWorker(handle),
35
+ enqueueVerification: async () => undefined,
36
+ updateDashboard: async () => undefined
37
+ });
38
+ const actualArtifacts = report.worker_lifecycle.every((row) => row.pid && row.worker_artifact_dir && fs.existsSync(path.join(row.worker_artifact_dir, 'worker-result.json')));
39
+ const ok = report.ok && report.max_observed_active_workers >= Math.ceil(target.safe_active_workers * 0.8) && report.active_pool_utilization >= 0.8 && report.headless_workers > 0 && report.visible_workers <= graph.total_work_items && actualArtifacts;
40
+ assertGate(ok, 'Naruto extreme parallelism must use actual child process active-pool lifecycle near cap with headless overflow', { report, target, actualArtifacts, tempRoot });
41
+ emitGate('naruto:extreme-parallelism-real', report);
42
+ //# sourceMappingURL=naruto-extreme-parallelism-real-check.js.map
@@ -32,7 +32,8 @@ const report = await runNarutoRealActivePool({
32
32
  dashboardEvents += 1;
33
33
  }
34
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;
35
+ const processEvidence = report.worker_lifecycle.every((row) => row.pid == null || row.worker_artifact_dir != null);
36
+ 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 && report.active_cap === target.safe_active_workers && processEvidence;
36
37
  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
+ emitGate('naruto:real-active-pool', { spawned, collected, active_cap: report.active_cap, max_observed_active_workers: report.max_observed_active_workers, refill_latency_ms_p95: report.refill_latency_ms_p95, active_pool_utilization: report.active_pool_utilization });
38
39
  //# sourceMappingURL=naruto-real-active-pool-check.js.map