sneakoscope 2.0.2 → 2.0.5

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 (126) hide show
  1. package/README.md +12 -8
  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 +86 -8
  8. package/dist/commands/doctor.js +14 -0
  9. package/dist/core/agents/agent-orchestrator.js +70 -4
  10. package/dist/core/agents/agent-patch-proof.js +5 -0
  11. package/dist/core/agents/agent-proof-evidence.js +61 -0
  12. package/dist/core/agents/agent-roster.js +35 -6
  13. package/dist/core/agents/agent-schema.js +1 -1
  14. package/dist/core/agents/native-worker-backend-router.js +31 -9
  15. package/dist/core/agents/ollama-worker-config.js +164 -15
  16. package/dist/core/codex/codex-0-137-compat.js +119 -0
  17. package/dist/core/codex-control/codex-control-proof.js +4 -1
  18. package/dist/core/codex-control/codex-fake-sdk-adapter.js +20 -0
  19. package/dist/core/codex-control/codex-output-schemas.js +5 -1
  20. package/dist/core/codex-control/codex-sdk-capability.js +1 -1
  21. package/dist/core/codex-control/codex-task-runner.js +329 -5
  22. package/dist/core/codex-control/gpt-final-arbiter.js +160 -0
  23. package/dist/core/codex-control/gpt-final-context-compressor.js +17 -0
  24. package/dist/core/codex-control/gpt-final-proof-pack.js +120 -0
  25. package/dist/core/codex-control/gpt-final-review-schema.js +71 -0
  26. package/dist/core/codex-control/python-codex-sdk-adapter.js +197 -0
  27. package/dist/core/codex-control/python-codex-sdk-event-translator.js +14 -0
  28. package/dist/core/commands/local-model-command.js +79 -18
  29. package/dist/core/commands/naruto-command.js +195 -12
  30. package/dist/core/commands/run-command.js +6 -2
  31. package/dist/core/doctor/doctor-readiness-matrix.js +34 -0
  32. package/dist/core/feature-fixtures.js +4 -0
  33. package/dist/core/fsx.js +1 -1
  34. package/dist/core/git-simple.js +143 -4
  35. package/dist/core/local-llm/local-collaboration-policy.js +93 -0
  36. package/dist/core/local-llm/local-llm-backpressure.js +20 -0
  37. package/dist/core/local-llm/local-llm-capability.js +29 -0
  38. package/dist/core/local-llm/local-llm-client.js +100 -0
  39. package/dist/core/local-llm/local-llm-config.js +20 -0
  40. package/dist/core/local-llm/local-llm-context-cache.js +21 -0
  41. package/dist/core/local-llm/local-llm-control-adapter.js +101 -0
  42. package/dist/core/local-llm/local-llm-json-repair.js +52 -0
  43. package/dist/core/local-llm/local-llm-metrics.js +42 -0
  44. package/dist/core/local-llm/local-llm-ollama-client.js +67 -0
  45. package/dist/core/local-llm/local-llm-openai-compatible-client.js +30 -0
  46. package/dist/core/local-llm/local-llm-prompt-cache.js +12 -0
  47. package/dist/core/local-llm/local-llm-scheduler.js +29 -0
  48. package/dist/core/local-llm/local-llm-schema-enforcer.js +15 -0
  49. package/dist/core/local-llm/local-llm-smoke.js +83 -0
  50. package/dist/core/local-llm/local-llm-warmup.js +20 -0
  51. package/dist/core/local-llm/local-worker-eligibility.js +27 -0
  52. package/dist/core/naruto/hardware-capacity-probe.js +36 -0
  53. package/dist/core/naruto/naruto-active-pool.js +118 -0
  54. package/dist/core/naruto/naruto-backpressure.js +13 -0
  55. package/dist/core/naruto/naruto-concurrency-governor.js +65 -0
  56. package/dist/core/naruto/naruto-finalizer.js +18 -0
  57. package/dist/core/naruto/naruto-generation-scheduler.js +18 -0
  58. package/dist/core/naruto/naruto-gpt-final-pack.js +49 -0
  59. package/dist/core/naruto/naruto-parallel-patch-apply.js +95 -0
  60. package/dist/core/naruto/naruto-patch-transaction-batch.js +42 -0
  61. package/dist/core/naruto/naruto-role-policy.js +107 -0
  62. package/dist/core/naruto/naruto-verification-dag.js +42 -0
  63. package/dist/core/naruto/naruto-verification-pool.js +18 -0
  64. package/dist/core/naruto/naruto-work-graph.js +198 -0
  65. package/dist/core/naruto/naruto-work-item.js +40 -0
  66. package/dist/core/naruto/naruto-work-stealing.js +11 -0
  67. package/dist/core/naruto/resource-pressure-monitor.js +32 -0
  68. package/dist/core/pipeline/final-gpt-patch-stage.js +31 -0
  69. package/dist/core/pipeline/final-gpt-review-stage.js +5 -0
  70. package/dist/core/pipeline/finalize-pipeline-result.js +58 -0
  71. package/dist/core/pipeline/gpt-final-required.js +12 -0
  72. package/dist/core/prompt/prompt-placeholder-guard.js +30 -0
  73. package/dist/core/router/capability-card.js +13 -0
  74. package/dist/core/router/route-cache.js +3 -0
  75. package/dist/core/router/ultra-router.js +2 -1
  76. package/dist/core/routes.js +4 -4
  77. package/dist/core/safety/mutation-guard.js +2 -0
  78. package/dist/core/update-check.js +60 -25
  79. package/dist/core/version.js +1 -1
  80. package/dist/core/zellij/zellij-lane-runtime.js +2 -2
  81. package/dist/core/zellij/zellij-naruto-dashboard.js +36 -0
  82. package/dist/core/zellij/zellij-worker-pane-manager.js +4 -4
  83. package/dist/scripts/blackbox-command-import-smoke.js +10 -1
  84. package/dist/scripts/check-package-boundary.js +12 -3
  85. package/dist/scripts/codex-0-137-compat-check.js +27 -0
  86. package/dist/scripts/codex-environment-scoped-approvals-check.js +10 -0
  87. package/dist/scripts/codex-plugin-list-json-check.js +8 -0
  88. package/dist/scripts/codex-sdk-team-naruto-agent-pipeline-check.js +2 -1
  89. package/dist/scripts/codex-thread-runtime-choice-check.js +10 -0
  90. package/dist/scripts/gpt-final-arbiter-check.js +63 -0
  91. package/dist/scripts/gpt-final-arbiter-performance-check.js +36 -0
  92. package/dist/scripts/local-collab-all-pipelines-final-gpt-check.js +21 -0
  93. package/dist/scripts/local-collab-gpt-final-availability-check.js +58 -0
  94. package/dist/scripts/local-collab-no-local-only-final-check.js +27 -0
  95. package/dist/scripts/local-collab-policy-check.js +17 -0
  96. package/dist/scripts/local-llm-all-pipelines-check.js +11 -0
  97. package/dist/scripts/local-llm-cache-performance-check.js +10 -0
  98. package/dist/scripts/local-llm-capability-check.js +14 -0
  99. package/dist/scripts/local-llm-smoke-check.js +23 -0
  100. package/dist/scripts/local-llm-structured-output-check.js +11 -0
  101. package/dist/scripts/local-llm-throughput-check.js +10 -0
  102. package/dist/scripts/local-llm-tool-call-repair-check.js +10 -0
  103. package/dist/scripts/local-llm-warmup-check.js +11 -0
  104. package/dist/scripts/naruto-active-pool-check.js +27 -0
  105. package/dist/scripts/naruto-concurrency-governor-check.js +52 -0
  106. package/dist/scripts/naruto-gpt-final-pack-check.js +34 -0
  107. package/dist/scripts/naruto-parallel-patch-apply-check.js +41 -0
  108. package/dist/scripts/naruto-real-local-gpt-final-smoke.js +16 -0
  109. package/dist/scripts/naruto-role-distribution-check.js +23 -0
  110. package/dist/scripts/naruto-shadow-clone-swarm-check.js +6 -0
  111. package/dist/scripts/naruto-verification-pool-check.js +36 -0
  112. package/dist/scripts/naruto-work-graph-check.js +24 -0
  113. package/dist/scripts/naruto-zellij-massive-ui-check.js +23 -0
  114. package/dist/scripts/prompt-placeholder-guard-check.js +33 -0
  115. package/dist/scripts/python-codex-sdk-all-pipelines-check.js +47 -0
  116. package/dist/scripts/python-codex-sdk-capability-check.js +75 -0
  117. package/dist/scripts/python-codex-sdk-sandbox-policy-check.js +10 -0
  118. package/dist/scripts/python-codex-sdk-stream-bridge-check.js +12 -0
  119. package/dist/scripts/release-parallel-check.js +1 -1
  120. package/dist/scripts/release-real-check.js +5 -0
  121. package/dist/scripts/zellij-worker-pane-manager-check.js +1 -1
  122. package/package.json +38 -4
  123. package/schemas/local-llm/local-collaboration-policy.schema.json +57 -0
  124. package/schemas/local-llm/local-model-config.schema.json +74 -0
  125. package/schemas/naruto/naruto-concurrency-governor.schema.json +21 -0
  126. package/schemas/naruto/naruto-work-graph.schema.json +22 -0
