sneakoscope 4.6.0 → 4.6.1

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
@@ -11,7 +11,7 @@
11
11
 
12
12
  `npm i -g sneakoscope` → `sks --mad` → watch up to **100 shadow-clone workers** code in parallel,<br/>each in a live Zellij pane, every claim backed by Completion Proof.
13
13
 
14
- Current package release: **4.6.0**.
14
+ Current package release: **4.6.1**.
15
15
 
16
16
  </div>
17
17
 
@@ -37,7 +37,7 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
37
37
 
38
38
  ## 🚀 Current Release
39
39
 
40
- SKS **4.6.0** adds the proof-backed `seo-geo-optimizer` command and route on one shared search-visibility kernel, plus Lean Engineering Policy evidence in pipeline plans, worker prompts, code-structure reports, GPT final review, and Completion Proof.
40
+ SKS **4.6.1** keeps the 4.6 search-visibility release surface and fixes the MadDB safety hook so direct Supabase MCP `apply_migration` calls use the active persisted MadDB capability when Codex hook payload state drifts.
41
41
 
42
42
  - **`sks seo-geo-optimizer` / `$SEO-GEO-OPTIMIZER`.** Run read-only audit, mutation plan, explicit apply, verification, rollback, and Completion Proof for both Search Engine Optimization and Generative Engine Optimization.
43
43
  - **Mode-specific evidence.** Use `--mode seo` for package/docs/website search visibility, including metadata, canonical, robots, sitemap, locale, structured data, and internal links. Use `--mode geo` for entity facts, claim evidence, answerability, AI crawler purpose policy, and optional `llms.txt` planning. GEO means Generative Engine Optimization, not geolocation.
