sneakoscope 3.1.12 → 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.
Files changed (38) hide show
  1. package/README.md +10 -12
  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/bin/sks.js +1 -1
  6. package/dist/commands/doctor.js +62 -32
  7. package/dist/core/agents/agent-role-config.js +12 -1
  8. package/dist/core/codex/agent-config-file-repair.js +115 -19
  9. package/dist/core/codex/codex-startup-config-postcheck.js +57 -4
  10. package/dist/core/codex-control/codex-0140-capability.js +72 -7
  11. package/dist/core/codex-control/codex-0140-feature-probes.js +174 -16
  12. package/dist/core/codex-control/codex-0140-real-probes.js +43 -3
  13. package/dist/core/codex-control/codex-0140-usage-parser.js +81 -0
  14. package/dist/core/codex-native/native-capability-postcheck.js +5 -2
  15. package/dist/core/codex-native/native-capability-repair-matrix.js +4 -4
  16. package/dist/core/config/secret-preservation.js +107 -10
  17. package/dist/core/doctor/context7-mcp-repair.js +15 -0
  18. package/dist/core/doctor/doctor-repair-postcheck.js +9 -3
  19. package/dist/core/doctor/doctor-transaction.js +98 -2
  20. package/dist/core/doctor/supabase-mcp-repair.js +36 -6
  21. package/dist/core/fsx.js +1 -1
  22. package/dist/core/loops/loop-concurrency-budget.js +22 -0
  23. package/dist/core/mcp/mcp-config-preservation.js +30 -7
  24. package/dist/core/naruto/naruto-loop-mesh.js +5 -1
  25. package/dist/core/version.js +1 -1
  26. package/dist/core/zellij/zellij-fake-adapter.js +8 -2
  27. package/dist/core/zellij/zellij-launcher.js +16 -0
  28. package/dist/scripts/codex-0140-feature-gate-lib.js +4 -2
  29. package/dist/scripts/release-3113-required-gates.js +25 -0
  30. package/package.json +11 -3
  31. package/dist/scripts/loop-directive-check-lib.js +0 -388
  32. package/dist/scripts/loop-hardening-check-lib.js +0 -289
  33. package/dist/scripts/sks-1-12-real-execution-check-lib.js +0 -27
  34. package/dist/scripts/sks-3-1-4-directive-check-lib.js +0 -212
  35. package/dist/scripts/sks-3-1-5-directive-check-lib.js +0 -318
  36. package/dist/scripts/sks-3-1-6-directive-check-lib.js +0 -522
  37. package/dist/scripts/sks-3-1-7-directive-check-lib.js +0 -58
  38. package/dist/scripts/sks-3-1-8-check-lib.js +0 -30
