sneakoscope 1.14.1 → 1.15.0
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 +9 -6
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/.sks-build-stamp.json +8 -0
- package/dist/bin/sks.js +1 -1
- package/dist/build-manifest.json +19 -1
- package/dist/commands/wiki.d.ts +1 -1
- package/dist/core/codex-exec-output-schema.d.ts +29 -0
- package/dist/core/codex-exec-output-schema.js +81 -0
- package/dist/core/commands/mad-sks-command.js +253 -1
- package/dist/core/commands/scouts-command.js +87 -13
- package/dist/core/commands/wiki-command.d.ts +2 -2
- package/dist/core/evidence/flagship-proof-graph-validator.d.ts +14 -0
- package/dist/core/evidence/flagship-proof-graph-validator.js +71 -0
- package/dist/core/feature-fixtures.js +1 -1
- package/dist/core/fsx.d.ts +1 -1
- package/dist/core/fsx.js +1 -1
- package/dist/core/hooks-runtime.js +25 -0
- package/dist/core/mad-sks/audit-ledger.d.ts +55 -0
- package/dist/core/mad-sks/audit-ledger.js +46 -0
- package/dist/core/mad-sks/authorization-manifest.d.ts +28 -0
- package/dist/core/mad-sks/authorization-manifest.js +58 -0
- package/dist/core/mad-sks/immutable-harness-guard.d.ts +142 -0
- package/dist/core/mad-sks/immutable-harness-guard.js +195 -0
- package/dist/core/mad-sks/permission-model.d.ts +54 -0
- package/dist/core/mad-sks/permission-model.js +167 -0
- package/dist/core/mad-sks/proof-evidence.d.ts +40 -0
- package/dist/core/mad-sks/proof-evidence.js +38 -0
- package/dist/core/mad-sks/rollback-plan.d.ts +39 -0
- package/dist/core/mad-sks/rollback-plan.js +26 -0
- package/dist/core/mad-sks/write-guard.d.ts +71 -0
- package/dist/core/mad-sks/write-guard.js +88 -0
- package/dist/core/permission-gates.js +18 -1
- package/dist/core/proof/evidence-collector.d.ts +1 -1
- package/dist/core/proof/route-adapter.d.ts +42 -0
- package/dist/core/proof/route-finalizer.d.ts +43 -1
- package/dist/core/proof/route-finalizer.js +2 -1
- package/dist/core/proof/selftest-proof-fixtures.d.ts +42 -0
- package/dist/core/scouts/engines/codex-exec-parallel-engine.js +3 -3
- package/dist/core/scouts/engines/scout-engine-detect.js +5 -3
- package/dist/core/triwiki-wrongness/wrongness-cli.d.ts +2 -2
- package/dist/core/triwiki-wrongness/wrongness-proof-linker.d.ts +1 -1
- package/dist/core/triwiki-wrongness/wrongness-retrieval.d.ts +1 -1
- package/dist/core/triwiki-wrongness/wrongness-schema.d.ts +1 -1
- package/dist/core/triwiki-wrongness/wrongness-schema.js +8 -0
- package/dist/core/trust-kernel/trust-report.d.ts +84 -0
- package/dist/core/trust-kernel/trust-report.js +36 -2
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/package.json +17 -7
package/README.md
CHANGED
|
@@ -10,15 +10,15 @@ SKS does not try to clone every other harness. It focuses on one thing: making C
|
|
|
10
10
|
|
|
11
11
|
## Current Release
|
|
12
12
|
|
|
13
|
-
SKS **1.
|
|
13
|
+
SKS **1.15.0** promotes MAD-SKS into explicit user-authorized full-system authority while keeping the SKS harness itself immutable. It also closes the 1.14.1 freshness gaps: release gates check for stale `dist`, Codex exec output-schema syntax is verified for both fresh `exec` and `exec resume`, Scout engine-run lookup covers status/consensus/handoff/validate plus opt-in real smoke, and flagship proof graph v3 binds MAD-SKS audit, rollback, immutable guard, Hook, UX/PPT, DFix, and Scout evidence.
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
+
sks mad-sks plan --target-root <path> --json
|
|
17
|
+
sks mad-sks permissions --json
|
|
18
|
+
sks mad-sks proof --json
|
|
16
19
|
sks features complete --json
|
|
17
|
-
sks
|
|
18
|
-
|
|
19
|
-
sks dfix fixture --json
|
|
20
|
-
sks hooks trust-doctor --actual --json
|
|
21
|
-
sks hooks install --managed --json
|
|
20
|
+
sks scouts status latest --engine-runs --json
|
|
21
|
+
npm run release:readiness
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
Detailed release history lives in [CHANGELOG.md](CHANGELOG.md). Current release gate status lives in [docs/release-readiness.md](docs/release-readiness.md).
|
|
@@ -38,6 +38,9 @@ Detailed release history lives in [CHANGELOG.md](CHANGELOG.md). Current release
|
|
|
38
38
|
- Package boundary: [docs/package-boundary.md](docs/package-boundary.md)
|
|
39
39
|
- Black-box package tests: [docs/black-box-package-tests.md](docs/black-box-package-tests.md)
|
|
40
40
|
- Codex CLI compatibility: [docs/codex-cli-compat.md](docs/codex-cli-compat.md)
|
|
41
|
+
- MAD-SKS: [docs/mad-sks.md](docs/mad-sks.md)
|
|
42
|
+
- Permission kernel: [docs/permission-kernel.md](docs/permission-kernel.md)
|
|
43
|
+
- Immutable harness guard: [docs/immutable-harness-guard.md](docs/immutable-harness-guard.md)
|
|
41
44
|
- Codex App: [docs/codex-app.md](docs/codex-app.md)
|
|
42
45
|
- Core dominance: [docs/core-dominance.md](docs/core-dominance.md)
|
|
43
46
|
- Performance budgets: [docs/performance-budgets.md](docs/performance-budgets.md)
|
|
@@ -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 1.
|
|
7
|
+
Some("--version") => println!("sks-rs 1.15.0"),
|
|
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
package/dist/build-manifest.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "sks.dist-build.v2",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
|
+
"package_version": "1.15.0",
|
|
4
5
|
"typescript": true,
|
|
5
6
|
"mjs_runtime_files": 0,
|
|
7
|
+
"source_digest": "0edaa5eb690818f453a1c1fdc205d0edda1766ad38fdf0ce69ecbc472e6bd23e",
|
|
8
|
+
"source_file_count": 1428,
|
|
9
|
+
"dist_stamp_schema": "sks.dist-build-stamp.v1",
|
|
6
10
|
"files": [
|
|
7
11
|
"bin/sks.d.ts",
|
|
8
12
|
"bin/sks.js",
|
|
@@ -456,6 +460,20 @@
|
|
|
456
460
|
"core/language-preference.js",
|
|
457
461
|
"core/loop-blocker.d.ts",
|
|
458
462
|
"core/loop-blocker.js",
|
|
463
|
+
"core/mad-sks/audit-ledger.d.ts",
|
|
464
|
+
"core/mad-sks/audit-ledger.js",
|
|
465
|
+
"core/mad-sks/authorization-manifest.d.ts",
|
|
466
|
+
"core/mad-sks/authorization-manifest.js",
|
|
467
|
+
"core/mad-sks/immutable-harness-guard.d.ts",
|
|
468
|
+
"core/mad-sks/immutable-harness-guard.js",
|
|
469
|
+
"core/mad-sks/permission-model.d.ts",
|
|
470
|
+
"core/mad-sks/permission-model.js",
|
|
471
|
+
"core/mad-sks/proof-evidence.d.ts",
|
|
472
|
+
"core/mad-sks/proof-evidence.js",
|
|
473
|
+
"core/mad-sks/rollback-plan.d.ts",
|
|
474
|
+
"core/mad-sks/rollback-plan.js",
|
|
475
|
+
"core/mad-sks/write-guard.d.ts",
|
|
476
|
+
"core/mad-sks/write-guard.js",
|
|
459
477
|
"core/managed-paths.d.ts",
|
|
460
478
|
"core/managed-paths.js",
|
|
461
479
|
"core/memory-governor.d.ts",
|
package/dist/commands/wiki.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare function run(_command: any, args?: any): Promise<void | {
|
|
|
15
15
|
};
|
|
16
16
|
active_records: {
|
|
17
17
|
id: string;
|
|
18
|
-
kind: "callout_extraction_schema_failed" | "missing_evidence" | "incorrect_claim" | "overconfident_claim" | "stale_evidence" | "test_failure" | "route_misclassification" | "scout_error" | "visual_anchor_error" | "image_bbox_error" | "db_safety_false_positive" | "db_safety_false_negative" | "hook_policy_mismatch" | "hook_semantic_mismatch" | "hook_strict_subset_misclassified" | "codex_lb_health_misread" | "codex_lb_missing_env_raw_message" | "codex_lb_setup_choice_drift" | "codex_lb_env_persistence_failure" | "computer_use_policy_misclassification" | "computer_use_live_smoke_mismatch" | "computer_use_external_block_overclaimed" | "mock_real_confusion" | "user_intent_misread" | "artifact_schema_error" | "trust_status_overclaim" | "ux_review_text_only_fallback" | "ux_generated_image_not_real" | "ux_fake_generic_callout_detected" | "ux_callout_ocr_uncertain" | "gpt_image_2_callout_generation_failed" | "callout_bbox_out_of_bounds" | "ux_patch_applied_without_recheck" | "ux_after_recheck_regression" | "ux_image_fidelity_mismatch" | "ux_output_schema_unavailable_fallback" | "fix_loop_noop_patch" | "visual_fix_not_rechecked" | "post_fix_regression_detected" | "ppt_text_only_review_fallback" | "ppt_slide_export_failed" | "ppt_imagegen_callout_generation_failed" | "ppt_slide_callout_extraction_failed" | "ppt_slide_bbox_out_of_bounds" | "ppt_deck_patch_noop" | "ppt_fix_not_reexported" | "ppt_slide_not_rechecked" | "ppt_post_fix_regression_detected" | "dfix_diagnosis_missing" | "dfix_root_cause_missing" | "dfix_patch_plan_missing" | "dfix_verification_missing" | "dfix_noop_patch" | "repeated_blocker_stop";
|
|
18
|
+
kind: "callout_extraction_schema_failed" | "missing_evidence" | "incorrect_claim" | "overconfident_claim" | "stale_evidence" | "test_failure" | "route_misclassification" | "scout_error" | "visual_anchor_error" | "image_bbox_error" | "db_safety_false_positive" | "db_safety_false_negative" | "hook_policy_mismatch" | "hook_semantic_mismatch" | "hook_strict_subset_misclassified" | "codex_lb_health_misread" | "codex_lb_missing_env_raw_message" | "codex_lb_setup_choice_drift" | "codex_lb_env_persistence_failure" | "computer_use_policy_misclassification" | "computer_use_live_smoke_mismatch" | "computer_use_external_block_overclaimed" | "mock_real_confusion" | "user_intent_misread" | "artifact_schema_error" | "trust_status_overclaim" | "ux_review_text_only_fallback" | "ux_generated_image_not_real" | "ux_fake_generic_callout_detected" | "ux_callout_ocr_uncertain" | "gpt_image_2_callout_generation_failed" | "callout_bbox_out_of_bounds" | "ux_patch_applied_without_recheck" | "ux_after_recheck_regression" | "ux_image_fidelity_mismatch" | "ux_output_schema_unavailable_fallback" | "fix_loop_noop_patch" | "visual_fix_not_rechecked" | "post_fix_regression_detected" | "ppt_text_only_review_fallback" | "ppt_slide_export_failed" | "ppt_imagegen_callout_generation_failed" | "ppt_slide_callout_extraction_failed" | "ppt_slide_bbox_out_of_bounds" | "ppt_deck_patch_noop" | "ppt_fix_not_reexported" | "ppt_slide_not_rechecked" | "ppt_post_fix_regression_detected" | "dfix_diagnosis_missing" | "dfix_root_cause_missing" | "dfix_patch_plan_missing" | "dfix_verification_missing" | "dfix_noop_patch" | "mad_sks_protected_core_write_attempt" | "mad_sks_symlink_escape_attempt" | "mad_sks_unapproved_system_access" | "mad_sks_missing_rollback_plan" | "mad_sks_secret_leak_detected" | "mad_sks_unverified_system_change" | "mad_sks_db_write_without_snapshot" | "mad_sks_service_control_without_previous_state" | "repeated_blocker_stop";
|
|
19
19
|
severity: "high" | "low" | "medium" | "critical";
|
|
20
20
|
route: string | null;
|
|
21
21
|
claim: string;
|
|
@@ -8,6 +8,26 @@ export interface CodexExecResumeOutputSchemaAvailability {
|
|
|
8
8
|
output_last_message_supported: boolean;
|
|
9
9
|
warnings: string[];
|
|
10
10
|
}
|
|
11
|
+
export interface CodexExecOutputSchemaSyntaxAvailability {
|
|
12
|
+
schema: 'sks.codex-exec-output-schema-syntax.v1';
|
|
13
|
+
ok: boolean;
|
|
14
|
+
status: 'available' | 'integration_optional' | 'degraded_supported';
|
|
15
|
+
codex_bin: string | null;
|
|
16
|
+
version: string | null;
|
|
17
|
+
exec: {
|
|
18
|
+
output_schema_supported: boolean;
|
|
19
|
+
output_last_message_supported: boolean;
|
|
20
|
+
help_checked: boolean;
|
|
21
|
+
};
|
|
22
|
+
resume: {
|
|
23
|
+
output_schema_supported: boolean;
|
|
24
|
+
output_last_message_supported: boolean;
|
|
25
|
+
help_checked: boolean;
|
|
26
|
+
};
|
|
27
|
+
parity: boolean;
|
|
28
|
+
blockers: string[];
|
|
29
|
+
warnings: string[];
|
|
30
|
+
}
|
|
11
31
|
export interface CodexResumeOutputSchemaCommandInput {
|
|
12
32
|
sessionId: string;
|
|
13
33
|
prompt?: string;
|
|
@@ -16,6 +36,14 @@ export interface CodexResumeOutputSchemaCommandInput {
|
|
|
16
36
|
json?: boolean;
|
|
17
37
|
extraArgs?: readonly string[];
|
|
18
38
|
}
|
|
39
|
+
export interface CodexExecOutputSchemaCommandInput {
|
|
40
|
+
prompt: string;
|
|
41
|
+
outputSchemaPath: string;
|
|
42
|
+
outputFile?: string | null;
|
|
43
|
+
json?: boolean;
|
|
44
|
+
extraArgs?: readonly string[];
|
|
45
|
+
}
|
|
46
|
+
export declare function detectCodexExecOutputSchemaSyntax(opts?: any): Promise<CodexExecOutputSchemaSyntaxAvailability>;
|
|
19
47
|
export interface CodexExecResumeOutputSchemaRunResult {
|
|
20
48
|
schema: 'sks.codex-exec-output-schema-run.v1';
|
|
21
49
|
ok: boolean;
|
|
@@ -35,6 +63,7 @@ export interface CodexExecResumeOutputSchemaRunResult {
|
|
|
35
63
|
exit_code: number | null;
|
|
36
64
|
}
|
|
37
65
|
export declare function detectCodexExecResumeOutputSchema(opts?: any): Promise<CodexExecResumeOutputSchemaAvailability>;
|
|
66
|
+
export declare function buildCodexExecOutputSchemaArgs(input: CodexExecOutputSchemaCommandInput): Promise<string[]>;
|
|
38
67
|
export declare function codexSchemaPath(name: string): Promise<string>;
|
|
39
68
|
export declare function assertCodexSchemaFile(schemaPath: string): Promise<{
|
|
40
69
|
ok: boolean;
|
|
@@ -3,6 +3,72 @@ import fsp from 'node:fs/promises';
|
|
|
3
3
|
import { ensureDir, exists, packageRoot, readJson, runProcess, which } from './fsx.js';
|
|
4
4
|
import { codexVersionPolicy, compareSemverLike, parseCodexVersionText } from './codex-compat/codex-version-policy.js';
|
|
5
5
|
import { validateJsonSchemaRecursive } from './json-schema-validator.js';
|
|
6
|
+
export async function detectCodexExecOutputSchemaSyntax(opts = {}) {
|
|
7
|
+
const codexBin = opts.codexBin || await which('codex').catch(() => null);
|
|
8
|
+
if (!codexBin) {
|
|
9
|
+
return {
|
|
10
|
+
schema: 'sks.codex-exec-output-schema-syntax.v1',
|
|
11
|
+
ok: true,
|
|
12
|
+
status: 'integration_optional',
|
|
13
|
+
codex_bin: null,
|
|
14
|
+
version: null,
|
|
15
|
+
exec: { output_schema_supported: false, output_last_message_supported: false, help_checked: false },
|
|
16
|
+
resume: { output_schema_supported: false, output_last_message_supported: false, help_checked: false },
|
|
17
|
+
parity: false,
|
|
18
|
+
blockers: [],
|
|
19
|
+
warnings: ['codex binary not detected; output-schema syntax check is integration_optional']
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const versionResult = opts.versionText
|
|
23
|
+
? { code: 0, stdout: String(opts.versionText), stderr: '' }
|
|
24
|
+
: await runProcess(codexBin, ['--version'], { timeoutMs: opts.timeoutMs || 3000, maxOutputBytes: 16 * 1024 });
|
|
25
|
+
const execHelpResult = opts.execHelpText
|
|
26
|
+
? { code: 0, stdout: String(opts.execHelpText), stderr: '' }
|
|
27
|
+
: await runProcess(codexBin, ['exec', '--help'], { timeoutMs: opts.timeoutMs || 5000, maxOutputBytes: 64 * 1024 });
|
|
28
|
+
const resumeHelpResult = opts.resumeHelpText
|
|
29
|
+
? { code: 0, stdout: String(opts.resumeHelpText), stderr: '' }
|
|
30
|
+
: await runProcess(codexBin, ['exec', 'resume', '--help'], { timeoutMs: opts.timeoutMs || 5000, maxOutputBytes: 64 * 1024 });
|
|
31
|
+
const rawVersion = `${versionResult.stdout || ''}\n${versionResult.stderr || ''}`;
|
|
32
|
+
const version = parseCodexVersionText(rawVersion);
|
|
33
|
+
const execHelp = `${execHelpResult.stdout || ''}\n${execHelpResult.stderr || ''}`;
|
|
34
|
+
const resumeHelp = `${resumeHelpResult.stdout || ''}\n${resumeHelpResult.stderr || ''}`;
|
|
35
|
+
const execSupported = /--output-schema\b/.test(execHelp);
|
|
36
|
+
const resumeSupported = /--output-schema\b/.test(resumeHelp) || Boolean(version && compareSemverLike(version, '0.132.0') >= 0 && /--output-schema\b/.test(resumeHelp));
|
|
37
|
+
const execLastMessage = /--output-last-message\b|-o,/.test(execHelp);
|
|
38
|
+
const resumeLastMessage = /--output-last-message\b|-o,/.test(resumeHelp);
|
|
39
|
+
const policy = codexVersionPolicy({ available: Boolean(version), version, source: 'codex --version' });
|
|
40
|
+
const blockers = [
|
|
41
|
+
...(execHelpResult.code === 0 ? [] : ['codex_exec_help_failed']),
|
|
42
|
+
...(resumeHelpResult.code === 0 ? [] : ['codex_exec_resume_help_failed'])
|
|
43
|
+
];
|
|
44
|
+
const status = policy.status === 'integration_optional'
|
|
45
|
+
? 'integration_optional'
|
|
46
|
+
: execSupported || resumeSupported ? 'available' : 'degraded_supported';
|
|
47
|
+
return {
|
|
48
|
+
schema: 'sks.codex-exec-output-schema-syntax.v1',
|
|
49
|
+
ok: blockers.length === 0,
|
|
50
|
+
status,
|
|
51
|
+
codex_bin: codexBin,
|
|
52
|
+
version,
|
|
53
|
+
exec: {
|
|
54
|
+
output_schema_supported: execSupported,
|
|
55
|
+
output_last_message_supported: execLastMessage,
|
|
56
|
+
help_checked: execHelpResult.code === 0
|
|
57
|
+
},
|
|
58
|
+
resume: {
|
|
59
|
+
output_schema_supported: resumeSupported,
|
|
60
|
+
output_last_message_supported: resumeLastMessage,
|
|
61
|
+
help_checked: resumeHelpResult.code === 0
|
|
62
|
+
},
|
|
63
|
+
parity: execSupported === resumeSupported,
|
|
64
|
+
blockers,
|
|
65
|
+
warnings: [
|
|
66
|
+
...policy.warnings,
|
|
67
|
+
...(execSupported ? [] : ['codex exec --output-schema unavailable']),
|
|
68
|
+
...(resumeSupported ? [] : ['codex exec resume --output-schema unavailable'])
|
|
69
|
+
]
|
|
70
|
+
};
|
|
71
|
+
}
|
|
6
72
|
export async function detectCodexExecResumeOutputSchema(opts = {}) {
|
|
7
73
|
const codexBin = opts.codexBin || await which('codex').catch(() => null);
|
|
8
74
|
if (!codexBin) {
|
|
@@ -47,6 +113,21 @@ export async function detectCodexExecResumeOutputSchema(opts = {}) {
|
|
|
47
113
|
warnings
|
|
48
114
|
};
|
|
49
115
|
}
|
|
116
|
+
export async function buildCodexExecOutputSchemaArgs(input) {
|
|
117
|
+
const schemaPath = path.resolve(input.outputSchemaPath);
|
|
118
|
+
const schema = await assertCodexSchemaFile(schemaPath);
|
|
119
|
+
if (!schema.ok)
|
|
120
|
+
throw new Error(`Invalid output schema: ${schema.issues.join(', ')}`);
|
|
121
|
+
const args = ['exec'];
|
|
122
|
+
if (input.json !== false)
|
|
123
|
+
args.push('--json');
|
|
124
|
+
args.push('--output-schema', schemaPath);
|
|
125
|
+
if (input.outputFile)
|
|
126
|
+
args.push('--output-last-message', path.resolve(input.outputFile));
|
|
127
|
+
args.push(...Array.from(input.extraArgs || []));
|
|
128
|
+
args.push(String(input.prompt || ''));
|
|
129
|
+
return args;
|
|
130
|
+
}
|
|
50
131
|
export async function codexSchemaPath(name) {
|
|
51
132
|
const clean = String(name || '').replace(/[^A-Za-z0-9_.-]+/g, '');
|
|
52
133
|
const file = clean.endsWith('.json') ? clean : `${clean}.schema.json`;
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { appendJsonlBounded, exists, nowIso, readJson, sksRoot, writeJsonAtomic } from '../fsx.js';
|
|
2
|
+
import { appendJsonlBounded, exists, nowIso, packageRoot, readJson, sksRoot, writeJsonAtomic } from '../fsx.js';
|
|
3
3
|
import { initProject } from '../init.js';
|
|
4
4
|
import { createMission, setCurrent } from '../mission.js';
|
|
5
5
|
import { enableMadHighProfile, madHighProfileName } from '../auto-review.js';
|
|
6
6
|
import { permissionGateSummary } from '../permission-gates.js';
|
|
7
7
|
import { defaultTmuxSessionName, launchMadTmuxUi, sanitizeTmuxSessionName } from '../tmux-ui.js';
|
|
8
|
+
import { createMadSksAuthorizationManifest, validateMadSksAuthorizationManifest } from '../mad-sks/authorization-manifest.js';
|
|
9
|
+
import { createMadSksAuditLedger, madSksAuditAction, writeMadSksAuditLedger } from '../mad-sks/audit-ledger.js';
|
|
10
|
+
import { compareProtectedCoreSnapshots, evaluateMadSksWrite, resolveProtectedCore, snapshotProtectedCore } from '../mad-sks/immutable-harness-guard.js';
|
|
11
|
+
import { buildMadSksPermissionModel, parseMadSksFlags } from '../mad-sks/permission-model.js';
|
|
12
|
+
import { createMadSksProofEvidence, writeMadSksProofEvidence } from '../mad-sks/proof-evidence.js';
|
|
13
|
+
import { createMadSksRollbackPlan, writeMadSksRollbackPlan } from '../mad-sks/rollback-plan.js';
|
|
8
14
|
export async function madHighCommand(args = [], deps = {}) {
|
|
15
|
+
const subcommand = firstSubcommand(args);
|
|
16
|
+
if (subcommand)
|
|
17
|
+
return madSksSubcommand(subcommand, args.filter((arg) => String(arg) !== subcommand));
|
|
9
18
|
const cleanArgs = args.filter((arg) => !['--mad', '--MAD', '--mad-sks', '--high', '--no-auto-install-tmux'].includes(arg));
|
|
10
19
|
if (args.includes('--json')) {
|
|
11
20
|
const profile = await enableMadHighProfile();
|
|
@@ -127,4 +136,247 @@ export async function madSksFixture(root) {
|
|
|
127
136
|
await writeJsonAtomic(path.join(dir, 'mad-sks-gate.json'), gate);
|
|
128
137
|
return { mission_id: id, dir, gate };
|
|
129
138
|
}
|
|
139
|
+
const MAD_SKS_COMMAND_SURFACE = Object.freeze([
|
|
140
|
+
'plan',
|
|
141
|
+
'run',
|
|
142
|
+
'apply',
|
|
143
|
+
'doctor',
|
|
144
|
+
'status',
|
|
145
|
+
'permissions',
|
|
146
|
+
'proof',
|
|
147
|
+
'rollback-plan',
|
|
148
|
+
'audit',
|
|
149
|
+
'explain'
|
|
150
|
+
]);
|
|
151
|
+
async function madSksSubcommand(subcommand, args = []) {
|
|
152
|
+
const json = args.includes('--json');
|
|
153
|
+
const targetRoot = path.resolve(readOption(args, '--target-root', process.cwd()));
|
|
154
|
+
const userIntent = readOption(args, '--intent', 'MAD-SKS user-authorized maintenance');
|
|
155
|
+
const flags = parseMadSksFlags(['--mad-sks', subcommand === 'plan' ? '--plan-only' : '', ...args].filter(Boolean));
|
|
156
|
+
const permission = buildMadSksPermissionModel({ targetRoot, userIntent, flags });
|
|
157
|
+
const root = await sksRoot();
|
|
158
|
+
if (subcommand === 'permissions') {
|
|
159
|
+
return emit({
|
|
160
|
+
schema: 'sks.mad-sks-permissions.v1',
|
|
161
|
+
ok: true,
|
|
162
|
+
command_surface: [...MAD_SKS_COMMAND_SURFACE],
|
|
163
|
+
permission_flags: [
|
|
164
|
+
'--mad-sks',
|
|
165
|
+
'--allow-system',
|
|
166
|
+
'--allow-db-write',
|
|
167
|
+
'--allow-package-install',
|
|
168
|
+
'--allow-service-control',
|
|
169
|
+
'--allow-admin',
|
|
170
|
+
'--allow-network',
|
|
171
|
+
'--allow-computer-use',
|
|
172
|
+
'--allow-browser-use',
|
|
173
|
+
'--allow-generated-assets',
|
|
174
|
+
'--allow-file-permissions',
|
|
175
|
+
'--allow-delete',
|
|
176
|
+
'--confirm-delete'
|
|
177
|
+
],
|
|
178
|
+
permission_model: permission,
|
|
179
|
+
protected_core: resolveProtectedCore({ packageRoot: packageRoot(), targetRoot }),
|
|
180
|
+
protected_core_immutable: true,
|
|
181
|
+
protected_core_write_allowed: false
|
|
182
|
+
}, json);
|
|
183
|
+
}
|
|
184
|
+
if (subcommand === 'explain') {
|
|
185
|
+
return emit({
|
|
186
|
+
schema: 'sks.mad-sks-explain.v1',
|
|
187
|
+
ok: true,
|
|
188
|
+
summary: 'MAD-SKS is a user-authorized high-power maintenance mode. Target project work can be widened by explicit flags, while SKS harness/package/dist/scripts/schemas/release metadata remain immutable protected core.',
|
|
189
|
+
command_surface: [...MAD_SKS_COMMAND_SURFACE],
|
|
190
|
+
catastrophic_safeguards: permission.forbidden_scopes,
|
|
191
|
+
immutable_harness_guard: 'always_on'
|
|
192
|
+
}, json);
|
|
193
|
+
}
|
|
194
|
+
if (subcommand === 'doctor' || subcommand === 'status') {
|
|
195
|
+
const protectedCore = resolveProtectedCore({ packageRoot: packageRoot(), targetRoot });
|
|
196
|
+
const before = await snapshotProtectedCore(packageRoot(), 'status');
|
|
197
|
+
return emit({
|
|
198
|
+
schema: subcommand === 'doctor' ? 'sks.mad-sks-doctor.v1' : 'sks.mad-sks-status.v1',
|
|
199
|
+
ok: true,
|
|
200
|
+
target_root: targetRoot,
|
|
201
|
+
permission_model: permission,
|
|
202
|
+
protected_core: protectedCore,
|
|
203
|
+
protected_core_snapshot: before,
|
|
204
|
+
protected_core_immutable: true,
|
|
205
|
+
permission_active: false
|
|
206
|
+
}, json);
|
|
207
|
+
}
|
|
208
|
+
if (subcommand === 'plan') {
|
|
209
|
+
const manifest = createMadSksAuthorizationManifest({ permission, userIntent });
|
|
210
|
+
return emit({
|
|
211
|
+
schema: 'sks.mad-sks-plan.v1',
|
|
212
|
+
ok: true,
|
|
213
|
+
dry_run: true,
|
|
214
|
+
writes_performed: false,
|
|
215
|
+
permission_model: permission,
|
|
216
|
+
authorization_manifest_preview: manifest,
|
|
217
|
+
protected_core: resolveProtectedCore({ packageRoot: packageRoot(), targetRoot }),
|
|
218
|
+
required_artifacts: [
|
|
219
|
+
'mad-sks-authorization.json',
|
|
220
|
+
'mad-sks-audit-ledger.json',
|
|
221
|
+
'mad-sks-rollback-plan.json',
|
|
222
|
+
'mad-sks-proof-evidence.json',
|
|
223
|
+
'mad-sks-protected-core-before.json',
|
|
224
|
+
'mad-sks-protected-core-after.json'
|
|
225
|
+
]
|
|
226
|
+
}, json);
|
|
227
|
+
}
|
|
228
|
+
if (subcommand === 'apply') {
|
|
229
|
+
const manifestPath = readOption(args, '--authorization-manifest', null);
|
|
230
|
+
const manifest = manifestPath ? await readJson(path.resolve(manifestPath), null) : null;
|
|
231
|
+
const validation = validateMadSksAuthorizationManifest(manifest);
|
|
232
|
+
if (!validation.ok) {
|
|
233
|
+
const result = {
|
|
234
|
+
schema: 'sks.mad-sks-apply.v1',
|
|
235
|
+
ok: false,
|
|
236
|
+
status: 'blocked',
|
|
237
|
+
target_root: targetRoot,
|
|
238
|
+
issues: ['authorization_manifest_required', ...validation.issues],
|
|
239
|
+
permission_model: permission
|
|
240
|
+
};
|
|
241
|
+
process.exitCode = 1;
|
|
242
|
+
return emit(result, json);
|
|
243
|
+
}
|
|
244
|
+
return materializeMadSksRun(root, targetRoot, permission, userIntent, json, { action: 'apply', authorizationManifest: validation.manifest, authorizationManifestPath: path.resolve(manifestPath) });
|
|
245
|
+
}
|
|
246
|
+
if (subcommand === 'run') {
|
|
247
|
+
return materializeMadSksRun(root, targetRoot, permission, userIntent, json, { action: 'run' });
|
|
248
|
+
}
|
|
249
|
+
if (subcommand === 'rollback-plan' || subcommand === 'audit' || subcommand === 'proof') {
|
|
250
|
+
const latest = await latestMadSksArtifact(root, subcommand);
|
|
251
|
+
if (!latest) {
|
|
252
|
+
const result = { schema: `sks.mad-sks-${subcommand}.v1`, ok: false, status: 'missing', missing: [`mad-sks-${subcommand}.json`] };
|
|
253
|
+
process.exitCode = 1;
|
|
254
|
+
return emit(result, json);
|
|
255
|
+
}
|
|
256
|
+
return emit(latest, json);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
async function materializeMadSksRun(root, targetRoot, permission, userIntent, json, opts = {}) {
|
|
260
|
+
if (!(await exists(path.join(root, '.sneakoscope'))))
|
|
261
|
+
await initProject(root, {});
|
|
262
|
+
const { id, dir } = await createMission(root, { mode: 'mad-sks', prompt: userIntent });
|
|
263
|
+
const before = await snapshotProtectedCore(packageRoot(), 'before');
|
|
264
|
+
const authorization = opts.authorizationManifest || createMadSksAuthorizationManifest({ permission, userIntent });
|
|
265
|
+
const authorizationPath = opts.authorizationManifestPath || path.join(dir, 'mad-sks-authorization.json');
|
|
266
|
+
if (!opts.authorizationManifestPath)
|
|
267
|
+
await writeJsonAtomic(authorizationPath, authorization);
|
|
268
|
+
const targetProbe = await evaluateMadSksWrite({ packageRoot: packageRoot(), targetRoot, operation: 'file_write', path: path.join(targetRoot, '.sneakoscope', 'mad-sks-target-probe') });
|
|
269
|
+
const protectedProbe = await evaluateMadSksWrite({ packageRoot: packageRoot(), targetRoot, operation: 'file_write', path: path.join(packageRoot(), 'src', 'core', 'version.ts') });
|
|
270
|
+
const audit = createMadSksAuditLedger({
|
|
271
|
+
authorizationManifestPath: authorizationPath,
|
|
272
|
+
targetRoot,
|
|
273
|
+
actions: [
|
|
274
|
+
madSksAuditAction({
|
|
275
|
+
type: 'file_write',
|
|
276
|
+
target: targetProbe.path,
|
|
277
|
+
rollback_available: true,
|
|
278
|
+
risk_level: 'low',
|
|
279
|
+
protected_core_impact: 'none',
|
|
280
|
+
notes: ['probe_only_no_target_write_performed']
|
|
281
|
+
})
|
|
282
|
+
],
|
|
283
|
+
blockedActions: [protectedProbe]
|
|
284
|
+
});
|
|
285
|
+
const rollback = createMadSksRollbackPlan({
|
|
286
|
+
targetRoot,
|
|
287
|
+
fileRollbacks: [{ path: targetProbe.path, previous_content_hash: null, status: 'snapshot_required_before_real_write' }],
|
|
288
|
+
unavailable: permission.high_risk_confirmation_required ? ['high_risk_final_confirmation_required_before_apply'] : []
|
|
289
|
+
});
|
|
290
|
+
const after = await snapshotProtectedCore(packageRoot(), 'after');
|
|
291
|
+
const comparison = compareProtectedCoreSnapshots(before, after);
|
|
292
|
+
const auditPath = path.join(dir, 'mad-sks-audit-ledger.json');
|
|
293
|
+
const rollbackPath = path.join(dir, 'mad-sks-rollback-plan.json');
|
|
294
|
+
const beforePath = path.join(dir, 'mad-sks-protected-core-before.json');
|
|
295
|
+
const afterPath = path.join(dir, 'mad-sks-protected-core-after.json');
|
|
296
|
+
const proofPath = path.join(dir, 'mad-sks-proof-evidence.json');
|
|
297
|
+
await writeJsonAtomic(beforePath, before);
|
|
298
|
+
await writeJsonAtomic(afterPath, after);
|
|
299
|
+
await writeJsonAtomic(path.join(dir, 'mad-sks-protected-core-comparison.json'), comparison);
|
|
300
|
+
await writeMadSksAuditLedger(auditPath, audit);
|
|
301
|
+
await writeMadSksRollbackPlan(rollbackPath, rollback);
|
|
302
|
+
const proof = createMadSksProofEvidence({
|
|
303
|
+
authorizationManifestPath: authorizationPath,
|
|
304
|
+
auditLedgerPath: auditPath,
|
|
305
|
+
rollbackPlanPath: rollbackPath,
|
|
306
|
+
immutableHarnessGuard: protectedProbe,
|
|
307
|
+
protectedCoreBefore: beforePath,
|
|
308
|
+
protectedCoreAfter: afterPath,
|
|
309
|
+
protectedCoreComparison: comparison,
|
|
310
|
+
changedTargetFiles: [],
|
|
311
|
+
blockedActions: [protectedProbe],
|
|
312
|
+
verification: [{ command: 'mad-sks protected core snapshot compare', ok: comparison.ok }]
|
|
313
|
+
});
|
|
314
|
+
await writeMadSksProofEvidence(proofPath, proof);
|
|
315
|
+
const gate = {
|
|
316
|
+
schema_version: 1,
|
|
317
|
+
passed: proof.ok === true,
|
|
318
|
+
mad_sks_permission_active: true,
|
|
319
|
+
permissions_deactivated: true,
|
|
320
|
+
full_system_authority: permission.mode === 'full_system_authority',
|
|
321
|
+
immutable_harness_guard_passed: comparison.ok === true,
|
|
322
|
+
audit_ledger: auditPath,
|
|
323
|
+
rollback_plan: rollbackPath,
|
|
324
|
+
proof_evidence: proofPath,
|
|
325
|
+
permission_profile: permissionGateSummary()
|
|
326
|
+
};
|
|
327
|
+
await writeJsonAtomic(path.join(dir, 'mad-sks-gate.json'), gate);
|
|
328
|
+
await setCurrent(root, {
|
|
329
|
+
mission_id: id,
|
|
330
|
+
route: 'MadSKS',
|
|
331
|
+
route_command: '$MAD-SKS',
|
|
332
|
+
mode: 'MADSKS',
|
|
333
|
+
phase: 'MADSKS_PERMISSION_CLOSED',
|
|
334
|
+
mad_sks_active: false,
|
|
335
|
+
mad_sks_modifier: true,
|
|
336
|
+
mad_sks_gate_file: 'mad-sks-gate.json',
|
|
337
|
+
prompt: userIntent
|
|
338
|
+
});
|
|
339
|
+
return emit({
|
|
340
|
+
schema: opts.action === 'apply' ? 'sks.mad-sks-apply.v1' : 'sks.mad-sks-run.v1',
|
|
341
|
+
ok: proof.ok === true,
|
|
342
|
+
status: proof.status,
|
|
343
|
+
mission_id: id,
|
|
344
|
+
target_root: targetRoot,
|
|
345
|
+
permission_model: permission,
|
|
346
|
+
authorization_manifest: authorizationPath,
|
|
347
|
+
audit_ledger: auditPath,
|
|
348
|
+
rollback_plan: rollbackPath,
|
|
349
|
+
proof_evidence: proofPath,
|
|
350
|
+
protected_core_before: beforePath,
|
|
351
|
+
protected_core_after: afterPath,
|
|
352
|
+
protected_core_unchanged: comparison.ok === true,
|
|
353
|
+
blocked_actions: [protectedProbe]
|
|
354
|
+
}, json);
|
|
355
|
+
}
|
|
356
|
+
async function latestMadSksArtifact(root, kind) {
|
|
357
|
+
const current = await readJson(path.join(root, '.sneakoscope', 'current.json'), null);
|
|
358
|
+
const missionId = current?.mission_id;
|
|
359
|
+
if (!missionId)
|
|
360
|
+
return null;
|
|
361
|
+
const fileMap = {
|
|
362
|
+
proof: 'mad-sks-proof-evidence.json',
|
|
363
|
+
audit: 'mad-sks-audit-ledger.json',
|
|
364
|
+
'rollback-plan': 'mad-sks-rollback-plan.json'
|
|
365
|
+
};
|
|
366
|
+
const file = path.join(root, '.sneakoscope', 'missions', missionId, fileMap[kind] || '');
|
|
367
|
+
return readJson(file, null);
|
|
368
|
+
}
|
|
369
|
+
function firstSubcommand(args = []) {
|
|
370
|
+
const found = args.find((arg) => MAD_SKS_COMMAND_SURFACE.includes(String(arg)));
|
|
371
|
+
return found ? String(found) : null;
|
|
372
|
+
}
|
|
373
|
+
function emit(result, json) {
|
|
374
|
+
if (json)
|
|
375
|
+
return console.log(JSON.stringify(result, null, 2));
|
|
376
|
+
if (result.ok === false) {
|
|
377
|
+
console.error(`${result.schema}: ${result.status || 'blocked'}`);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
console.log(JSON.stringify(result, null, 2));
|
|
381
|
+
}
|
|
130
382
|
//# sourceMappingURL=mad-sks-command.js.map
|