sneakoscope 0.6.85 → 0.6.87

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 CHANGED
@@ -215,6 +215,8 @@ sks gx init homepage
215
215
  sks gx render homepage --format html
216
216
  sks validate-artifacts latest --json
217
217
  sks perf run --json
218
+ sks perf workflow --json --intent "small CLI change" --changed src/cli/main.mjs,src/core/routes.mjs
219
+ sks proof-field scan --json --intent "small CLI change"
218
220
  sks code-structure scan --json
219
221
  ```
220
222
 
@@ -274,7 +276,7 @@ Use these inside Codex App or another agent prompt. They are prompt commands, no
274
276
  | `$Research` | You need frontier-style research with hypotheses and falsification. |
275
277
  | `$AutoResearch` | You want iterative improve/test/keep-or-discard optimization. |
276
278
  | `$DB` | You need database, Supabase, migration, SQL, or MCP safety checks. |
277
- | `$MAD-SKS` | You explicitly authorize a scoped high-risk DB permission modifier for the active invocation only. |
279
+ | `$MAD-SKS` | You explicitly authorize scoped Supabase MCP DB cleanup/write permissions for the active invocation only, while keeping catastrophic wipe safeguards. |
278
280
  | `$GX` | You need deterministic visual context cartridges. |
279
281
  | `$Wiki` | You want TriWiki refresh, pack, prune, validate, or maintenance. |
280
282
  | `$Help` | You want installed command and workflow explanation. |
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sneakoscope",
3
3
  "displayName": "ㅅㅋㅅ",
4
- "version": "0.6.85",
4
+ "version": "0.6.87",
5
5
  "description": "Sneakoscope Codex: database-safe Codex CLI/App harness with Team, Goal, AutoResearch, TriWiki, and Honest Mode.",
6
6
  "type": "module",
7
7
  "homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
package/src/cli/main.mjs CHANGED
@@ -14,7 +14,7 @@ import { containsUserQuestion, noQuestionContinuationReason } from '../core/no-q
14
14
  import { evaluateDoneGate, defaultDoneGate } from '../core/hproof.mjs';
15
15
  import { emitHook } from '../core/hooks-runtime.mjs';
16
16
  import { storageReport, enforceRetention, pruneWikiArtifacts } from '../core/retention.mjs';
17
- import { classifySql, classifyCommand, loadDbSafetyPolicy, safeSupabaseMcpConfig, checkSqlFile, checkDbOperation, scanDbSafety, handleMadSksUserConfirmation } from '../core/db-safety.mjs';
17
+ import { classifySql, classifyCommand, checkDbOperation, handleMadSksUserConfirmation } from '../core/db-safety.mjs';
18
18
  import { checkHarnessModification, harnessGuardStatus, isHarnessSourceProject } from '../core/harness-guard.mjs';
19
19
  import { formatHarnessConflictReport, llmHarnessCleanupPrompt, scanHarnessConflicts } from '../core/harness-conflicts.mjs';
20
20
  import { context7Docs, context7Resolve, context7Text, context7Tools } from '../core/context7-client.mjs';
@@ -36,6 +36,8 @@ import { buildFromChatImgVisualMap } from '../core/from-chat-img-forensics.mjs';
36
36
  import { classifyDogfoodFinding, createDogfoodReport, writeDogfoodReport } from '../core/dogfood-loop.mjs';
37
37
  import { createSkillCandidate, decideSkillInjection, writeSkillCandidate, writeSkillForgeReport, writeSkillInjectionDecision } from '../core/skill-forge.mjs';
38
38
  import { classifyToolError, harnessGrowthReport } from '../core/evaluation.mjs';
39
+ import { runWorkflowPerfBench, validateWorkflowPerfReport } from '../core/perf-bench.mjs';
40
+ import { proofFieldFixture, validateProofFieldReport } from '../core/proof-field.mjs';
39
41
  import { recordMistake, writeMistakeMemoryReport } from '../core/mistake-memory.mjs';
40
42
  import { buildPromptContext } from '../core/prompt-context-builder.mjs';
41
43
  import { renderTeamDashboardState, writeTeamDashboardState } from '../core/team-dashboard-renderer.mjs';
@@ -43,11 +45,10 @@ import { GOAL_WORKFLOW_ARTIFACT } from '../core/goal-workflow.mjs';
43
45
  import { CODEX_APP_DOCS_URL, codexAppIntegrationStatus, formatCodexAppStatus } from '../core/codex-app.mjs';
44
46
  import { buildWarpLaunchConfigYaml, buildWarpLaunchPlan, buildWarpOpenArgs, runWarpLaunchConfigSyntaxCheck, warpReadiness, warpStatusKind, defaultWarpWorkspaceName, formatWarpBanner, launchWarpTeamView, launchWarpUi, platformWarpInstallHint, runWarpStatus, sanitizeWarpWorkspaceName, teamLaneStyle, writeWarpLaunchConfig } from '../core/warp-ui.mjs';
45
47
  import { autoReviewProfileName, autoReviewStatus, autoReviewSummary, enableAutoReview, disableAutoReview, enableMadHighProfile, madHighProfileName } from '../core/auto-review.mjs';
46
- import { buildTeamPlan, codeStructureCommand, defaultBeta, defaultVGraph, evalCommand, gcCommand, goalCommand, gxCommand, harnessCommand, hproofCommand, memoryCommand, migrateWikiContextPack, parseTeamCreateArgs, perfCommand, profileCommand, projectWikiClaims, qaLoopCommand, researchCommand, statsCommand, team, teamWorkflowMarkdown, validateArtifactsCommand, wikiCommand, wikiVoxelRowCount, writeWikiContextPack } from './maintenance-commands.mjs';
48
+ import { buildTeamPlan, codeStructureCommand, dbCommand, defaultBeta, defaultVGraph, evalCommand, gcCommand, goalCommand, gxCommand, harnessCommand, hproofCommand, memoryCommand, migrateWikiContextPack, parseTeamCreateArgs, perfCommand, profileCommand, projectWikiClaims, proofFieldCommand, qaLoopCommand, quickstartCommand, researchCommand, statsCommand, team, teamWorkflowMarkdown, validateArtifactsCommand, wikiCommand, wikiVoxelRowCount, writeWikiContextPack } from './maintenance-commands.mjs';
47
49
 
48
50
  const flag = (args, name) => args.includes(name);
49
51
  const promptOf = (args) => args.filter((x) => !String(x).startsWith('--')).join(' ').trim();
50
- const REPOSITORY_URL = 'https://github.com/mandarange/Sneakoscope-Codex.git';
51
52
  const REFLECTION_ARTIFACT = 'reflection.md';
52
53
  const REFLECTION_GATE = 'reflection-gate.json';
53
54
  const TEAM_SESSION_CLEANUP_ARTIFACT = 'team-session-cleanup.json';
@@ -76,7 +77,7 @@ export async function main(args) {
76
77
  if (cmd === 'commands') return commands(tail);
77
78
  if (cmd === 'usage') return usage(tail);
78
79
  if (cmd === 'root') return rootCommand(tail);
79
- if (cmd === 'quickstart') return quickstart();
80
+ if (cmd === 'quickstart') return quickstartCommand();
80
81
  if (cmd === 'codex-app') return codexAppHelp(tail);
81
82
  if (cmd === 'bootstrap') return bootstrap(tail);
82
83
  if (cmd === 'deps') return deps(sub, rest);
@@ -102,11 +103,12 @@ export async function main(args) {
102
103
  if (cmd === 'hproof') return hproofCommand(sub, rest);
103
104
  if (cmd === 'validate-artifacts') return validateArtifactsCommand(tail);
104
105
  if (cmd === 'perf') return perfCommand(sub, rest);
106
+ if (cmd === 'proof-field') return proofFieldCommand(sub, rest);
105
107
  if (cmd === 'code-structure') return codeStructureCommand(sub, rest);
106
108
  if (cmd === 'memory') return memoryCommand(sub, rest);
107
109
  if (cmd === 'gx') return gxCommand(sub, rest);
108
110
  if (cmd === 'team') return team(tail);
109
- if (cmd === 'db') return db(sub, rest);
111
+ if (cmd === 'db') return dbCommand(sub, rest);
110
112
  if (cmd === 'eval') return evalCommand(sub, rest);
111
113
  if (cmd === 'harness') return harnessCommand(sub, rest);
112
114
  if (cmd === 'wiki') return wikiCommand(sub, rest);
@@ -178,7 +180,8 @@ Usage:
178
180
  sks validate-artifacts [mission-id|latest] [--json]
179
181
  sks eval run [--json] [--out report.json]
180
182
  sks eval compare --baseline old.json --candidate new.json [--json]
181
- sks perf run [--json]
183
+ sks perf run|workflow [--json] [--intent "task"] [--changed file1,file2]
184
+ sks proof-field scan [--json] [--intent "task"]
182
185
  sks harness fixture [--json]
183
186
  sks code-structure scan [--json]
184
187
  sks wiki coords --rgba 12,34,56,255
@@ -812,15 +815,16 @@ async function materializeAfterPipelineAnswer(root, id, dir, mission, route, rou
812
815
  passed: false,
813
816
  mad_sks_permission_active: true,
814
817
  permissions_deactivated: false,
815
- table_delete_confirmation_required: true,
816
- table_delete_confirmation_timeout_ms: 30000,
818
+ supabase_mcp_schema_cleanup_allowed: true,
819
+ direct_execute_sql_allowed: true,
820
+ catastrophic_safety_guard_active: true,
817
821
  contract_hash: contract.sealed_hash || null
818
822
  });
819
823
  await appendJsonlBounded(path.join(dir, 'events.jsonl'), {
820
824
  ts: nowIso(),
821
825
  type: 'mad_sks.scoped_permission_opened',
822
826
  route: route.id,
823
- table_delete_confirmation_timeout_ms: 30000
827
+ catastrophic_safety_guard_active: true
824
828
  });
825
829
  return {
826
830
  phase: 'MADSKS_SCOPED_PERMISSION_ACTIVE',
@@ -830,7 +834,9 @@ async function materializeAfterPipelineAnswer(root, id, dir, mission, route, rou
830
834
  mad_sks_modifier: true,
831
835
  mad_sks_gate_file: 'mad-sks-gate.json',
832
836
  mad_sks_gate_ready: true,
833
- table_delete_confirmation_timeout_ms: 30000
837
+ supabase_mcp_schema_cleanup_allowed: true,
838
+ direct_execute_sql_allowed: true,
839
+ catastrophic_safety_guard_active: true
834
840
  }
835
841
  };
836
842
  }
@@ -901,8 +907,9 @@ async function materializeMadSksAuthorization(dir, id, route, routeContext = {},
901
907
  status: 'active',
902
908
  active_only_for_current_route: true,
903
909
  deactivates_when_gate_passed: gateFile,
904
- table_delete_confirmation_required: true,
905
- table_delete_confirmation_timeout_ms: 30000,
910
+ supabase_mcp_schema_cleanup_allowed: true,
911
+ direct_execute_sql_allowed: true,
912
+ catastrophic_safety_guard_active: true,
906
913
  contract_hash: contract.sealed_hash || null
907
914
  };
908
915
  await writeJsonAtomic(path.join(dir, 'mad-sks-authorization.json'), artifact);
@@ -911,13 +918,15 @@ async function materializeMadSksAuthorization(dir, id, route, routeContext = {},
911
918
  type: 'mad_sks.modifier_authorization_opened',
912
919
  route: route?.id || null,
913
920
  gate: gateFile,
914
- table_delete_confirmation_timeout_ms: 30000
921
+ catastrophic_safety_guard_active: true
915
922
  });
916
923
  return {
917
924
  mad_sks_active: true,
918
925
  mad_sks_modifier: true,
919
926
  mad_sks_gate_file: gateFile,
920
- table_delete_confirmation_timeout_ms: 30000
927
+ supabase_mcp_schema_cleanup_allowed: true,
928
+ direct_execute_sql_allowed: true,
929
+ catastrophic_safety_guard_active: true
921
930
  };
922
931
  }
923
932
 
@@ -1346,60 +1355,6 @@ async function autoReviewCommand(sub = 'status', args = []) {
1346
1355
  process.exitCode = 1;
1347
1356
  }
1348
1357
 
1349
- function quickstart() {
1350
- console.log(`ㅅㅋㅅ Quickstart
1351
-
1352
- First install and bootstrap this project:
1353
- npm i -g sneakoscope
1354
- sks root
1355
- sks bootstrap
1356
- sks
1357
-
1358
- Use outside a project:
1359
- sks root
1360
- sks deps check
1361
- sks team "global mission"
1362
-
1363
- If warp is missing:
1364
- sks deps install warp
1365
-
1366
- Initialize this project for CLI and Codex App:
1367
- sks setup --bootstrap
1368
-
1369
- Open from terminal:
1370
- sks
1371
- sks --auto-review --high
1372
- sks auto-review start --high
1373
-
1374
- Verify:
1375
- sks deps check
1376
- sks codex-app check
1377
- sks warp check
1378
- sks auto-review status
1379
- sks doctor --fix
1380
- sks context7 check
1381
- sks selftest --mock
1382
- sks commands
1383
- sks dollar-commands
1384
-
1385
- If hooks cannot find the command:
1386
- sks fix-path
1387
-
1388
- Project-only install:
1389
- npm i -D sneakoscope
1390
- npx sks setup --install-scope project
1391
-
1392
- Local-only install artifacts:
1393
- sks setup --local-only
1394
- # writes generated SKS files but excludes .sneakoscope/, .codex/, .agents/, AGENTS.md through .git/info/exclude
1395
- # user-owned AGENTS.md is preserved; an existing SKS managed block is refreshed
1396
-
1397
- GitHub install for unreleased commits:
1398
- npm i -g git+${REPOSITORY_URL}
1399
- sks bootstrap
1400
- `);
1401
- }
1402
-
1403
1358
  async function codexAppHelp(args = []) {
1404
1359
  const action = args[0] || 'help';
1405
1360
  if (action === 'check' || action === 'status') {
@@ -2904,17 +2859,17 @@ async function selftest() {
2904
2859
  const madMission = await createMission(tmp, { mode: 'mad-sks', prompt: '$MAD-SKS selftest scoped DB override' });
2905
2860
  await writeJsonAtomic(path.join(madMission.dir, 'team-gate.json'), { schema_version: 1, passed: false, team_roster_confirmed: true });
2906
2861
  const madState = { mission_id: madMission.id, mode: 'TEAM', route_command: '$Team', stop_gate: 'team-gate.json', mad_sks_active: true, mad_sks_modifier: true, mad_sks_gate_file: 'team-gate.json' };
2862
+ const columnCleanupSql = 'alter table users ' + 'dr' + 'op column legacy_name;';
2863
+ const madColumnCleanupDecision = await checkDbOperation(tmp, madState, { tool_name: 'mcp__supabase__execute_sql', sql: columnCleanupSql }, { duringNoQuestion: false });
2864
+ if (madColumnCleanupDecision.action !== 'allow') throw new Error('selftest failed: MAD-SKS column cleanup was not allowed');
2907
2865
  const tableRemovalSql = 'dr' + 'op table users;';
2908
- const madNeedsConfirmation = await checkDbOperation(tmp, madState, { tool_name: 'mcp__supabase__execute_sql', sql: tableRemovalSql }, { duringNoQuestion: false });
2909
- if (madNeedsConfirmation.action !== 'confirm') throw new Error('selftest failed: MAD-SKS table deletion did not require confirmation');
2910
- await setCurrent(tmp, madState);
2911
- const madConfirmation = await handleMadSksUserConfirmation(tmp, madState, 'yes');
2912
- if (!madConfirmation?.handled) throw new Error('selftest failed: MAD-SKS confirmation was not accepted');
2913
- const madConfirmedState = await readJson(stateFile(tmp), {});
2914
- const madConfirmedDecision = await checkDbOperation(tmp, madConfirmedState, { tool_name: 'mcp__supabase__execute_sql', sql: tableRemovalSql }, { duringNoQuestion: false });
2915
- if (madConfirmedDecision.action !== 'allow') throw new Error('selftest failed: MAD-SKS confirmed table deletion was not allowed in the short confirmation window');
2866
+ const madTableRemovalDecision = await checkDbOperation(tmp, madState, { tool_name: 'mcp__supabase__execute_sql', sql: tableRemovalSql }, { duringNoQuestion: false });
2867
+ if (madTableRemovalDecision.action !== 'block') throw new Error('selftest failed: MAD-SKS catastrophic table removal was not blocked');
2868
+ const allRowsSql = 'de' + 'lete from users;';
2869
+ const madAllRowsDecision = await checkDbOperation(tmp, madState, { tool_name: 'mcp__supabase__execute_sql', sql: allRowsSql }, { duringNoQuestion: false });
2870
+ if (madAllRowsDecision.action !== 'block') throw new Error('selftest failed: MAD-SKS all-row DML was not blocked');
2916
2871
  await writeJsonAtomic(path.join(madMission.dir, 'team-gate.json'), { schema_version: 1, passed: true, team_roster_confirmed: true, permissions_deactivated: true });
2917
- const madClosedDecision = await checkDbOperation(tmp, madConfirmedState, { tool_name: 'mcp__supabase__execute_sql', sql: tableRemovalSql }, { duringNoQuestion: false });
2872
+ const madClosedDecision = await checkDbOperation(tmp, madState, { tool_name: 'mcp__supabase__execute_sql', sql: columnCleanupSql }, { duringNoQuestion: false });
2918
2873
  if (madClosedDecision.action !== 'block') throw new Error('selftest failed: MAD-SKS permission persisted after gate close');
2919
2874
  const nonDbDecision = await checkDbOperation(tmp, {}, { command: 'npm test' }, { duringNoQuestion: true });
2920
2875
  if (nonDbDecision.action !== 'allow') throw new Error('selftest failed: non-DB command blocked by DB guard');
@@ -2924,6 +2879,15 @@ async function selftest() {
2924
2879
  if (evalReport.candidate.wiki?.voxel_schema !== 'sks.wiki-voxel.v1' || evalReport.candidate.wiki?.voxel_rows < 1) throw new Error('selftest failed: eval did not include voxel overlay metrics');
2925
2880
  const harnessReport = harnessGrowthReport({});
2926
2881
  if (!harnessReport.forgetting.fixture.passed || !harnessReport.warp.views.includes('Harness Experiments View') || !harnessReport.reliability.tool_error_taxonomy.includes('Unknown')) throw new Error('selftest failed: harness growth fixture incomplete');
2882
+ const proofField = await proofFieldFixture();
2883
+ if (!proofField.validation.ok || !validateProofFieldReport(proofField.report).ok) throw new Error('selftest failed: proof field report invalid');
2884
+ if (!proofField.checks.route_cone_selected || !proofField.checks.cli_cone_selected || !proofField.checks.catastrophic_guard_present || !proofField.checks.negative_release_work_recorded) throw new Error('selftest failed: proof field fixture checks incomplete');
2885
+ const workflowPerf = await runWorkflowPerfBench(tmp, {
2886
+ iterations: 2,
2887
+ intent: 'small CLI help surface update',
2888
+ changedFiles: ['src/cli/maintenance-commands.mjs', 'src/core/routes.mjs']
2889
+ });
2890
+ if (!validateWorkflowPerfReport(workflowPerf).ok || workflowPerf.metrics.decision_mode !== 'fast_lane' || !workflowPerf.metrics.fast_lane_eligible) throw new Error('selftest failed: workflow perf proof field did not produce a valid fast lane report');
2927
2891
  if (classifyToolError({ message: 'operation timed out' }) !== 'Timeout' || classifyToolError({ message: 'unclassified weirdness' }) !== 'Unknown') throw new Error('selftest failed: tool error taxonomy classification');
2928
2892
  const coord = rgbaToWikiCoord({ r: 12, g: 34, b: 56, a: 255 });
2929
2893
  if (coord.schema !== 'sks.wiki-coordinate.v1' || coord.xyzw.length !== 4) throw new Error('selftest failed: RGBA wiki coordinate conversion');
@@ -2995,49 +2959,3 @@ async function selftest() {
2995
2959
  console.log('ㅅㅋㅅ selftest passed.');
2996
2960
  console.log(`temp: ${tmp}`);
2997
2961
  }
2998
-
2999
- async function db(sub, args) {
3000
- const root = await sksRoot();
3001
- if (sub === 'policy') {
3002
- console.log(JSON.stringify(await loadDbSafetyPolicy(root), null, 2));
3003
- return;
3004
- }
3005
- if (sub === 'scan') {
3006
- const report = await scanDbSafety(root, { includeMigrations: flag(args, '--migrations') });
3007
- console.log(JSON.stringify(report, null, 2));
3008
- process.exitCode = report.ok ? 0 : 2;
3009
- return;
3010
- }
3011
- if (sub === 'mcp-config') {
3012
- const projectIdx = args.indexOf('--project-ref');
3013
- const featuresIdx = args.indexOf('--features');
3014
- const projectRef = projectIdx >= 0 ? args[projectIdx + 1] : '<project_ref>';
3015
- const features = featuresIdx >= 0 ? args[featuresIdx + 1] : 'database,docs';
3016
- console.log(JSON.stringify(safeSupabaseMcpConfig({ projectRef, readOnly: true, features }), null, 2));
3017
- return;
3018
- }
3019
- if (sub === 'classify' || sub === 'check') {
3020
- const sqlIdx = args.indexOf('--sql');
3021
- const commandIdx = args.indexOf('--command');
3022
- const fileIdx = args.indexOf('--file');
3023
- let result;
3024
- if (fileIdx >= 0 && args[fileIdx + 1]) result = await checkSqlFile(path.resolve(args[fileIdx + 1]));
3025
- else if (commandIdx >= 0 && args[commandIdx + 1]) result = classifyCommand(args[commandIdx + 1]);
3026
- else if (sqlIdx >= 0 && args[sqlIdx + 1]) result = classifySql(args[sqlIdx + 1]);
3027
- else if (sub === 'check' && args[0]) result = await checkSqlFile(path.resolve(args[0]));
3028
- else result = classifySql(args.join(' ').trim());
3029
- console.log(JSON.stringify(result, null, 2));
3030
- process.exitCode = ['destructive', 'write', 'possible_db'].includes(result.level) ? 2 : 0;
3031
- return;
3032
- }
3033
- if (sub === 'scan-payload') {
3034
- const raw = await fsp.readFile(0, 'utf8');
3035
- const payload = raw.trim() ? JSON.parse(raw) : {};
3036
- const decision = await checkDbOperation(root, {}, payload, { duringNoQuestion: false });
3037
- console.log(JSON.stringify(decision, null, 2));
3038
- process.exitCode = decision.action === 'block' ? 2 : 0;
3039
- return;
3040
- }
3041
- console.error('Usage: sks db policy | db scan [--migrations] | db mcp-config --project-ref <id> | db check --sql "..." | db check --command "..." | db check --file file.sql');
3042
- process.exitCode = 1;
3043
- }
@@ -23,22 +23,78 @@ import { writeEffortDecision } from '../core/effort-orchestrator.mjs';
23
23
  import { createWorkOrderLedger, writeWorkOrderLedger } from '../core/work-order-ledger.mjs';
24
24
  import { writeFromChatImgArtifacts } from '../core/from-chat-img-forensics.mjs';
25
25
  import { renderTeamDashboardState, writeTeamDashboardState } from '../core/team-dashboard-renderer.mjs';
26
- import { runPerfBench } from '../core/perf-bench.mjs';
26
+ import { runPerfBench, runWorkflowPerfBench } from '../core/perf-bench.mjs';
27
+ import { writeProofFieldReport } from '../core/proof-field.mjs';
27
28
  import { GOAL_BRIDGE_ARTIFACT, GOAL_WORKFLOW_ARTIFACT, updateGoalWorkflow, writeGoalWorkflow } from '../core/goal-workflow.mjs';
28
29
  import { scanCodeStructure, writeCodeStructureReport } from '../core/code-structure.mjs';
29
30
  import { writeMemorySweepReport } from '../core/memory-governor.mjs';
30
31
  import { cleanupWarpTeamView, launchWarpTeamView } from '../core/warp-ui.mjs';
31
32
  import { writeSkillForgeReport } from '../core/skill-forge.mjs';
32
33
  import { writeMistakeMemoryReport } from '../core/mistake-memory.mjs';
33
- import { scanDbSafety } from '../core/db-safety.mjs';
34
+ import { checkDbOperation, checkSqlFile, classifyCommand, classifySql, loadDbSafetyPolicy, safeSupabaseMcpConfig, scanDbSafety } from '../core/db-safety.mjs';
34
35
  import { harnessGrowthReport, writeHarnessGrowthReport } from '../core/evaluation.mjs';
35
36
 
36
37
  const flag = (args, name) => args.includes(name);
37
38
  const promptOf = (args) => args.filter((x) => !String(x).startsWith('--')).join(' ').trim();
38
39
  const TEAM_SESSION_CLEANUP_ARTIFACT = 'team-session-cleanup.json';
40
+ const REPOSITORY_URL = 'https://github.com/mandarange/Sneakoscope-Codex.git';
39
41
 
40
42
  async function resolveMissionId(root, arg) { return (!arg || arg === 'latest') ? findLatestMission(root) : arg; }
41
43
 
44
+ export function quickstartCommand() {
45
+ console.log(`ㅅㅋㅅ Quickstart
46
+
47
+ First install and bootstrap this project:
48
+ npm i -g sneakoscope
49
+ sks root
50
+ sks bootstrap
51
+ sks
52
+
53
+ Use outside a project:
54
+ sks root
55
+ sks deps check
56
+ sks team "global mission"
57
+
58
+ If warp is missing:
59
+ sks deps install warp
60
+
61
+ Initialize this project for CLI and Codex App:
62
+ sks setup --bootstrap
63
+
64
+ Open from terminal:
65
+ sks
66
+ sks --auto-review --high
67
+ sks auto-review start --high
68
+
69
+ Verify:
70
+ sks deps check
71
+ sks codex-app check
72
+ sks warp check
73
+ sks auto-review status
74
+ sks doctor --fix
75
+ sks context7 check
76
+ sks selftest --mock
77
+ sks commands
78
+ sks dollar-commands
79
+
80
+ If hooks cannot find the command:
81
+ sks fix-path
82
+
83
+ Project-only install:
84
+ npm i -D sneakoscope
85
+ npx sks setup --install-scope project
86
+
87
+ Local-only install artifacts:
88
+ sks setup --local-only
89
+ # writes generated SKS files but excludes .sneakoscope/, .codex/, .agents/, AGENTS.md through .git/info/exclude
90
+ # user-owned AGENTS.md is preserved; an existing SKS managed block is refreshed
91
+
92
+ GitHub install for unreleased commits:
93
+ npm i -g git+${REPOSITORY_URL}
94
+ sks bootstrap
95
+ `);
96
+ }
97
+
42
98
  export async function researchCommand(sub, args) {
43
99
  if (sub === 'prepare') return researchPrepare(args);
44
100
  if (sub === 'run') return researchRun(args);
@@ -385,6 +441,52 @@ export async function hproofCommand(sub, args) {
385
441
  console.log(JSON.stringify(await evaluateDoneGate(root, id), null, 2));
386
442
  }
387
443
 
444
+ export async function dbCommand(sub, args = []) {
445
+ const root = await sksRoot();
446
+ if (sub === 'policy') {
447
+ console.log(JSON.stringify(await loadDbSafetyPolicy(root), null, 2));
448
+ return;
449
+ }
450
+ if (sub === 'scan') {
451
+ const report = await scanDbSafety(root, { includeMigrations: flag(args, '--migrations') });
452
+ console.log(JSON.stringify(report, null, 2));
453
+ process.exitCode = report.ok ? 0 : 2;
454
+ return;
455
+ }
456
+ if (sub === 'mcp-config') {
457
+ const projectIdx = args.indexOf('--project-ref');
458
+ const featuresIdx = args.indexOf('--features');
459
+ const projectRef = projectIdx >= 0 ? args[projectIdx + 1] : '<project_ref>';
460
+ const features = featuresIdx >= 0 ? args[featuresIdx + 1] : 'database,docs';
461
+ console.log(JSON.stringify(safeSupabaseMcpConfig({ projectRef, readOnly: true, features }), null, 2));
462
+ return;
463
+ }
464
+ if (sub === 'classify' || sub === 'check') {
465
+ const sqlIdx = args.indexOf('--sql');
466
+ const commandIdx = args.indexOf('--command');
467
+ const fileIdx = args.indexOf('--file');
468
+ let result;
469
+ if (fileIdx >= 0 && args[fileIdx + 1]) result = await checkSqlFile(path.resolve(args[fileIdx + 1]));
470
+ else if (commandIdx >= 0 && args[commandIdx + 1]) result = classifyCommand(args[commandIdx + 1]);
471
+ else if (sqlIdx >= 0 && args[sqlIdx + 1]) result = classifySql(args[sqlIdx + 1]);
472
+ else if (sub === 'check' && args[0]) result = await checkSqlFile(path.resolve(args[0]));
473
+ else result = classifySql(args.join(' ').trim());
474
+ console.log(JSON.stringify(result, null, 2));
475
+ process.exitCode = ['destructive', 'write', 'possible_db'].includes(result.level) ? 2 : 0;
476
+ return;
477
+ }
478
+ if (sub === 'scan-payload') {
479
+ const raw = await fsp.readFile(0, 'utf8');
480
+ const payload = raw.trim() ? JSON.parse(raw) : {};
481
+ const decision = await checkDbOperation(root, {}, payload, { duringNoQuestion: false });
482
+ console.log(JSON.stringify(decision, null, 2));
483
+ process.exitCode = decision.action === 'block' ? 2 : 0;
484
+ return;
485
+ }
486
+ console.error('Usage: sks db policy | db scan [--migrations] | db mcp-config --project-ref <id> | db check --sql "..." | db check --command "..." | db check --file file.sql');
487
+ process.exitCode = 1;
488
+ }
489
+
388
490
  export async function validateArtifactsCommand(args = []) {
389
491
  const root = await sksRoot();
390
492
  const missionArg = args[0] && !String(args[0]).startsWith('--') ? args[0] : 'latest';
@@ -404,12 +506,32 @@ export async function validateArtifactsCommand(args = []) {
404
506
  }
405
507
 
406
508
  export async function perfCommand(sub, args = []) {
407
- if (sub !== 'run') {
408
- console.error('Usage: sks perf run [--json] [--iterations N]');
509
+ if (!['run', 'workflow'].includes(sub)) {
510
+ console.error('Usage: sks perf run|workflow [--json] [--iterations N] [--intent "task"] [--changed file1,file2]');
409
511
  process.exitCode = 1;
410
512
  return;
411
513
  }
412
514
  const root = await sksRoot();
515
+ if (sub === 'workflow') {
516
+ const changedRaw = readFlagValue(args, '--changed', null);
517
+ const report = await runWorkflowPerfBench(root, {
518
+ iterations: readFlagValue(args, '--iterations', 3),
519
+ intent: readFlagValue(args, '--intent', positionalArgs(args).join(' ')),
520
+ changedFiles: changedRaw ? changedRaw.split(',').filter(Boolean) : undefined
521
+ });
522
+ const outPath = path.join(root, '.sneakoscope', 'reports', `workflow-perf-${Date.now()}.json`);
523
+ await writeJsonAtomic(outPath, report);
524
+ if (flag(args, '--json')) return console.log(JSON.stringify({ ...report, report_path: outPath }, null, 2));
525
+ console.log('SKS Workflow Performance');
526
+ console.log(`Mode: ${report.metrics.decision_mode}`);
527
+ console.log(`Fast lane: ${report.metrics.fast_lane_eligible ? 'yes' : 'no'}`);
528
+ console.log(`Proof Field p95: ${report.metrics.proof_field_build_ms_p95}ms`);
529
+ console.log(`Proof cones: ${report.metrics.proof_cone_count}`);
530
+ console.log(`Negative work skipped: ${report.metrics.negative_work_skipped_count}`);
531
+ console.log(`Next: ${report.recommendation.next.join('; ')}`);
532
+ console.log(`Report: ${path.relative(root, outPath)}`);
533
+ return;
534
+ }
413
535
  const report = await runPerfBench(root, { iterations: readFlagValue(args, '--iterations', 3) });
414
536
  const outPath = path.join(root, '.sneakoscope', 'reports', `perf-${Date.now()}.json`);
415
537
  await writeJsonAtomic(outPath, report);
@@ -421,6 +543,34 @@ export async function perfCommand(sub, args = []) {
421
543
  console.log(`Report: ${path.relative(root, outPath)}`);
422
544
  }
423
545
 
546
+ export async function proofFieldCommand(sub, args = []) {
547
+ const action = sub || 'scan';
548
+ if (!['scan', 'help', '--help'].includes(action)) {
549
+ console.error('Usage: sks proof-field scan [--json] [--intent "task"] [--changed file1,file2]');
550
+ process.exitCode = 1;
551
+ return;
552
+ }
553
+ if (action === 'help' || action === '--help') {
554
+ console.log('Usage: sks proof-field scan [--json] [--intent "task"] [--changed file1,file2]');
555
+ console.log('Build a Potential Proof Field report: proof cones, negative-work cache, and fast-lane eligibility for the current change set.');
556
+ return;
557
+ }
558
+ const root = await sksRoot();
559
+ const changedRaw = readFlagValue(args, '--changed', null);
560
+ const report = await writeProofFieldReport(root, {
561
+ intent: readFlagValue(args, '--intent', positionalArgs(args).join(' ')),
562
+ changedFiles: changedRaw ? changedRaw.split(',').filter(Boolean) : undefined
563
+ });
564
+ if (flag(args, '--json')) return console.log(JSON.stringify(report, null, 2));
565
+ console.log('SKS Proof Field');
566
+ console.log(`Mode: ${report.fast_lane_decision.mode}`);
567
+ console.log(`Eligible: ${report.fast_lane_decision.eligible ? 'yes' : 'no'}`);
568
+ if (report.fast_lane_decision.blockers.length) console.log(`Blockers: ${report.fast_lane_decision.blockers.join(', ')}`);
569
+ console.log(`Proof cones: ${report.proof_cones.map((cone) => cone.id).join(', ')}`);
570
+ console.log(`Verification: ${report.fast_lane_decision.verification.join('; ')}`);
571
+ console.log(`Report: ${path.relative(root, report.report_path)}`);
572
+ }
573
+
424
574
  export async function harnessCommand(sub, args = []) {
425
575
  const action = sub || 'fixture';
426
576
  if (!['fixture', 'review'].includes(action)) {
@@ -1084,7 +1234,7 @@ export async function statsCommand(args) {
1084
1234
 
1085
1235
  function positionalArgs(args = []) {
1086
1236
  const out = [];
1087
- const valueFlags = new Set(['--format', '--iterations', '--out', '--baseline', '--candidate', '--install-scope', '--max-cycles', '--depth', '--scope', '--transport', '--query', '--topic', '--tokens', '--timeout-ms', '--sql', '--command', '--project-ref', '--agent', '--phase', '--message', '--role', '--max-anchors', '--lines']);
1237
+ const valueFlags = new Set(['--format', '--iterations', '--out', '--baseline', '--candidate', '--install-scope', '--max-cycles', '--depth', '--scope', '--transport', '--query', '--topic', '--tokens', '--timeout-ms', '--sql', '--command', '--project-ref', '--agent', '--phase', '--message', '--role', '--max-anchors', '--lines', '--intent', '--changed']);
1088
1238
  for (let i = 0; i < args.length; i++) {
1089
1239
  const arg = String(args[i]);
1090
1240
  if (valueFlags.has(arg)) {
@@ -226,7 +226,27 @@ function hasTableRemovalRisk(cls = {}) {
226
226
  ...(cls.sql?.reasons || []),
227
227
  ...(cls.command?.reasons || [])
228
228
  ]);
229
- return ['drop_table', 'alter_table_drop', 'truncate'].some((reason) => reasons.has(reason));
229
+ return ['drop_table', 'truncate'].some((reason) => reasons.has(reason));
230
+ }
231
+
232
+ function hasMadSksCatastrophicDbRisk(cls = {}) {
233
+ const reasons = new Set([
234
+ ...(cls.reasons || []),
235
+ ...(cls.sql?.reasons || []),
236
+ ...(cls.command?.reasons || [])
237
+ ]);
238
+ return [
239
+ 'drop_database',
240
+ 'drop_schema',
241
+ 'drop_table',
242
+ 'truncate',
243
+ 'delete_without_where',
244
+ 'update_without_where',
245
+ 'supabase_db_reset',
246
+ 'prisma_migrate_reset',
247
+ 'postgres_database_admin_command'
248
+ ].some((reason) => reasons.has(reason))
249
+ || cls.toolReasons?.includes?.('dangerous_supabase_management_tool');
230
250
  }
231
251
 
232
252
  function isMadSksRouteState(state = {}) {
@@ -259,23 +279,32 @@ export function evaluateDbSafety({ classification, policy = DEFAULT_DB_SAFETY_PO
259
279
  if (cls.level === 'safe') return { allowed: true, action: 'allow', reasons: ['read_only_operation'], classification: cls };
260
280
  if (cls.level === 'possible_db') return { allowed: !noQuestion, action: noQuestion ? 'block' : 'warn', reasons: noQuestion ? ['unknown_database_operation_blocked_during_no_question_run'] : ['unknown_database_operation'], classification: cls };
261
281
  if (madSks?.active && (cls.level === 'write' || cls.level === 'destructive')) {
262
- if (hasTableRemovalRisk(cls) && !madSks.tableDeleteConfirmed) {
282
+ if (hasMadSksCatastrophicDbRisk(cls)) {
263
283
  return {
264
284
  allowed: false,
265
- action: 'confirm',
266
- reasons: ['mad_sks_table_delete_requires_user_confirmation_30s'],
285
+ action: 'block',
286
+ reasons: ['mad_sks_catastrophic_db_operation_blocked'],
267
287
  classification: cls,
268
288
  effective,
269
- mad_sks: { active: true, table_delete_confirmation_required: true, timeout_ms: MAD_SKS_TABLE_DELETE_TIMEOUT_MS }
289
+ mad_sks: {
290
+ active: true,
291
+ catastrophic_safety_guard_active: true,
292
+ blocked_categories: ['whole_database_or_table_removal', 'all_rows_delete_or_update', 'dangerous_project_management']
293
+ }
270
294
  };
271
295
  }
272
296
  return {
273
297
  allowed: true,
274
298
  action: 'allow',
275
- reasons: hasTableRemovalRisk(cls) ? ['mad_sks_table_delete_confirmed'] : ['mad_sks_scoped_override_active'],
299
+ reasons: ['mad_sks_scoped_override_active'],
276
300
  classification: cls,
277
301
  effective,
278
- mad_sks: { active: true, table_delete_confirmed_until: madSks.tableDeleteConfirmedUntil || null }
302
+ mad_sks: {
303
+ active: true,
304
+ sks_db_constraints_removed: true,
305
+ catastrophic_safety_guard_active: true,
306
+ supabase_mcp_schema_cleanup_allowed: true
307
+ }
279
308
  };
280
309
  }
281
310
  if (cls.level === 'destructive') reasons.push('destructive_database_operation_blocked_always');
@@ -384,6 +413,13 @@ export async function checkSqlFile(file) {
384
413
  }
385
414
 
386
415
  export function dbBlockReason(decision) {
416
+ if ((decision.reasons || []).includes('mad_sks_catastrophic_db_operation_blocked')) {
417
+ return [
418
+ 'Sneakoscope Codex MAD-SKS catastrophic database safeguard blocked this operation.',
419
+ 'MAD-SKS opens Supabase MCP column/schema cleanup, direct execute SQL, and normal DB writes only while the mission gate is active.',
420
+ 'Whole database/table removal, all-row value wipes, database reset, and dangerous project or branch management remain blocked.'
421
+ ].join(' ');
422
+ }
387
423
  if ((decision.reasons || []).includes('mad_sks_table_delete_requires_user_confirmation_30s')) {
388
424
  return [
389
425
  'Sneakoscope Codex MAD-SKS gate paused a table deletion operation.',
@@ -87,21 +87,23 @@ export function buildDecisionContract({ mission, schema, answers }) {
87
87
  mad_sks_mode: madSks ? 'explicit_invocation_only' : false,
88
88
  production_database_writes_allowed: madSks ? 'mad_sks_scoped' : false,
89
89
  mcp_direct_execute_sql_writes_allowed: madSks ? 'mad_sks_scoped' : false,
90
- db_reset_allowed: madSks ? 'mad_sks_scoped' : false,
91
- db_drop_allowed: madSks ? 'requires_table_delete_confirmation_when_table_removal' : false,
92
- db_truncate_allowed: madSks ? 'requires_table_delete_confirmation_when_table_removal' : false,
90
+ db_reset_allowed: false,
91
+ db_drop_allowed: madSks ? 'column_and_non_catastrophic_schema_cleanup_only' : false,
92
+ db_truncate_allowed: false,
93
93
  db_mass_delete_update_allowed: madSks ? 'mad_sks_scoped' : false
94
94
  },
95
95
  database_safety: {
96
- policy: madSks ? 'mad_sks_scoped_override_table_delete_confirmation_required' : 'destructive_denied_always',
96
+ policy: madSks ? 'mad_sks_scoped_override_with_catastrophic_db_guard' : 'destructive_denied_always',
97
97
  supabase_mcp_recommended_url: 'https://mcp.supabase.com/mcp?project_ref=<project_ref>&read_only=true&features=database,docs',
98
98
  allowed_targets_for_write: madSks ? ['main_branch', 'production', 'local_dev', 'preview_branch', 'supabase_branch'] : ['local_dev', 'preview_branch', 'supabase_branch'],
99
- forbidden_operations: madSks ? ['TABLE_REMOVAL_WITHOUT_RUNTIME_CONFIRMATION'] : ['DROP', 'TRUNCATE', 'DELETE_WITHOUT_WHERE', 'UPDATE_WITHOUT_WHERE', 'DB_RESET', 'DB_PUSH', 'PROJECT_DELETE', 'BRANCH_RESET_OR_MERGE_OR_DELETE', 'DISABLE_RLS', 'BROAD_GRANT_REVOKE'],
99
+ forbidden_operations: madSks ? ['DROP_DATABASE', 'DROP_SCHEMA', 'DROP_TABLE', 'TRUNCATE', 'DELETE_WITHOUT_WHERE', 'UPDATE_WITHOUT_WHERE', 'DB_RESET', 'PROJECT_DELETE', 'BRANCH_RESET_OR_MERGE_OR_DELETE'] : ['DROP', 'TRUNCATE', 'DELETE_WITHOUT_WHERE', 'UPDATE_WITHOUT_WHERE', 'DB_RESET', 'DB_PUSH', 'PROJECT_DELETE', 'BRANCH_RESET_OR_MERGE_OR_DELETE', 'DISABLE_RLS', 'BROAD_GRANT_REVOKE'],
100
100
  mad_sks_scope: madSks ? {
101
101
  active_only_when_prompt_contains: '$MAD-SKS',
102
102
  may_combine_with_primary_route: true,
103
103
  deactivates_when_active_mission_gate_passes: true,
104
- table_delete_confirmation_timeout_ms: 30000
104
+ supabase_mcp_schema_cleanup_allowed: true,
105
+ direct_execute_sql_allowed: true,
106
+ catastrophic_safety_guard_active: true
105
107
  } : null,
106
108
  migration_apply_allowed: answers.DB_MIGRATION_APPLY_ALLOWED || 'no',
107
109
  read_only_query_limit: answers.DB_READ_ONLY_QUERY_LIMIT || '1000'
package/src/core/fsx.mjs CHANGED
@@ -5,7 +5,7 @@ import os from 'node:os';
5
5
  import crypto from 'node:crypto';
6
6
  import { spawn } from 'node:child_process';
7
7
 
8
- export const PACKAGE_VERSION = '0.6.85';
8
+ export const PACKAGE_VERSION = '0.6.87';
9
9
  export const DEFAULT_PROCESS_TAIL_BYTES = 256 * 1024;
10
10
  export const DEFAULT_PROCESS_TIMEOUT_MS = 30 * 60 * 1000;
11
11
 
package/src/core/init.mjs CHANGED
@@ -505,7 +505,7 @@ export async function installSkills(root) {
505
505
  'research': `---\nname: research\ndescription: Dollar-command route for $Research or $research frontier discovery workflows.\n---\n\nUse when the user invokes $Research/$research or asks for research, hypotheses, new mechanisms, falsification, or testable predictions. Prefer sks research prepare and sks research run. Do not use for ordinary code edits.\n`,
506
506
  'autoresearch': `---\nname: autoresearch\ndescription: Dollar-command route for $AutoResearch or $autoresearch iterative experiment loops.\n---\n\nUse for $AutoResearch, iterative improvement, SEO/GEO, ranking, workflow, benchmark, or experiments. Define program, hypothesis, experiment, metric, keep/discard, falsification, next step, and Honest Mode. Load seo-geo-optimizer for README/npm/GitHub/schema/AI-search work.\n`,
507
507
  'db': `---\nname: db\ndescription: Dollar-command route for $DB or $db database and Supabase safety checks.\n---\n\nUse when the user invokes $DB/$db or the task touches SQL, Supabase, Postgres, migrations, Prisma, Drizzle, Knex, MCP database tools, or production data. Run or follow sks db policy, sks db scan, sks db classify, and sks db check. Destructive database operations remain forbidden.\n`,
508
- 'mad-sks': `---\nname: mad-sks\ndescription: Explicit high-risk authorization modifier for $MAD-SKS scoped Supabase MCP DB permission widening.\n---\n\nUse only when the user explicitly invokes $MAD-SKS. It can be combined with another route, such as $MAD-SKS $Team or $DB ... $MAD-SKS; in that case the other command remains the primary workflow and MAD-SKS is only the temporary permission grant. The widened DB permission applies only while the active mission gate is open, and must be deactivated when the task ends. Table deletion remains special: pause, ask the user for explicit confirmation, and abort that operation if no confirmation arrives within about 30 seconds. Do not carry MAD-SKS permission into later prompts or routes.\n`,
508
+ 'mad-sks': `---\nname: mad-sks\ndescription: Explicit high-risk authorization modifier for $MAD-SKS scoped Supabase MCP DB permission widening.\n---\n\nUse only when the user explicitly invokes $MAD-SKS. It can be combined with another route, such as $MAD-SKS $Team or $DB ... $MAD-SKS; in that case the other command remains the primary workflow and MAD-SKS is only the temporary permission grant. The widened DB permission applies only while the active mission gate is open, must be deactivated when the task ends, and opens Supabase MCP column/schema cleanup, direct execute SQL, and normal DB write permissions. Keep only catastrophic database-wipe safeguards: whole database/table removal, all-row delete/update, reset, and dangerous project/branch management remain blocked. Do not carry MAD-SKS permission into later prompts or routes.\n`,
509
509
  'gx': `---\nname: gx\ndescription: Dollar-command route for $GX or $gx deterministic GX visual context cartridges.\n---\n\nUse when the user invokes $GX/$gx or asks for architecture/context visualization through SKS. Prefer sks gx init, render, validate, drift, and snapshot. vgraph.json remains the source of truth.\n`,
510
510
  'help': `---\nname: help\ndescription: Dollar-command route for $Help or $help explaining installed SKS commands and workflows.\n---\n\nUse when the user invokes $Help/$help or asks what commands exist. Prefer concise output from sks commands, sks usage <topic>, sks quickstart, sks aliases, and sks codex-app.\n`,
511
511
  'prompt-pipeline': `---\nname: prompt-pipeline\ndescription: Default SKS prompt optimization pipeline for execution prompts; Answer and DFix bypass it.\n---\n\nClassify intent: Answer only for real questions; question-shaped implicit instructions, complaints, and mandatory-policy statements route to Team. DFix handles tiny design/content; code defaults to Team unless safety/research/GX route fits. Infer goal, target, constraints, acceptance, risk, and smallest safe route. Ask only scope/safety/behavior/acceptance-changing questions; otherwise seal inferred answers. Code work surfaces route/guard/scopes, materializes team-roster.json from default or explicit counts before implementation, compiles concrete Team runtime graph/inbox artifacts after consensus, and parent owns integration/tests/Context7/Honest Mode.\n\n${chatCaptureIntakeText()}\n\nDesign: read design.md; if missing use design-system-builder; use imagegen for image/logo/raster. TriWiki context-tracking SSOT: .sneakoscope/wiki/context-pack.json; read only the latest coordinate+voxel overlay pack before every route stage, run sks wiki refresh/pack after changes, validate before handoffs/final.\n`,
@@ -1,6 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import { performance } from 'node:perf_hooks';
3
3
  import { dirSize, fileSize, nowIso, packageRoot, runProcess, writeJsonAtomic } from './fsx.mjs';
4
+ import { buildProofField, validateProofFieldReport } from './proof-field.mjs';
4
5
 
5
6
  export const DEFAULT_PERF_BUDGETS = {
6
7
  cli_startup_ms_p95: 250,
@@ -8,6 +9,8 @@ export const DEFAULT_PERF_BUDGETS = {
8
9
  context_build_ms_p95: 500,
9
10
  artifact_validation_ms_p95: 150,
10
11
  dashboard_render_ms_p95: 100,
12
+ proof_field_build_ms_p95: 150,
13
+ workflow_scan_ms_p95: 1000,
11
14
  fast_selftest_ms_p95: 5000,
12
15
  package_size_kb_max: 1024,
13
16
  notes: 'Package payload budget is 1024KB because the current low-dependency CLI payload is already above 512KB; reduce only with measured justification.'
@@ -52,6 +55,90 @@ export async function runPerfBench(root, opts = {}) {
52
55
  };
53
56
  }
54
57
 
58
+ export async function runWorkflowPerfBench(root, opts = {}) {
59
+ const iterations = Math.max(1, Math.min(20, Number(opts.iterations || 3)));
60
+ const intent = String(opts.intent || '').trim();
61
+ const changedFiles = normalizeChangedFiles(opts.changedFiles);
62
+ const proofFieldBuild = [];
63
+ let proofField = null;
64
+ for (let i = 0; i < iterations; i++) {
65
+ const t0 = performance.now();
66
+ proofField = await buildProofField(root, {
67
+ intent,
68
+ changedFiles: changedFiles.length ? changedFiles : undefined
69
+ });
70
+ proofFieldBuild.push(performance.now() - t0);
71
+ }
72
+ const proofValidation = validateProofFieldReport(proofField);
73
+ const verification = proofField?.fast_lane_decision?.verification || [];
74
+ const negativeWork = proofField?.negative_work_cache || [];
75
+ const estimatedSavedWork = negativeWork.filter((item) => item.disposition === 'skip_with_evidence').length;
76
+ const proofFieldMsP95 = Math.round(percentile(proofFieldBuild, 95));
77
+ const workflowScanMsP95 = proofFieldMsP95;
78
+ return {
79
+ schema_version: 1,
80
+ measured_at: nowIso(),
81
+ theory: 'Potential Proof Field',
82
+ iterations,
83
+ intent: intent || null,
84
+ budgets: DEFAULT_PERF_BUDGETS,
85
+ metrics: {
86
+ proof_field_build_ms_p95: proofFieldMsP95,
87
+ workflow_scan_ms_p95: workflowScanMsP95,
88
+ decision_mode: proofField?.fast_lane_decision?.mode || null,
89
+ fast_lane_eligible: Boolean(proofField?.fast_lane_decision?.eligible),
90
+ proof_cone_count: proofField?.proof_cones?.length || 0,
91
+ verification_count: verification.length,
92
+ negative_work_skipped_count: estimatedSavedWork,
93
+ proof_field_valid: proofValidation.ok
94
+ },
95
+ proof_field: proofField,
96
+ recommendation: workflowRecommendation(proofField, proofValidation),
97
+ raw: {
98
+ proof_field_build_ms: proofFieldBuild.map((value) => Math.round(value))
99
+ }
100
+ };
101
+ }
102
+
103
+ export function validateWorkflowPerfReport(report = {}) {
104
+ const issues = [];
105
+ if (report.schema_version !== 1) issues.push('schema_version');
106
+ if (report.theory !== 'Potential Proof Field') issues.push('theory');
107
+ if (!report.metrics || !Number.isFinite(Number(report.metrics.proof_field_build_ms_p95))) issues.push('proof_field_build_ms_p95');
108
+ if (!report.metrics?.decision_mode) issues.push('decision_mode');
109
+ if (!report.proof_field || !validateProofFieldReport(report.proof_field).ok) issues.push('proof_field');
110
+ if (!report.recommendation?.mode) issues.push('recommendation');
111
+ return { ok: issues.length === 0, issues };
112
+ }
113
+
114
+ function normalizeChangedFiles(files) {
115
+ return [...new Set((files || []).flatMap((value) => String(value || '').split(',')).map((file) => file.trim()).filter(Boolean))]
116
+ .sort();
117
+ }
118
+
119
+ function workflowRecommendation(proofField, validation) {
120
+ if (!validation.ok) {
121
+ return {
122
+ mode: 'full_proof',
123
+ reason: `proof field invalid: ${validation.issues.join(', ')}`,
124
+ next: ['repair proof-field report generation', 'rerun sks perf workflow --json']
125
+ };
126
+ }
127
+ const decision = proofField.fast_lane_decision;
128
+ if (decision.eligible) {
129
+ return {
130
+ mode: 'fast_lane',
131
+ reason: 'selected proof cones are narrow and all unrelated work is safely cached as negative work',
132
+ next: decision.verification
133
+ };
134
+ }
135
+ return {
136
+ mode: decision.mode,
137
+ reason: decision.blockers.length ? `blocked by ${decision.blockers.join(', ')}` : 'balanced proof required',
138
+ next: decision.verification
139
+ };
140
+ }
141
+
55
142
  async function packagePayloadSize(root) {
56
143
  let total = 0;
57
144
  for (const rel of ['bin', 'src']) total += await dirSize(path.join(root, rel));
@@ -258,16 +258,16 @@ function applyMadSksAuthorizationToSchema(schema = {}) {
258
258
  DATABASE_TARGET_ENVIRONMENT: 'main_branch',
259
259
  DATABASE_WRITE_MODE: 'mad_sks_full_mcp_write_for_invocation',
260
260
  SUPABASE_MCP_POLICY: 'mad_sks_project_scoped_write_for_invocation',
261
- DESTRUCTIVE_DB_OPERATIONS_ALLOWED: 'mad_sks_scoped_with_table_delete_confirmation',
261
+ DESTRUCTIVE_DB_OPERATIONS_ALLOWED: 'mad_sks_scoped_except_catastrophic_db_wipe',
262
262
  DB_BACKUP_OR_BRANCH_REQUIRED: 'recommended_but_not_required_in_mad_sks',
263
- DB_MAX_BLAST_RADIUS: 'mad_sks_active_invocation_only_table_delete_confirmation_required',
263
+ DB_MAX_BLAST_RADIUS: 'mad_sks_active_invocation_only_catastrophic_wipe_blocked',
264
264
  DB_MIGRATION_APPLY_ALLOWED: 'mad_sks_active_invocation_only',
265
265
  DB_READ_ONLY_QUERY_LIMIT: '100'
266
266
  };
267
267
  schema.inference_notes = {
268
268
  ...(schema.inference_notes || {}),
269
269
  MAD_SKS_MODE: 'explicit dollar command modifier is the permission boundary',
270
- DESTRUCTIVE_DB_OPERATIONS_ALLOWED: 'MAD-SKS scoped override with table deletion confirmation'
270
+ DESTRUCTIVE_DB_OPERATIONS_ALLOWED: 'MAD-SKS opens Supabase MCP DB cleanup while blocking only catastrophic database wipe operations'
271
271
  };
272
272
  schema.slots = (schema.slots || []).filter((slot) => !/^(DB_|DATABASE_|DESTRUCTIVE_DB_|SUPABASE_MCP_POLICY$)/.test(slot.id));
273
273
  return schema;
@@ -0,0 +1,219 @@
1
+ import path from 'node:path';
2
+ import { nowIso, readText, rel, runProcess, sha256, writeJsonAtomic } from './fsx.mjs';
3
+
4
+ export const PROOF_FIELD_SCHEMA_VERSION = 1;
5
+
6
+ export const INVARIANT_LEDGER = Object.freeze([
7
+ { id: 'db-catastrophic-guard', severity: 'critical', description: 'Database/table wipe, all-row DML, reset, and dangerous project/branch operations remain blocked.' },
8
+ { id: 'honest-evidence', severity: 'critical', description: 'Final claims must be backed by current code, tests, artifacts, or explicitly marked unverified.' },
9
+ { id: 'route-surface-consistency', severity: 'high', description: 'User-visible route surfaces must agree across CLI help, command catalog, generated skills, and docs.' },
10
+ { id: 'triwiki-hydratable-context', severity: 'high', description: 'TriWiki context must remain coordinate+voxel backed and hydratable by source/hash/anchor.' },
11
+ { id: 'no-unrequested-fallback-code', severity: 'high', description: 'Do not add substitute paths, mocks, shims, or fallback behavior unless explicitly requested.' }
12
+ ]);
13
+
14
+ export const PROOF_CONE_DEFINITIONS = Object.freeze([
15
+ {
16
+ id: 'db_safety',
17
+ surfaces: ['database', 'supabase', 'mad-sks'],
18
+ match: [/db-safety|supabase|migration|rls|schema|sql/i],
19
+ verification: ['npm run packcheck', 'npm run selftest -- --mock', 'sks db scan --json'],
20
+ negative_work: ['browser_ui_e2e', 'visual_snapshot']
21
+ },
22
+ {
23
+ id: 'route_surface',
24
+ surfaces: ['routes', 'skills', 'cli-help', 'docs'],
25
+ match: [/routes\.mjs|init\.mjs|codex-app|README|AGENTS|skills/i],
26
+ verification: ['npm run packcheck', 'npm run selftest -- --mock', 'sks commands --json'],
27
+ negative_work: ['database_migration', 'from_chat_img_forensics']
28
+ },
29
+ {
30
+ id: 'cli_runtime',
31
+ surfaces: ['cli', 'commands', 'runtime'],
32
+ match: [/src\/cli|bin\/sks|maintenance-commands|fsx|codex-adapter/i],
33
+ verification: ['npm run packcheck', 'node ./bin/sks.mjs commands --json', 'node ./bin/sks.mjs proof-field scan --json'],
34
+ negative_work: ['browser_ui_e2e']
35
+ },
36
+ {
37
+ id: 'context_memory',
38
+ surfaces: ['triwiki', 'memory', 'evaluation'],
39
+ match: [/triwiki|wiki|memory|evaluation|perf-bench|proof-field/i],
40
+ verification: ['npm run packcheck', 'node ./bin/sks.mjs eval run --json', 'node ./bin/sks.mjs wiki validate .sneakoscope/wiki/context-pack.json'],
41
+ negative_work: ['database_migration', 'browser_ui_e2e']
42
+ },
43
+ {
44
+ id: 'release_surface',
45
+ surfaces: ['package', 'changelog', 'release'],
46
+ match: [/package\.json|package-lock\.json|CHANGELOG|README/i],
47
+ verification: ['npm run release:check'],
48
+ negative_work: []
49
+ },
50
+ {
51
+ id: 'visual_forensic',
52
+ surfaces: ['from-chat-img', 'visual', 'qa-loop'],
53
+ match: [/from-chat-img|visual|screenshot|qa-loop|dogfood/i],
54
+ verification: ['npm run packcheck', 'npm run selftest -- --mock'],
55
+ negative_work: ['database_migration']
56
+ }
57
+ ]);
58
+
59
+ export async function buildProofField(root, opts = {}) {
60
+ const changedFiles = normalizeChangedFiles(opts.changedFiles || await gitChangedFiles(root));
61
+ const intent = String(opts.intent || '').trim();
62
+ const selectedCones = selectProofCones(changedFiles, intent);
63
+ const risk = riskSummary(changedFiles, selectedCones, intent);
64
+ const negativeWork = buildNegativeWorkCache(selectedCones, risk);
65
+ const fastLane = fastLaneDecision({ changedFiles, selectedCones, risk, negativeWork });
66
+ const sourceHash = await sourceDigest(root, changedFiles);
67
+ return {
68
+ schema_version: PROOF_FIELD_SCHEMA_VERSION,
69
+ generated_at: nowIso(),
70
+ theory: 'Potential Proof Field',
71
+ intent: intent || null,
72
+ source_hash: sourceHash,
73
+ changed_files: changedFiles,
74
+ invariant_ledger: INVARIANT_LEDGER,
75
+ proof_cones: selectedCones,
76
+ negative_work_cache: negativeWork,
77
+ fast_lane_decision: fastLane,
78
+ next_action: nextAction(fastLane)
79
+ };
80
+ }
81
+
82
+ export async function writeProofFieldReport(root, opts = {}) {
83
+ const report = await buildProofField(root, opts);
84
+ const file = path.join(root, '.sneakoscope', 'reports', `proof-field-${Date.now()}.json`);
85
+ await writeJsonAtomic(file, report);
86
+ return { ...report, report_path: file };
87
+ }
88
+
89
+ export function validateProofFieldReport(report = {}) {
90
+ const issues = [];
91
+ if (report.schema_version !== PROOF_FIELD_SCHEMA_VERSION) issues.push('schema_version');
92
+ if (!Array.isArray(report.invariant_ledger) || !report.invariant_ledger.length) issues.push('invariant_ledger');
93
+ if (!Array.isArray(report.proof_cones)) issues.push('proof_cones');
94
+ if (!Array.isArray(report.negative_work_cache)) issues.push('negative_work_cache');
95
+ if (!report.fast_lane_decision?.mode) issues.push('fast_lane_decision');
96
+ if (report.fast_lane_decision?.mode === 'fast_lane' && report.fast_lane_decision?.escalate_on?.length < 1) issues.push('fast_lane_escalation');
97
+ return { ok: issues.length === 0, issues };
98
+ }
99
+
100
+ export async function proofFieldFixture() {
101
+ const report = await buildProofField(process.cwd(), {
102
+ intent: 'small CLI help surface update',
103
+ changedFiles: ['src/cli/maintenance-commands.mjs', 'src/core/routes.mjs']
104
+ });
105
+ return {
106
+ report,
107
+ validation: validateProofFieldReport(report),
108
+ checks: {
109
+ route_cone_selected: report.proof_cones.some((cone) => cone.id === 'route_surface'),
110
+ cli_cone_selected: report.proof_cones.some((cone) => cone.id === 'cli_runtime'),
111
+ catastrophic_guard_present: report.invariant_ledger.some((item) => item.id === 'db-catastrophic-guard'),
112
+ negative_release_work_recorded: report.negative_work_cache.some((item) => item.id === 'full_release_gate' && item.disposition === 'skip_with_evidence')
113
+ }
114
+ };
115
+ }
116
+
117
+ async function gitChangedFiles(root) {
118
+ const result = await runProcess('git', ['diff', '--name-only', 'HEAD', '--'], { cwd: root, timeoutMs: 10000, maxOutputBytes: 128 * 1024 });
119
+ if (result.code !== 0) return [];
120
+ return result.stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
121
+ }
122
+
123
+ function normalizeChangedFiles(files = []) {
124
+ return [...new Set((files || []).flatMap((value) => String(value || '').split(',')).map((file) => file.trim()).filter(Boolean))]
125
+ .sort();
126
+ }
127
+
128
+ function selectProofCones(files, intent) {
129
+ const haystack = `${files.join('\n')}\n${intent || ''}`;
130
+ const selected = PROOF_CONE_DEFINITIONS
131
+ .filter((cone) => cone.match.some((re) => re.test(haystack)))
132
+ .map((cone) => ({
133
+ id: cone.id,
134
+ surfaces: cone.surfaces,
135
+ verification: cone.verification,
136
+ matched_files: files.filter((file) => cone.match.some((re) => re.test(file)))
137
+ }));
138
+ if (!selected.length) {
139
+ selected.push({
140
+ id: 'generic_local_change',
141
+ surfaces: ['unknown'],
142
+ verification: ['npm run packcheck', 'focused relevant tests or documented justification'],
143
+ matched_files: files
144
+ });
145
+ }
146
+ return selected;
147
+ }
148
+
149
+ function riskSummary(files, cones, intent) {
150
+ const text = `${files.join('\n')}\n${intent || ''}`;
151
+ const flags = {
152
+ database: /\b(db|database|supabase|sql|migration|rls|schema)\b/i.test(text),
153
+ security: /\b(auth|permission|token|secret|security|권한|보안)\b/i.test(text),
154
+ visual_forensic: /from-chat-img|screenshot|visual|이미지|스크린샷/i.test(text),
155
+ release: /package\.json|package-lock\.json|CHANGELOG|release|publish/i.test(text),
156
+ broad_change: files.length > 3,
157
+ unknown_surface: cones.some((cone) => cone.id === 'generic_local_change')
158
+ };
159
+ const score = Object.values(flags).filter(Boolean).length;
160
+ const level = score >= 3 ? 'high' : score === 2 ? 'medium' : score === 1 ? 'low' : 'minimal';
161
+ return { level, score, flags };
162
+ }
163
+
164
+ function buildNegativeWorkCache(cones, risk) {
165
+ const required = new Set(cones.flatMap((cone) => cone.verification));
166
+ const candidates = new Set(cones.flatMap((cone) => cone.negative_work || []));
167
+ const out = [];
168
+ for (const id of candidates) {
169
+ const blockedByRisk = (id === 'database_migration' && risk.flags.database)
170
+ || (id === 'browser_ui_e2e' && risk.flags.visual_forensic);
171
+ out.push({
172
+ id,
173
+ disposition: blockedByRisk ? 'not_skipped_risk_present' : 'skip_with_evidence',
174
+ reason: blockedByRisk ? 'risk flag requires explicit verification' : 'selected proof cones do not touch this surface'
175
+ });
176
+ }
177
+ if (!required.has('npm run release:check') && !risk.flags.release) {
178
+ out.push({ id: 'full_release_gate', disposition: 'skip_with_evidence', reason: 'no package/release surface in selected cones' });
179
+ }
180
+ return out.sort((a, b) => a.id.localeCompare(b.id));
181
+ }
182
+
183
+ function fastLaneDecision({ changedFiles, selectedCones, risk, negativeWork }) {
184
+ const verification = [...new Set(selectedCones.flatMap((cone) => cone.verification))];
185
+ const safeSkips = negativeWork.filter((item) => item.disposition === 'skip_with_evidence').map((item) => item.id);
186
+ const blockers = [];
187
+ if (!changedFiles.length) blockers.push('no_changed_files');
188
+ if (changedFiles.length > 3) blockers.push('broad_change_set');
189
+ if (risk.flags.database) blockers.push('database_surface');
190
+ if (risk.flags.security) blockers.push('security_surface');
191
+ if (risk.flags.visual_forensic) blockers.push('visual_forensic_surface');
192
+ if (risk.flags.unknown_surface) blockers.push('unknown_surface');
193
+ const mode = blockers.length ? (risk.level === 'high' ? 'full_proof' : 'balanced') : 'fast_lane';
194
+ return {
195
+ mode,
196
+ eligible: mode === 'fast_lane',
197
+ blockers,
198
+ verification,
199
+ negative_work: safeSkips,
200
+ escalate_on: ['verification_failed', 'proof_cone_unknown', 'source_hash_changed', 'unsupported_claim', 'user_scope_expanded']
201
+ };
202
+ }
203
+
204
+ function nextAction(decision) {
205
+ if (decision.mode === 'fast_lane') return 'apply minimal patch, run listed verification, then Honest Mode against the proof field report';
206
+ if (decision.mode === 'balanced') return 'narrow the change set or run parent-led implementation with listed verification and reviewer escalation if checks fail';
207
+ return 'use full Team/Honest proof path; fast lane is intentionally blocked for this risk state';
208
+ }
209
+
210
+ async function sourceDigest(root, files) {
211
+ const rows = [];
212
+ for (const file of files) {
213
+ const abs = path.resolve(root, file);
214
+ if (!abs.startsWith(path.resolve(root))) continue;
215
+ const text = await readText(abs, null);
216
+ rows.push([rel(root, abs), text == null ? null : sha256(text).slice(0, 16)]);
217
+ }
218
+ return sha256(JSON.stringify(rows)).slice(0, 24);
219
+ }
@@ -13,16 +13,16 @@ function buildMadSksQuestionSchema(prompt) {
13
13
  const task = String(prompt || '').trim() || 'MAD-SKS scoped database override';
14
14
  return {
15
15
  schema_version: 1,
16
- description: 'MAD-SKS is explicit-invocation-only. It auto-seals because the dollar command itself is the permission boundary; table deletion still requires runtime user confirmation with an approximately 30 second timeout.',
16
+ description: 'MAD-SKS is explicit-invocation-only. It auto-seals because the dollar command itself is the permission boundary; while active, SKS opens Supabase MCP schema cleanup and direct DB write permissions, leaving only catastrophic database-wipe safeguards.',
17
17
  prompt,
18
18
  domain_hints: ['db', 'mad-sks'],
19
19
  inferred_answers: {
20
20
  GOAL_PRECISE: `명시적인 MAD-SKS 호출 범위에서만 DB 권한 조건을 넓혀 작업한다: ${task}`,
21
21
  ACCEPTANCE_CRITERIA: [
22
22
  '$MAD-SKS is listed in dollar commands and routes to MADSKS mode',
23
- 'broad Supabase MCP DB manipulation is allowed only while the active MAD-SKS mission gate remains open',
23
+ 'Supabase MCP column cleanup, schema cleanup, direct execute SQL, and normal DB writes are allowed only while the active MAD-SKS mission gate remains open',
24
24
  'the widened permission is inactive after the MAD-SKS gate is passed or permissions_deactivated is true',
25
- 'table deletion requires explicit user confirmation and expires after about 30 seconds without confirmation'
25
+ 'whole database/table removal and all-row delete/update operations remain blocked as non-sensible catastrophic operations'
26
26
  ],
27
27
  NON_GOALS: [],
28
28
  PUBLIC_API_CHANGE_ALLOWED: 'yes_if_needed',
@@ -33,21 +33,21 @@ function buildMadSksQuestionSchema(prompt) {
33
33
  RISK_BOUNDARY: [
34
34
  'MAD-SKS permission widening is explicit-invocation-only',
35
35
  'MAD-SKS permission widening does not persist after the active task gate closes',
36
- 'table deletion must pause for explicit user confirmation and timeout-abort after about 30 seconds'
36
+ 'catastrophic database wipe operations remain blocked even in MAD-SKS'
37
37
  ],
38
38
  MAD_SKS_MODE: 'explicit_invocation_only',
39
39
  DATABASE_TARGET_ENVIRONMENT: 'main_branch',
40
40
  DATABASE_WRITE_MODE: 'mad_sks_full_mcp_write_for_invocation',
41
41
  SUPABASE_MCP_POLICY: 'mad_sks_project_scoped_write_for_invocation',
42
- DESTRUCTIVE_DB_OPERATIONS_ALLOWED: 'mad_sks_scoped_with_table_delete_confirmation',
42
+ DESTRUCTIVE_DB_OPERATIONS_ALLOWED: 'mad_sks_scoped_except_catastrophic_db_wipe',
43
43
  DB_BACKUP_OR_BRANCH_REQUIRED: 'recommended_but_not_required_in_mad_sks',
44
- DB_MAX_BLAST_RADIUS: 'mad_sks_active_invocation_only_table_delete_confirmation_required',
44
+ DB_MAX_BLAST_RADIUS: 'mad_sks_active_invocation_only_catastrophic_wipe_blocked',
45
45
  DB_MIGRATION_APPLY_ALLOWED: 'mad_sks_active_invocation_only',
46
46
  DB_READ_ONLY_QUERY_LIMIT: '100'
47
47
  },
48
48
  inference_notes: {
49
49
  MAD_SKS_MODE: 'explicit dollar command is the permission boundary',
50
- DESTRUCTIVE_DB_OPERATIONS_ALLOWED: 'MAD-SKS scoped override with table deletion confirmation'
50
+ DESTRUCTIVE_DB_OPERATIONS_ALLOWED: 'MAD-SKS opens Supabase MCP DB cleanup while blocking only catastrophic database wipe operations'
51
51
  },
52
52
  slots: []
53
53
  };
@@ -7,7 +7,7 @@ export const FROM_CHAT_IMG_CHECKLIST_ARTIFACT = 'from-chat-img-checklist.md';
7
7
  export const FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT = 'from-chat-img-temp-triwiki.json';
8
8
  export const FROM_CHAT_IMG_QA_LOOP_ARTIFACT = 'from-chat-img-qa-loop.json';
9
9
  export const FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS = 5;
10
- export const USAGE_TOPICS = 'install|setup|bootstrap|root|deps|warp|auto-review|team|qa-loop|goal|research|db|codex-app|dfix|design|imagegen|dollar|context7|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|code-structure';
10
+ export const USAGE_TOPICS = 'install|setup|bootstrap|root|deps|warp|auto-review|team|qa-loop|goal|research|db|codex-app|dfix|design|imagegen|dollar|context7|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|code-structure|proof-field';
11
11
  export const CODEX_COMPUTER_USE_EVIDENCE_SOURCE = 'codex_computer_use';
12
12
  export const CODEX_COMPUTER_USE_ONLY_POLICY = 'Pipeline UI/browser verification and visual inspection must use Codex Computer Use only. Do not use Playwright, Chrome MCP, Browser Use, Selenium, Puppeteer, or any other browser automation substitute; if Codex Computer Use is unavailable, mark the UI/browser evidence unverified instead of substituting another tool.';
13
13
  export const FORBIDDEN_BROWSER_AUTOMATION_RE = /\b(playwright|chrome\s+mcp|browser\s+use|selenium|puppeteer)\b/i;
@@ -276,14 +276,14 @@ export const ROUTES = [
276
276
  command: '$MAD-SKS',
277
277
  mode: 'MADSKS',
278
278
  route: 'explicit scoped database authorization modifier',
279
- description: 'Explicit high-risk authorization modifier that can be combined with other $ commands to temporarily widen Supabase MCP DB permissions for that active invocation only; table deletion still requires user confirmation with an approximately 30 second timeout.',
279
+ description: 'Explicit high-risk authorization modifier that can be combined with other $ commands to temporarily open Supabase MCP column/schema cleanup, direct execute SQL, and normal DB write permissions for the active invocation, while blocking only catastrophic database-wipe operations.',
280
280
  requiredSkills: ['mad-sks', 'db-safety-guard', 'pipeline-runner', 'context7-docs', REFLECTION_SKILL_NAME, 'honest-mode'],
281
- lifecycle: ['explicit_invocation', 'auto_sealed_permission_scope', 'scoped_db_override', 'table_delete_confirmation_gate', 'permission_deactivation', 'post_route_reflection', 'honest_mode'],
281
+ lifecycle: ['explicit_invocation', 'auto_sealed_permission_scope', 'scoped_db_cleanup_override', 'catastrophic_db_guard', 'permission_deactivation', 'post_route_reflection', 'honest_mode'],
282
282
  context7Policy: 'required',
283
283
  reasoningPolicy: 'high',
284
284
  stopGate: 'mad-sks-gate.json',
285
285
  cliEntrypoint: 'Codex App prompt route only: $MAD-SKS <task>',
286
- examples: ['$MAD-SKS $Team Supabase MCP로 main 대상 DB 작업을 수행하되 테이블 삭제는 확인받아', '$DB Supabase 점검 $MAD-SKS']
286
+ examples: ['$MAD-SKS $Team Supabase MCP로 main 대상 DB 컬럼 정리를 수행해', '$DB Supabase 점검 $MAD-SKS']
287
287
  },
288
288
  {
289
289
  id: 'GX',
@@ -376,7 +376,8 @@ export const COMMAND_CATALOG = [
376
376
  { name: 'db', usage: 'sks db policy|scan|mcp-config|classify|check ...', description: 'Inspect and enforce database/Supabase safety policy.' },
377
377
  { name: 'eval', usage: 'sks eval run|compare|thresholds ...', description: 'Run deterministic context-quality and performance evidence checks.' },
378
378
  { name: 'harness', usage: 'sks harness fixture|review [--json]', description: 'Run Harness Growth Factory fixtures for forgetting, skills, experiments, tool taxonomy, permissions, MultiAgentV2, and Warp views.' },
379
- { name: 'perf', usage: 'sks perf run [--json] [--iterations N]', description: 'Measure structured GPT-5.5/SKS performance budgets such as CLI startup and package size.' },
379
+ { name: 'perf', usage: 'sks perf run|workflow [--json] [--iterations N] [--intent "task"] [--changed file1,file2]', description: 'Measure structured GPT-5.5/SKS performance budgets, including Proof Field workflow decisions and fast-lane evidence.' },
380
+ { name: 'proof-field', usage: 'sks proof-field scan [--json] [--intent "task"] [--changed file1,file2]', description: 'Analyze Potential Proof Field cones, negative-work cache, and fast-lane eligibility for a change set.' },
380
381
  { name: 'code-structure', usage: 'sks code-structure scan [--json]', description: 'Scan handwritten source files for 1000/2000/3000-line structure gates and split-review exceptions.' },
381
382
  { name: 'validate-artifacts', usage: 'sks validate-artifacts [mission-id|latest] [--json]', description: 'Validate schema-backed mission artifacts for work orders, effort decisions, visual maps, dogfood reports, skills, mistake memory, Team dashboard state, and Honest Mode.' },
382
383
  { name: 'wiki', usage: 'sks wiki coords|pack|refresh|prune|validate ...', description: 'Build, refresh, prune, and validate RGBA/trig LLM Wiki context packs with attention.use_first and attention.hydrate_first for compact recall plus source hydration.' },