@@ -1,318 +0,0 @@
1
- #!/usr/bin/env node
2
- import fs from 'node:fs';
3
- import fsp from 'node:fs/promises';
4
- import os from 'node:os';
5
- import path from 'node:path';
6
- import { assertGate, emitGate, importDist, root } from './sks-1-18-gate-lib.js';
7
- const CORE_NO_TS_NOCHECK_DIRS = [
8
- 'src/core/zellij',
9
- 'src/core/doctor',
10
- 'src/core/codex-app',
11
- 'src/core/loops',
12
- 'src/core/naruto'
13
- ];
14
- const TARGET_TYPED_FILES = [
15
- 'src/core/zellij/zellij-self-heal.ts',
16
- 'src/core/zellij/homebrew-policy.ts',
17
- 'src/core/doctor/doctor-zellij-repair.ts',
18
- 'src/core/codex-app/codex-app-harness-matrix.ts',
19
- 'src/core/codex-native/codex-native-pattern-analysis.ts',
20
- 'src/core/codex-app/codex-skill-sync.ts',
21
- 'src/core/codex-app/codex-agent-role-sync.ts',
22
- 'src/core/codex-app/codex-init-deep.ts',
23
- 'src/core/codex-app/codex-hook-lifecycle.ts',
24
- 'src/core/codex-app/codex-app-execution-profile.ts',
25
- 'src/core/codex-native/codex-native-interop-policy.ts',
26
- 'src/core/loops/loop-continuation-enforcer.ts'
27
- ];
28
- export async function runDirective315Gate(id) {
29
- if (id === 'lint:no-ts-nocheck-core')
30
- return noTsNoCheckCore(id);
31
- if (id === 'codex-app:type-safety')
32
- return codexAppTypeSafety(id);
33
- if (id === 'type-surface:codex-app')
34
- return typeSurfaceCodexApp(id);
35
- if (id.startsWith('zellij:'))
36
- return zellijGate(id);
37
- if (id.startsWith('codex-app:hook-approval'))
38
- return hookApprovalGate(id);
39
- if (id.startsWith('codex-app:agent-type'))
40
- return agentTypeGate(id);
41
- if (id.includes('init-deep') || id.includes('planner-project-memory-deep'))
42
- return initDeepGate(id);
43
- if (id.includes('execution-profile-routing'))
44
- return executionProfileRoutingGate(id);
45
- if (id === 'codex-app:skill-rich-content')
46
- return richContentGate(id);
47
- if (id === 'codex-app:agent-role-rich-content')
48
- return richContentGate(id);
49
- throw new Error(`unknown_gate:${id}`);
50
- }
51
- function noTsNoCheckCore(id) {
52
- const offenders = [];
53
- for (const dir of CORE_NO_TS_NOCHECK_DIRS) {
54
- for (const file of walkTs(path.join(root, dir))) {
55
- const text = fs.readFileSync(file, 'utf8');
56
- if (/^\s*\/\/\s*@ts-nocheck\b/m.test(text))
57
- offenders.push(path.relative(root, file));
58
- }
59
- }
60
- assertGate(offenders.length === 0, 'core @ts-nocheck offenders found', { offenders });
61
- emitGate(id, { scanned_dirs: CORE_NO_TS_NOCHECK_DIRS.length });
62
- }
63
- function codexAppTypeSafety(id) {
64
- const required = [
65
- 'src/core/codex-app/codex-app-types.ts',
66
- 'src/core/zellij/zellij-self-heal-types.ts',
67
- 'src/core/codex-app/codex-hook-approval-probe.ts',
68
- 'src/core/codex-app/codex-agent-type-probe.ts',
69
- 'src/core/codex-native/codex-native-reference-source.ts'
70
- ];
71
- for (const file of [...required, ...TARGET_TYPED_FILES])
72
- assertGate(fs.existsSync(path.join(root, file)), `missing ${file}`);
73
- for (const file of TARGET_TYPED_FILES) {
74
- const text = fs.readFileSync(path.join(root, file), 'utf8');
75
- assertGate(!/^\s*\/\/\s*@ts-nocheck\b/m.test(text), `target file still has @ts-nocheck: ${file}`);
76
- }
77
- const matrix = fs.readFileSync(path.join(root, 'src/core/codex-app/codex-app-harness-matrix.ts'), 'utf8');
78
- assertGate(!/hookApprovalKnown\s*=\s*false/.test(matrix), 'harness matrix must not hardcode hook approval unknown');
79
- assertGate(!/SKS_CODEX_AGENT_TYPE_SUPPORTED\s*===\s*['"]1['"]/.test(matrix), 'harness matrix must not use env-only agent_type support');
80
- emitGate(id, { target_files: TARGET_TYPED_FILES.length });
81
- }
82
- async function typeSurfaceCodexApp(id) {
83
- const types = await importDist('core/codex-app/codex-app-types.js');
84
- const zellijTypes = await importDist('core/zellij/zellij-self-heal-types.js');
85
- const agentProbe = await importDist('core/codex-app/codex-agent-type-probe.js');
86
- const sampleMatrix = {
87
- schema: 'sks.codex-app-harness-matrix.v1',
88
- generated_at: new Date().toISOString(),
89
- ok: true,
90
- codex_cli: { available: true, version: 'codex test' },
91
- app_features: {
92
- plugin_json: true,
93
- marketplace_add: true,
94
- marketplace_upgrade: true,
95
- startup_review_detectable: true,
96
- hook_approval_state_detectable: true,
97
- hook_approval_state: 'approved',
98
- skill_picker_ready: true,
99
- agent_type_supported: true,
100
- mcp_inventory_ready: true,
101
- app_handoff_ready: true,
102
- image_path_exposure_ready: true
103
- },
104
- sks_integrations: {
105
- dollar_skills_synced: true,
106
- agent_roles_synced: true,
107
- hooks_synced: true,
108
- init_deep_available: true,
109
- loop_mesh_app_profile_available: true
110
- },
111
- probes: {},
112
- blockers: [],
113
- warnings: []
114
- };
115
- assertGate(types.isCodexAppHarnessMatrix(sampleMatrix) === true, 'CodexAppHarnessMatrix guard rejected valid sample');
116
- const normalized = zellijTypes.normalizeZellijSelfHealResult({ schema: 'sks.zellij-self-heal.v1', ok: true, requested_by: 'setup', strategy: 'none-current', before: {}, after: {}, blockers: [], warnings: [] });
117
- assertGate(normalized.dry_run === false && Array.isArray(normalized.planned_mutations), 'zellij self-heal normalizer must backfill new fields', normalized);
118
- const payload = agentProbe.agentRolePayloadFor('sks-checker', { supported: true, schema: 'sks.codex-agent-type-probe.v1' });
119
- assertGate(payload.strategy === 'agent_type' && payload.agent_type === 'sks-checker', 'agent role payload must select agent_type when supported', payload);
120
- emitGate(id, { guards: 3 });
121
- }
122
- async function zellijGate(id) {
123
- const rootDir = await tempRoot(id);
124
- const selfHeal = await importDist('core/zellij/zellij-self-heal.js');
125
- if (id === 'zellij:self-heal-status-contract') {
126
- const update = await importDist('core/zellij/zellij-update.js');
127
- const result = await update.maybePromptZellijUpdateForLaunch(['--yes'], {
128
- label: 'MAD launch',
129
- root: rootDir,
130
- selfHealOnMissing: true,
131
- allowHeadlessFallback: true,
132
- env: fakeZellijEnv('missing', { brew: false })
133
- });
134
- assertGate(result.status === 'headless_fallback', 'missing zellij with headless fallback must return headless_fallback', result);
135
- return emitGate(id, { status: result.status });
136
- }
137
- const result = await selfHeal.repairZellijForSks({
138
- root: rootDir,
139
- requestedBy: 'doctor --fix',
140
- fixRequested: true,
141
- autoApprove: true,
142
- dryRun: id.includes('dry-run') || id.includes('typed-blackbox'),
143
- installHomebrew: false,
144
- env: fakeZellijEnv('missing', { brew: true })
145
- });
146
- assertGate(result.dry_run === true, 'dry-run zellij result must set dry_run', result);
147
- assertGate(result.planned_mutations.length >= 1, 'dry-run zellij result must include planned mutations', result);
148
- assertGate(result.mutation_guard_artifact?.endsWith('#planned'), 'dry-run zellij mutation artifact must be planned-only', result);
149
- emitGate(id, { planned: result.planned_mutations.length });
150
- }
151
- async function hookApprovalGate(id) {
152
- const rootDir = await tempRoot(id);
153
- const previous = swapEnv({ SKS_CODEX_HOOK_APPROVAL_FIXTURE: id.includes('blackbox') ? 'modified' : 'approved' });
154
- try {
155
- const probe = await importDist('core/codex-app/codex-hook-approval-probe.js');
156
- const report = await probe.probeCodexHookApprovalState(rootDir);
157
- if (id.includes('blackbox')) {
158
- assertGate(report.approval_state === 'modified_requires_reapproval' && report.ok === false, 'modified hook approval must require reapproval', report);
159
- }
160
- else {
161
- assertGate(report.approval_state === 'approved' && report.detectable === true, 'fixture approved hook state must be detectable', report);
162
- }
163
- if (id === 'codex-app:hook-approval-matrix') {
164
- const matrixMod = await importDist('core/codex-app/codex-app-harness-matrix.js');
165
- const matrix = await matrixMod.buildCodexAppHarnessMatrix({ root: rootDir });
166
- assertGate(matrix.app_features.hook_approval_state === report.approval_state, 'matrix must embed hook approval probe state', matrix);
167
- assertGate(matrix.probes.hook_approval.schema === 'sks.codex-hook-approval-probe.v1', 'matrix must embed hook approval probe');
168
- }
169
- emitGate(id, { state: report.approval_state });
170
- }
171
- finally {
172
- restoreEnv(previous);
173
- }
174
- }
175
- async function agentTypeGate(id) {
176
- const rootDir = await tempRoot(id);
177
- const schema = JSON.stringify([{ name: 'spawn_agent', parameters: { properties: { agent_type: { type: 'string' } } } }]);
178
- const previous = swapEnv({ SKS_CODEX_TOOL_SCHEMA_JSON: schema });
179
- try {
180
- const probeMod = await importDist('core/codex-app/codex-agent-type-probe.js');
181
- const probe = await probeMod.probeCodexAgentTypeSupport(rootDir);
182
- assertGate(probe.supported === true && probe.source === 'codex-tool-schema', 'agent_type probe must detect schema support', probe);
183
- if (id.includes('routing') || id.includes('blackbox')) {
184
- const roleMod = await importDist('core/codex-app/codex-agent-role-sync.js');
185
- const report = await roleMod.syncCodexAgentRoles({ root: rootDir, codexHome: path.join(rootDir, 'codex-home'), apply: true });
186
- assertGate(report.fallback === 'agent_type', 'agent role sync must route to agent_type when probe supports it', report);
187
- }
188
- emitGate(id, { supported: probe.supported });
189
- }
190
- finally {
191
- restoreEnv(previous);
192
- }
193
- }
194
- async function initDeepGate(id) {
195
- const rootDir = await tempRoot(id);
196
- await fsp.mkdir(path.join(rootDir, 'src/core/zellij'), { recursive: true });
197
- for (let i = 0; i < 18; i += 1)
198
- await fsp.writeFile(path.join(rootDir, 'src/core/zellij', `f${i}.ts`), 'export {}\n');
199
- await fsp.writeFile(path.join(rootDir, 'src/core/zellij', 'AGENTS.md'), '# User local guidance\nKeep me.\n');
200
- const init = await importDist('core/codex-app/codex-init-deep.js');
201
- const report = await init.runCodexInitDeep({ root: rootDir, apply: true, directoryLocal: true });
202
- const agents = fs.readFileSync(path.join(rootDir, 'src/core/zellij', 'AGENTS.md'), 'utf8');
203
- assertGate(/BEGIN SKS INIT-DEEP MANAGED SECTION/.test(agents), 'directory AGENTS.md managed block missing', { agents });
204
- assertGate(agents.includes('Keep me.'), 'directory AGENTS.md must preserve user content', { agents });
205
- assertGate(report.directory_local_agents.backup_paths.length >= 1, 'directory AGENTS.md backup missing', report);
206
- if (id === 'loop:planner-project-memory-deep') {
207
- const planner = await importDist('core/loops/loop-planner.js');
208
- const plan = await planner.planLoopsFromRequest({ root: rootDir, missionId: 'M-memory-deep', request: 'change zellij self heal and loop planner', sourceCommand: 'loop' });
209
- assertGate(plan.graph.nodes.some((node) => Array.isArray(node.memory_hints) && node.memory_hints.length), 'loop nodes must consume deep memory hints', plan);
210
- }
211
- emitGate(id, { managed_agents: report.directory_local_agents.created.length + report.directory_local_agents.updated.length });
212
- }
213
- async function executionProfileRoutingGate(id) {
214
- const rootDir = await tempRoot(id);
215
- const previous = swapEnv({ SKS_CODEX_HOOK_APPROVAL_FIXTURE: 'approved', SKS_CODEX_AGENT_TYPE_FIXTURE: 'supported' });
216
- try {
217
- const profileMod = await importDist('core/codex-app/codex-app-execution-profile.js');
218
- const profile = await profileMod.resolveCodexAppExecutionProfile({ root: rootDir });
219
- assertGate(profile.agent_role_strategy === 'agent_type', 'execution profile must consume agent_type probe fixture', profile);
220
- if (id === 'qa-loop:execution-profile-routing' || id === 'pipeline:execution-profile-routing-blackbox') {
221
- const qa = await importDist('core/qa-loop.js');
222
- const dir = path.join(rootDir, '.sneakoscope', 'missions', 'M-qa');
223
- await fsp.mkdir(dir, { recursive: true });
224
- await qa.writeQaLoopArtifacts(dir, { id: 'M-qa', prompt: 'QA no UI' }, { sealed_hash: 'sealed', answers: { QA_SCOPE: 'api_e2e_only', TARGET_ENVIRONMENT: 'local_dev_server', DESTRUCTIVE_DEPLOYED_TESTS_ALLOWED: 'never' } });
225
- const gate = JSON.parse(fs.readFileSync(path.join(dir, 'qa-gate.json'), 'utf8'));
226
- assertGate(gate.codex_app_execution_profile?.agent_role_strategy === 'agent_type', 'QA gate must consume execution profile', gate);
227
- }
228
- if (id === 'research:execution-profile-routing' || id === 'pipeline:execution-profile-routing-blackbox') {
229
- const research = await importDist('core/research.js');
230
- const dir = path.join(rootDir, '.sneakoscope', 'missions', 'M-research');
231
- await fsp.mkdir(dir, { recursive: true });
232
- const plan = await research.writeResearchPlan(dir, 'research execution profile routing', { root: rootDir, missionId: 'M-research' });
233
- assertGate(plan.codex_app_execution_profile?.agent_role_strategy === 'agent_type', 'Research plan must consume execution profile', plan);
234
- assertGate(plan.web_research_policy.source_tool_routing, 'Research plan must include source tool routing', plan);
235
- }
236
- if (id === 'loop:execution-profile-routing' || id === 'pipeline:execution-profile-routing-blackbox') {
237
- const source = fs.readFileSync(path.join(root, 'src/core/loops/loop-worker-runtime.ts'), 'utf8');
238
- assertGate(source.includes('codex_app_execution_profile') && source.includes('SKS_CODEX_APP_EXECUTION_PROFILE'), 'Loop worker runtime must persist execution profile routing');
239
- }
240
- emitGate(id, { mode: profile.mode, strategy: profile.agent_role_strategy });
241
- }
242
- finally {
243
- restoreEnv(previous);
244
- }
245
- }
246
- async function richContentGate(id) {
247
- const rootDir = await tempRoot(id);
248
- if (id === 'codex-app:skill-rich-content') {
249
- const mod = await importDist('core/codex-app/codex-skill-sync.js');
250
- const skillsRoot = path.join(rootDir, 'skills');
251
- const report = await mod.syncCodexSksSkills({ root: rootDir, skillsRoot, apply: true });
252
- const skill = fs.readFileSync(path.join(skillsRoot, 'loop', 'SKILL.md'), 'utf8');
253
- assertGate(/Purpose:|Evidence:|Fallback:/.test(skill), 'managed skill must include rich route content', { skill, report });
254
- return emitGate(id, { skills: report.created.length });
255
- }
256
- const previous = swapEnv({ SKS_CODEX_AGENT_TYPE_FIXTURE: 'supported' });
257
- try {
258
- const mod = await importDist('core/codex-app/codex-agent-role-sync.js');
259
- const codexHome = path.join(rootDir, 'codex-home');
260
- const report = await mod.syncCodexAgentRoles({ root: rootDir, codexHome, apply: true });
261
- const role = fs.readFileSync(path.join(codexHome, 'agents', 'sks-checker.toml'), 'utf8');
262
- assertGate(/SKS managed 3\.1\.[67] directive role/.test(role) && role.includes('Execution role strategy'), 'managed agent role must include rich directive content', { role, report });
263
- emitGate(id, { roles: report.created.length });
264
- }
265
- finally {
266
- restoreEnv(previous);
267
- }
268
- }
269
- function* walkTs(dir) {
270
- if (!fs.existsSync(dir))
271
- return;
272
- for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
273
- const full = path.join(dir, entry.name);
274
- if (entry.isDirectory())
275
- yield* walkTs(full);
276
- else if (entry.isFile() && full.endsWith('.ts'))
277
- yield full;
278
- }
279
- }
280
- async function tempRoot(id) {
281
- const dir = await fsp.mkdtemp(path.join(os.tmpdir(), `sks-315-${id.replace(/[^a-z0-9]+/gi, '-')}-`));
282
- await fsp.mkdir(path.join(dir, '.sneakoscope', 'reports'), { recursive: true });
283
- return dir;
284
- }
285
- function fakeZellijEnv(status, opts = {}) {
286
- return {
287
- ...process.env,
288
- SKS_ZELLIJ_CAPABILITY_FAKE_STATUS: status,
289
- SKS_ZELLIJ_CAPABILITY_FAKE_VERSION: status === 'too_old' ? '0.40.0' : '0.44.0',
290
- SKS_ZELLIJ_SELF_HEAL_BEFORE_STATUS: status,
291
- SKS_ZELLIJ_SELF_HEAL_BEFORE_VERSION: status === 'too_old' ? '0.40.0' : '',
292
- SKS_ZELLIJ_SELF_HEAL_AFTER_STATUS: 'ok',
293
- SKS_ZELLIJ_SELF_HEAL_AFTER_VERSION: '0.44.3',
294
- SKS_ZELLIJ_LATEST_VERSION: '0.44.3',
295
- SKS_ZELLIJ_SELF_HEAL_FAKE_RUN: '1',
296
- SKS_ZELLIJ_SELF_HEAL_BREW_PRESENT: opts.brew ? '1' : '0'
297
- };
298
- }
299
- function swapEnv(next) {
300
- const previous = {};
301
- for (const [key, value] of Object.entries(next)) {
302
- previous[key] = process.env[key];
303
- if (value === '')
304
- delete process.env[key];
305
- else
306
- process.env[key] = value;
307
- }
308
- return previous;
309
- }
310
- function restoreEnv(previous) {
311
- for (const [key, value] of Object.entries(previous)) {
312
- if (value === undefined)
313
- delete process.env[key];
314
- else
315
- process.env[key] = value;
316
- }
317
- }
318
- //# sourceMappingURL=sks-3-1-5-directive-check-lib.js.map