@@ -0,0 +1,107 @@
1
+ export const NARUTO_WRITE_ROLES = new Set([
2
+ 'implementer',
3
+ 'modifier',
4
+ 'test_writer',
5
+ 'conflict_resolver',
6
+ 'rollback_planner',
7
+ 'integrator'
8
+ ]);
9
+ export const NARUTO_IMPLEMENTATION_LIKE_ROLES = new Set([
10
+ 'implementer',
11
+ 'modifier',
12
+ 'test_writer',
13
+ 'conflict_resolver'
14
+ ]);
15
+ export function narutoRoleAllowsWrite(role) {
16
+ return NARUTO_WRITE_ROLES.has(role);
17
+ }
18
+ export function mapWorkKindToNarutoRole(kind) {
19
+ switch (kind) {
20
+ case 'implementation':
21
+ return 'implementer';
22
+ case 'code_modification':
23
+ case 'refactor':
24
+ case 'patch_rebase':
25
+ return 'modifier';
26
+ case 'test_generation':
27
+ return 'test_writer';
28
+ case 'test_execution':
29
+ case 'verification':
30
+ case 'ux_review':
31
+ case 'ppt_review':
32
+ case 'image_review':
33
+ return 'verifier';
34
+ case 'research':
35
+ return 'researcher';
36
+ case 'documentation':
37
+ return 'modifier';
38
+ case 'conflict_resolution':
39
+ return 'conflict_resolver';
40
+ case 'rollback_preparation':
41
+ return 'rollback_planner';
42
+ case 'integration_support':
43
+ return 'integrator';
44
+ case 'final_review_input_pack':
45
+ return 'gpt_final_arbiter';
46
+ }
47
+ }
48
+ export function mapNarutoRoleToAgentRole(role) {
49
+ switch (role) {
50
+ case 'implementer':
51
+ case 'modifier':
52
+ case 'test_writer':
53
+ return 'implementer';
54
+ case 'researcher':
55
+ return 'research';
56
+ case 'conflict_resolver':
57
+ case 'rollback_planner':
58
+ case 'integrator':
59
+ case 'gpt_final_arbiter':
60
+ return 'integrator';
61
+ case 'verifier':
62
+ return 'verifier';
63
+ }
64
+ }
65
+ export function buildNarutoRoleDistribution(workItems, opts = {}) {
66
+ const readonly = opts.readonly === true;
67
+ const counts = new Map();
68
+ const workItemRoles = workItems.map((item) => {
69
+ const role = mapWorkKindToNarutoRole(item.kind);
70
+ counts.set(role, (counts.get(role) || 0) + 1);
71
+ return {
72
+ work_item_id: item.id,
73
+ kind: item.kind,
74
+ role,
75
+ write_allowed: item.write_allowed && narutoRoleAllowsWrite(role)
76
+ };
77
+ });
78
+ const entries = [...counts.entries()].sort((a, b) => a[0].localeCompare(b[0])).map(([role, count]) => ({
79
+ role,
80
+ count,
81
+ write_allowed: narutoRoleAllowsWrite(role)
82
+ }));
83
+ const implementationLikeWorkers = workItemRoles.filter((row) => NARUTO_IMPLEMENTATION_LIKE_ROLES.has(row.role)).length;
84
+ const totalWorkers = workItems.length;
85
+ const implementationLikeRatio = totalWorkers ? implementationLikeWorkers / totalWorkers : 0;
86
+ const verifierOnly = totalWorkers > 0 && workItemRoles.every((row) => row.role === 'verifier');
87
+ const writeAllowedCount = workItemRoles.filter((row) => row.write_allowed).length;
88
+ const blockers = [
89
+ ...(totalWorkers === 0 ? ['naruto_role_distribution_empty'] : []),
90
+ ...(!readonly && verifierOnly ? ['naruto_default_must_not_be_verifier_only'] : []),
91
+ ...(!readonly && implementationLikeRatio < 0.4 ? ['naruto_write_capable_route_requires_40_percent_implementation_like_roles'] : []),
92
+ ...(!readonly && writeAllowedCount === 0 ? ['naruto_write_capable_route_requires_write_roles'] : [])
93
+ ];
94
+ return {
95
+ schema: 'sks.naruto-role-distribution.v1',
96
+ readonly,
97
+ total_workers: totalWorkers,
98
+ implementation_like_workers: implementationLikeWorkers,
99
+ implementation_like_ratio: Math.round(implementationLikeRatio * 1000) / 1000,
100
+ verifier_only: verifierOnly,
101
+ entries,
102
+ work_item_roles: workItemRoles,
103
+ ok: blockers.length === 0,
104
+ blockers
105
+ };
106
+ }
107
+ //# sourceMappingURL=naruto-role-policy.js.map
@@ -0,0 +1,42 @@
1
+ import { buildVerificationDag } from '../verification/verification-dag.js';
2
+ const NODE_KIND_CYCLE = [
3
+ 'typecheck_shard',
4
+ 'unit_test_shard',
5
+ 'route_gate_shard',
6
+ 'lint_static_scan_shard',
7
+ 'schema_validation_shard',
8
+ 'patch_specific_test_shard',
9
+ 'docs_changelog_check',
10
+ 'side_effect_check',
11
+ 'mutation_ledger_check',
12
+ 'zellij_proof_check',
13
+ 'local_llm_structured_output_check'
14
+ ];
15
+ export function buildNarutoVerificationDag(graph, input = {}) {
16
+ const command = input.command || 'node -e "process.exit(0)"';
17
+ const verifiableItems = graph.work_items.filter((item) => item.verification_required);
18
+ const taskIdByWorkItemId = new Map(verifiableItems.map((item, index) => [item.id, `NV-${String(index + 1).padStart(6, '0')}`]));
19
+ const tasks = verifiableItems
20
+ .map((item, index) => {
21
+ const kind = NODE_KIND_CYCLE[index % NODE_KIND_CYCLE.length] || 'route_gate_shard';
22
+ const taskId = taskIdByWorkItemId.get(item.id) || `NV-${String(index + 1).padStart(6, '0')}`;
23
+ return {
24
+ id: taskId,
25
+ command,
26
+ ...(input.cwd ? { cwd: input.cwd } : {}),
27
+ inputs: [...item.target_paths],
28
+ outputs: [`.sneakoscope/reports/naruto-verification/${item.id}.json`],
29
+ dependencies: item.dependencies.map((dep) => taskIdByWorkItemId.get(dep)).filter((dep) => typeof dep === 'string' && dep !== taskId),
30
+ timeout_ms: 60000,
31
+ read_only: true
32
+ };
33
+ });
34
+ const dag = buildVerificationDag(tasks);
35
+ return {
36
+ ...dag,
37
+ naruto_schema: 'sks.naruto-verification-dag.v1',
38
+ node_kinds: NODE_KIND_CYCLE,
39
+ starts_when_dependencies_ready: true
40
+ };
41
+ }
42
+ //# sourceMappingURL=naruto-verification-dag.js.map
@@ -0,0 +1,18 @@
1
+ import { runVerificationDag } from '../verification/verification-worker-pool.js';
2
+ export async function runNarutoVerificationPool(dag, governor, opts = {}) {
3
+ const safeConcurrency = Math.max(1, governor.verification_parallel);
4
+ const result = await runVerificationDag(dag, {
5
+ ...(opts.cwd ? { cwd: opts.cwd } : {}),
6
+ ...(opts.logDir ? { logDir: opts.logDir } : {}),
7
+ concurrency: safeConcurrency
8
+ });
9
+ return {
10
+ ...result,
11
+ naruto_schema: 'sks.naruto-verification-pool.v1',
12
+ safe_concurrency: safeConcurrency,
13
+ cpu_heavy_cap_respected: safeConcurrency <= Math.max(1, governor.hardware.cpu_core_count * 2),
14
+ io_heavy_cap_respected: governor.backpressure !== 'saturated',
15
+ api_rate_cap_respected: safeConcurrency <= Math.max(1, governor.remote_codex_parallel)
16
+ };
17
+ }
18
+ //# sourceMappingURL=naruto-verification-pool.js.map
@@ -0,0 +1,198 @@
1
+ import { mapWorkKindToNarutoRole } from './naruto-role-policy.js';
2
+ import { isNarutoWriteKind, normalizeNarutoPath } from './naruto-work-item.js';
3
+ const WRITE_CAPABLE_KIND_CYCLE = [
4
+ 'implementation',
5
+ 'code_modification',
6
+ 'test_generation',
7
+ 'verification',
8
+ 'research',
9
+ 'documentation',
10
+ 'refactor',
11
+ 'test_execution',
12
+ 'conflict_resolution',
13
+ 'patch_rebase',
14
+ 'rollback_preparation',
15
+ 'integration_support',
16
+ 'final_review_input_pack'
17
+ ];
18
+ const READONLY_KIND_CYCLE = [
19
+ 'verification',
20
+ 'research',
21
+ 'test_execution',
22
+ 'ux_review',
23
+ 'ppt_review',
24
+ 'image_review',
25
+ 'final_review_input_pack'
26
+ ];
27
+ export function buildNarutoWorkGraph(input = {}) {
28
+ const requestedClones = normalizePositiveInt(input.requestedClones, 12);
29
+ const readonly = input.readonly === true;
30
+ const writeCapable = input.writeCapable !== false && !readonly;
31
+ const totalWorkItems = Math.max(requestedClones, normalizePositiveInt(input.totalWorkItems, requestedClones));
32
+ const kindCycle = writeCapable ? WRITE_CAPABLE_KIND_CYCLE : READONLY_KIND_CYCLE;
33
+ const basePath = normalizeNarutoPath(input.leaseBasePath || '.sneakoscope/naruto/patch-envelopes');
34
+ const targetPaths = normalizePaths(input.targetPaths || []);
35
+ const readonlyPaths = normalizePaths(input.readonlyPaths || []);
36
+ const workItems = [];
37
+ for (let index = 0; index < totalWorkItems; index += 1) {
38
+ const id = `NW-${String(index + 1).padStart(6, '0')}`;
39
+ const kind = kindCycle[index % kindCycle.length] || 'verification';
40
+ const kindWrites = writeCapable && isNarutoWriteKind(kind);
41
+ const selectedTarget = targetPaths.length ? targetPaths[index % targetPaths.length] || targetPaths[0] || '' : `${basePath}/${id}.json`;
42
+ const writePaths = kindWrites ? [selectedTarget].filter(Boolean) : [];
43
+ const readPaths = readonlyPaths.length ? readonlyPaths : targetPaths.filter((item) => !writePaths.includes(item));
44
+ const leaseRequirements = [
45
+ ...writePaths.map((file) => ({ path: file, kind: 'write' })),
46
+ ...readPaths.map((file) => ({ path: file, kind: 'read' }))
47
+ ];
48
+ workItems.push({
49
+ id,
50
+ kind,
51
+ title: titleForKind(kind, id),
52
+ target_paths: [...new Set([...(writePaths.length ? writePaths : [selectedTarget].filter(Boolean)), ...readPaths])],
53
+ readonly_paths: readPaths,
54
+ write_paths: writePaths,
55
+ required_role: mapWorkKindToNarutoRole(kind),
56
+ write_allowed: writePaths.length > 0,
57
+ verification_required: kind !== 'research' && kind !== 'final_review_input_pack',
58
+ dependencies: dependenciesForKind(kind, workItems),
59
+ can_run_in_parallel_with: [],
60
+ conflicts_with: [],
61
+ estimated_cost: estimateCost(kind),
62
+ lease_requirements: leaseRequirements,
63
+ acceptance: {
64
+ requires_patch_envelope: writePaths.length > 0,
65
+ requires_verification: kind !== 'research' && kind !== 'final_review_input_pack',
66
+ requires_gpt_final: writePaths.length > 0 || kind === 'final_review_input_pack'
67
+ }
68
+ });
69
+ }
70
+ const activeWaves = planNarutoWorkWaves(workItems, Math.max(1, normalizePositiveInt(input.maxActiveWorkers, requestedClones)));
71
+ annotateParallelCompatibility(workItems, activeWaves);
72
+ const mixedWorkKinds = [...new Set(workItems.map((item) => item.kind))];
73
+ const writeAllowedCount = workItems.filter((item) => item.write_allowed).length;
74
+ const blockers = [
75
+ ...(mixedWorkKinds.length < 2 ? ['naruto_work_graph_not_mixed'] : []),
76
+ ...(!readonly && writeAllowedCount === 0 ? ['naruto_write_capable_graph_missing_write_items'] : []),
77
+ ...(workItems.length < requestedClones ? ['naruto_work_graph_below_requested_clones'] : []),
78
+ ...activeWaves.flatMap((wave) => wave.conflict_count > 0 ? [`naruto_wave_write_conflict:${wave.wave_id}`] : [])
79
+ ];
80
+ return {
81
+ schema: 'sks.naruto-work-graph.v1',
82
+ route: '$Naruto',
83
+ requested_clones: requestedClones,
84
+ total_work_items: workItems.length,
85
+ readonly,
86
+ write_capable: writeCapable,
87
+ work_items: workItems,
88
+ active_waves: activeWaves,
89
+ mixed_work_kinds: mixedWorkKinds,
90
+ write_allowed_count: writeAllowedCount,
91
+ ok: blockers.length === 0,
92
+ blockers
93
+ };
94
+ }
95
+ export function validateNarutoWorkGraph(graph) {
96
+ const ids = new Set();
97
+ const blockers = [...graph.blockers];
98
+ for (const item of graph.work_items) {
99
+ if (ids.has(item.id))
100
+ blockers.push(`duplicate_work_item:${item.id}`);
101
+ ids.add(item.id);
102
+ for (const dep of item.dependencies) {
103
+ if (!ids.has(dep) && !graph.work_items.some((candidate) => candidate.id === dep))
104
+ blockers.push(`missing_dependency:${item.id}:${dep}`);
105
+ }
106
+ if (item.write_allowed && item.acceptance.requires_patch_envelope !== true)
107
+ blockers.push(`write_item_missing_patch_envelope_acceptance:${item.id}`);
108
+ }
109
+ if (graph.total_work_items !== graph.work_items.length)
110
+ blockers.push('naruto_work_graph_count_mismatch');
111
+ if (!graph.readonly && graph.write_allowed_count === 0)
112
+ blockers.push('naruto_write_capable_graph_missing_write_items');
113
+ return { ok: blockers.length === 0, blockers: [...new Set(blockers)] };
114
+ }
115
+ export function planNarutoWorkWaves(items, maxActiveWorkers) {
116
+ const pending = [...items];
117
+ const waves = [];
118
+ while (pending.length) {
119
+ const waveItems = [];
120
+ const writePaths = new Set();
121
+ for (let index = 0; index < pending.length && waveItems.length < maxActiveWorkers;) {
122
+ const item = pending[index];
123
+ if (!item) {
124
+ index += 1;
125
+ continue;
126
+ }
127
+ const conflicts = item.write_paths.some((file) => writePaths.has(file));
128
+ if (conflicts) {
129
+ index += 1;
130
+ continue;
131
+ }
132
+ waveItems.push(item);
133
+ for (const file of item.write_paths)
134
+ writePaths.add(file);
135
+ pending.splice(index, 1);
136
+ }
137
+ if (!waveItems.length) {
138
+ const item = pending.shift();
139
+ if (item)
140
+ waveItems.push(item);
141
+ }
142
+ const paths = waveItems.flatMap((item) => item.write_paths);
143
+ waves.push({
144
+ wave_id: `NWAVE-${String(waves.length + 1).padStart(4, '0')}`,
145
+ work_item_ids: waveItems.map((item) => item.id),
146
+ write_paths: [...new Set(paths)],
147
+ conflict_count: paths.length - new Set(paths).size
148
+ });
149
+ }
150
+ return waves;
151
+ }
152
+ function annotateParallelCompatibility(items, waves) {
153
+ const byId = new Map(items.map((item) => [item.id, item]));
154
+ for (const wave of waves) {
155
+ for (const id of wave.work_item_ids) {
156
+ const item = byId.get(id);
157
+ if (!item)
158
+ continue;
159
+ item.can_run_in_parallel_with = wave.work_item_ids.filter((other) => other !== id);
160
+ item.conflicts_with = items
161
+ .filter((other) => other.id !== id && other.write_paths.some((file) => item.write_paths.includes(file)))
162
+ .map((other) => other.id);
163
+ }
164
+ }
165
+ }
166
+ function dependenciesForKind(kind, previous) {
167
+ if (kind === 'verification' || kind === 'test_execution') {
168
+ const candidate = [...previous].reverse().find((item) => item.write_allowed);
169
+ return candidate ? [candidate.id] : [];
170
+ }
171
+ if (kind === 'final_review_input_pack') {
172
+ return previous.slice(-3).map((item) => item.id);
173
+ }
174
+ return [];
175
+ }
176
+ function estimateCost(kind) {
177
+ const heavy = kind === 'implementation' || kind === 'code_modification' || kind === 'refactor' || kind === 'conflict_resolution';
178
+ return {
179
+ tokens: heavy ? 8000 : 3000,
180
+ latency_ms: heavy ? 90000 : 30000,
181
+ cpu_weight: kind === 'test_execution' || kind === 'verification' ? 2 : 1,
182
+ memory_mb: heavy ? 512 : 256,
183
+ gpu_weight: 0
184
+ };
185
+ }
186
+ function titleForKind(kind, id) {
187
+ return `${id} ${kind.replace(/_/g, ' ')}`;
188
+ }
189
+ function normalizePositiveInt(value, fallback) {
190
+ const parsed = Number(value);
191
+ if (!Number.isFinite(parsed) || parsed < 1)
192
+ return Math.max(1, Math.floor(fallback));
193
+ return Math.floor(parsed);
194
+ }
195
+ function normalizePaths(paths) {
196
+ return [...new Set(paths.map(normalizeNarutoPath).filter(Boolean))];
197
+ }
198
+ //# sourceMappingURL=naruto-work-graph.js.map
@@ -0,0 +1,40 @@
1
+ export const NARUTO_WORK_KINDS = [
2
+ 'implementation',
3
+ 'code_modification',
4
+ 'refactor',
5
+ 'test_generation',
6
+ 'test_execution',
7
+ 'verification',
8
+ 'research',
9
+ 'documentation',
10
+ 'ux_review',
11
+ 'ppt_review',
12
+ 'image_review',
13
+ 'conflict_resolution',
14
+ 'patch_rebase',
15
+ 'rollback_preparation',
16
+ 'integration_support',
17
+ 'final_review_input_pack'
18
+ ];
19
+ export const NARUTO_WRITE_WORK_KINDS = new Set([
20
+ 'implementation',
21
+ 'code_modification',
22
+ 'refactor',
23
+ 'test_generation',
24
+ 'documentation',
25
+ 'conflict_resolution',
26
+ 'patch_rebase',
27
+ 'rollback_preparation',
28
+ 'integration_support'
29
+ ]);
30
+ export function isNarutoWriteKind(kind) {
31
+ return NARUTO_WRITE_WORK_KINDS.has(kind);
32
+ }
33
+ export function normalizeNarutoWorkKind(value, fallback = 'verification') {
34
+ const text = String(value || '');
35
+ return NARUTO_WORK_KINDS.includes(text) ? text : fallback;
36
+ }
37
+ export function normalizeNarutoPath(value) {
38
+ return String(value || '').replace(/\\/g, '/').replace(/^\.\/+/, '').split('/').filter((part) => part && part !== '.').join('/');
39
+ }
40
+ //# sourceMappingURL=naruto-work-item.js.map
@@ -0,0 +1,11 @@
1
+ export function stealNarutoWork(queue, input = {}) {
2
+ const item = queue.shift() || null;
3
+ return {
4
+ schema: 'sks.naruto-work-stealing.v1',
5
+ stolen: Boolean(item),
6
+ work_item_id: item?.id || null,
7
+ from_queue: input.fromQueue || 'pending',
8
+ to_slot: input.toSlot || 'idle-slot'
9
+ };
10
+ }
11
+ //# sourceMappingURL=naruto-work-stealing.js.map
@@ -0,0 +1,32 @@
1
+ export function monitorNarutoResourcePressure(probe, input = {}) {
2
+ const activeWorkers = Math.max(1, Math.floor(Number(input.activeWorkers || 1)));
3
+ const zellijCap = Math.max(1, Math.floor(Number(input.zellijVisiblePaneCap || 12)));
4
+ const memoryPressure = 1 - (probe.free_memory_bytes / Math.max(1, probe.total_memory_bytes));
5
+ const cpuPressure = Math.min(1, (probe.current_load_average[0] || 0) / Math.max(1, probe.cpu_core_count));
6
+ const fdPressure = Math.min(1, (activeWorkers * 6 + probe.process_count) / Math.max(1, probe.file_descriptor_limit));
7
+ const zellijPressure = Math.min(1, probe.zellij_pane_count / zellijCap);
8
+ const diskIoPressure = probe.disk_io_pressure;
9
+ const reasons = [
10
+ ...(memoryPressure > 0.8 ? ['memory_cap'] : []),
11
+ ...(cpuPressure > 0.9 ? ['cpu_load_cap'] : []),
12
+ ...(fdPressure > 0.75 ? ['file_descriptor_budget'] : []),
13
+ ...(zellijPressure > 0.9 ? ['zellij_ui_pane_budget'] : []),
14
+ ...(diskIoPressure > 0.75 ? ['disk_io_pressure'] : [])
15
+ ];
16
+ const maxPressure = Math.max(memoryPressure, cpuPressure, fdPressure, zellijPressure, diskIoPressure);
17
+ const state = maxPressure >= 0.92 ? 'saturated' : maxPressure >= 0.72 ? 'throttled' : 'normal';
18
+ return {
19
+ schema: 'sks.naruto-resource-pressure.v1',
20
+ state,
21
+ memory_pressure: round(memoryPressure),
22
+ cpu_pressure: round(cpuPressure),
23
+ fd_pressure: round(fdPressure),
24
+ zellij_pressure: round(zellijPressure),
25
+ disk_io_pressure: round(diskIoPressure),
26
+ reasons
27
+ };
28
+ }
29
+ function round(value) {
30
+ return Math.round(Math.max(0, Math.min(1, value)) * 1000) / 1000;
31
+ }
32
+ //# sourceMappingURL=resource-pressure-monitor.js.map
@@ -0,0 +1,31 @@
1
+ export function selectFinalGptPatchSource(gptFinal, localPatchEnvelopes = []) {
2
+ const status = String(gptFinal?.result?.status || gptFinal?.status || '');
3
+ if (status === 'modified') {
4
+ return {
5
+ schema: 'sks.final-gpt-patch-stage.v1',
6
+ ok: true,
7
+ final_patch_source: 'gpt_final_arbiter',
8
+ patch_envelopes: Array.isArray(gptFinal?.result?.modified_patch_envelopes) ? gptFinal.result.modified_patch_envelopes : [],
9
+ blockers: []
10
+ };
11
+ }
12
+ if (status === 'approved') {
13
+ return {
14
+ schema: 'sks.final-gpt-patch-stage.v1',
15
+ ok: true,
16
+ final_patch_source: 'gpt_final_arbiter',
17
+ patch_envelopes: Array.isArray(gptFinal?.result?.accepted_patch_envelopes) && gptFinal.result.accepted_patch_envelopes.length
18
+ ? gptFinal.result.accepted_patch_envelopes
19
+ : localPatchEnvelopes,
20
+ blockers: []
21
+ };
22
+ }
23
+ return {
24
+ schema: 'sks.final-gpt-patch-stage.v1',
25
+ ok: false,
26
+ final_patch_source: 'blocked',
27
+ patch_envelopes: [],
28
+ blockers: ['gpt_final_not_approved']
29
+ };
30
+ }
31
+ //# sourceMappingURL=final-gpt-patch-stage.js.map
@@ -0,0 +1,5 @@
1
+ import { runGptFinalArbiter } from '../codex-control/gpt-final-arbiter.js';
2
+ export async function runFinalGptReviewStage(input, opts = {}) {
3
+ return runGptFinalArbiter(input, opts);
4
+ }
5
+ //# sourceMappingURL=final-gpt-review-stage.js.map
@@ -0,0 +1,58 @@
1
+ import path from 'node:path';
2
+ import { nowIso, writeJsonAtomic } from '../fsx.js';
3
+ import { runGptFinalArbiter } from '../codex-control/gpt-final-arbiter.js';
4
+ import { gptFinalRequiredForPipeline } from './gpt-final-required.js';
5
+ export async function finalizePipelineResult(input) {
6
+ const cwd = path.resolve(input.cwd || process.cwd());
7
+ const root = path.resolve(input.mutationLedgerRoot || path.join(cwd, '.sneakoscope', 'tmp', 'pipeline-finalize', safeName(input.missionId)));
8
+ const requirement = gptFinalRequiredForPipeline({
9
+ localParticipated: input.localParticipated,
10
+ candidateResults: input.candidateResults
11
+ });
12
+ let arbiter = null;
13
+ let blockers = [];
14
+ if (requirement.gpt_final_required) {
15
+ arbiter = await runGptFinalArbiter({
16
+ schema: 'sks.gpt-final-arbiter-input.v1',
17
+ route: input.route,
18
+ mission_id: input.missionId,
19
+ local_mode: 'local-parallel-gpt-final',
20
+ local_outputs: input.candidateResults,
21
+ candidate_patch_envelopes: input.candidatePatchEnvelopes
22
+ }, {
23
+ cwd,
24
+ mutationLedgerRoot: path.join(root, 'gpt-final-arbiter'),
25
+ ...(typeof input.forceGptFinalUnavailable === 'boolean' ? { forceUnavailable: input.forceGptFinalUnavailable } : {})
26
+ });
27
+ blockers = [
28
+ ...(arbiter.ok ? [] : ['gpt_final_arbiter_required_not_passed']),
29
+ ...(Array.isArray(arbiter.blockers) ? arbiter.blockers.map(String) : [])
30
+ ];
31
+ }
32
+ const result = {
33
+ schema: 'sks.pipeline-finalize-result.v1',
34
+ generated_at: nowIso(),
35
+ ok: blockers.length === 0,
36
+ route: input.route,
37
+ mission_id: input.missionId,
38
+ local_participated: requirement.local_participated,
39
+ gpt_final_required: requirement.gpt_final_required,
40
+ gpt_final_arbiter: arbiter,
41
+ final_status: blockers.length ? 'blocked' : 'accepted',
42
+ apply_allowed: blockers.length === 0 && input.applyPatches === true,
43
+ final_patch_source: requirement.gpt_final_required ? 'gpt_final_arbiter' : 'deterministic_finalize',
44
+ candidate_results_count: input.candidateResults.length,
45
+ candidate_patch_envelope_count: input.candidatePatchEnvelopes.length,
46
+ verification_results_count: input.verificationResults.length,
47
+ side_effect_report: input.sideEffectReport,
48
+ mutation_ledger: input.mutationLedger,
49
+ rollback_plan: input.rollbackPlan,
50
+ blockers
51
+ };
52
+ await writeJsonAtomic(path.join(root, 'pipeline-finalize-result.json'), result);
53
+ return result;
54
+ }
55
+ function safeName(value) {
56
+ return String(value || 'unknown').replace(/[^a-zA-Z0-9_.-]+/g, '-').slice(0, 80);
57
+ }
58
+ //# sourceMappingURL=finalize-pipeline-result.js.map
@@ -0,0 +1,12 @@
1
+ import { localCollaborationParticipated } from '../local-llm/local-collaboration-policy.js';
2
+ export function gptFinalRequiredForPipeline(input) {
3
+ const localParticipated = input.localParticipated === true
4
+ || localCollaborationParticipated(Array.isArray(input.candidateResults) ? input.candidateResults : []);
5
+ return {
6
+ schema: 'sks.gpt-final-required.v1',
7
+ local_participated: localParticipated,
8
+ gpt_final_required: localParticipated,
9
+ reason: localParticipated ? 'local_llm_outputs_are_drafts' : 'no_local_participation'
10
+ };
11
+ }
12
+ //# sourceMappingURL=gpt-final-required.js.map
@@ -0,0 +1,30 @@
1
+ const PLACEHOLDER_PATTERNS = [
2
+ /@filename\b/i,
3
+ /<file>/i,
4
+ /\bTODO_PATH\b/i,
5
+ /\bINSERT_PATH_HERE\b/i,
6
+ /\/path\/to\/file\b/i
7
+ ];
8
+ export function checkPromptPlaceholders(input = {}) {
9
+ const prompt = String(input.prompt || '');
10
+ const writeCapable = input.writeCapable === true;
11
+ const placeholders = PLACEHOLDER_PATTERNS
12
+ .filter((pattern) => pattern.test(prompt))
13
+ .map((pattern) => pattern.source);
14
+ const emptyTargetPaths = writeCapable && (!Array.isArray(input.targetPaths) || input.targetPaths.length === 0);
15
+ const blockers = writeCapable ? [
16
+ ...placeholders.map((placeholder) => `unresolved_prompt_placeholder:${placeholder}`),
17
+ ...(emptyTargetPaths ? ['write_capable_prompt_target_paths_empty'] : [])
18
+ ] : [];
19
+ const warnings = writeCapable ? [] : placeholders.map((placeholder) => `readonly_prompt_placeholder_warning:${placeholder}`);
20
+ return {
21
+ schema: 'sks.prompt-placeholder-guard.v1',
22
+ ok: blockers.length === 0,
23
+ write_capable: writeCapable,
24
+ placeholders,
25
+ empty_target_paths: emptyTargetPaths,
26
+ blockers,
27
+ warnings
28
+ };
29
+ }
30
+ //# sourceMappingURL=prompt-placeholder-guard.js.map
@@ -1,4 +1,17 @@
1
1
  export const DEFAULT_CAPABILITY_CARDS = [
2
+ {
3
+ id: 'local-llm-worker',
4
+ tier: 'worker',
5
+ supports_images: false,
6
+ supports_write: true,
7
+ supports_research: false,
8
+ reliability: 0.78,
9
+ latency_cost: 1,
10
+ token_cost: 0,
11
+ mutation_risk_cost: 2,
12
+ model_price_cost: 0,
13
+ queue_pressure_cost: 2
14
+ },
2
15
  {
3
16
  id: 'fast-worker',
4
17
  tier: 'worker',
@@ -8,6 +8,9 @@ export function codexRouteCacheKey(input) {
8
8
  files: input.inputFiles || [],
9
9
  images: (input.inputImages || []).length,
10
10
  sandbox: input.sandboxPolicy,
11
+ allow_local_llm: input.allowLocalLlm === true,
12
+ backend_preference: input.backendPreference || [],
13
+ local_llm_policy: input.localLlmPolicy || null,
11
14
  write_paths: input.requestedScopeContract?.write_paths || [],
12
15
  allowed_paths: input.requestedScopeContract?.allowed_paths || []
13
16
  }));
