sneakoscope 3.1.11 → 3.1.13
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.
- package/README.md +8 -7
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/bin/sks.js +1 -1
- package/dist/commands/doctor.js +161 -2
- package/dist/core/agents/agent-role-config.js +12 -1
- package/dist/core/codex/agent-config-file-repair.js +157 -0
- package/dist/core/codex/codex-startup-config-postcheck.js +83 -0
- package/dist/core/codex-control/codex-0140-capability.js +136 -0
- package/dist/core/codex-control/codex-0140-feature-probes.js +195 -0
- package/dist/core/codex-control/codex-0140-probe-runner.js +5 -0
- package/dist/core/codex-control/codex-0140-real-probe-summary.js +12 -0
- package/dist/core/codex-control/codex-0140-real-probes.js +69 -0
- package/dist/core/codex-control/codex-0140-usage-parser.js +81 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +15 -1
- package/dist/core/codex-native/native-capability-postcheck.js +5 -2
- package/dist/core/codex-native/native-capability-repair-matrix.js +4 -4
- package/dist/core/config/config-migration-journal.js +2 -0
- package/dist/core/config/secret-preservation.js +108 -11
- package/dist/core/config/supabase-secret-preservation.js +1 -0
- package/dist/core/doctor/codex-startup-config-repair.js +40 -0
- package/dist/core/doctor/context7-mcp-repair.js +77 -0
- package/dist/core/doctor/doctor-codex-startup-repair.js +127 -15
- package/dist/core/doctor/doctor-context7-repair.js +40 -1
- package/dist/core/doctor/doctor-repair-postcheck.js +17 -0
- package/dist/core/doctor/doctor-transaction.js +126 -0
- package/dist/core/doctor/supabase-mcp-repair.js +66 -0
- package/dist/core/fsx.js +1 -1
- package/dist/core/loops/loop-concurrency-budget.js +22 -0
- package/dist/core/mcp/mcp-config-preservation.js +53 -0
- package/dist/core/naruto/naruto-loop-mesh.js +5 -1
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-fake-adapter.js +8 -2
- package/dist/core/zellij/zellij-launcher.js +16 -0
- package/dist/core/zellij/zellij-worker-pane-manager.js +19 -2
- package/dist/scripts/codex-0140-feature-gate-lib.js +14 -0
- package/dist/scripts/release-3112-required-gates.js +30 -0
- package/dist/scripts/release-3113-required-gates.js +25 -0
- package/package.json +38 -2
- package/dist/.sks-build-stamp.json +0 -8
- package/dist/scripts/loop-directive-check-lib.js +0 -388
- package/dist/scripts/loop-hardening-check-lib.js +0 -289
- package/dist/scripts/sks-1-12-real-execution-check-lib.js +0 -27
- package/dist/scripts/sks-3-1-4-directive-check-lib.js +0 -212
- package/dist/scripts/sks-3-1-5-directive-check-lib.js +0 -318
- package/dist/scripts/sks-3-1-6-directive-check-lib.js +0 -522
- package/dist/scripts/sks-3-1-7-directive-check-lib.js +0 -58
- package/dist/scripts/sks-3-1-8-check-lib.js +0 -30
|
@@ -1,388 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// @ts-nocheck
|
|
3
|
-
import fs from 'node:fs/promises';
|
|
4
|
-
import os from 'node:os';
|
|
5
|
-
import path from 'node:path';
|
|
6
|
-
import { COMMANDS } from '../cli/command-registry.js';
|
|
7
|
-
import { runProcess } from '../core/fsx.js';
|
|
8
|
-
import { compileGoalToLoopPlan } from '../core/loops/goal-to-loop-compat.js';
|
|
9
|
-
import { loopGraphProofPath, loopPlanPath, loopProofPath, loopRoot, loopStatePath } from '../core/loops/loop-artifacts.js';
|
|
10
|
-
import { decomposeRequestIntoLoopDomains } from '../core/loops/loop-decomposer.js';
|
|
11
|
-
import { selectLoopGates } from '../core/loops/loop-gate-selector.js';
|
|
12
|
-
import { runLoopGates } from '../core/loops/loop-gate-runner.js';
|
|
13
|
-
import { canEscalateLoopLevel } from '../core/loops/loop-gate-ladder.js';
|
|
14
|
-
import { acquireLoopLease } from '../core/loops/loop-lease.js';
|
|
15
|
-
import { inferLoopOwnerScope } from '../core/loops/loop-owner-inference.js';
|
|
16
|
-
import { planLoopsFromRequest } from '../core/loops/loop-planner.js';
|
|
17
|
-
import { validateLoopPlan } from '../core/loops/loop-schema.js';
|
|
18
|
-
import { scheduleLoopGraph } from '../core/loops/loop-scheduler.js';
|
|
19
|
-
import { runLoopNode, runLoopPlan } from '../core/loops/loop-runtime.js';
|
|
20
|
-
import { readLoopGraphProof, summarizeLoopGraphProof } from '../core/loops/loop-observability.js';
|
|
21
|
-
import { renderLoopProofSummary } from '../core/loops/loop-proof-summary.js';
|
|
22
|
-
import { routeNarutoLoopWorker } from '../core/naruto/naruto-loop-worker-router.js';
|
|
23
|
-
import { runNarutoLoopMesh, splitActiveWorkerBudget } from '../core/naruto/naruto-loop-mesh.js';
|
|
24
|
-
import { renderZellijSlotColumnAnchor } from '../core/zellij/zellij-slot-column-anchor.js';
|
|
25
|
-
import { renderZellijSlotPane } from '../core/zellij/zellij-slot-pane-renderer.js';
|
|
26
|
-
export async function runLoopDirectiveCheck(id) {
|
|
27
|
-
const root = await fs.mkdtemp(path.join(os.tmpdir(), `sks-loop-check-${id.replace(/[^a-z0-9]+/gi, '-')}-`));
|
|
28
|
-
await fs.mkdir(path.join(root, '.sneakoscope', 'missions'), { recursive: true });
|
|
29
|
-
const missionId = `M-check-${id.replace(/[^a-z0-9]+/gi, '-')}`;
|
|
30
|
-
const request = 'fix zellij telemetry, release cache, and codex probe docs';
|
|
31
|
-
const plan = await planLoopsFromRequest({ root, missionId, request, sourceCommand: 'loop' });
|
|
32
|
-
const byId = new Map(plan.graph.nodes.map((node) => [node.loop_id, node]));
|
|
33
|
-
const realRuntimeMode = process.env.SKS_LOOP_RUNTIME_REAL === '1'
|
|
34
|
-
|| id === 'loop:runtime-real-workers'
|
|
35
|
-
|| id === 'loop:maker-checker-real'
|
|
36
|
-
|| id === 'loop:integration-finalizer-real'
|
|
37
|
-
|| id === 'loop:real-maker-checker-blackbox'
|
|
38
|
-
|| id === 'naruto:loop-mesh-real-blackbox'
|
|
39
|
-
|| id === 'goal:loop-runtime-real-blackbox';
|
|
40
|
-
if (!realRuntimeMode && process.env.SKS_LOOP_RUNTIME_FIXTURE !== '1') {
|
|
41
|
-
process.env.SKS_LOOP_RUNTIME_FIXTURE = '1';
|
|
42
|
-
}
|
|
43
|
-
const fixtureMode = process.env.SKS_LOOP_RUNTIME_FIXTURE === '1' || process.env.SKS_LOOP_GATE_FIXTURE === '1';
|
|
44
|
-
const result = await runLoopPlan({ root, plan, parallelism: 'extreme', noMutation: fixtureMode ? true : !realRuntimeMode });
|
|
45
|
-
const assertions = [];
|
|
46
|
-
const assert = (condition, message) => assertions.push({ ok: Boolean(condition), message });
|
|
47
|
-
assert(validateLoopPlan(plan).ok, 'loop plan validates');
|
|
48
|
-
assert(await exists(loopPlanPath(root, missionId)), 'loop plan artifact exists');
|
|
49
|
-
if (id === 'loop:schema') {
|
|
50
|
-
assert(plan.schema === 'sks.loop-plan.v1', 'loop plan schema present');
|
|
51
|
-
assert(plan.graph.nodes.every((node) => node.schema === 'sks.loop-node.v1'), 'loop node schemas present');
|
|
52
|
-
}
|
|
53
|
-
else if (id === 'loop:artifact-paths') {
|
|
54
|
-
assert(loopRoot(root, missionId).includes('.sneakoscope/missions'), 'artifact root layout matches directive');
|
|
55
|
-
assert(throws(() => loopRoot(root, '../../escape')), 'loop artifact root rejects mission traversal');
|
|
56
|
-
assert(throws(() => loopRoot(root, 'bad/mission')), 'loop artifact root rejects path separators in mission id');
|
|
57
|
-
assert(throws(() => loopStatePath(root, missionId, '../loop-escape')), 'loop node artifact path rejects loop traversal');
|
|
58
|
-
}
|
|
59
|
-
else if (id === 'loop:state') {
|
|
60
|
-
assert(await exists(loopStatePath(root, missionId, 'loop-zellij')), 'loop state exists');
|
|
61
|
-
}
|
|
62
|
-
else if (id === 'loop:planner') {
|
|
63
|
-
assert(byId.has('loop-integration'), 'integration loop always created');
|
|
64
|
-
assert(plan.graph.nodes.length >= 2, 'planner creates action plus integration loops');
|
|
65
|
-
assert(plan.graph.nodes.some((node) => node.route !== '$Integration' && node.maker.worker_count > 2), 'planner scales maker workers above the old hardcoded two');
|
|
66
|
-
assert(plan.graph.nodes.some((node) => node.route !== '$Integration' && node.checker.worker_count > 1), 'planner scales checker reviewers above the old hardcoded one');
|
|
67
|
-
}
|
|
68
|
-
else if (id === 'loop:decomposer') {
|
|
69
|
-
const domains = decomposeRequestIntoLoopDomains(request);
|
|
70
|
-
assert(['zellij', 'release', 'codex-control', 'docs'].every((domain) => domains.some((row) => row.id === domain)), 'multi-domain request decomposes');
|
|
71
|
-
}
|
|
72
|
-
else if (id === 'loop:risk-classifier') {
|
|
73
|
-
assert(plan.graph.nodes.some((node) => node.risk.requires_worktree), 'risk classifier marks code loops worktree-required');
|
|
74
|
-
assert(!plan.graph.nodes.some((node) => node.level === 'L3-unattended' && ['high', 'critical'].includes(node.risk.level)), 'high risk cannot be L3');
|
|
75
|
-
}
|
|
76
|
-
else if (id === 'loop:owner-inference') {
|
|
77
|
-
assert(plan.graph.nodes.every((node) => node.owner_scope), 'owner scopes inferred');
|
|
78
|
-
assert(byId.get('loop-integration')?.owner_scope.files.includes('CHANGELOG.md'), 'integration owns changelog/final proof');
|
|
79
|
-
}
|
|
80
|
-
else if (id === 'loop:scheduler') {
|
|
81
|
-
const schedule = scheduleLoopGraph(plan.graph.nodes, 'extreme');
|
|
82
|
-
assert(schedule.max_active_loops >= 2, 'independent loops can run concurrently');
|
|
83
|
-
}
|
|
84
|
-
else if (id === 'loop:runtime') {
|
|
85
|
-
assert(result.ok, 'loop runtime produces ok graph result');
|
|
86
|
-
assert(await exists(loopGraphProofPath(root, missionId)), 'graph proof exists');
|
|
87
|
-
}
|
|
88
|
-
else if (id === 'loop:fixture-safety') {
|
|
89
|
-
const runtimeSource = await fs.readFile(path.join(process.cwd(), 'src/core/loops/loop-runtime.ts'), 'utf8');
|
|
90
|
-
const workerSource = await fs.readFile(path.join(process.cwd(), 'src/core/loops/loop-worker-runtime.ts'), 'utf8');
|
|
91
|
-
assert(!/noMutation\s*\?\s*\{\s*fixture:\s*true\s*\}/.test(runtimeSource), 'noMutation must not force fixture mode');
|
|
92
|
-
assert(workerSource.includes('decideLoopFixturePolicy'), 'fixture runtime has an explicit shared test-context policy guard');
|
|
93
|
-
assert(workerSource.includes('loop_fixture_runtime_forbidden'), 'fixture runtime fails closed outside test context');
|
|
94
|
-
assert(workerSource.includes("process.env.SKS_LOOP_RUNTIME_FIXTURE === '1'"), 'fixture runtime remains opt-in through SKS_LOOP_RUNTIME_FIXTURE');
|
|
95
|
-
assert(!workerSource.includes('visualLaneCount: Math.min(4'), 'zellij visual lane count must use the configurable pane cap');
|
|
96
|
-
const negative = await productionFixtureNegativeCheck();
|
|
97
|
-
assert(negative.code === 0 && negative.stdout.includes('loop_fixture_runtime_forbidden'), 'production fixture request is blocked at runtime');
|
|
98
|
-
}
|
|
99
|
-
else if (id === 'loop:worker-runtime') {
|
|
100
|
-
const proof = await readJson(loopProofPath(root, missionId, 'loop-zellij'));
|
|
101
|
-
assert(proof.maker_result.backend === 'deterministic-fixture' || proof.maker_result.backend === 'native-agent-orchestrator', 'maker backend recorded');
|
|
102
|
-
assert(proof.checker_result.backend === 'deterministic-fixture' || proof.checker_result.backend === 'native-agent-orchestrator', 'checker backend recorded');
|
|
103
|
-
assert(proof.maker_result.runtime_proof_path, 'maker runtime proof path recorded');
|
|
104
|
-
assert(proof.checker_result.runtime_proof_path, 'checker runtime proof path recorded');
|
|
105
|
-
}
|
|
106
|
-
else if (id === 'loop:worker-prompts') {
|
|
107
|
-
const prompts = await import('../core/loops/loop-worker-prompts.js');
|
|
108
|
-
const node = byId.get('loop-zellij');
|
|
109
|
-
assert(prompts.buildLoopMakerPrompt({ plan, node }).includes('Do not mutate outside the owner scope'), 'maker prompt constrains owner scope');
|
|
110
|
-
assert(prompts.buildLoopCheckerPrompt({ plan, node, makerArtifacts: ['maker.json'] }).includes('must not mutate source files'), 'checker prompt forbids mutation');
|
|
111
|
-
assert(prompts.buildLoopCheckerPrompt({ plan, node, makerArtifacts: ['maker.json'] }).includes('fresh session'), 'checker prompt requires fresh session');
|
|
112
|
-
}
|
|
113
|
-
else if (id === 'loop:runtime-real-workers' || id === 'loop:maker-checker-real') {
|
|
114
|
-
const proof = await readJson(loopProofPath(root, missionId, 'loop-zellij'));
|
|
115
|
-
assert(proof.maker_result.artifacts.length > 0, 'maker worker runtime artifacts exist');
|
|
116
|
-
assert(proof.checker_result.artifacts.length > 0, 'checker worker runtime artifacts exist');
|
|
117
|
-
assert(!proof.maker_result.artifacts.includes('fresh-checker-session'), 'placeholder checker string is not used');
|
|
118
|
-
}
|
|
119
|
-
else if (id === 'loop:checker-freshness') {
|
|
120
|
-
const proof = await readJson(loopProofPath(root, missionId, 'loop-zellij'));
|
|
121
|
-
const checker = await readJson(proof.checker_result.checker_findings[0]);
|
|
122
|
-
assert(checker.fresh_session === true, 'checker artifact proves fresh session');
|
|
123
|
-
assert(Array.isArray(checker.reviewed_maker_artifacts), 'checker reviewed maker artifacts');
|
|
124
|
-
assert(proof.checker_result.fresh_session === true, 'loop proof records checker freshness');
|
|
125
|
-
}
|
|
126
|
-
else if (id === 'loop:gate-registry') {
|
|
127
|
-
const registry = await import('../core/loops/loop-gate-registry.js');
|
|
128
|
-
const defs = await registry.listLoopGateDefinitions(process.cwd());
|
|
129
|
-
assert(defs.some((gate) => gate.id === 'gpt:final-arbiter' && gate.source === 'builtin-pseudo'), 'gpt final pseudo gate registered');
|
|
130
|
-
assert(await registry.resolveLoopGate(process.cwd(), 'definitely:unknown') === null, 'unknown gate does not resolve');
|
|
131
|
-
}
|
|
132
|
-
else if (id === 'loop:gate-runner-real' || id === 'loop:gate-artifacts') {
|
|
133
|
-
const proof = await readJson(loopProofPath(root, missionId, 'loop-zellij'));
|
|
134
|
-
assert(proof.gate_result.selected_gates.length > 0, 'gates selected');
|
|
135
|
-
assert(proof.gate_result.passed_gates.length > 0 || proof.gate_result.failed_gates.length > 0, 'gate outcomes recorded');
|
|
136
|
-
assert(await exists(path.join(loopRoot(root, missionId), 'loop-zellij', 'gates')), 'gate artifact directory exists');
|
|
137
|
-
}
|
|
138
|
-
else if (id === 'loop:worktree-runtime') {
|
|
139
|
-
assert(await exists(path.join(loopRoot(root, missionId), 'loop-zellij', 'worktree.json')), 'worktree record exists');
|
|
140
|
-
}
|
|
141
|
-
else if (id === 'loop:worktree-diff-scope') {
|
|
142
|
-
const mod = await import('../core/loops/loop-worktree-runtime.js');
|
|
143
|
-
assert(mod.enforceLoopOwnerScope(['src/core/zellij/zellij-slot-pane-renderer.ts'], byId.get('loop-zellij').owner_scope).length === 0, 'owner-scoped file passes');
|
|
144
|
-
assert(mod.enforceLoopOwnerScope(['README.md'], byId.get('loop-zellij').owner_scope).length > 0, 'outside owner scope blocks');
|
|
145
|
-
}
|
|
146
|
-
else if (id === 'loop:integration-merge') {
|
|
147
|
-
assert(await exists(path.join(loopRoot(root, missionId), 'integration-merge.json')), 'integration merge artifact exists');
|
|
148
|
-
}
|
|
149
|
-
else if (id === 'loop:integration-finalizer-real') {
|
|
150
|
-
const graph = await readJson(loopGraphProofPath(root, missionId));
|
|
151
|
-
assert(graph.integration_merge && typeof graph.integration_merge.ok === 'boolean', 'graph proof includes integration merge');
|
|
152
|
-
}
|
|
153
|
-
else if (id === 'file-lock:atomic') {
|
|
154
|
-
const lock = await import('../core/locks/file-lock.js');
|
|
155
|
-
let count = 0;
|
|
156
|
-
await lock.withFileLock({ lockPath: path.join(root, '.sneakoscope/locks/test.lock'), timeoutMs: 1000, staleMs: 10000 }, async () => { count += 1; });
|
|
157
|
-
assert(count === 1, 'file lock executes critical section');
|
|
158
|
-
}
|
|
159
|
-
else if (id === 'loop:lease-atomic') {
|
|
160
|
-
const node = byId.get('loop-zellij');
|
|
161
|
-
const lease = await acquireLoopLease(root, plan, node);
|
|
162
|
-
assert(lease.status === 'active' || lease.status === 'conflict', 'atomic lease returns status');
|
|
163
|
-
}
|
|
164
|
-
else if (id === 'loop:gpt-final-arbiter' || id === 'loop:integration-gpt-final') {
|
|
165
|
-
const mod = await import('../core/loops/loop-gpt-final-arbiter.js');
|
|
166
|
-
const arbiter = await mod.runLoopGptFinalArbiter({ root, plan, proofs: result.proofs, integrationMerge: { schema: 'sks.loop-integration-merge.v1', ok: true, applied_loops: [], conflict_loops: [], changed_files: ['src/core/loops/loop-runtime.ts'], blockers: [] }, forceVerdict: 'approve' });
|
|
167
|
-
assert(arbiter.ok && arbiter.verdict === 'approve', 'loop GPT final arbiter can approve');
|
|
168
|
-
}
|
|
169
|
-
else if (id === 'loop:checkpoint') {
|
|
170
|
-
assert(await exists(path.join(loopRoot(root, missionId), 'loop-zellij', 'checkpoint-latest.json')), 'latest checkpoint exists');
|
|
171
|
-
}
|
|
172
|
-
else if (id === 'loop:kill-resume' || id === 'loop:cli-kill-resume') {
|
|
173
|
-
const control = await import('../core/loops/loop-runtime-control.js');
|
|
174
|
-
await control.writeLoopKillRequest(root, missionId, 'loop-zellij');
|
|
175
|
-
assert(await control.shouldKillLoop(root, missionId, 'loop-zellij'), 'kill request targets loop');
|
|
176
|
-
}
|
|
177
|
-
else if (id === 'loop:real-maker-checker-blackbox') {
|
|
178
|
-
const proof = await readJson(loopProofPath(root, missionId, 'loop-zellij'));
|
|
179
|
-
assert(proof.maker_result.worker_count > 0 && proof.checker_result.worker_count > 0, 'maker/checker worker counts recorded');
|
|
180
|
-
assert(proof.checker_result.checker_findings.length > 0, 'checker findings artifact exists');
|
|
181
|
-
}
|
|
182
|
-
else if (id === 'naruto:loop-mesh-real-blackbox') {
|
|
183
|
-
assert(plan.graph.nodes.length >= 5, 'at least four domain loops plus integration are planned');
|
|
184
|
-
assert(result.proofs.every((proof) => proof.maker_result.artifacts.length && proof.checker_result.artifacts.length), 'worker runtime artifacts exist for every loop');
|
|
185
|
-
assert(result.graph_proof.integration_merge, 'integration finalizer ran');
|
|
186
|
-
}
|
|
187
|
-
else if (id === 'goal:loop-runtime-real-blackbox') {
|
|
188
|
-
const goalPlan = await compileGoalToLoopPlan({ root, missionId: `${missionId}-goal-real`, goalText: 'fix release cache', legacyGoalOptions: {} });
|
|
189
|
-
const goalResult = await runLoopPlan({ root, plan: goalPlan, parallelism: 'balanced', noMutation: true });
|
|
190
|
-
assert(await exists(path.join(root, '.sneakoscope', 'missions', `${missionId}-goal-real`, 'goal-compat.json')), 'goal compat artifact exists');
|
|
191
|
-
assert(goalResult.proofs.some((proof) => proof.maker_result.artifacts.length), 'goal loop worker runtime artifacts exist');
|
|
192
|
-
assert(await exists(loopGraphProofPath(root, `${missionId}-goal-real`)), 'goal graph proof exists');
|
|
193
|
-
}
|
|
194
|
-
else if (id === 'loop:status-ux') {
|
|
195
|
-
assert(await exists(loopGraphProofPath(root, missionId)), 'status has graph proof source');
|
|
196
|
-
}
|
|
197
|
-
else if (id === 'loop:zellij-real-runtime-ui') {
|
|
198
|
-
assert(renderZellijSlotPane({ slotId: 'slot-003', generationIndex: 1, loopId: 'loop-zellij', loopRole: 'maker', loopGate: 'loop:test', backend: 'fixture', patchStatus: 'fixture', verifyStatus: 'pass' }).includes('fixture loop proof'), 'zellij marks fixture proof');
|
|
199
|
-
}
|
|
200
|
-
else if (id === 'loop:proof') {
|
|
201
|
-
assert(await exists(loopProofPath(root, missionId, 'loop-zellij')), 'loop proof exists');
|
|
202
|
-
}
|
|
203
|
-
else if (id === 'loop:integration-finalizer') {
|
|
204
|
-
const proof = await readJson(loopGraphProofPath(root, missionId));
|
|
205
|
-
assert(proof.gates.selected.includes('gpt:final-arbiter'), 'integration proof requires GPT final arbiter for source mutation');
|
|
206
|
-
}
|
|
207
|
-
else if (id === 'loop:gate-selector') {
|
|
208
|
-
const node = byId.get('loop-zellij');
|
|
209
|
-
const gates = selectLoopGates({ node, changedFiles: ['src/core/zellij/zellij-slot-telemetry.ts'], risk: node.risk });
|
|
210
|
-
assert(gates.local.some((gate) => gate.startsWith('zellij:')), 'zellij affected gates selected');
|
|
211
|
-
assert(!gates.local.includes('release:check'), 'full release check not selected inside domain loop');
|
|
212
|
-
}
|
|
213
|
-
else if (id === 'loop:gate-runner') {
|
|
214
|
-
const node = byId.get('loop-zellij');
|
|
215
|
-
const gates = await runLoopGates({ root, missionId, node, gates: node.gates });
|
|
216
|
-
assert(gates.skipped_gates.includes('release:check') === false, 'gate runner avoids full release check inside loop');
|
|
217
|
-
const checkerDir = path.join(root, '.sneakoscope', 'missions', missionId, 'agents', 'sessions');
|
|
218
|
-
await fs.mkdir(checkerDir, { recursive: true });
|
|
219
|
-
await fs.writeFile(path.join(checkerDir, 'checker-findings.json'), JSON.stringify({ fresh_session: true, approved: true }));
|
|
220
|
-
const checkerGate = await runLoopGates({
|
|
221
|
-
root,
|
|
222
|
-
missionId,
|
|
223
|
-
node,
|
|
224
|
-
gates: { triage: [], local: [], checker: ['loop:checker-fresh-session'], integration: [], final: [] },
|
|
225
|
-
checkerArtifacts: ['sessions/checker-findings.json']
|
|
226
|
-
});
|
|
227
|
-
assert(checkerGate.ok, 'builtin checker gate resolves mission-ledger relative artifacts');
|
|
228
|
-
const foreignChecker = path.join(path.dirname(root), `${missionId}-foreign-checker-findings.json`);
|
|
229
|
-
await fs.writeFile(foreignChecker, JSON.stringify({ fresh_session: true, approved: true }));
|
|
230
|
-
const foreignRelative = path.relative(path.join(root, '.sneakoscope', 'missions', missionId, 'agents'), foreignChecker);
|
|
231
|
-
const unsafeCheckerGate = await runLoopGates({
|
|
232
|
-
root,
|
|
233
|
-
missionId,
|
|
234
|
-
node,
|
|
235
|
-
gates: { triage: [], local: [], checker: ['loop:checker-fresh-session'], integration: [], final: [] },
|
|
236
|
-
checkerArtifacts: [foreignRelative, foreignChecker]
|
|
237
|
-
});
|
|
238
|
-
assert(!unsafeCheckerGate.ok && unsafeCheckerGate.blockers.includes('loop_checker_fresh_session_missing'), 'builtin checker gate rejects foreign absolute and traversal artifacts');
|
|
239
|
-
const repoLocalChecker = path.join(root, 'repo-local-checker-findings.json');
|
|
240
|
-
await fs.writeFile(repoLocalChecker, JSON.stringify({ fresh_session: true, approved: true }));
|
|
241
|
-
const repoLocalCheckerGate = await runLoopGates({
|
|
242
|
-
root,
|
|
243
|
-
missionId,
|
|
244
|
-
node,
|
|
245
|
-
gates: { triage: [], local: [], checker: ['loop:checker-fresh-session'], integration: [], final: [] },
|
|
246
|
-
checkerArtifacts: ['repo-local-checker-findings.json', repoLocalChecker]
|
|
247
|
-
});
|
|
248
|
-
assert(!repoLocalCheckerGate.ok && repoLocalCheckerGate.blockers.includes('loop_checker_fresh_session_missing'), 'builtin checker gate rejects repo-local non-mission artifacts');
|
|
249
|
-
const symlinkChecker = path.join(checkerDir, 'checker-findings-symlink.json');
|
|
250
|
-
await fs.symlink(repoLocalChecker, symlinkChecker);
|
|
251
|
-
const symlinkCheckerGate = await runLoopGates({
|
|
252
|
-
root,
|
|
253
|
-
missionId,
|
|
254
|
-
node,
|
|
255
|
-
gates: { triage: [], local: [], checker: ['loop:checker-fresh-session'], integration: [], final: [] },
|
|
256
|
-
checkerArtifacts: ['sessions/checker-findings-symlink.json']
|
|
257
|
-
});
|
|
258
|
-
assert(!symlinkCheckerGate.ok && symlinkCheckerGate.blockers.includes('loop_checker_fresh_session_missing'), 'builtin checker gate rejects mission-local symlinks that escape the mission root');
|
|
259
|
-
}
|
|
260
|
-
else if (id === 'loop:gate-ladder') {
|
|
261
|
-
const node = byId.get('loop-zellij');
|
|
262
|
-
const proof = await readJson(loopProofPath(root, missionId, node.loop_id));
|
|
263
|
-
assert(canEscalateLoopLevel({ node, previousProof: proof, ownerLeaseAcquired: true }).ok === false || proof.gate_result.ok, 'ladder checks proof/budget/lease');
|
|
264
|
-
}
|
|
265
|
-
else if (id === 'loop:lease' || id === 'loop:worktree-policy') {
|
|
266
|
-
const node = byId.get('loop-zellij');
|
|
267
|
-
assert(node.worktree.required === true, 'medium/high code loops require worktree');
|
|
268
|
-
const lease = await acquireLoopLease(root, plan, node);
|
|
269
|
-
assert(['active', 'conflict'].includes(lease.status), 'lease ledger writes status');
|
|
270
|
-
}
|
|
271
|
-
else if (id === 'loop:collision-blackbox') {
|
|
272
|
-
const node = { ...byId.get('loop-zellij'), owner_scope: { ...byId.get('loop-zellij').owner_scope, files: ['src/core/zellij/zellij-worker-pane-manager.ts'], exclusive: true } };
|
|
273
|
-
const first = await acquireLoopLease(root, plan, { ...node, loop_id: 'loop-a' });
|
|
274
|
-
const second = await acquireLoopLease(root, plan, { ...node, loop_id: 'loop-b' });
|
|
275
|
-
assert(first.status === 'active' && second.status === 'conflict', 'exclusive file collision blocks second loop');
|
|
276
|
-
const docsScope = inferLoopOwnerScope({ domain: { id: 'docs', dirs: ['docs'], files: ['docs/a.md'], gates: ['docs:*'] } });
|
|
277
|
-
const docsA = await acquireLoopLease(root, plan, { ...node, loop_id: 'loop-docs-a', owner_scope: docsScope });
|
|
278
|
-
const docsB = await acquireLoopLease(root, plan, { ...node, loop_id: 'loop-docs-b', owner_scope: docsScope });
|
|
279
|
-
assert(docsA.status === 'active' && docsB.status === 'active', 'docs overlap is allowed when non-exclusive');
|
|
280
|
-
}
|
|
281
|
-
else if (id === 'naruto:loop-mesh' || id === 'naruto:loop-maker-checker') {
|
|
282
|
-
const mesh = await runNarutoLoopMesh({ root, plan, parallelism: 'balanced', noMutation: fixtureMode ? true : !realRuntimeMode });
|
|
283
|
-
assert(mesh.proofs.every((proof) => proof.maker_result.worker_count > 0 && proof.checker_result.worker_count > 0), 'maker/checker artifacts exist for each loop');
|
|
284
|
-
}
|
|
285
|
-
else if (id === 'naruto:loop-worker-router') {
|
|
286
|
-
const route = routeNarutoLoopWorker(byId.get('loop-zellij'), 'maker');
|
|
287
|
-
assert(route.prompt.includes('owner files') && route.mutation_outside_owner_scope_allowed === false, 'worker prompt constrains owner scope');
|
|
288
|
-
}
|
|
289
|
-
else if (id === 'naruto:loop-mesh-blackbox') {
|
|
290
|
-
assert(['loop-zellij', 'loop-release', 'loop-codex-control', 'loop-docs', 'loop-integration'].every((loopId) => byId.has(loopId)), 'expected domain loops exist');
|
|
291
|
-
assert(splitActiveWorkerBudget(plan, 'extreme').global_active_workers === 32, 'global worker cap is governed');
|
|
292
|
-
}
|
|
293
|
-
else if (id === 'loop:cli' || id === 'loop:cli-registry') {
|
|
294
|
-
assert(Boolean(COMMANDS.loop), 'loop command is registered');
|
|
295
|
-
}
|
|
296
|
-
else if (id === 'loop:observability') {
|
|
297
|
-
assert(summarizeLoopGraphProof(await readLoopGraphProof(root, missionId)).total >= 2, 'loop graph summary is available');
|
|
298
|
-
}
|
|
299
|
-
else if (id === 'loop:zellij-ui') {
|
|
300
|
-
assert(renderZellijSlotPane({ slotId: 'slot-003', generationIndex: 1, loopId: 'loop-zellij', loopRole: 'maker', loopGate: 'zellij:slot-telemetry-live-flush' }).includes('loop-zellij'), 'slot pane shows loop id');
|
|
301
|
-
assert(renderZellijSlotColumnAnchor({ loopsTotal: 5, loopsRunning: 3, loopsBlocked: 1, loopsCompleted: 1, activeWorkers: 32 }).includes('LOOPS 5'), 'anchor shows loop summary');
|
|
302
|
-
}
|
|
303
|
-
else if (id === 'loop:proof-summary-cli') {
|
|
304
|
-
assert(renderLoopProofSummary(await readJson(loopGraphProofPath(root, missionId))).includes('Loop graph:'), 'proof summary renders');
|
|
305
|
-
}
|
|
306
|
-
else if (id === 'goal:loop-compat' || id === 'goal:artifact-compat') {
|
|
307
|
-
const goalPlan = await compileGoalToLoopPlan({ root, missionId: `${missionId}-goal`, goalText: 'fix release cache', legacyGoalOptions: {} });
|
|
308
|
-
assert(goalPlan.compatibility.source_command === 'goal', 'goal compiles to loop plan');
|
|
309
|
-
assert(await exists(path.join(root, '.sneakoscope', 'missions', `${missionId}-goal`, 'goal-compat.json')), 'goal compat artifact exists');
|
|
310
|
-
}
|
|
311
|
-
else if (id === 'goal:loop-runtime-default' || id === 'goal:legacy-runtime-escape') {
|
|
312
|
-
assert(await exists('../src/core/commands/goal-command.ts') || true, 'goal command has loop runtime default and legacy escape wiring');
|
|
313
|
-
}
|
|
314
|
-
else if (id === 'docs:loop-runtime') {
|
|
315
|
-
const docs = await Promise.all(['docs/loop-runtime.md', 'docs/naruto-loop-mesh.md', 'docs/loop-gate-selector.md', 'docs/goal-to-loop-migration.md'].map((file) => fs.readFile(path.join(process.cwd(), file), 'utf8')));
|
|
316
|
-
assert(docs.every((text) => text.includes('Loop Graph') || text.includes('loop graph')), 'loop docs mention loop graph');
|
|
317
|
-
}
|
|
318
|
-
const failed = assertions.filter((row) => !row.ok);
|
|
319
|
-
const report = { schema: 'sks.loop-directive-check.v1', id, ok: failed.length === 0, assertions, root };
|
|
320
|
-
console.log(JSON.stringify(report, null, 2));
|
|
321
|
-
if (failed.length)
|
|
322
|
-
process.exitCode = 1;
|
|
323
|
-
}
|
|
324
|
-
async function exists(file) {
|
|
325
|
-
try {
|
|
326
|
-
await fs.access(file);
|
|
327
|
-
return true;
|
|
328
|
-
}
|
|
329
|
-
catch {
|
|
330
|
-
return false;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
function throws(fn) {
|
|
334
|
-
try {
|
|
335
|
-
fn();
|
|
336
|
-
return false;
|
|
337
|
-
}
|
|
338
|
-
catch {
|
|
339
|
-
return true;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
async function readJson(file) {
|
|
343
|
-
return JSON.parse(await fs.readFile(file, 'utf8'));
|
|
344
|
-
}
|
|
345
|
-
async function productionFixtureNegativeCheck() {
|
|
346
|
-
const code = `
|
|
347
|
-
import { runLoopMakerWorkers } from './dist/core/loops/loop-worker-runtime.js';
|
|
348
|
-
const node = {
|
|
349
|
-
mission_id: 'M-production-fixture-negative',
|
|
350
|
-
loop_id: 'loop-production-fixture-negative',
|
|
351
|
-
owner_scope: { files: ['README.md'], directories: [], package_scripts: [], release_gate_ids: [], exclusive: true, collision_policy: 'handoff' },
|
|
352
|
-
maker: { worker_count: 1 },
|
|
353
|
-
checker: { worker_count: 1 },
|
|
354
|
-
risk: { requires_gpt_final: false },
|
|
355
|
-
worktree: { required: false }
|
|
356
|
-
};
|
|
357
|
-
const plan = { mission_id: 'M-production-fixture-negative' };
|
|
358
|
-
try {
|
|
359
|
-
await runLoopMakerWorkers({ root: process.cwd(), plan, node, fixture: true });
|
|
360
|
-
console.error('fixture unexpectedly allowed outside test context');
|
|
361
|
-
process.exit(1);
|
|
362
|
-
} catch (err) {
|
|
363
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
364
|
-
if (!message.includes('loop_fixture_runtime_forbidden')) {
|
|
365
|
-
console.error(message);
|
|
366
|
-
process.exit(2);
|
|
367
|
-
}
|
|
368
|
-
console.log(message);
|
|
369
|
-
}
|
|
370
|
-
`;
|
|
371
|
-
return runProcess('/usr/bin/env', [
|
|
372
|
-
'-u', 'NODE_ENV',
|
|
373
|
-
'-u', 'SKS_TEST_RUNTIME_FIXTURE_ALLOWED',
|
|
374
|
-
'-u', 'VITEST_WORKER_ID',
|
|
375
|
-
'-u', 'JEST_WORKER_ID',
|
|
376
|
-
'-u', 'NODE_V8_COVERAGE',
|
|
377
|
-
'SKS_LOOP_RUNTIME_FIXTURE=1',
|
|
378
|
-
process.execPath,
|
|
379
|
-
'--input-type=module',
|
|
380
|
-
'-e',
|
|
381
|
-
code
|
|
382
|
-
], {
|
|
383
|
-
cwd: process.cwd(),
|
|
384
|
-
timeoutMs: 30000,
|
|
385
|
-
maxOutputBytes: 8192
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
//# sourceMappingURL=loop-directive-check-lib.js.map
|