@@ -76,7 +76,7 @@ dependencies = [
76
76
 
77
77
  [[package]]
78
78
  name = "sks-core"
79
- version = "4.6.0"
79
+ version = "4.6.1"
80
80
  dependencies = [
81
81
  "serde_json",
82
82
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "sks-core"
3
- version = "4.6.0"
3
+ version = "4.6.1"
4
4
  edition = "2021"
5
5
 
6
6
  [dependencies]
@@ -4,7 +4,7 @@ use std::io::{self, Read, Seek, SeekFrom};
4
4
  fn main() {
5
5
  let mut args = std::env::args().skip(1);
6
6
  match args.next().as_deref() {
7
- Some("--version") => println!("sks-rs 4.6.0"),
7
+ Some("--version") => println!("sks-rs 4.6.1"),
8
8
  Some("compact-info") => {
9
9
  let mut input = String::new();
10
10
  let _ = io::stdin().read_to_string(&mut input);
package/dist/bin/sks.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const FAST_PACKAGE_VERSION = '4.6.0';
2
+ const FAST_PACKAGE_VERSION = '4.6.1';
3
3
  const args = process.argv.slice(2);
4
4
  try {
5
5
  if (args[0] === '--agent' && args[1] === 'worker') {
@@ -510,15 +510,16 @@ export async function checkDbOperation(root, state, payload, { duringNoQuestion
510
510
  const contract = await loadMissionContract(root, state);
511
511
  const classification = classifyToolPayload(payload);
512
512
  const madDb = await resolveMadDbMutationPolicy(root, state, classification);
513
- if (madDb.allowed === true && state?.mission_id) {
513
+ if (madDb.allowed === true && madDb.mission_id) {
514
514
  const madDbDecision = madDb;
515
+ const madDbMissionId = String(madDbDecision.mission_id);
515
516
  const sqlText = classification.sql?.statements?.length ? String(classification.sql.statements.join('\n')) : null;
516
517
  const sqlHash = sqlText ? sha256(sqlText) : null;
517
518
  const toolCallId = extractCanonicalToolCallId(payload) || `payload-${sha256(JSON.stringify({ tool: classification.toolName || '', sqlHash, level: classification.level })).slice(0, 16)}`;
518
519
  const operationClasses = madDbDecision.operation_classes?.length ? madDbDecision.operation_classes : madDbOperationClassesFromClassification(classification);
519
520
  const reservation = await reserveMadDbOperation({
520
521
  root,
521
- missionId: String(state.mission_id),
522
+ missionId: madDbMissionId,
522
523
  capability: madDbDecision.capability,
523
524
  toolCallId,
524
525
  toolName: classification.toolName || 'unknown_database_tool',
@@ -527,12 +528,12 @@ export async function checkDbOperation(root, state, payload, { duringNoQuestion
527
528
  });
528
529
  await transitionMadDbOperation({
529
530
  root,
530
- missionId: String(state.mission_id),
531
+ missionId: madDbMissionId,
531
532
  toolCallId,
532
533
  state: 'started'
533
534
  });
534
535
  const lifecycleHook = {
535
- mission_id: String(state.mission_id),
536
+ mission_id: madDbMissionId,
536
537
  operation_id: reservation.operation.operation_id,
537
538
  tool_call_id: toolCallId,
538
539
  cycle_id: madDbDecision.cycle_id || null,
@@ -560,12 +561,13 @@ export async function checkDbOperation(root, state, payload, { duringNoQuestion
560
561
  lifecycle_result_pending: true,
561
562
  ledger_result_hook: lifecycleHook,
562
563
  operation_classes: operationClasses,
564
+ state_source: madDbDecision.state_source || 'hook_state',
563
565
  counters: reservation.capability.counters,
564
566
  idempotent_reservation_reused: reservation.reused
565
567
  }
566
568
  };
567
- await appendMadDbLedgerEvent(root, state.mission_id, { type: 'db_mutation.allowed', cycle_id: madDbDecision.cycle_id, mode: madDbDecision.mode, classification, operation_id: reservation.operation.operation_id, tool_call_id: toolCallId });
568
- await appendJsonlBounded(path.join(missionDir(root, state.mission_id), 'db-safety.jsonl'), { ts: nowIso(), decision });
569
+ await appendMadDbLedgerEvent(root, madDbMissionId, { type: 'db_mutation.allowed', cycle_id: madDbDecision.cycle_id, mode: madDbDecision.mode, classification, operation_id: reservation.operation.operation_id, tool_call_id: toolCallId });
570
+ await appendJsonlBounded(path.join(missionDir(root, madDbMissionId), 'db-safety.jsonl'), { ts: nowIso(), decision });
569
571
  return decision;
570
572
  }
571
573
  const madSks = await madSksOverrideState(root, state);
package/dist/core/fsx.js 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
  import { fileURLToPath } from 'node:url';
8
- export const PACKAGE_VERSION = '4.6.0';
8
+ export const PACKAGE_VERSION = '4.6.1';
9
9
  export const DEFAULT_PROCESS_TAIL_BYTES = 256 * 1024;
10
10
  export const DEFAULT_PROCESS_TIMEOUT_MS = 30 * 60 * 1000;
11
11
  export function nowIso() {
@@ -1,8 +1,26 @@
1
1
  import { isMadDbCapabilityActive, readMadDbCapability } from './mad-db-capability.js';
2
2
  import { activeMadDbAllowsSqlPlane, isMadDbControlPlaneDeniedTool, madDbOperationClassesFromClassification } from './mad-db-policy.js';
3
- import { sha256 } from '../fsx.js';
3
+ import { readJson, sha256 } from '../fsx.js';
4
+ import { stateFile } from '../mission.js';
4
5
  export const MAD_DB_POLICY_DECISION_SCHEMA = 'sks.mad-db-policy-decision.v2';
5
6
  export async function resolveMadDbMutationPolicy(root, state = {}, classification = {}, explicitCapability) {
7
+ const primary = await resolveMadDbMutationPolicyForState(root, state, classification, explicitCapability);
8
+ if (primary.allowed === true || explicitCapability)
9
+ return primary;
10
+ const persistedState = await readJson(stateFile(root), null).catch(() => null);
11
+ if (persistedState && persistedState !== state) {
12
+ const fallback = await resolveMadDbMutationPolicyForState(root, persistedState, classification, null);
13
+ if (fallback.allowed === true) {
14
+ return {
15
+ ...fallback,
16
+ state_source: 'persisted_sks_state',
17
+ reasons: [...fallback.reasons, 'mad_db_persisted_state_binding_used']
18
+ };
19
+ }
20
+ }
21
+ return primary;
22
+ }
23
+ async function resolveMadDbMutationPolicyForState(root, state = {}, classification = {}, explicitCapability) {
6
24
  const missionId = explicitCapability?.mission_id || state?.mad_db_capability_mission_id || state?.mission_id;
7
25
  if (!missionId)
8
26
  return inactive('mission_id_missing');
@@ -39,7 +57,10 @@ export function validateCapabilityBinding(capability, state = {}, classification
39
57
  return { ok: false, reason: `mad_db_capability_${capability.status || 'inactive'}` };
40
58
  if (!capability.project_ref)
41
59
  return { ok: false, reason: 'mad_db_project_ref_missing' };
42
- if (state?.mission_id && String(state.mission_id) !== capability.mission_id)
60
+ const boundMadDbMissionId = state?.mad_db_capability_mission_id ? String(state.mad_db_capability_mission_id) : null;
61
+ if (boundMadDbMissionId === capability.mission_id && state?.mad_db_active === false)
62
+ return { ok: false, reason: 'mad_db_state_inactive' };
63
+ if (state?.mission_id && String(state.mission_id) !== capability.mission_id && boundMadDbMissionId !== capability.mission_id)
43
64
  return { ok: false, reason: 'mad_db_mission_binding_mismatch' };
44
65
  if (state?.mad_db_cycle_id && String(state.mad_db_cycle_id) !== capability.cycle_id)
45
66
  return { ok: false, reason: 'mad_db_cycle_binding_mismatch' };
@@ -1,2 +1,2 @@
1
- export const PACKAGE_VERSION = '4.6.0';
1
+ export const PACKAGE_VERSION = '4.6.1';
2
2
  //# sourceMappingURL=version.js.map
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { createMission, setCurrent, missionDir } from '../core/mission.js';
6
+ import { checkDbOperation } from '../core/db-safety.js';
7
+ import { createMadDbCapability, MAD_DB_ACK, readMadDbCapability } from '../core/mad-db/mad-db-capability.js';
8
+ import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
9
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-mad-db-direct-apply-'));
10
+ const mission = await createMission(root, { mode: 'mad-db', prompt: '$MAD-DB direct apply_migration fixture' });
11
+ const capability = await createMadDbCapability(root, {
12
+ missionId: mission.id,
13
+ ack: MAD_DB_ACK,
14
+ cwd: root,
15
+ ttlMs: 60000,
16
+ projectRef: 'fixture-project-ref',
17
+ status: 'active'
18
+ });
19
+ await setCurrent(root, {
20
+ mission_id: mission.id,
21
+ mode: 'MADDB',
22
+ route: 'MadDB',
23
+ route_command: '$MAD-DB',
24
+ phase: 'MADDB_SQL_PLANE_CAPABILITY_ACTIVE',
25
+ implementation_allowed: true,
26
+ mad_db_active: true,
27
+ mad_db_capability_mission_id: mission.id,
28
+ mad_db_cycle_id: capability.cycle_id,
29
+ mad_db_runtime_session_id: capability.runtime_session_id,
30
+ mad_db_profile_sha256: capability.transport.profile_sha256,
31
+ mad_db_capability_file: 'mad-db-capability.json'
32
+ });
33
+ const payloadStateFromCodex = { mission_id: 'codex-payload-state', mode: 'AGENT', phase: 'TOOL_CALL' };
34
+ const decision = await checkDbOperation(root, payloadStateFromCodex, {
35
+ tool_name: 'mcp__supabase__apply_migration',
36
+ tool_call_id: 'direct-apply-migration-call',
37
+ tool_input: {
38
+ name: 'direct_apply_fixture',
39
+ query: 'alter table public.fixture add column if not exists direct_apply_fixture text;'
40
+ }
41
+ });
42
+ const updated = await readMadDbCapability(root, mission.id);
43
+ const wrongMissionDirExists = fs.existsSync(missionDir(root, payloadStateFromCodex.mission_id));
44
+ assertGate(decision.allowed === true && decision.mad_db?.active === true, 'direct Supabase MCP apply_migration must be allowed by persisted active MadDB capability', decision);
45
+ assertGate(decision.mad_db.operation_classes.includes('migration_apply'), 'direct apply_migration must reserve a migration_apply operation class', decision);
46
+ assertGate(decision.mad_db.state_source === 'persisted_sks_state', 'drifted hook payload state must fall back to persisted SKS MadDB state', decision);
47
+ assertGate(updated?.counters.reserved === 1, 'direct apply_migration reservation must land on the real MadDB mission capability', updated || {});
48
+ assertGate(wrongMissionDirExists === false, 'direct apply_migration must not create or write under the drifted payload mission id');
49
+ emitGate('mad-db:direct-apply-migration-hook', { mission_id: mission.id, operation_id: decision.mad_db.operation_id, counters: updated?.counters });
50
+ //# sourceMappingURL=mad-db-direct-apply-migration-hook-check.js.map
@@ -115,6 +115,7 @@ const requiredReleasePresetIds = [
115
115
  'mad-db:operation-lifecycle-ledger',
116
116
  'mad-db:route-identity',
117
117
  'mad-db:hook-idempotency',
118
+ 'mad-db:direct-apply-migration-hook',
118
119
  'mad-db:parallel-lifecycle',
119
120
  'mad-db:runtime-profile',
120
121
  'mad-db:skill-policy',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sneakoscope",
3
3
  "displayName": "ㅅㅋㅅ",
4
- "version": "4.6.0",
4
+ "version": "4.6.1",
5
5
  "description": "Sneakoscope Codex: fast proof-first Codex trust layer with image-based Voxel TriWiki.",
6
6
  "type": "module",
7
7
  "homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
@@ -739,6 +739,7 @@
739
739
  "mad-db:operation-lifecycle-ledger": "node ./dist/scripts/mad-db-operation-lifecycle-ledger-check.js",
740
740
  "mad-db:route-identity": "node ./dist/scripts/mad-db-route-identity-check.js",
741
741
  "mad-db:hook-idempotency": "node ./dist/scripts/mad-db-hook-idempotency-check.js",
742
+ "mad-db:direct-apply-migration-hook": "node ./dist/scripts/mad-db-direct-apply-migration-hook-check.js",
742
743
  "mad-db:parallel-lifecycle": "node ./dist/scripts/mad-db-parallel-lifecycle-check.js",
743
744
  "mad-db:runtime-profile": "node ./dist/scripts/mad-db-runtime-profile-lifecycle-check.js",
744
745
  "mad-db:skill-policy": "node ./dist/scripts/mad-db-skill-policy-snapshot-check.js",
@@ -776,7 +777,7 @@
776
777
  "mad-db:lifecycle-hook-decision": "node ./dist/scripts/mad-db-lifecycle-hook-decision-check.js",
777
778
  "mad-db:mcp-result-lifecycle": "node ./dist/scripts/mad-db-mcp-result-lifecycle-check.js",
778
779
  "mad-db:operation-lifecycle-blackbox": "node ./dist/scripts/mad-db-operation-lifecycle-blackbox.js",
779
- "mad-db:unit": "npm run mad-db:capability && npm run mad-db:command && npm run mad-db:mad-command && npm run mad-db:priority-resolver && npm run mad-db:ledger && npm run mad-db:one-cycle-consumption && npm run mad-db:safety-conflict-matrix && npm run mad-db:one-cycle-bounded && npm run mad-db:operation-lifecycle-ledger && npm run mad-db:route-identity && npm run mad-db:hook-idempotency && npm run mad-db:parallel-lifecycle && npm run mad-db:runtime-profile && npm run mad-db:skill-policy && npm run mad-db:policy-v2 && npm run mad-db:lifecycle-hook-decision && npm run mad-db:mcp-result-lifecycle && npm run mad-db:operation-lifecycle-blackbox",
780
+ "mad-db:unit": "npm run mad-db:capability && npm run mad-db:command && npm run mad-db:mad-command && npm run mad-db:priority-resolver && npm run mad-db:ledger && npm run mad-db:one-cycle-consumption && npm run mad-db:safety-conflict-matrix && npm run mad-db:one-cycle-bounded && npm run mad-db:operation-lifecycle-ledger && npm run mad-db:route-identity && npm run mad-db:hook-idempotency && npm run mad-db:direct-apply-migration-hook && npm run mad-db:parallel-lifecycle && npm run mad-db:runtime-profile && npm run mad-db:skill-policy && npm run mad-db:policy-v2 && npm run mad-db:lifecycle-hook-decision && npm run mad-db:mcp-result-lifecycle && npm run mad-db:operation-lifecycle-blackbox",
780
781
  "mad-db:real-e2e": "node ./dist/scripts/mad-db-real-supabase-e2e.js --require-real",
781
782
  "mad-db:all": "npm run build && npm run mad-db:unit",
782
783
  "mad-db:release": "npm run mad-db:all && npm run mad-db:real-e2e",