sneakoscope 2.0.11 → 2.0.12

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 (44) hide show
  1. package/README.md +5 -3
  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 +11 -8
  8. package/dist/core/agents/agent-orchestrator.js +279 -1
  9. package/dist/core/agents/agent-scheduler.js +12 -1
  10. package/dist/core/agents/agent-slot-pane-binding-proof.js +3 -3
  11. package/dist/core/agents/agent-work-queue.js +26 -2
  12. package/dist/core/agents/agent-worker-pipeline.js +2 -0
  13. package/dist/core/agents/native-cli-session-swarm.js +2 -2
  14. package/dist/core/commands/naruto-command.js +104 -51
  15. package/dist/core/fsx.js +1 -1
  16. package/dist/core/git/git-worktree-merge-queue.js +34 -14
  17. package/dist/core/naruto/naruto-rebalance-policy.js +15 -3
  18. package/dist/core/naruto/naruto-work-graph.js +13 -0
  19. package/dist/core/version.js +1 -1
  20. package/dist/core/zellij/zellij-slot-column-anchor.js +163 -4
  21. package/dist/core/zellij/zellij-worker-pane-manager.js +13 -7
  22. package/dist/scripts/agent-real-codex-in-zellij-worker-pane-check.js +8 -2
  23. package/dist/scripts/agent-slot-pane-binding-proof-check.js +4 -4
  24. package/dist/scripts/codex-sdk-release-review-pipeline-check.js +2 -1
  25. package/dist/scripts/codex-sdk-zellij-pane-binding-check.js +2 -2
  26. package/dist/scripts/git-worktree-cross-rebase-check.js +13 -1
  27. package/dist/scripts/git-worktree-merge-queue-check.js +1 -0
  28. package/dist/scripts/local-collab-worktree-gpt-final-apply-policy-check.js +63 -0
  29. package/dist/scripts/naruto-actual-worker-control-plane-check.js +30 -3
  30. package/dist/scripts/naruto-allocation-runtime-wiring-check.js +92 -0
  31. package/dist/scripts/naruto-orchestrator-runtime-source-check.js +65 -6
  32. package/dist/scripts/naruto-rebalance-policy-check.js +15 -2
  33. package/dist/scripts/naruto-shadow-clone-swarm-check.js +1 -1
  34. package/dist/scripts/release-dag-full-coverage-check.js +4 -0
  35. package/dist/scripts/release-real-check.js +258 -77
  36. package/dist/scripts/zellij-first-slot-down-stack-check.js +1 -1
  37. package/dist/scripts/zellij-first-slot-down-stack-real-check.js +344 -4
  38. package/dist/scripts/zellij-right-column-manager-check.js +1 -1
  39. package/dist/scripts/zellij-slot-column-anchor-check.js +23 -2
  40. package/dist/scripts/zellij-slot-only-ui-check.js +3 -1
  41. package/dist/scripts/zellij-slot-renderer-proof-semantics-check.js +59 -0
  42. package/dist/scripts/zellij-worker-pane-manager-check.js +23 -1
  43. package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +21 -4
  44. package/package.json +5 -2
