sneakoscope 4.8.7 → 5.1.2
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 +51 -726
- package/bench/tasks/t01-off-by-one/repo/package.json +9 -0
- package/bench/tasks/t01-off-by-one/repo/src/pagination.js +5 -0
- package/bench/tasks/t01-off-by-one/repo/test.js +5 -0
- package/bench/tasks/t01-off-by-one/task.json +13 -0
- package/bench/tasks/t02-signature-cochange/repo/package.json +9 -0
- package/bench/tasks/t02-signature-cochange/repo/src/admin.js +5 -0
- package/bench/tasks/t02-signature-cochange/repo/src/audit.js +5 -0
- package/bench/tasks/t02-signature-cochange/repo/src/labels.js +3 -0
- package/bench/tasks/t02-signature-cochange/repo/src/profile.js +5 -0
- package/bench/tasks/t02-signature-cochange/repo/test.js +9 -0
- package/bench/tasks/t02-signature-cochange/task.json +12 -0
- package/bench/tasks/t03-type-puzzle/repo/package.json +9 -0
- package/bench/tasks/t03-type-puzzle/repo/src/config.js +4 -0
- package/bench/tasks/t03-type-puzzle/repo/test.js +6 -0
- package/bench/tasks/t03-type-puzzle/task.json +13 -0
- package/bench/tasks/t04-refactor-preserve/repo/package.json +9 -0
- package/bench/tasks/t04-refactor-preserve/repo/src/cart.js +8 -0
- package/bench/tasks/t04-refactor-preserve/repo/test.js +4 -0
- package/bench/tasks/t04-refactor-preserve/task.json +12 -0
- package/bench/tasks/t05-performance/repo/package.json +9 -0
- package/bench/tasks/t05-performance/repo/src/pairs.js +9 -0
- package/bench/tasks/t05-performance/repo/test.js +11 -0
- package/bench/tasks/t05-performance/task.json +12 -0
- package/bench/tasks/t06-mistake-rule/repo/package.json +9 -0
- package/bench/tasks/t06-mistake-rule/repo/src/loader.js +6 -0
- package/bench/tasks/t06-mistake-rule/repo/test.js +7 -0
- package/bench/tasks/t06-mistake-rule/task.json +12 -0
- package/config/bench-baseline.json +7 -0
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/bin/install.js +35 -0
- package/dist/bin/sks.js +1 -1
- package/dist/cli/cli-theme.js +51 -0
- package/dist/cli/command-registry.js +15 -4
- package/dist/cli/help-fast.js +18 -8
- package/dist/cli/insane-search-command.js +36 -8
- package/dist/cli/install-helpers.js +32 -0
- package/dist/commands/codex-lb.js +2 -0
- package/dist/commands/doctor.js +62 -6
- package/dist/commands/proof.js +6 -3
- package/dist/config/skills-manifest.json +82 -54
- package/dist/core/agents/agent-conflict-graph.js +5 -0
- package/dist/core/agents/agent-lease.js +5 -0
- package/dist/core/agents/agent-ledger-schemas.js +1 -0
- package/dist/core/agents/agent-orchestrator.js +268 -62
- package/dist/core/agents/agent-output-validator.js +14 -3
- package/dist/core/agents/agent-patch-queue-store.js +95 -2
- package/dist/core/agents/agent-patch-queue.js +6 -3
- package/dist/core/agents/agent-patch-schema.js +13 -0
- package/dist/core/agents/agent-proof-evidence.js +6 -1
- package/dist/core/agents/agent-runner-fake.js +40 -0
- package/dist/core/agents/agent-worker-pipeline.js +36 -2
- package/dist/core/agents/codex-exec-worker-adapter.js +2 -0
- package/dist/core/agents/native-worker-backend-router.js +58 -1
- package/dist/core/codex-app/sks-menubar.js +18 -5
- package/dist/core/codex-app.js +1 -0
- package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
- package/dist/core/codex-control/codex-sdk-env-policy.js +1 -1
- package/dist/core/codex-control/schemas/agent-worker-result.schema.js +12 -3
- package/dist/core/codex-hooks/codex-hook-managed-install.js +5 -0
- package/dist/core/codex-hooks/codex-hook-state-writer.js +70 -11
- package/dist/core/codex-hooks/codex-hook-trust-doctor.js +2 -2
- package/dist/core/codex-lb/codex-lb-env.js +20 -1
- package/dist/core/commands/basic-cli.js +21 -2
- package/dist/core/commands/check-command.js +37 -5
- package/dist/core/commands/computer-use-command.js +62 -7
- package/dist/core/commands/db-command.js +31 -5
- package/dist/core/commands/fast-mode-command.js +3 -0
- package/dist/core/commands/gate-result-contract.js +43 -0
- package/dist/core/commands/gates-command.js +6 -1
- package/dist/core/commands/gc-command.js +29 -2
- package/dist/core/commands/goal-command.js +9 -2
- package/dist/core/commands/gx-command.js +79 -7
- package/dist/core/commands/image-ux-review-command.js +188 -13
- package/dist/core/commands/mad-db-command.js +85 -176
- package/dist/core/commands/mad-sks-command.js +230 -29
- package/dist/core/commands/menubar-command.js +22 -1
- package/dist/core/commands/naruto-command.js +64 -10
- package/dist/core/commands/plan-command.js +76 -0
- package/dist/core/commands/ppt-command.js +159 -24
- package/dist/core/commands/qa-loop-command.js +6 -2
- package/dist/core/commands/release-command.js +55 -2
- package/dist/core/commands/research-command.js +1 -1
- package/dist/core/commands/review-command.js +217 -0
- package/dist/core/commands/route-success-helpers.js +59 -0
- package/dist/core/commands/run-command.js +19 -7
- package/dist/core/commands/seo-command.js +49 -1
- package/dist/core/commands/ui-command.js +161 -0
- package/dist/core/commands/uninstall-command.js +15 -1
- package/dist/core/db-safety.js +2 -2
- package/dist/core/doctor/doctor-transaction.js +8 -0
- package/dist/core/doctor/doctor-zellij-repair.js +1 -0
- package/dist/core/doctor/imagegen-repair.js +161 -0
- package/dist/core/feature-fixture-runner.js +2 -2
- package/dist/core/feature-fixtures.js +58 -37
- package/dist/core/feature-registry.js +102 -2
- package/dist/core/fsx.js +39 -6
- package/dist/core/image-ux-review/imagegen-adapter.js +48 -11
- package/dist/core/image-ux-review.js +16 -0
- package/dist/core/imagegen/imagegen-capability.js +11 -5
- package/dist/core/imagegen/require-imagegen.js +57 -0
- package/dist/core/init/skills.js +10 -5
- package/dist/core/mad-db/mad-db-coordinator.js +94 -18
- package/dist/core/mad-db/mad-db-policy.js +12 -10
- package/dist/core/mad-sks/executors/executor-base.js +8 -2
- package/dist/core/mad-sks/executors/index.js +4 -0
- package/dist/core/mad-sks/executors/sql-plane-executor.js +194 -0
- package/dist/core/naruto/naruto-active-pool.js +15 -4
- package/dist/core/naruto/naruto-real-worker-child.js +10 -0
- package/dist/core/naruto/naruto-role-policy.js +3 -0
- package/dist/core/naruto/naruto-task-hints.js +10 -0
- package/dist/core/naruto/naruto-work-graph.js +8 -2
- package/dist/core/naruto/naruto-work-item.js +6 -0
- package/dist/core/naruto/solution-tournament.js +101 -0
- package/dist/core/permission-gates.js +30 -0
- package/dist/core/pipeline-internals/runtime-core.js +11 -3
- package/dist/core/pipeline-internals/runtime-gates.js +27 -0
- package/dist/core/ppt-review/index.js +6 -1
- package/dist/core/ppt-review/slide-imagegen-review.js +75 -10
- package/dist/core/ppt.js +70 -2
- package/dist/core/proof/auto-finalize.js +70 -11
- package/dist/core/proof/proof-schema.js +2 -0
- package/dist/core/proof/route-adapter.js +5 -1
- package/dist/core/proof/route-finalizer.js +8 -5
- package/dist/core/proof/selftest-proof-fixtures.js +18 -5
- package/dist/core/proof/validation.js +2 -0
- package/dist/core/provider/model-router.js +53 -0
- package/dist/core/release/release-gate-node.js +3 -0
- package/dist/core/release/release-gate-resource-governor.js +1 -0
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes.js +65 -18
- package/dist/core/safety/mutation-guard.js +5 -1
- package/dist/core/stop-gate/gate-evaluator.js +102 -0
- package/dist/core/stop-gate/stop-gate-check.js +16 -1
- package/dist/core/stop-gate/stop-gate-writer.js +4 -0
- package/dist/core/triwiki/agents-md-projector.js +184 -0
- package/dist/core/triwiki-wrongness/wrongness-schema.js +3 -1
- package/dist/core/trust-kernel/trust-kernel-schema.js +1 -0
- package/dist/core/trust-kernel/trust-report.js +1 -1
- package/dist/core/trust-kernel/trust-status.js +2 -0
- package/dist/core/ui/dashboard-html.js +111 -0
- package/dist/core/update/update-migration-state.js +366 -15
- package/dist/core/update-check.js +178 -81
- package/dist/core/verification/diff-quality.js +100 -0
- package/dist/core/verification/impact-scan.js +164 -0
- package/dist/core/verification/machine-feedback.js +146 -0
- package/dist/core/verification/mistake-rule-compiler.js +195 -0
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-self-heal.js +9 -6
- package/dist/scripts/check-feature-quality.js +2 -2
- package/dist/scripts/cli-output-consistency-check.js +57 -0
- package/dist/scripts/coding-bench-check.js +136 -0
- package/dist/scripts/doctor-imagegen-repair-check.js +62 -0
- package/dist/scripts/ensure-bin-executable.js +11 -3
- package/dist/scripts/harness-benchmark-check.js +104 -0
- package/dist/scripts/legacy-update-e2e-check.js +228 -0
- package/dist/scripts/mad-db-command-check.js +11 -8
- package/dist/scripts/mad-db-route-identity-check.js +8 -6
- package/dist/scripts/mad-db-safety-conflict-matrix-check.js +31 -8
- package/dist/scripts/mad-db-skill-policy-snapshot-check.js +4 -5
- package/dist/scripts/ppt-real-imagegen-wiring-check.js +5 -1
- package/dist/scripts/proof-root-cause-policy-check.js +2 -0
- package/dist/scripts/release-dag-full-coverage-check.js +13 -4
- package/dist/scripts/release-gate-dag-runner.js +14 -0
- package/dist/scripts/release-gate-existence-audit.js +2 -1
- package/dist/scripts/release-gate-planner.js +2 -1
- package/dist/scripts/release-gate-script-parity-check.js +1 -1
- package/dist/scripts/release-metadata-1-19-check.js +2 -1
- package/dist/scripts/seo-geo-feature-fixture-quality-check.js +1 -1
- package/dist/scripts/sks-1-11-gate-lib.js +8 -6
- package/dist/scripts/ux-review-real-loop-fixture-check.js +9 -4
- package/dist/scripts/ux-review-run-wires-imagegen-check.js +4 -0
- package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
- package/docs/demo.tape +28 -0
- package/package.json +67 -3
- package/schemas/codex/completion-proof.schema.json +3 -2
- package/schemas/release/release-gate-node.schema.json +2 -1
- package/dist/scripts/agent-backfill-route-blackbox.js +0 -5
- package/dist/scripts/agent-dynamic-pool-route-blackbox.js +0 -5
- package/dist/scripts/agent-parallel-write-blackbox.js +0 -56
- package/dist/scripts/agent-patch-swarm-route-blackbox.js +0 -10
- package/dist/scripts/agent-route-blackbox-lib.js +0 -132
- package/dist/scripts/blackbox-command-import-smoke.js +0 -143
- package/dist/scripts/blackbox-global-shim.js +0 -77
- package/dist/scripts/blackbox-matrix.js +0 -70
- package/dist/scripts/blackbox-npx-one-shot.js +0 -69
- package/dist/scripts/blackbox-pack-install.js +0 -174
- package/dist/scripts/brand-neutrality-zero-leakage-blackbox.js +0 -4
- package/dist/scripts/build-once-runner-blackbox.js +0 -34
- package/dist/scripts/codex-0140-integration-blackbox.js +0 -13
- package/dist/scripts/codex-agent-type-blackbox.js +0 -4
- package/dist/scripts/codex-app-harness-blackbox.js +0 -4
- package/dist/scripts/codex-app-skill-agent-blackbox.js +0 -4
- package/dist/scripts/codex-hook-approval-blackbox.js +0 -4
- package/dist/scripts/codex-init-deep-directory-local-blackbox.js +0 -4
- package/dist/scripts/codex-native-feature-broker-blackbox.js +0 -4
- package/dist/scripts/codex-native-pattern-analysis-blackbox.js +0 -4
- package/dist/scripts/codex-native-read-repair-split-blackbox.js +0 -55
- package/dist/scripts/codex-native-reference-cache-blackbox.js +0 -41
- package/dist/scripts/core-skill-integrity-blackbox.js +0 -32
- package/dist/scripts/dfix-fast-blackbox-check.js +0 -37
- package/dist/scripts/dfix-parallel-write-blackbox.js +0 -48
- package/dist/scripts/dfix-patch-swarm-route-blackbox.js +0 -10
- package/dist/scripts/doctor-context7-mcp-repair-blackbox.js +0 -16
- package/dist/scripts/doctor-dirty-repair-blackbox.js +0 -22
- package/dist/scripts/doctor-dirty-semantic-blackbox.js +0 -8
- package/dist/scripts/doctor-fix-production-blackbox.js +0 -26
- package/dist/scripts/doctor-native-capability-repair-blackbox.js +0 -39
- package/dist/scripts/doctor-startup-config-repair-blackbox.js +0 -13
- package/dist/scripts/doctor-supabase-mcp-repair-blackbox.js +0 -14
- package/dist/scripts/doctor-transaction-engine-blackbox.js +0 -28
- package/dist/scripts/doctor-zellij-fix-blackbox.js +0 -4
- package/dist/scripts/doctor-zellij-no-homebrew-blackbox.js +0 -4
- package/dist/scripts/doctor-zellij-upgrade-blackbox.js +0 -4
- package/dist/scripts/gate-pack-runner-blackbox.js +0 -27
- package/dist/scripts/gate-pack-v2-blackbox.js +0 -18
- package/dist/scripts/geo-cli-blackbox-check.js +0 -18
- package/dist/scripts/loop-collision-blackbox.js +0 -3
- package/dist/scripts/loop-concurrency-oversubscription-blackbox.js +0 -3
- package/dist/scripts/loop-fixture-production-misuse-blackbox.js +0 -3
- package/dist/scripts/loop-kill-interrupt-real-blackbox.js +0 -3
- package/dist/scripts/loop-merge-strategy-blackbox.js +0 -3
- package/dist/scripts/loop-mesh-production-e2e-blackbox.js +0 -3
- package/dist/scripts/loop-side-effect-blackbox.js +0 -3
- package/dist/scripts/mad-db-operation-lifecycle-blackbox.js +0 -29
- package/dist/scripts/mad-sks-actual-executor-blackbox.js +0 -5
- package/dist/scripts/mad-zellij-headless-fallback-blackbox.js +0 -4
- package/dist/scripts/mad-zellij-self-heal-blackbox.js +0 -4
- package/dist/scripts/naruto-loop-mesh-blackbox.js +0 -3
- package/dist/scripts/naruto-real-parallelism-blackbox.js +0 -307
- package/dist/scripts/naruto-worktree-coding-blackbox.js +0 -29
- package/dist/scripts/parallel-runtime-real-blackbox.js +0 -44
- package/dist/scripts/pipeline-codex-native-doctor-mad-routing-real-blackbox.js +0 -77
- package/dist/scripts/pipeline-codex-native-e2e-blackbox.js +0 -13
- package/dist/scripts/pipeline-codex-native-image-routing-real-blackbox.js +0 -50
- package/dist/scripts/pipeline-codex-native-loop-routing-real-blackbox.js +0 -74
- package/dist/scripts/pipeline-codex-native-qa-routing-real-blackbox.js +0 -51
- package/dist/scripts/pipeline-codex-native-research-routing-real-blackbox.js +0 -45
- package/dist/scripts/pipeline-execution-profile-routing-blackbox.js +0 -4
- package/dist/scripts/postinstall-global-doctor-blackbox.js +0 -12
- package/dist/scripts/ppt-full-e2e-blackbox-check.js +0 -109
- package/dist/scripts/ppt-imagegen-blackbox-check.js +0 -46
- package/dist/scripts/project-skill-dedupe-blackbox.js +0 -36
- package/dist/scripts/qa-backfill-route-blackbox.js +0 -5
- package/dist/scripts/qa-patch-swarm-route-blackbox.js +0 -10
- package/dist/scripts/release-full-parallelism-blackbox.js +0 -41
- package/dist/scripts/release-triwiki-first-runner-blackbox.js +0 -48
- package/dist/scripts/release-wiring-3110-blackbox.js +0 -27
- package/dist/scripts/release-wiring-3112-blackbox.js +0 -17
- package/dist/scripts/release-wiring-3113-blackbox.js +0 -17
- package/dist/scripts/research-backfill-route-blackbox.js +0 -5
- package/dist/scripts/research-final-reviewer-blackbox.js +0 -70
- package/dist/scripts/research-stage-cycle-runtime-blackbox.js +0 -40
- package/dist/scripts/research-synthesis-writer-blackbox.js +0 -24
- package/dist/scripts/route-blackbox-realism-check.js +0 -21
- package/dist/scripts/scheduler-resource-claim-blackbox.js +0 -24
- package/dist/scripts/seo-cli-blackbox-check.js +0 -18
- package/dist/scripts/sks-3110-all-feature-regression-blackbox.js +0 -116
- package/dist/scripts/sks-3112-all-feature-regression-blackbox.js +0 -29
- package/dist/scripts/sks-3113-all-feature-regression-blackbox.js +0 -17
- package/dist/scripts/sks-400-all-feature-regression-blackbox.js +0 -21
- package/dist/scripts/sks-400-extreme-parallel-blackbox.js +0 -8
- package/dist/scripts/sks-400-five-minute-blackbox.js +0 -9
- package/dist/scripts/sks-400-legacy-purge-blackbox.js +0 -8
- package/dist/scripts/sks-401-all-feature-regression-blackbox.js +0 -46
- package/dist/scripts/sks-401-five-minute-actual-blackbox.js +0 -23
- package/dist/scripts/sks-402-all-feature-regression-blackbox.js +0 -9
- package/dist/scripts/sks-402-five-minute-real-blackbox.js +0 -22
- package/dist/scripts/sksd-warm-cache-blackbox.js +0 -12
- package/dist/scripts/supabase-secret-preservation-blackbox.js +0 -29
- package/dist/scripts/team-backfill-route-blackbox.js +0 -5
- package/dist/scripts/team-parallel-write-blackbox.js +0 -55
- package/dist/scripts/team-patch-swarm-route-blackbox.js +0 -10
- package/dist/scripts/triwiki-affected-graph-blackbox.js +0 -28
- package/dist/scripts/triwiki-proof-bank-blackbox.js +0 -30
- package/dist/scripts/triwiki-proof-bank-lock-blackbox.js +0 -7
- package/dist/scripts/update-preserves-supabase-keys-blackbox.js +0 -27
- package/dist/scripts/ux-patch-swarm-route-blackbox.js +0 -10
- package/dist/scripts/ux-review-imagegen-blackbox-check.js +0 -67
- package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -28
- package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -80
- package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -137
- package/dist/scripts/zellij-self-heal-typed-blackbox.js +0 -4
- package/dist/scripts/zellij-slot-telemetry-real-blackbox.js +0 -20
- package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -81
- package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -202
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { repairCodexImagegen } from '../core/doctor/imagegen-repair.js';
|
|
7
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-doctor-imagegen-repair-'));
|
|
8
|
+
const stateFile = path.join(root, 'imagegen-enabled');
|
|
9
|
+
const reportPath = path.join(root, 'doctor-imagegen-repair.json');
|
|
10
|
+
const codexBin = path.join(root, 'codex');
|
|
11
|
+
await fs.writeFile(codexBin, `#!/usr/bin/env node
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const stateFile = ${JSON.stringify(stateFile)};
|
|
14
|
+
const args = process.argv.slice(2).join(' ');
|
|
15
|
+
if (args === '--version') {
|
|
16
|
+
console.log('codex-cli 99.0.0');
|
|
17
|
+
process.exit(0);
|
|
18
|
+
}
|
|
19
|
+
if (args === 'features enable image_generation') {
|
|
20
|
+
fs.writeFileSync(stateFile, '1');
|
|
21
|
+
console.log('enabled image_generation');
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
if (args === 'features list --json') {
|
|
25
|
+
const enabled = fs.existsSync(stateFile);
|
|
26
|
+
console.log(JSON.stringify({ features: { image_generation: enabled } }));
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
if (args === 'features list') {
|
|
30
|
+
const enabled = fs.existsSync(stateFile) ? 'true' : 'false';
|
|
31
|
+
console.log('image_generation stable ' + enabled);
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
34
|
+
console.error('unexpected fake codex args: ' + args);
|
|
35
|
+
process.exit(64);
|
|
36
|
+
`, { mode: 0o755 });
|
|
37
|
+
const report = await repairCodexImagegen({
|
|
38
|
+
root,
|
|
39
|
+
apply: true,
|
|
40
|
+
codexBin,
|
|
41
|
+
reportPath,
|
|
42
|
+
timeoutMs: 1000
|
|
43
|
+
});
|
|
44
|
+
const reportFile = JSON.parse(await fs.readFile(reportPath, 'utf8'));
|
|
45
|
+
const ok = report.schema === 'sks.doctor-imagegen-repair.v1'
|
|
46
|
+
&& report.attempted === true
|
|
47
|
+
&& report.recovered === true
|
|
48
|
+
&& report.after?.core_ready === true
|
|
49
|
+
&& report.steps?.some((step) => step.id === 'image_generation_feature_enable' && step.ok === true)
|
|
50
|
+
&& reportFile.recovered === true;
|
|
51
|
+
console.log(JSON.stringify({
|
|
52
|
+
schema: 'sks.doctor-imagegen-repair-check.v1',
|
|
53
|
+
ok,
|
|
54
|
+
repair_schema: report.schema,
|
|
55
|
+
attempted: report.attempted,
|
|
56
|
+
recovered: report.recovered,
|
|
57
|
+
after_core_ready: report.after?.core_ready === true,
|
|
58
|
+
report_path: reportPath
|
|
59
|
+
}, null, 2));
|
|
60
|
+
if (!ok)
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
//# sourceMappingURL=doctor-imagegen-repair-check.js.map
|
|
@@ -4,7 +4,15 @@ import fsp from 'node:fs/promises';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const bins = [
|
|
8
|
+
path.join(root, 'dist', 'bin', 'sks.js'),
|
|
9
|
+
path.join(root, 'dist', 'bin', 'install.js')
|
|
10
|
+
];
|
|
11
|
+
for (const bin of bins) {
|
|
12
|
+
await fsp.chmod(bin, 0o755).catch((err) => {
|
|
13
|
+
if (err?.code !== 'ENOENT')
|
|
14
|
+
throw err;
|
|
15
|
+
});
|
|
16
|
+
console.log(`bin executable: ${path.relative(root, bin)}`);
|
|
17
|
+
}
|
|
10
18
|
//# sourceMappingURL=ensure-bin-executable.js.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { performance } from 'node:perf_hooks';
|
|
6
|
+
import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
|
|
7
|
+
import { ensureDir, nowIso, runProcess, writeJsonAtomic } from '../core/fsx.js';
|
|
8
|
+
import { reviewCommand } from '../core/commands/review-command.js';
|
|
9
|
+
import { collectUiState } from '../core/commands/ui-command.js';
|
|
10
|
+
import { simulateNarutoActivePool } from '../core/naruto/naruto-active-pool.js';
|
|
11
|
+
import { decideNarutoConcurrency } from '../core/naruto/naruto-concurrency-governor.js';
|
|
12
|
+
import { buildNarutoWorkGraph } from '../core/naruto/naruto-work-graph.js';
|
|
13
|
+
const reportPath = path.join(root, '.sneakoscope', 'reports', 'harness-benchmark.json');
|
|
14
|
+
const metrics = [];
|
|
15
|
+
metrics.push(await measure('install_entrypoint_readiness', 300000, async () => {
|
|
16
|
+
await assertFile('dist/bin/install.js');
|
|
17
|
+
await assertFile('plugins/sks/.codex-plugin/plugin.json');
|
|
18
|
+
return { mode: 'hermetic_readiness', command: 'npx sneakoscope install --yes' };
|
|
19
|
+
}));
|
|
20
|
+
metrics.push(await measure('stop_hook_light_budget', 25, async () => {
|
|
21
|
+
const started = performance.now();
|
|
22
|
+
await assertFile('dist/scripts/hook-latency-budget-check.js');
|
|
23
|
+
return { mode: 'script_presence_budget_proxy', measured_ms: performance.now() - started };
|
|
24
|
+
}));
|
|
25
|
+
metrics.push(await measure('swarm_14_worker_fixture', 20000, async () => {
|
|
26
|
+
const graph = buildNarutoWorkGraph({
|
|
27
|
+
requestedClones: 14,
|
|
28
|
+
totalWorkItems: 14,
|
|
29
|
+
honorExplicitTotalWorkItems: true,
|
|
30
|
+
readonly: true,
|
|
31
|
+
writeCapable: false,
|
|
32
|
+
maxActiveWorkers: 14
|
|
33
|
+
});
|
|
34
|
+
const governor = decideNarutoConcurrency({
|
|
35
|
+
requestedClones: 14,
|
|
36
|
+
totalWorkItems: 14,
|
|
37
|
+
pendingWorkQueueSize: 14,
|
|
38
|
+
backend: 'fake',
|
|
39
|
+
hardware: { remoteApiRateLimitBudget: 14, fileDescriptorLimit: 4096, freeMemoryBytes: 8 * 1024 * 1024 * 1024, totalMemoryBytes: 16 * 1024 * 1024 * 1024 }
|
|
40
|
+
});
|
|
41
|
+
const report = simulateNarutoActivePool({ graph, governor: { ...governor, safe_active_workers: 14 } });
|
|
42
|
+
return {
|
|
43
|
+
command: 'simulateNarutoActivePool --fake --clones 14',
|
|
44
|
+
ok: report.ok === true && report.completed_count >= 14 && report.max_observed_active_workers >= 7,
|
|
45
|
+
completed_count: report.completed_count,
|
|
46
|
+
max_observed_active_workers: report.max_observed_active_workers,
|
|
47
|
+
blockers: report.blockers
|
|
48
|
+
};
|
|
49
|
+
}));
|
|
50
|
+
metrics.push(await measure('review_10_file_diff', 120000, async () => {
|
|
51
|
+
const fixture = await makeReviewFixture();
|
|
52
|
+
const previousExitCode = process.exitCode;
|
|
53
|
+
const review = await reviewCommand(['--root', fixture]);
|
|
54
|
+
process.exitCode = previousExitCode;
|
|
55
|
+
return {
|
|
56
|
+
files: review?.files || 0,
|
|
57
|
+
machine_evidence: (review?.findings || []).filter((finding) => finding.evidence === 'machine').length,
|
|
58
|
+
verdict: review?.verdict || 'unknown'
|
|
59
|
+
};
|
|
60
|
+
}));
|
|
61
|
+
metrics.push(await measure('dashboard_first_state', 2000, async () => {
|
|
62
|
+
const state = await collectUiState(root, 'latest');
|
|
63
|
+
return { ok: state.ok === true, mission_id: state.mission_id || null, gates: Array.isArray(state.gates) ? state.gates.length : 0 };
|
|
64
|
+
}));
|
|
65
|
+
const report = {
|
|
66
|
+
schema: 'sks.harness-benchmark.v1',
|
|
67
|
+
generated_at: nowIso(),
|
|
68
|
+
ok: metrics.every((metric) => metric.ok),
|
|
69
|
+
metrics,
|
|
70
|
+
report_path: path.relative(root, reportPath)
|
|
71
|
+
};
|
|
72
|
+
await writeJsonAtomic(reportPath, report);
|
|
73
|
+
assertGate(report.ok, 'harness benchmark check failed', report);
|
|
74
|
+
emitGate('harness:benchmark', report);
|
|
75
|
+
async function measure(id, budgetMs, fn) {
|
|
76
|
+
const started = performance.now();
|
|
77
|
+
try {
|
|
78
|
+
const detail = await fn();
|
|
79
|
+
const elapsed_ms = Math.round((performance.now() - started) * 100) / 100;
|
|
80
|
+
return { id, ok: elapsed_ms <= budgetMs && detail.ok !== false, budget_ms: budgetMs, elapsed_ms, detail };
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
const elapsed_ms = Math.round((performance.now() - started) * 100) / 100;
|
|
84
|
+
return { id, ok: false, budget_ms: budgetMs, elapsed_ms, error: err?.message || String(err) };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async function assertFile(rel) {
|
|
88
|
+
await fs.access(path.join(root, rel));
|
|
89
|
+
}
|
|
90
|
+
async function makeReviewFixture() {
|
|
91
|
+
const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-review-bench-'));
|
|
92
|
+
await runProcess('git', ['init'], { cwd: dir, timeoutMs: 15000, maxOutputBytes: 64 * 1024 });
|
|
93
|
+
for (let i = 0; i < 10; i += 1) {
|
|
94
|
+
await ensureDir(path.join(dir, 'src'));
|
|
95
|
+
await fs.writeFile(path.join(dir, 'src', `file-${i}.txt`), `baseline ${i}\n`, 'utf8');
|
|
96
|
+
}
|
|
97
|
+
await runProcess('git', ['add', '.'], { cwd: dir, timeoutMs: 15000, maxOutputBytes: 64 * 1024 });
|
|
98
|
+
for (let i = 0; i < 10; i += 1) {
|
|
99
|
+
const content = i === 0 ? '<<<<<<< HEAD\nleft\n=======\nright\n>>>>>>> branch\n' : `changed ${i}\n`;
|
|
100
|
+
await fs.writeFile(path.join(dir, 'src', `file-${i}.txt`), content, 'utf8');
|
|
101
|
+
}
|
|
102
|
+
return dir;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=harness-benchmark-check.js.map
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import fsp from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { PACKAGE_VERSION, packageRoot, readJson, writeReceiptRotated } from '../core/fsx.js';
|
|
7
|
+
import { runSksUpdateNow } from '../core/update-check.js';
|
|
8
|
+
import { ensureCurrentMigrationBeforeCommand, projectUpdateMigrationReceiptPath, runPackageLocalDoctor } from '../core/update/update-migration-state.js';
|
|
9
|
+
const REQUIRED_LEGACY_STAGES = [
|
|
10
|
+
'legacy-team-artifacts',
|
|
11
|
+
'session-state-split',
|
|
12
|
+
'skills-reconcile',
|
|
13
|
+
'menubar-retarget',
|
|
14
|
+
'config-fastmode-normalize',
|
|
15
|
+
'hook-trust-refresh',
|
|
16
|
+
'receipt-rotation'
|
|
17
|
+
];
|
|
18
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-legacy-update-e2e-'));
|
|
19
|
+
const savedHome = process.env.HOME;
|
|
20
|
+
const savedGlobalRoot = process.env.SKS_GLOBAL_ROOT;
|
|
21
|
+
const savedCwd = process.cwd();
|
|
22
|
+
try {
|
|
23
|
+
const home = path.join(tempRoot, 'home');
|
|
24
|
+
const project = path.join(tempRoot, 'project');
|
|
25
|
+
await seedLegacyFixture(home, project);
|
|
26
|
+
process.env.HOME = home;
|
|
27
|
+
process.env.SKS_GLOBAL_ROOT = path.join(home, '.sneakoscope-global');
|
|
28
|
+
process.chdir(project);
|
|
29
|
+
const output = await captureConsole(async () => runSksUpdateNow({
|
|
30
|
+
version: PACKAGE_VERSION,
|
|
31
|
+
projectRoot: project,
|
|
32
|
+
currentVersion: '4.8.4',
|
|
33
|
+
json: false,
|
|
34
|
+
quiet: false,
|
|
35
|
+
timeoutMs: 60_000,
|
|
36
|
+
env: {
|
|
37
|
+
...process.env,
|
|
38
|
+
HOME: home,
|
|
39
|
+
SKS_GLOBAL_ROOT: path.join(home, '.sneakoscope-global'),
|
|
40
|
+
SKS_INSTALLED_SKS_VERSION: '4.8.4',
|
|
41
|
+
SKS_NPM_VIEW_SNEAKOSCOPE_VERSION: PACKAGE_VERSION,
|
|
42
|
+
SKS_UPDATE_FAKE_INSTALL: '1',
|
|
43
|
+
SKS_TEST_DOCTOR_OK: '1',
|
|
44
|
+
SKS_TEST_OLD_DOCTOR_FAIL: '1',
|
|
45
|
+
SKS_UPDATE_SKIP_SKS_MENUBAR: '1',
|
|
46
|
+
SKS_REQUIRE_ZELLIJ: '0',
|
|
47
|
+
SKS_POSTINSTALL_GLOBAL_DOCTOR: '0',
|
|
48
|
+
SKS_MIGRATION_DOCTOR_TIMEOUT_MS: '5000'
|
|
49
|
+
}
|
|
50
|
+
}));
|
|
51
|
+
const result = output.value;
|
|
52
|
+
assertGate(result.status === 'updated', 'fake legacy update must finish updated', { status: result.status, error: result.error, stages: result.stages });
|
|
53
|
+
assertGate(result.verification.length === 4 && result.verification.every((row) => row.ok), 'all final self-verification checks must pass', { verification: result.verification });
|
|
54
|
+
assertGate(result.stages.some((stage) => stage.id === 'old_version_doctor_preflight' && stage.status === 'failed_continuing'), 'old-version doctor failure must continue', { stages: result.stages });
|
|
55
|
+
assertGate(result.stages.some((stage) => stage.id === 'npm_global_install' && stage.status === 'fake_installed'), 'fake install stage missing', { stages: result.stages });
|
|
56
|
+
assertGate(/[▸>].*npm_global_install|npm_global_install/.test(output.text) && /final_self_verification/.test(output.text), 'progress output must include stage start/end lines', { output: output.text.slice(-2000) });
|
|
57
|
+
const receipt = await readJson(projectUpdateMigrationReceiptPath(project), null);
|
|
58
|
+
const stageIds = new Set((receipt?.legacy_migration_stages || []).map((stage) => stage.id));
|
|
59
|
+
for (const id of REQUIRED_LEGACY_STAGES)
|
|
60
|
+
assertGate(stageIds.has(id), `legacy stage missing from receipt: ${id}`, { receipt });
|
|
61
|
+
const badStages = (receipt?.legacy_migration_stages || []).filter((stage) => stage.ok !== true);
|
|
62
|
+
assertGate(badStages.length === 0, 'legacy migration stages must all be ok', { badStages, receipt });
|
|
63
|
+
const retryProject = path.join(tempRoot, 'retry-project');
|
|
64
|
+
await fsp.mkdir(path.join(retryProject, '.sneakoscope'), { recursive: true });
|
|
65
|
+
const retry = await ensureCurrentMigrationBeforeCommand({
|
|
66
|
+
command: 'legacy-e2e',
|
|
67
|
+
cwd: retryProject,
|
|
68
|
+
env: {
|
|
69
|
+
...process.env,
|
|
70
|
+
HOME: home,
|
|
71
|
+
SKS_GLOBAL_ROOT: path.join(home, '.sneakoscope-global'),
|
|
72
|
+
SKS_TEST_DOCTOR_TIMEOUT_ONCE: '1',
|
|
73
|
+
SKS_MIGRATION_DOCTOR_TIMEOUT_MS: '1'
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
assertGate(retry.ok === true && retry.status === 'repaired', 'timeout doctor must retry once and repair', retry);
|
|
77
|
+
assertGate(retry.warnings.some((warning) => warning.startsWith('doctor_migration_timeout_retry')), 'timeout retry warning missing', retry);
|
|
78
|
+
const failProject = path.join(tempRoot, 'fail-project');
|
|
79
|
+
await fsp.mkdir(path.join(failProject, '.sneakoscope'), { recursive: true });
|
|
80
|
+
const failed = await ensureCurrentMigrationBeforeCommand({
|
|
81
|
+
command: 'legacy-e2e',
|
|
82
|
+
cwd: failProject,
|
|
83
|
+
env: {
|
|
84
|
+
...process.env,
|
|
85
|
+
HOME: home,
|
|
86
|
+
SKS_GLOBAL_ROOT: path.join(home, '.sneakoscope-global'),
|
|
87
|
+
SKS_TEST_DOCTOR_FAIL: '1',
|
|
88
|
+
SKS_MIGRATION_DOCTOR_TIMEOUT_MS: '1'
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
assertGate(failed.ok === false && failed.blockers.includes('doctor_migration_failed'), 'non-timeout doctor failure must not be reported as timeout', failed);
|
|
92
|
+
assertGate(!failed.warnings.some((warning) => warning.startsWith('doctor_migration_timeout_retry')), 'non-timeout failure must not retry', failed);
|
|
93
|
+
const currentDryRunProject = path.join(tempRoot, 'current-dry-run-project');
|
|
94
|
+
await fsp.mkdir(path.join(currentDryRunProject, '.sneakoscope'), { recursive: true });
|
|
95
|
+
const currentDryRun = await captureConsole(async () => runSksUpdateNow({
|
|
96
|
+
projectRoot: currentDryRunProject,
|
|
97
|
+
currentVersion: PACKAGE_VERSION,
|
|
98
|
+
dryRun: true,
|
|
99
|
+
json: false,
|
|
100
|
+
quiet: false,
|
|
101
|
+
timeoutMs: 5000,
|
|
102
|
+
env: {
|
|
103
|
+
...process.env,
|
|
104
|
+
HOME: home,
|
|
105
|
+
SKS_GLOBAL_ROOT: path.join(home, '.sneakoscope-global'),
|
|
106
|
+
SKS_INSTALLED_SKS_VERSION: PACKAGE_VERSION,
|
|
107
|
+
SKS_NPM_VIEW_SNEAKOSCOPE_VERSION: PACKAGE_VERSION,
|
|
108
|
+
SKS_UPDATE_SKIP_SKS_MENUBAR: '1'
|
|
109
|
+
}
|
|
110
|
+
}));
|
|
111
|
+
assertGate(currentDryRun.value.status === 'dry_run', 'already-current update dry-run must stay dry_run', { result: currentDryRun.value });
|
|
112
|
+
assertGate(!currentDryRun.value.stages.some((stage) => ['project_receipt', 'sks_menubar', 'global_skills_reconcile'].includes(stage.id)), 'already-current dry-run must not run mutating current-version repair stages', { stages: currentDryRun.value.stages });
|
|
113
|
+
assertGate(!fs.existsSync(projectUpdateMigrationReceiptPath(currentDryRunProject)), 'already-current dry-run must not write a project receipt', { receipt: projectUpdateMigrationReceiptPath(currentDryRunProject) });
|
|
114
|
+
const timeoutEntrypoint = path.join(tempRoot, 'timeout-doctor.js');
|
|
115
|
+
await fsp.writeFile(timeoutEntrypoint, 'setInterval(() => {}, 1000)\n');
|
|
116
|
+
const actualTimeout = await runPackageLocalDoctor({
|
|
117
|
+
root: project,
|
|
118
|
+
entrypoint: timeoutEntrypoint,
|
|
119
|
+
args: [],
|
|
120
|
+
env: {
|
|
121
|
+
...process.env,
|
|
122
|
+
HOME: home,
|
|
123
|
+
SKS_GLOBAL_ROOT: path.join(home, '.sneakoscope-global')
|
|
124
|
+
},
|
|
125
|
+
timeoutMs: 25,
|
|
126
|
+
maxOutputBytes: 1024
|
|
127
|
+
});
|
|
128
|
+
assertGate(actualTimeout.ok === false && actualTimeout.timedOut === true && actualTimeout.timed_out === true, 'package-local doctor timeout must come from real child process timeout path', actualTimeout);
|
|
129
|
+
const rotationProject = path.join(tempRoot, 'rotation-project');
|
|
130
|
+
const rotationReceipt = projectUpdateMigrationReceiptPath(rotationProject);
|
|
131
|
+
await fsp.mkdir(path.dirname(rotationReceipt), { recursive: true });
|
|
132
|
+
const base = path.basename(rotationReceipt);
|
|
133
|
+
const dir = path.dirname(rotationReceipt);
|
|
134
|
+
for (let index = 0; index < 5; index += 1) {
|
|
135
|
+
const rotated = path.join(dir, `${base}.2026-07-03T00-00-0${index}-000Z.json`);
|
|
136
|
+
await fsp.writeFile(rotated, JSON.stringify({ index }) + '\n');
|
|
137
|
+
await fsp.utimes(rotated, new Date(2026, 6, 3, 0, 0, index), new Date(2026, 6, 3, 0, 0, index));
|
|
138
|
+
}
|
|
139
|
+
await fsp.writeFile(rotationReceipt, JSON.stringify({ current: true }) + '\n');
|
|
140
|
+
await writeReceiptRotated(rotationReceipt, { next: true }, { keep: 5 });
|
|
141
|
+
const rotatedAfterWrite = (await fsp.readdir(dir)).filter((name) => name.startsWith(`${base}.`) && name.endsWith('.json'));
|
|
142
|
+
assertGate(rotatedAfterWrite.length <= 5, 'receipt rotation must include the just-rotated current receipt in keep=5 pruning', { rotatedAfterWrite });
|
|
143
|
+
console.log(JSON.stringify({
|
|
144
|
+
schema: 'sks.legacy-update-e2e-check.v1',
|
|
145
|
+
ok: true,
|
|
146
|
+
package_version: PACKAGE_VERSION,
|
|
147
|
+
update_status: result.status,
|
|
148
|
+
verification: result.verification.map((row) => ({ id: row.id, ok: row.ok })),
|
|
149
|
+
legacy_stage_count: REQUIRED_LEGACY_STAGES.length,
|
|
150
|
+
progress_lines: output.text.split(/\r?\n/).filter(Boolean).length,
|
|
151
|
+
retry_status: retry.status,
|
|
152
|
+
failure_blockers: failed.blockers,
|
|
153
|
+
current_dry_run_status: currentDryRun.value.status,
|
|
154
|
+
actual_timeout_timed_out: actualTimeout.timedOut,
|
|
155
|
+
rotated_receipt_count: rotatedAfterWrite.length
|
|
156
|
+
}, null, 2));
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
process.chdir(savedCwd);
|
|
160
|
+
if (savedHome === undefined)
|
|
161
|
+
delete process.env.HOME;
|
|
162
|
+
else
|
|
163
|
+
process.env.HOME = savedHome;
|
|
164
|
+
if (savedGlobalRoot === undefined)
|
|
165
|
+
delete process.env.SKS_GLOBAL_ROOT;
|
|
166
|
+
else
|
|
167
|
+
process.env.SKS_GLOBAL_ROOT = savedGlobalRoot;
|
|
168
|
+
await fsp.rm(tempRoot, { recursive: true, force: true }).catch(() => undefined);
|
|
169
|
+
}
|
|
170
|
+
async function seedLegacyFixture(home, project) {
|
|
171
|
+
await fsp.mkdir(path.join(home, '.agents', 'skills'), { recursive: true });
|
|
172
|
+
await fsp.mkdir(path.join(home, '.codex', 'sks-menubar'), { recursive: true });
|
|
173
|
+
await fsp.mkdir(path.join(project, '.sneakoscope'), { recursive: true });
|
|
174
|
+
await fsp.mkdir(path.join(project, '.codex'), { recursive: true });
|
|
175
|
+
await fsp.writeFile(path.join(home, '.agents', 'skills', '.sks-generated.json'), JSON.stringify({
|
|
176
|
+
schema_version: 1,
|
|
177
|
+
generated_by: 'sneakoscope',
|
|
178
|
+
version: '4.8.4',
|
|
179
|
+
skills: [],
|
|
180
|
+
files: []
|
|
181
|
+
}, null, 2) + '\n');
|
|
182
|
+
await fsp.writeFile(path.join(home, '.codex', 'config.toml'), [
|
|
183
|
+
'default_profile = "legacy"',
|
|
184
|
+
'',
|
|
185
|
+
'[hooks.state."legacy"]',
|
|
186
|
+
'trusted_hash = "old-hash"',
|
|
187
|
+
''
|
|
188
|
+
].join('\n'));
|
|
189
|
+
await fsp.writeFile(path.join(home, '.codex', 'sks-menubar', 'sks-menubar-action.sh'), [
|
|
190
|
+
'#!/usr/bin/env sh',
|
|
191
|
+
'SKS_ENTRY="/old/sneakoscope/dist/bin/sks.js"',
|
|
192
|
+
'exec "$SKS_ENTRY" "$@"',
|
|
193
|
+
''
|
|
194
|
+
].join('\n'));
|
|
195
|
+
await fsp.writeFile(path.join(project, '.sneakoscope', 'current.json'), JSON.stringify({
|
|
196
|
+
mission_id: 'M-legacy',
|
|
197
|
+
phase: 'LEGACY'
|
|
198
|
+
}, null, 2) + '\n');
|
|
199
|
+
await fsp.writeFile(path.join(project, '.codex', 'config.toml'), [
|
|
200
|
+
'[user.fast_mode]',
|
|
201
|
+
'visible = true',
|
|
202
|
+
'default_profile = "sks-fast-high"',
|
|
203
|
+
''
|
|
204
|
+
].join('\n'));
|
|
205
|
+
const stamp = path.join(packageRoot(), 'dist', '.sks-build-stamp.json');
|
|
206
|
+
assertGate(fs.existsSync(stamp), 'dist build stamp missing; run npm run build:incremental first', { stamp });
|
|
207
|
+
}
|
|
208
|
+
async function captureConsole(fn) {
|
|
209
|
+
const originalLog = console.log;
|
|
210
|
+
const lines = [];
|
|
211
|
+
console.log = (...args) => {
|
|
212
|
+
lines.push(args.map((arg) => typeof arg === 'string' ? arg : JSON.stringify(arg)).join(' '));
|
|
213
|
+
};
|
|
214
|
+
try {
|
|
215
|
+
const value = await fn();
|
|
216
|
+
return { value, text: lines.join('\n') };
|
|
217
|
+
}
|
|
218
|
+
finally {
|
|
219
|
+
console.log = originalLog;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function assertGate(condition, message, detail = {}) {
|
|
223
|
+
if (condition)
|
|
224
|
+
return;
|
|
225
|
+
console.error(JSON.stringify({ schema: 'sks.legacy-update-e2e-check.v1', ok: false, message, detail }, null, 2));
|
|
226
|
+
process.exit(1);
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=legacy-update-e2e-check.js.map
|
|
@@ -3,13 +3,16 @@ import { DOLLAR_COMMAND_ALIASES, DOLLAR_COMMANDS, routeByDollarCommand } from '.
|
|
|
3
3
|
import { assertGate, emitGate, readText } from './sks-1-18-gate-lib.js';
|
|
4
4
|
assertGate(readText('src/cli/command-registry.ts').includes("'mad-db'"), 'mad-db command must be registered');
|
|
5
5
|
assertGate(readText('src/commands/mad-db.ts').includes('madDbCommand'), 'mad-db command wrapper missing');
|
|
6
|
-
|
|
7
|
-
assertGate(
|
|
8
|
-
assertGate(
|
|
9
|
-
assertGate(
|
|
10
|
-
assertGate(routeByDollarCommand('
|
|
6
|
+
const madDbCommandSource = readText('src/core/commands/mad-db-command.ts');
|
|
7
|
+
assertGate(madDbCommandSource.includes('mad-db is deprecated') && madDbCommandSource.includes('deprecated_alias'), 'mad-db command must warn and annotate deprecated_alias');
|
|
8
|
+
assertGate(!DOLLAR_COMMANDS.some((entry) => entry.command === '$MAD-DB'), '$MAD-DB deprecated alias must be hidden from new dollar-command listings');
|
|
9
|
+
assertGate(DOLLAR_COMMAND_ALIASES.some((entry) => entry.canonical === '$MAD-DB' && entry.app_skill === '$mad-db'), '$mad-db app skill alias must remain for deprecated $MAD-DB');
|
|
10
|
+
assertGate(routeByDollarCommand('MAD-DB')?.command === '$MAD-DB' && routeByDollarCommand('MAD-DB')?.deprecated === true, '$MAD-DB must resolve to the deprecated alias route');
|
|
11
|
+
assertGate(routeByDollarCommand('mad-db')?.command === '$MAD-DB' && routeByDollarCommand('mad-db')?.aliasTo === '$MAD-SKS', '$mad-db must resolve to deprecated alias redirecting to $MAD-SKS');
|
|
11
12
|
const initText = readText('src/core/init.ts');
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const skillInitText = readText('src/core/init/skills.ts');
|
|
14
|
+
const typedSkillSource = `${initText}\n${skillInitText}`;
|
|
15
|
+
assertGate(typedSkillSource.includes("'mad-db':") && typedSkillSource.includes('merged into mad-sks') && typedSkillSource.includes('madDbSkillText()') && typedSkillSource.includes('dbSafetyGuardSkillText()'), 'mad-db generated skill must be deprecated and SQL-plane policy must be merged into mad-sks');
|
|
16
|
+
assertGate(madDbCommandSource.includes('run') && madDbCommandSource.includes('exec') && madDbCommandSource.includes('apply-migration') && madDbCommandSource.includes('sql'), 'mad-db command must translate legacy execution subcommands');
|
|
17
|
+
emitGate('mad-db:command', { command: 'sks mad-db', dollar_command: '$MAD-DB', app_skill_alias: '$mad-db', alias_to: '$MAD-SKS' });
|
|
15
18
|
//# sourceMappingURL=mad-db-command-check.js.map
|
|
@@ -10,18 +10,20 @@ import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
|
|
|
10
10
|
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-mad-db-route-identity-'));
|
|
11
11
|
const prepared = await prepareMadDbMission({
|
|
12
12
|
root,
|
|
13
|
-
task: '$MAD-
|
|
13
|
+
task: '$MAD-SKS truncate public.fixture',
|
|
14
14
|
args: ['--project-ref', 'fixture-project-ref', '--target', 'preview'],
|
|
15
15
|
verifyTools: false,
|
|
16
|
-
runtimeSessionId: 'route-identity-session'
|
|
16
|
+
runtimeSessionId: 'route-identity-session',
|
|
17
|
+
route: 'MadSKS',
|
|
18
|
+
routeCommand: '$MAD-SKS'
|
|
17
19
|
});
|
|
18
20
|
const proof = await madDbRouteIdentityProof(root, prepared.mission_id);
|
|
19
|
-
assertGate(routeByDollarCommand('MAD-DB')?.id === 'MadDB', '$MAD-DB must
|
|
20
|
-
assertGate(routeByDollarCommand('MAD-SKS')?.id === 'MadSKS', '$MAD-SKS must
|
|
21
|
-
assertGate(prepared.ok === true && prepared.capability.mission_id === prepared.mission_id, '
|
|
21
|
+
assertGate(routeByDollarCommand('MAD-DB')?.id === 'MadDB' && routeByDollarCommand('MAD-DB')?.deprecated === true && routeByDollarCommand('MAD-DB')?.aliasTo === '$MAD-SKS', '$MAD-DB must remain a deprecated alias to $MAD-SKS', routeByDollarCommand('MAD-DB'));
|
|
22
|
+
assertGate(routeByDollarCommand('MAD-SKS')?.id === 'MadSKS', '$MAD-SKS must be the merged scoped permission + SQL-plane route', routeByDollarCommand('MAD-SKS'));
|
|
23
|
+
assertGate(prepared.ok === true && prepared.capability.mission_id === prepared.mission_id, 'MAD-SKS sql-plane prepare must create one authoritative mission/capability', prepared);
|
|
22
24
|
assertGate(prepared.capability.runtime_session_id === 'route-identity-session' && prepared.capability.transport.profile_sha256 === prepared.runtime_profile.profile_sha256, 'capability must bind the runtime profile hash/session', prepared.capability);
|
|
23
25
|
assertGate(isMadDbCapabilityActive(prepared.capability) === true, 'prepared capability must be active/transport-ready', prepared.capability);
|
|
24
|
-
assertGate(proof.ok === true && proof.same_mission === true && proof.route_command === '$MAD-
|
|
26
|
+
assertGate(proof.ok === true && proof.same_mission === true && proof.route_command === '$MAD-SKS' && proof.deprecated_route_accepted === true, 'route identity proof mismatch', proof);
|
|
25
27
|
await closeMadDbRuntimeProfile({ root, missionId: prepared.mission_id, reason: 'route_identity_check' });
|
|
26
28
|
await closeMadDbCycle(root, prepared.mission_id, prepared.cycle_id, 'route_identity_check');
|
|
27
29
|
emitGate('mad-db:route-identity', { mission_id: prepared.mission_id, cycle_id: prepared.cycle_id, profile_sha256: prepared.runtime_profile.profile_sha256 });
|
|
@@ -5,18 +5,41 @@ import path from 'node:path';
|
|
|
5
5
|
import { assertGate, emitGate, importDist } from './sks-1-18-gate-lib.js';
|
|
6
6
|
const missionMod = await importDist('core/mission.js');
|
|
7
7
|
const capMod = await importDist('core/mad-db/mad-db-capability.js');
|
|
8
|
+
const runtimeMod = await importDist('core/mad-db/mad-db-runtime-profile.js');
|
|
9
|
+
const coordinatorMod = await importDist('core/mad-db/mad-db-coordinator.js');
|
|
8
10
|
const db = await importDist('core/db-safety.js');
|
|
9
11
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-mad-db-matrix-'));
|
|
10
12
|
const mission = await missionMod.createMission(root, { mode: 'mad-sks', prompt: 'fixture' });
|
|
11
13
|
const madSksState = { mission_id: mission.id, mode: 'MADSKS', mad_sks_active: true, mad_sks_gate_file: 'mad-sks-gate.json' };
|
|
12
14
|
fs.writeFileSync(path.join(mission.dir, 'mad-sks-gate.json'), JSON.stringify({ passed: false, permissions_deactivated: false }, null, 2));
|
|
13
15
|
const catastrophic = await db.checkDbOperation(root, madSksState, { tool_name: 'supabase.execute_sql', sql: 'truncate users;' });
|
|
14
|
-
assertGate(catastrophic.allowed === false && catastrophic.reasons.includes('mad_sks_catastrophic_db_operation_blocked'), 'MAD-SKS catastrophic guard must remain without
|
|
15
|
-
await
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
assertGate(catastrophic.allowed === false && catastrophic.reasons.includes('mad_sks_catastrophic_db_operation_blocked'), 'MAD-SKS catastrophic guard must remain without active sql-plane capability', catastrophic);
|
|
17
|
+
const prepared = await coordinatorMod.prepareMadDbMission({
|
|
18
|
+
root,
|
|
19
|
+
task: '$MAD-SKS truncate users',
|
|
20
|
+
args: ['--project-ref', 'fixture-project-ref', '--target', 'preview'],
|
|
21
|
+
verifyTools: false,
|
|
22
|
+
route: 'MadSKS',
|
|
23
|
+
routeCommand: '$MAD-SKS'
|
|
24
|
+
});
|
|
25
|
+
const activeState = {
|
|
26
|
+
mission_id: prepared.mission_id,
|
|
27
|
+
mode: 'MADSKS',
|
|
28
|
+
route: 'MadSKS',
|
|
29
|
+
route_command: '$MAD-SKS',
|
|
30
|
+
mad_sks_active: true,
|
|
31
|
+
mad_db_active: true,
|
|
32
|
+
mad_db_capability_mission_id: prepared.mission_id,
|
|
33
|
+
mad_db_cycle_id: prepared.cycle_id,
|
|
34
|
+
mad_db_runtime_session_id: prepared.capability.runtime_session_id,
|
|
35
|
+
mad_db_profile_sha256: prepared.runtime_profile.profile_sha256,
|
|
36
|
+
mad_sks_gate_file: 'mad-sks-gate.json'
|
|
37
|
+
};
|
|
38
|
+
const sqlPlane = await db.checkDbOperation(root, activeState, { tool_name: 'supabase.execute_sql', tool_call_id: 'matrix-truncate-active', sql: 'truncate users;' });
|
|
39
|
+
assertGate(sqlPlane.allowed === true && sqlPlane.mad_db?.active === true && sqlPlane.mad_db?.state_source !== 'legacy_mad_db_route', 'MAD-SKS sql-plane capability must authorize the bounded SQL-plane cycle', sqlPlane);
|
|
40
|
+
await runtimeMod.closeMadDbRuntimeProfile({ root, missionId: prepared.mission_id, reason: 'matrix-cycle-close' });
|
|
41
|
+
await capMod.closeMadDbCycle(root, prepared.mission_id, prepared.cycle_id, 'matrix-cycle-close');
|
|
42
|
+
const afterClose = await db.checkDbOperation(root, { ...activeState, mad_db_active: false, mad_sks_active: false }, { tool_name: 'supabase.execute_sql', tool_call_id: 'matrix-truncate-closed', sql: 'truncate users;' });
|
|
43
|
+
assertGate(afterClose.allowed === false, 'after bounded sql-plane close, MAD-SKS catastrophic guard must block again', afterClose);
|
|
44
|
+
emitGate('mad-db:safety-conflict-matrix', { states: ['mad-sks-blocks-without-sql-plane', 'mad-sks-sql-plane-allows-cycle', 'mad-sks-blocks-after-cycle-close'] });
|
|
22
45
|
//# sourceMappingURL=mad-db-safety-conflict-matrix-check.js.map
|
|
@@ -3,16 +3,15 @@ import { MAD_DB_POLICY, dbSafetyGuardSkillText, madDbSkillText } from '../core/m
|
|
|
3
3
|
import { assertGate, emitGate, readText } from './sks-1-18-gate-lib.js';
|
|
4
4
|
const madDbSkill = madDbSkillText();
|
|
5
5
|
const dbSafetySkill = dbSafetyGuardSkillText();
|
|
6
|
-
const initText = readText('src/core/init.ts')
|
|
6
|
+
const initText = `${readText('src/core/init.ts')}\n${readText('src/core/init/skills.ts')}`;
|
|
7
7
|
for (const token of ['table/schema DROP', 'all-row mutations', 'TRUNCATE', 'execute_sql', 'apply_migration']) {
|
|
8
8
|
assertGate(madDbSkill.includes(token), `MadDB skill SSOT missing ${token}`, { madDbSkill });
|
|
9
9
|
}
|
|
10
|
-
assertGate(dbSafetySkill.includes('Active
|
|
10
|
+
assertGate(dbSafetySkill.includes('Active MAD-SKS sql-plane is the explicit exception'), 'db safety skill must name active MAD-SKS sql-plane exception', { dbSafetySkill });
|
|
11
11
|
assertGate(!madDbSkill.includes('Keep catastrophic safeguards active: whole database/schema/table removal'), 'MadDB skill must not carry old destructive-operation denial text', { madDbSkill });
|
|
12
|
-
assertGate(
|
|
13
|
-
assertGate(madDbSkill.includes('Do not add prompt-only SQL deny lists inside active MadDB'), 'MadDB skill must prevent SQL-plane prompt veto lists', { madDbSkill });
|
|
12
|
+
assertGate(madDbSkill.includes('Do not add prompt-only SQL deny lists inside active sql-plane'), 'MadDB skill must prevent SQL-plane prompt veto lists', { madDbSkill });
|
|
14
13
|
assertGate(!dbSafetySkill.includes('do not run DROP'), 'db safety skill must not conflict with active MadDB SQL-plane allowance', { dbSafetySkill });
|
|
15
|
-
assertGate(dbSafetySkill.includes('Default read-only restrictions do not apply to SQL-plane work while the active
|
|
14
|
+
assertGate(dbSafetySkill.includes('Default read-only restrictions do not apply to SQL-plane work while the active MAD-SKS sql-plane capability v2 is bound'), 'db safety skill must explicitly remove default restrictions during active MAD-SKS sql-plane', { dbSafetySkill });
|
|
16
15
|
assertGate(initText.includes('madDbSkillText()') && initText.includes('dbSafetyGuardSkillText()'), 'init must generate skills from typed MadDB policy SSOT', {});
|
|
17
16
|
assertGate(MAD_DB_POLICY.active_mode.sql_plane === 'allow_all_mutations' && MAD_DB_POLICY.normal_supabase_mcp.read_only_required === true, 'typed policy must encode active SQL-plane and normal read-only modes', MAD_DB_POLICY);
|
|
18
17
|
emitGate('mad-db:skill-policy', { schema: MAD_DB_POLICY.schema, operation_classes: MAD_DB_POLICY.sql_plane_allowed.length });
|
|
@@ -5,12 +5,16 @@ requireContains('ppt:real-imagegen-wiring', 'src/core/ppt-review/slide-imagegen-
|
|
|
5
5
|
'generateGptImage2CalloutReview',
|
|
6
6
|
'PPT_SLIDE_IMAGEGEN_REQUEST_ARTIFACT',
|
|
7
7
|
'PPT_SLIDE_IMAGEGEN_RESPONSE_ARTIFACT',
|
|
8
|
+
'buildSlideImagegenEvidence',
|
|
9
|
+
'evidence_class',
|
|
10
|
+
'output_sha256',
|
|
8
11
|
'extraction_pending_count',
|
|
9
12
|
'callout_extraction_status'
|
|
10
13
|
]);
|
|
11
14
|
requireContains('ppt:real-imagegen-wiring', 'src/core/ppt-review/index.ts', [
|
|
12
15
|
'buildSlideImagegenRequestArtifact',
|
|
13
|
-
'buildSlideImagegenResponseArtifact'
|
|
16
|
+
'buildSlideImagegenResponseArtifact',
|
|
17
|
+
'imagegen_evidence'
|
|
14
18
|
]);
|
|
15
19
|
emitGate('ppt:real-imagegen-wiring', { adapter: 'shared UX generateGptImage2CalloutReview' });
|
|
16
20
|
//# sourceMappingURL=ppt-real-imagegen-wiring-check.js.map
|
|
@@ -11,6 +11,7 @@ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-root-cause-policy-'));
|
|
|
11
11
|
await writeRouteCompletionProof(root, {
|
|
12
12
|
missionId: 'M-root-cause-missing',
|
|
13
13
|
route: '$Wiki',
|
|
14
|
+
executionClass: 'real',
|
|
14
15
|
status: 'verified_partial',
|
|
15
16
|
unverified: ['fallback path was used without RCA']
|
|
16
17
|
});
|
|
@@ -23,6 +24,7 @@ assert.ok(missingGate.issues.includes('root_cause_analysis_missing'));
|
|
|
23
24
|
const fixed = await writeRouteCompletionProof(root, {
|
|
24
25
|
missionId: 'M-root-cause-complete',
|
|
25
26
|
route: '$Wiki',
|
|
27
|
+
executionClass: 'real',
|
|
26
28
|
status: 'verified_partial',
|
|
27
29
|
unverified: ['fallback path was used, root cause corrected below'],
|
|
28
30
|
failureAnalysis: {
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
|
|
5
|
-
const
|
|
6
|
-
const
|
|
5
|
+
const packageJson = readPackageJson(path.join(root, 'package.json'));
|
|
6
|
+
const releaseManifest = readReleaseGateManifest(path.join(root, 'release-gates.v2.json'), 'sks.release-gates.v2');
|
|
7
|
+
const harnessManifest = readReleaseGateManifest(path.join(root, 'infra-harness-gates.json'), 'sks.infra-harness-gates.v1');
|
|
7
8
|
const releasePreset = releaseManifest.gates.filter((gate) => gate.preset.includes('release'));
|
|
8
9
|
const harnessPreset = harnessManifest.gates.filter((gate) => gate.preset.includes('harness'));
|
|
9
10
|
const releaseIds = new Set(releasePreset.map((gate) => gate.id));
|
|
@@ -58,11 +59,19 @@ const report = {
|
|
|
58
59
|
release_zellij: releaseZellij,
|
|
59
60
|
harness_non_zellij: harnessNonZellij,
|
|
60
61
|
npm_run_commands: npmRunCommands,
|
|
61
|
-
schema_complete: schemaComplete
|
|
62
|
+
schema_complete: schemaComplete,
|
|
63
|
+
package_script_count: Object.keys(packageJson.scripts || {}).length
|
|
62
64
|
};
|
|
63
65
|
assertGate(report.ok, 'release/harness gate manifests must satisfy consolidated v2 coverage policy', report);
|
|
64
66
|
emitGate('release:dag-full-coverage', report);
|
|
65
|
-
function
|
|
67
|
+
function readPackageJson(file) {
|
|
68
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
69
|
+
assertGate(isRecord(parsed), 'package.json must be an object', { file });
|
|
70
|
+
const record = parsed;
|
|
71
|
+
const scripts = isRecord(record.scripts) ? Object.fromEntries(Object.entries(record.scripts).filter((entry) => typeof entry[1] === 'string')) : {};
|
|
72
|
+
return { scripts };
|
|
73
|
+
}
|
|
74
|
+
function readReleaseGateManifest(file, expectedSchema) {
|
|
66
75
|
const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
67
76
|
assertGate(isRecord(parsed), 'gate manifest must be an object', { file });
|
|
68
77
|
assertGate(parsed.schema === expectedSchema, 'gate manifest schema mismatch', { file, schema: parsed.schema, expected_schema: expectedSchema });
|