@@ -8,7 +8,8 @@ export function routeCodexTask(input, cards = DEFAULT_CAPABILITY_CARDS) {
8
8
  return { ...cached, cache_hit: true };
9
9
  const classification = classifyCodexTask(input);
10
10
  const hardFilters = [];
11
- const scored = cards.map((card) => {
11
+ const availableCards = input.allowLocalLlm === true ? cards : cards.filter((card) => card.id !== 'local-llm-worker');
12
+ const scored = availableCards.map((card) => {
12
13
  const score = scoreCapabilityCard(card, classification);
13
14
  if (score === 0)
14
15
  hardFilters.push(card.id);
@@ -371,16 +371,16 @@ export const ROUTES = [
371
371
  id: 'Naruto',
372
372
  command: '$Naruto',
373
373
  mode: 'NARUTO',
374
- route: 'shadow clone swarm (high-scale parallel agents)',
375
- description: 'Shadow Clone Swarm (影分身 / Kage Bunshin no Jutsu): fan out up to 100 parallel clone sessions on the native agent kernel for high-throughput work, with lease-based safe parallel writes, scheduler backfill, and per-clone proof.',
374
+ route: 'hardware-safe massive parallel work swarm',
375
+ description: '$Naruto mode launches a hardware-safe massive parallel work swarm. Clones may implement, modify, verify, test, research, document, and resolve conflicts according to role and lease policy; write-capable output is accepted only through patch envelopes, verification DAG, mutation guard, and GPT final arbiter.',
376
376
  requiredSkills: ['team', 'pipeline-runner', 'prompt-pipeline', 'honest-mode'],
377
377
  dollarAliases: ['$ShadowClone', '$Kagebunshin'],
378
378
  appSkillAliases: ['shadow-clone', 'kage-bunshin'],
379
- lifecycle: ['clone_roster_build', 'work_partition', 'parallel_clone_scheduling', 'lease_based_write_swarm', 'per_clone_proof', 'session_cleanup', 'honest_mode'],
379
+ lifecycle: ['clone_roster_build', 'massive_work_graph', 'hardware_safe_governor', 'dynamic_active_pool', 'lease_based_write_swarm', 'parallel_verification_dag', 'gpt_final_arbiter_pack', 'per_clone_proof', 'session_cleanup', 'honest_mode'],
380
380
  context7Policy: 'optional',
381
381
  reasoningPolicy: 'high',
382
382
  stopGate: 'team-gate.json',
383
- cliEntrypoint: 'sks naruto run "task" [--clones N] [--backend codex-exec|fake] | sks naruto status',
383
+ cliEntrypoint: 'sks naruto run "task" [--clones N] [--backend codex-sdk|fake|ollama] [--parallel-write] | sks naruto status',
384
384
  examples: ['$Naruto run sweep the codebase for TODO comments with 50 clones', '$ShadowClone --clones 100 fan out and draft tests for every module']
385
385
  },
386
386
  {