@@ -26,7 +26,13 @@ export function buildWorkerPaneArtifact(input) {
26
26
  const blockers = input.blockers || [];
27
27
  const providerContext = normalizePaneProviderContext(input.providerContext, input.serviceTier);
28
28
  const paneTitle = buildWorkerPaneTitle(input.slotId, input.generationIndex, providerContext, input.serviceTier, input.backend, input.statusLabel || input.status, input.worktree || null);
29
- const directionRequested = input.directionRequested || 'right';
29
+ const commandText = String(input.workerCommand || '');
30
+ const isSlotRenderer = commandText.includes('zellij-slot-pane');
31
+ const paneKind = input.paneKind || (isSlotRenderer ? 'slot_status_renderer' : 'worker_codex_sdk');
32
+ const scalingPrimitive = input.scalingPrimitive || (isSlotRenderer
33
+ ? 'native_cli_process_with_zellij_slot_renderer'
34
+ : 'native_cli_process_in_zellij_worker_pane');
35
+ const directionRequested = input.directionRequested || 'down';
30
36
  const directionApplied = input.directionApplied || 'not_applied';
31
37
  return {
32
38
  schema: ZELLIJ_WORKER_PANE_SCHEMA,
@@ -41,7 +47,7 @@ export function buildWorkerPaneArtifact(input) {
41
47
  session_id: input.sessionId,
42
48
  pane_name: paneTitle,
43
49
  pane_title: paneTitle,
44
- pane_kind: 'worker_codex_sdk',
50
+ pane_kind: paneKind,
45
51
  pane_id: input.paneId || null,
46
52
  pane_id_source: paneIdSource,
47
53
  provider: providerContext.provider,
@@ -55,8 +61,8 @@ export function buildWorkerPaneArtifact(input) {
55
61
  stdout_log: input.stdoutLog,
56
62
  stderr_log: input.stderrLog,
57
63
  parent_child_transport: 'worker-result-json-and-heartbeat',
58
- scaling_primitive: input.scalingPrimitive || 'native_cli_process_in_zellij_worker_pane',
59
- command: String(input.workerCommand || '').includes('zellij-slot-pane') ? '<zellij-slot-pane-renderer-command>' : '<native-cli-worker-command>',
64
+ scaling_primitive: scalingPrimitive,
65
+ command: isSlotRenderer ? '<zellij-slot-pane-renderer-command>' : '<native-cli-worker-command>',
60
66
  create_session: input.createSession || null,
61
67
  launch: input.launch || null,
62
68
  pane_reconciliation: input.paneReconciliation || null,
@@ -182,7 +188,7 @@ export async function openWorkerPane(input) {
182
188
  }
183
189
  }
184
190
  const focusPaneId = rightColumn?.focusPaneId || slotColumnAnchorPaneId || null;
185
- const directionRequested = rightColumn ? 'down' : 'right';
191
+ const directionRequested = 'down';
186
192
  const focus = focusPaneId
187
193
  ? await focusZellijPaneById(input.sessionName, focusPaneId, cwd)
188
194
  : null;
@@ -282,7 +288,7 @@ export async function openWorkerPane(input) {
282
288
  session_name: input.sessionName,
283
289
  pane_name: paneName,
284
290
  pane_title: paneName,
285
- pane_kind: 'worker_codex_sdk',
291
+ pane_kind: record.pane_kind,
286
292
  pane_id: record.pane_id,
287
293
  pane_id_source: record.pane_id_source,
288
294
  provider: record.provider,
@@ -302,7 +308,7 @@ export async function openWorkerPane(input) {
302
308
  patch_envelope_path: input.patchEnvelopePath,
303
309
  parent_child_transport: 'worker-result-json-and-heartbeat',
304
310
  persistent_slot_lane: false,
305
- scaling_primitive: 'native_cli_process_in_zellij_worker_pane',
311
+ scaling_primitive: record.scaling_primitive,
306
312
  blockers
307
313
  });
308
314
  return record;
@@ -123,7 +123,7 @@ async function runRealGate({ sourceOk, eventProof }) {
123
123
  async function inspectRealLedger(ledgerRoot) {
124
124
  const swarm = await readJson(path.join(ledgerRoot, 'agent-native-cli-session-swarm.json'), null);
125
125
  const records = Array.isArray(swarm?.records) ? swarm.records : [];
126
- const workerRecords = records.filter((row) => row.scaling_primitive === 'native_cli_process_in_zellij_worker_pane');
126
+ const workerRecords = records.filter(isZellijCodexWorkerRecord);
127
127
  const eventsByWorker = [];
128
128
  for (const record of workerRecords) {
129
129
  const workerDir = String(record.worker_artifact_dir || '');
@@ -137,7 +137,7 @@ async function inspectRealLedger(ledgerRoot) {
137
137
  const blockers = [
138
138
  ...(swarm?.ok === true ? [] : ['real_codex_zellij_swarm_not_ok']),
139
139
  ...(workerRecords.length >= 1 ? [] : ['real_codex_zellij_worker_record_missing']),
140
- ...(workerRecords.some((row) => row.pane_kind === 'worker_codex_sdk') ? [] : ['real_codex_zellij_worker_pane_kind_missing']),
140
+ ...(workerRecords.some((row) => row.pane_kind === 'worker_codex_sdk' || row.pane_kind === 'slot_status_renderer') ? [] : ['real_codex_zellij_worker_pane_kind_missing']),
141
141
  ...(workerRecords.every((row) => manager.isRealZellijWorkerPaneIdSource(row.zellij_pane_id_source)) ? [] : ['real_codex_zellij_pane_id_source_not_real']),
142
142
  ...(workerRecords.every((row) => row.zellij_pane_id) ? [] : ['real_codex_zellij_pane_id_missing']),
143
143
  ...(workerRecords.every((row) => row.sdk_thread_id) ? [] : ['real_codex_zellij_sdk_thread_missing']),
@@ -171,6 +171,12 @@ async function inspectRealLedger(ledgerRoot) {
171
171
  blockers
172
172
  };
173
173
  }
174
+ function isZellijCodexWorkerRecord(row) {
175
+ return row?.scaling_primitive === 'native_cli_process_in_zellij_worker_pane'
176
+ || row?.scaling_primitive === 'native_cli_process_with_zellij_slot_renderer'
177
+ || row?.pane_kind === 'worker_codex_sdk'
178
+ || row?.pane_kind === 'slot_status_renderer';
179
+ }
174
180
  async function emit(report) {
175
181
  await fs.mkdir(path.join(root, '.sneakoscope', 'reports'), { recursive: true });
176
182
  await fs.writeFile(path.join(root, '.sneakoscope', 'reports', 'agent-real-codex-in-zellij-worker-pane.json'), `${JSON.stringify(report, null, 2)}\n`);
@@ -14,10 +14,10 @@ const records = [1, 2, 3].map((index) => ({
14
14
  session_id: `slot-001-gen-${index}`,
15
15
  slot_id: 'slot-001',
16
16
  generation_index: index,
17
- pane_kind: 'worker_codex_sdk',
17
+ pane_kind: index === 1 ? 'slot_status_renderer' : 'worker_codex_sdk',
18
18
  zellij_pane_id: String(100 + index),
19
19
  zellij_pane_id_source: index % 2 ? 'zellij_worker_new_pane_stdout' : 'zellij_worker_list_panes',
20
- scaling_primitive: 'native_cli_process_in_zellij_worker_pane',
20
+ scaling_primitive: index === 1 ? 'native_cli_process_with_zellij_slot_renderer' : 'native_cli_process_in_zellij_worker_pane',
21
21
  sdk_thread_id: `sdk-thread-${index}`,
22
22
  sdk_run_id: `sdk-run-${index}`,
23
23
  stream_event_count: 4,
@@ -35,9 +35,9 @@ await fs.writeFile(path.join(tmp, 'agent-native-cli-session-swarm.json'), `${JSO
35
35
  }, null, 2)}\n`);
36
36
  await fs.writeFile(path.join(tmp, 'agent-zellij-pane-launch-ledger.jsonl'), records.map((record) => JSON.stringify({
37
37
  schema: 'sks.agent-zellij-pane-launch.v1',
38
- pane_kind: 'worker_codex_sdk',
38
+ pane_kind: record.pane_kind,
39
39
  persistent_slot_lane: false,
40
- scaling_primitive: 'native_cli_process_in_zellij_worker_pane',
40
+ scaling_primitive: record.scaling_primitive,
41
41
  slot_id: record.slot_id,
42
42
  generation_index: record.generation_index,
43
43
  pane_id: record.zellij_pane_id,
@@ -3,10 +3,11 @@
3
3
  import { assertGate, emitGate, packageScripts, readText, releaseGateIds } from './lib/codex-sdk-gate-lib.js';
4
4
  const scripts = packageScripts();
5
5
  const releaseRealCheck = String(scripts['release:real-check'] || '');
6
+ const releaseRealCheckSource = readText('src/scripts/release-real-check.ts');
6
7
  const releaseGates = releaseGateIds();
7
8
  assertGate(releaseGates.has('codex-sdk:capability'), 'release gate DAG must include Codex SDK capability gate');
8
9
  assertGate(releaseGates.has('codex-sdk:all-pipelines'), 'release gate DAG must include Codex SDK all-pipelines gate');
9
- assertGate(releaseRealCheck.includes('codex-sdk:real-smoke'), 'release:real-check must include Codex SDK real smoke');
10
+ assertGate(releaseRealCheck.includes('codex-sdk:real-smoke') || releaseRealCheckSource.includes('codex-sdk:real-smoke'), 'release:real-check must include Codex SDK real smoke');
10
11
  assertGate(readText('src/core/agents/agent-orchestrator.ts').includes('legacy_codex_exec_runtime_removed'), 'orchestrator must block legacy codex-exec requests');
11
12
  emitGate('codex-sdk:release-review-pipeline', { release_gate_dag_contains_sdk: true });
12
13
  //# sourceMappingURL=codex-sdk-release-review-pipeline-check.js.map
@@ -7,7 +7,7 @@ const proofSource = readText('src/core/agents/agent-slot-pane-binding-proof.ts')
7
7
  const managerSource = readText('src/core/zellij/zellij-worker-pane-manager.ts');
8
8
  assertGate(fixture.proof.zellij_pane_id === 'pane-999', 'control proof must link zellij pane id', fixture.proof);
9
9
  assertGate(swarmSource.includes('codex_sdk_thread_started'), 'swarm must emit SDK thread event');
10
- assertGate(proofSource.includes('worker_codex_sdk'), 'slot-pane proof must require worker_codex_sdk pane kind');
11
- assertGate(managerSource.includes("pane_kind: 'worker_codex_sdk'"), 'worker pane manager must record worker_codex_sdk pane kind');
10
+ assertGate(proofSource.includes('worker_codex_sdk') && proofSource.includes('slot_status_renderer'), 'slot-pane proof must accept worker command panes and compact slot renderer panes');
11
+ assertGate(managerSource.includes('slot_status_renderer') && managerSource.includes('worker_codex_sdk'), 'worker pane manager must distinguish slot renderer and worker command pane kinds');
12
12
  emitGate('codex-sdk:zellij-pane-binding', { zellij_pane_id: fixture.proof.zellij_pane_id, sdk_thread_id: fixture.proof.sdk_thread_id });
13
13
  //# sourceMappingURL=codex-sdk-zellij-pane-binding-check.js.map
@@ -13,15 +13,27 @@ fs.writeFileSync(path.join(root, 'base.txt'), 'base\n');
13
13
  await runGitCommand(root, ['add', 'base.txt']);
14
14
  await runGitCommand(root, ['commit', '-m', 'base']);
15
15
  const workerPath = path.join(root, '..', `worker-${process.pid}`);
16
+ const dirtyWorkerPath = path.join(root, '..', `worker-dirty-${process.pid}`);
17
+ const runningWorkerPath = path.join(root, '..', `worker-running-${process.pid}`);
16
18
  await runGitCommand(root, ['worktree', 'add', workerPath, 'HEAD']);
19
+ await runGitCommand(root, ['worktree', 'add', dirtyWorkerPath, 'HEAD']);
20
+ await runGitCommand(root, ['worktree', 'add', runningWorkerPath, 'HEAD']);
21
+ fs.writeFileSync(path.join(dirtyWorkerPath, 'dirty.txt'), 'dirty\n');
17
22
  fs.writeFileSync(path.join(root, 'integration.txt'), 'integration\n');
18
23
  await runGitCommand(root, ['add', 'integration.txt']);
19
24
  await runGitCommand(root, ['commit', '-m', 'integration']);
20
25
  const head = gitOutputLine(await runGitCommand(root, ['rev-parse', 'HEAD']));
21
26
  const report = await crossRebaseIdleWorktrees({
22
27
  integrationHead: head,
23
- workers: [{ worker_id: 'W1', worktree_path: workerPath, state: 'idle' }]
28
+ workers: [
29
+ { worker_id: 'W1', worktree_path: workerPath, state: 'idle' },
30
+ { worker_id: 'W-dirty', worktree_path: dirtyWorkerPath, state: 'idle' },
31
+ { worker_id: 'W-running', worktree_path: runningWorkerPath, state: 'running' }
32
+ ]
24
33
  });
25
34
  assertGate(report.ok && report.applied_count === 1, 'Idle worktrees must cross-rebase to the integration head', report);
35
+ assertGate(report.skipped_count === 2, 'Dirty and running worktrees must be skipped during cross-rebase', report);
36
+ assertGate(report.records.some((row) => row.worker_id === 'W-dirty' && row.status === 'skipped' && row.reason === 'dirty_worktree_skipped'), 'Dirty worktree must skip cross-rebase', report);
37
+ assertGate(report.records.some((row) => row.worker_id === 'W-running' && row.status === 'skipped' && row.reason === 'worker_not_idle'), 'Running worktree must skip cross-rebase', report);
26
38
  emitGate('git:worktree-cross-rebase', report);
27
39
  //# sourceMappingURL=git-worktree-cross-rebase-check.js.map
@@ -20,6 +20,7 @@ const diffB = await diffMod.exportGitWorktreeDiff({ mainRepoRoot: repo, worktree
20
20
  const integration = await integrationMod.createGitIntegrationWorktree({ repoRoot: repo, missionId: 'M-merge' });
21
21
  const report = await queueMod.applyGitWorktreeMergeQueue({ integrationWorktreePath: integration.worktree_path, diffs: [diffA, diffB] });
22
22
  assertGate(report.ok === true && report.applied_count === 2, 'merge queue must apply non-conflicting worktree diffs', report);
23
+ assertGate((report.strategy_results || []).every((row) => row.strategy === 'diff-apply-3way'), 'merge queue must record the diff apply strategy for worktree diffs', report.strategy_results || []);
23
24
  assertGate(fs.readFileSync(path.join(integration.worktree_path, 'a.txt'), 'utf8').includes('from-a'), 'integration worktree must include first diff');
24
25
  assertGate(fs.readFileSync(path.join(integration.worktree_path, 'b.txt'), 'utf8').includes('from-b'), 'integration worktree must include second diff');
25
26
  assertGate(fs.readFileSync(path.join(repo, 'a.txt'), 'utf8') === 'alpha\n', 'main worktree must remain unchanged before integration commit');
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
4
+ import { gptFinalRequiredForPipeline } from '../core/pipeline/gpt-final-required.js';
5
+ import { finalizePipelineResult } from '../core/pipeline/finalize-pipeline-result.js';
6
+ import { selectFinalGptPatchSource } from '../core/pipeline/final-gpt-patch-stage.js';
7
+ const worktreeEnvelope = {
8
+ schema: 'sks.agent-patch-envelope.v1',
9
+ source: 'git-worktree-diff',
10
+ git_worktree: {
11
+ worktree_path: '/tmp/sks-worker',
12
+ changed_files: ['src/core/example.ts']
13
+ },
14
+ operations: [{ op: 'git_apply_patch', path: '.', diff: 'diff --git a/src/core/example.ts b/src/core/example.ts\n' }]
15
+ };
16
+ const requirement = gptFinalRequiredForPipeline({
17
+ localParticipated: false,
18
+ candidateResults: [{ backend: 'codex-sdk', patch_envelopes: [worktreeEnvelope] }],
19
+ candidatePatchEnvelopes: [worktreeEnvelope]
20
+ });
21
+ const blocked = await finalizePipelineResult({
22
+ route: '$Naruto',
23
+ missionId: 'M-worktree-gpt-final-policy',
24
+ localParticipated: false,
25
+ candidateResults: [{ backend: 'codex-sdk', patch_envelopes: [worktreeEnvelope] }],
26
+ candidatePatchEnvelopes: [worktreeEnvelope],
27
+ verificationResults: [],
28
+ sideEffectReport: {},
29
+ mutationLedger: {},
30
+ rollbackPlan: {},
31
+ applyPatches: true,
32
+ forceGptFinalUnavailable: true
33
+ });
34
+ const modified = selectFinalGptPatchSource({
35
+ result: {
36
+ status: 'modified',
37
+ modified_patch_envelopes: [{ ...worktreeEnvelope, source: 'model_authored', operations: [{ op: 'replace', path: 'src/core/example.ts', search: 'old', replace: 'new' }] }]
38
+ }
39
+ }, [worktreeEnvelope]);
40
+ const rejected = selectFinalGptPatchSource({ result: { status: 'rejected' } }, [worktreeEnvelope]);
41
+ const ok = requirement.gpt_final_required === true
42
+ && requirement.worktree_participated === true
43
+ && blocked.ok === false
44
+ && blocked.apply_allowed === false
45
+ && blocked.blockers.includes('gpt_final_arbiter_required_not_passed')
46
+ && modified.ok === true
47
+ && modified.final_patch_source === 'gpt_final_arbiter'
48
+ && modified.patch_envelopes[0]?.source === 'model_authored'
49
+ && rejected.ok === false
50
+ && rejected.final_patch_source === 'blocked';
51
+ assertGate(ok, 'Worktree/local candidate output must require GPT Final before apply, and GPT modified/rejected decisions must control final patch source', {
52
+ requirement,
53
+ blocked,
54
+ modified,
55
+ rejected
56
+ });
57
+ emitGate('local-collab:worktree-gpt-final-apply-policy', {
58
+ requirement,
59
+ blocked_apply_allowed: blocked.apply_allowed,
60
+ modified_source: modified.final_patch_source,
61
+ rejected_source: rejected.final_patch_source
62
+ });
63
+ //# sourceMappingURL=local-collab-worktree-gpt-final-apply-policy-check.js.map
@@ -6,6 +6,7 @@ import path from 'node:path';
6
6
  import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
7
7
  import { buildNarutoWorkGraph } from '../core/naruto/naruto-work-graph.js';
8
8
  import { collectActualNarutoWorker, spawnActualNarutoWorker } from '../core/naruto/naruto-real-worker-runtime.js';
9
+ import { narutoCommand } from '../core/commands/naruto-command.js';
9
10
  process.env.SKS_CODEX_SDK_FAKE = '1';
10
11
  const root = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-naruto-actual-worker-'));
11
12
  const graph = buildNarutoWorkGraph({ requestedClones: 1, totalWorkItems: 1, readonly: true, writeCapable: false });
@@ -20,10 +21,36 @@ const handle = await spawnActualNarutoWorker({
20
21
  });
21
22
  const collected = await collectActualNarutoWorker(handle);
22
23
  const result = JSON.parse(fs.readFileSync(path.join(handle.worker_artifact_dir, 'worker-result.json'), 'utf8'));
24
+ const fullRoute = await narutoCommand([
25
+ 'run',
26
+ 'Naruto actual worker full command control plane check',
27
+ '--json',
28
+ '--backend',
29
+ 'fake',
30
+ '--backend-explicit',
31
+ '--clones',
32
+ '2',
33
+ '--work-items',
34
+ '2',
35
+ '--readonly',
36
+ '--no-open-zellij',
37
+ '--smoke'
38
+ ]);
39
+ const missionRoot = path.join(process.cwd(), '.sneakoscope', 'missions', fullRoute.mission_id || '', 'agents', 'naruto-real-workers');
40
+ const fullWorkerResults = fs.existsSync(missionRoot)
41
+ ? fs.readdirSync(missionRoot).map((name) => {
42
+ const file = path.join(missionRoot, name, 'worker-result.json');
43
+ return fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf8')) : null;
44
+ }).filter(Boolean)
45
+ : [];
23
46
  const ok = collected.ok === true
24
47
  && result.ok === true
25
48
  && result.control_plane_result?.worker_result_path
26
- && result.control_plane_result?.structured_output_valid === true;
27
- assertGate(ok, 'Naruto actual worker must call Codex Control Plane and write structured result evidence', { collected, result });
28
- emitGate('naruto:actual-worker-control-plane', { collected, result });
49
+ && result.control_plane_result?.structured_output_valid === true
50
+ && fullRoute.active_pool?.real_runtime?.runtime_source_of_truth === 'pre_run_smoke_only'
51
+ && fullRoute.runtime_source_of_truth === 'agent-orchestrator-scheduler'
52
+ && fullWorkerResults.length >= 1
53
+ && fullWorkerResults.every((row) => row.control_plane_result?.structured_output_valid === true);
54
+ assertGate(ok, 'Naruto actual worker must call Codex Control Plane directly and through the explicit full-route smoke path', { collected, result, fullRoute, fullWorkerResults });
55
+ emitGate('naruto:actual-worker-control-plane', { collected, result, full_route_mission_id: fullRoute.mission_id, full_worker_result_count: fullWorkerResults.length });
29
56
  //# sourceMappingURL=naruto-actual-worker-control-plane-check.js.map
@@ -0,0 +1,92 @@
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 { runNativeAgentOrchestrator } from '../core/agents/agent-orchestrator.js';
8
+ import { buildNarutoCloneRoster } from '../core/agents/agent-roster.js';
9
+ import { buildNarutoWorkGraph } from '../core/naruto/naruto-work-graph.js';
10
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-naruto-runtime-wiring-'));
11
+ const roster = buildNarutoCloneRoster({ clones: 3, readonly: true, prompt: 'runtime wiring check' });
12
+ const graph = buildNarutoWorkGraph({
13
+ requestedClones: 3,
14
+ totalWorkItems: 3,
15
+ readonly: true,
16
+ writeCapable: false,
17
+ allocationAssignments: [
18
+ assignment('NW-000001', 'naruto_clone_001', 42),
19
+ assignment('NW-000002', 'naruto_clone_002', 41),
20
+ assignment('NW-000003', 'naruto_clone_999', 1)
21
+ ]
22
+ });
23
+ const result = await runNativeAgentOrchestrator({
24
+ root,
25
+ route: '$Naruto',
26
+ routeCommand: 'sks naruto run',
27
+ routeBlackboxKind: 'allocation_runtime_wiring_gate',
28
+ prompt: 'Naruto allocation runtime wiring check',
29
+ roster,
30
+ agents: 3,
31
+ concurrency: 2,
32
+ targetActiveSlots: 2,
33
+ desiredWorkItemCount: 3,
34
+ minimumWorkItems: 3,
35
+ backend: 'fake',
36
+ backendExplicit: true,
37
+ mock: true,
38
+ readonly: true,
39
+ nativeCliSwarm: false,
40
+ narutoMode: true,
41
+ narutoWorkGraph: graph,
42
+ narutoAllocationPolicy: { schema: 'sks.naruto-allocation-policy.v1', ok: true, assignments: graph.work_items.map((item) => ({ task_id: item.id, owner: item.owner })) },
43
+ narutoRebalancePolicy: { schema: 'sks.naruto-rebalance-policy.v1', ok: true, decisions: [] }
44
+ });
45
+ const ledgerRoot = path.join(root, result.ledger_root || '.');
46
+ const wiring = JSON.parse(fs.readFileSync(path.join(ledgerRoot, 'naruto-runtime-wiring.json'), 'utf8'));
47
+ const queue = JSON.parse(fs.readFileSync(path.join(ledgerRoot, 'agent-work-queue.json'), 'utf8'));
48
+ const owners = queue.items.map((item) => item.slice?.owner_agent_id);
49
+ const runtimeProofs = (result.results || []).map((row) => row.naruto_runtime).filter(Boolean);
50
+ const schedulerOk = result.scheduler?.state?.completed_count === 3
51
+ && result.scheduler?.state?.failed_count === 0
52
+ && result.scheduler?.state?.blocked_count === 0
53
+ && result.scheduler?.state?.pending_queue_drained === true
54
+ && Array.isArray(result.scheduler?.state?.blockers)
55
+ && result.scheduler.state.blockers.length === 0;
56
+ const ok = schedulerOk
57
+ && wiring.ok === true
58
+ && wiring.scheduler_slice_count === 3
59
+ && owners.includes('naruto_clone_001')
60
+ && owners.includes('naruto_clone_002')
61
+ && wiring.slice_owners.some((row) => row.original_owner === 'naruto_clone_999' && row.rebalanced === true)
62
+ && runtimeProofs.length === 3
63
+ && runtimeProofs.every((row) => row.source_of_truth === 'agent-orchestrator-scheduler');
64
+ assertGate(ok, 'Naruto allocation must be wired into scheduler slices, queue ownership, and worker runtime proof', {
65
+ result_ok: result.ok,
66
+ result_proof_blockers: result.proof?.blockers || [],
67
+ scheduler: result.scheduler?.state || null,
68
+ wiring,
69
+ owners,
70
+ runtimeProofs
71
+ });
72
+ emitGate('naruto:allocation-runtime-wiring', {
73
+ wiring,
74
+ owners,
75
+ scheduler_ok: schedulerOk,
76
+ runtime_proof_count: runtimeProofs.length
77
+ });
78
+ function assignment(taskId, owner, score) {
79
+ return {
80
+ task_id: taskId,
81
+ owner,
82
+ allocation_reason: `fixture owner ${owner}`,
83
+ allocation_score: score,
84
+ hints: {
85
+ role: 'verifier',
86
+ paths: ['src/core/naruto/runtime.ts'],
87
+ domains: ['src/core/naruto'],
88
+ writePaths: []
89
+ }
90
+ };
91
+ }
92
+ //# sourceMappingURL=naruto-allocation-runtime-wiring-check.js.map
@@ -2,10 +2,69 @@
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
5
- const source = fs.readFileSync(path.join(process.cwd(), 'src/core/commands/naruto-command.ts'), 'utf8');
6
- const ok = source.includes("runtime_source_of_truth: 'agent-orchestrator-scheduler'")
7
- && source.includes("production_runtime_source_of_truth: 'agent-orchestrator-scheduler'")
8
- && source.includes('pre_run_smoke_never_owns_production_runtime');
9
- assertGate(ok, 'Naruto production runtime source of truth must be the native agent orchestrator scheduler, not pre-run active-pool smoke', { ok });
10
- emitGate('naruto:orchestrator-runtime-source', { ok });
5
+ import { narutoCommand } from '../core/commands/naruto-command.js';
6
+ const summary = await narutoCommand([
7
+ 'run',
8
+ 'Naruto orchestrator runtime source artifact check',
9
+ '--json',
10
+ '--backend',
11
+ 'fake',
12
+ '--clones',
13
+ '2',
14
+ '--work-items',
15
+ '2',
16
+ '--readonly',
17
+ '--no-open-zellij'
18
+ ]);
19
+ const ledgerRoot = path.join(process.cwd(), '.sneakoscope', 'missions', summary.mission_id || '', 'agents');
20
+ const realPool = readJson(path.join(ledgerRoot, 'naruto-real-active-pool.json'));
21
+ const wiring = readJson(path.join(ledgerRoot, 'naruto-runtime-wiring.json'));
22
+ const artifactText = collectText(ledgerRoot);
23
+ const ok = summary.runtime_source_of_truth === 'agent-orchestrator-scheduler'
24
+ && summary.pre_run_real_active_pool_source === 'skipped'
25
+ && realPool?.status === 'skipped'
26
+ && realPool?.runtime_source_of_truth === 'agent-orchestrator-scheduler'
27
+ && realPool?.reason === 'pre_run_smoke_disabled_for_production'
28
+ && wiring?.source_of_truth === 'naruto-work-graph'
29
+ && artifactText.includes('agent-orchestrator-scheduler')
30
+ && artifactText.includes('pre_run_smoke_never_owns_production_runtime');
31
+ assertGate(ok, 'Naruto production runtime source of truth must be proven by command artifacts, not source-string checks', {
32
+ summary,
33
+ realPool,
34
+ wiring
35
+ });
36
+ emitGate('naruto:orchestrator-runtime-source', {
37
+ mission_id: summary.mission_id,
38
+ runtime_source_of_truth: summary.runtime_source_of_truth,
39
+ pre_run_real_active_pool_source: summary.pre_run_real_active_pool_source,
40
+ real_pool_status: realPool?.status || null,
41
+ wiring_ok: wiring?.ok === true
42
+ });
43
+ function readJson(file) {
44
+ try {
45
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }
51
+ function collectText(root) {
52
+ const chunks = [];
53
+ const stack = [root];
54
+ while (stack.length) {
55
+ const current = stack.pop();
56
+ if (!current || !fs.existsSync(current))
57
+ continue;
58
+ const stat = fs.statSync(current);
59
+ if (stat.isDirectory()) {
60
+ for (const child of fs.readdirSync(current))
61
+ stack.push(path.join(current, child));
62
+ continue;
63
+ }
64
+ if (!/\.(json|jsonl)$/.test(current))
65
+ continue;
66
+ chunks.push(fs.readFileSync(current, 'utf8'));
67
+ }
68
+ return chunks.join('\n');
69
+ }
11
70
  //# sourceMappingURL=naruto-orchestrator-runtime-source-check.js.map
@@ -23,6 +23,19 @@ const decisions = rebalanceNarutoReadyWork({
23
23
  workers: [{ id: 'idle-1', role: 'verifier', lane: 'src/core', alive: true, state: 'idle' }],
24
24
  completedTaskIds: []
25
25
  });
26
- assertGate(decisions.length === 1 && decisions[0]?.task_id === 'A', 'Naruto rebalance must assign only dependency-ready pending work to idle workers', { decisions });
27
- emitGate('naruto:rebalance-policy', { decisions });
26
+ const inactiveOwner = rebalanceNarutoReadyWork({
27
+ tasks: [{ ...item('C'), owner: 'missing-worker' }],
28
+ workers: [{ id: 'idle-2', role: 'verifier', lane: 'src/core', alive: true, state: 'idle' }],
29
+ completedTaskIds: []
30
+ });
31
+ const writeConflict = rebalanceNarutoReadyWork({
32
+ tasks: [{ ...item('D'), write_paths: ['src/core/naruto/runtime.ts'], write_allowed: true }],
33
+ workers: [{ id: 'idle-3', role: 'verifier', lane: 'src/core', alive: true, state: 'idle' }],
34
+ completedTaskIds: [],
35
+ activeWritePaths: ['src/core/naruto/runtime.ts']
36
+ });
37
+ assertGate(decisions.length === 1 && decisions[0]?.task_id === 'A'
38
+ && inactiveOwner.length === 1 && inactiveOwner[0]?.worker_id === 'idle-2'
39
+ && writeConflict.length === 0, 'Naruto rebalance must assign dependency-ready work, reassign inactive owners, and skip active write conflicts', { decisions, inactiveOwner, writeConflict });
40
+ emitGate('naruto:rebalance-policy', { decisions, inactiveOwner, writeConflict });
28
41
  //# sourceMappingURL=naruto-rebalance-policy-check.js.map
@@ -114,7 +114,7 @@ const writePaths = commandGraph.work_items.filter((row) => row.write_allowed).fl
114
114
  assertGate(new Set(writePaths).size > 1, 'naruto command default patch-envelope leases must be per work item, not one shared write path', { sample: writePaths.slice(0, 8), unique: new Set(writePaths).size });
115
115
  assertGate(commandGraph.active_waves.some((wave) => wave.write_paths.length > 1), 'naruto command graph must contain a parallel write wave when route-local patch envelopes do not overlap', { waves: commandGraph.active_waves.slice(0, 3) });
116
116
  const state = parsed.run?.scheduler?.state || parsed.run?.scheduler || {};
117
- assertGate(Number(state.completed_count) === proofClones, 'all clone work items must complete despite throttling', { completed_count: state.completed_count });
117
+ assertGate(Number(state.completed_count) === Number(parsed.work_graph?.total_work_items || 0) && Number(state.completed_count) >= proofClones, 'all clone work items must complete despite throttling', { completed_count: state.completed_count, total_work_items: parsed.work_graph?.total_work_items, proofClones });
118
118
  const explicitConcurrency = spawnSync(process.execPath, [cli, 'naruto', 'run', 'explicit concurrency', '--clones', '6', '--backend', 'fake', '--work-items', '6', '--concurrency', '6', '--json'], { cwd: root, env: childEnv, encoding: 'utf8', timeout: 120000, maxBuffer: 4 * 1024 * 1024 });
119
119
  const explicitParsed = parseJson(explicitConcurrency.stdout);
120
120
  assertGate(explicitConcurrency.status === 0 && explicitParsed?.target_active_slots === 6, 'explicit --concurrency must let Naruto use the requested parallel slot count', { status: explicitConcurrency.status, target_active_slots: explicitParsed?.target_active_slots });
@@ -19,12 +19,16 @@ const gateIds = new Set(manifest.gates.map((gate) => gate.id));
19
19
  const releasePresetIds = new Set(manifest.gates.filter((gate) => Array.isArray(gate.preset) && gate.preset.includes('release')).map((gate) => gate.id));
20
20
  const requiredReleasePresetIds = [
21
21
  'zellij:first-slot-down-stack',
22
+ 'zellij:slot-renderer-proof-semantics',
22
23
  'naruto:allocation-policy',
23
24
  'naruto:rebalance-policy',
25
+ 'naruto:allocation-runtime-wiring',
24
26
  'naruto:actual-worker-control-plane',
25
27
  'naruto:orchestrator-runtime-source',
26
28
  'git:worktree-checkpoint',
27
29
  'git:worktree-cross-rebase',
30
+ 'local-collab:worktree-gpt-final-apply-policy',
31
+ 'release:cache-glob-hashing',
28
32
  'release:dag-full-coverage'
29
33
  ];
30
34
  const missing = legacyIds.filter((id) => !gateIds.has(id) && !allowlist.has(id));