sneakoscope 6.0.2 → 6.1.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 +5 -3
- package/config/codex-releases/{rust-v0.142.0.json → rust-v0.144.1.json} +6 -6
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/cli/install-helpers.js +255 -440
- package/dist/cli/router.js +53 -4
- package/dist/commands/codex-app.js +8 -3
- package/dist/commands/codex-lb.js +169 -40
- package/dist/commands/codex.js +6 -5
- package/dist/commands/doctor.js +60 -26
- package/dist/commands/versioning.js +7 -0
- package/dist/config/skills-manifest.json +57 -57
- package/dist/core/agents/agent-central-ledger.js +9 -0
- package/dist/core/agents/agent-cleanup-executor.js +334 -41
- package/dist/core/agents/agent-cleanup.js +20 -1
- package/dist/core/agents/agent-command-surface.js +2 -1
- package/dist/core/agents/agent-effort-policy.js +46 -33
- package/dist/core/agents/agent-janitor.js +9 -10
- package/dist/core/agents/agent-namespace-safety.js +56 -0
- package/dist/core/agents/agent-orchestrator.js +26 -4
- package/dist/core/agents/agent-output-validator.js +1 -1
- package/dist/core/agents/agent-proof-evidence.js +16 -2
- package/dist/core/agents/agent-role-config.js +3 -6
- package/dist/core/agents/agent-roster.js +2 -2
- package/dist/core/agents/agent-runner-codex-exec.js +2 -0
- package/dist/core/agents/agent-runner-process.js +1 -0
- package/dist/core/agents/fast-mode-policy.js +3 -5
- package/dist/core/agents/native-cli-session-swarm.js +18 -1
- package/dist/core/agents/native-worker-backend-router.js +180 -108
- package/dist/core/agents/parallel-write-fixture.js +15 -10
- package/dist/core/agents/runtime-proof-summary.js +21 -3
- package/dist/core/agents/work-partition/repo-inventory.js +68 -7
- package/dist/core/code-structure.js +5 -4
- package/dist/core/codex/codex-config-guard.js +31 -9
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +51 -20
- package/dist/core/codex-app/codex-app-restart.js +38 -8
- package/dist/core/codex-app/codex-app-ui-state-snapshot.js +11 -3
- package/dist/core/codex-app/sks-menubar.js +100 -40
- package/dist/core/codex-app.js +60 -17
- package/dist/core/codex-compat/codex-hook-warning-detector.js +10 -1
- package/dist/core/codex-compat/codex-release-manifest.js +6 -6
- package/dist/core/codex-control/codex-0139-doctor-real-probe.js +7 -1
- package/dist/core/codex-control/codex-0139-image-path-real-probe.js +14 -8
- package/dist/core/codex-control/codex-0139-probe-runner.js +103 -28
- package/dist/core/codex-control/codex-0139-real-probe-summary.js +7 -3
- package/dist/core/codex-control/codex-0139-real-probes.js +21 -6
- package/dist/core/codex-control/codex-0139-sandbox-real-probe.js +39 -13
- package/dist/core/codex-control/codex-0139-web-search-probe.js +11 -8
- package/dist/core/codex-control/{codex-0142-capability.js → codex-0144-capability.js} +22 -22
- package/dist/core/codex-control/codex-0144-collab-agent-real-probe.js +63 -0
- package/dist/core/codex-control/codex-model-metadata.js +8 -4
- package/dist/core/codex-control/codex-multi-agent-event-normalizer.js +5 -1
- package/dist/core/codex-control/codex-reliability-shield.js +4 -1
- package/dist/core/codex-control/codex-sdk-adapter.js +53 -6
- package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
- package/dist/core/codex-control/codex-sdk-sandbox-policy.js +6 -3
- package/dist/core/codex-lb/codex-lb-env.js +107 -0
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +478 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +22 -22
- package/dist/core/codex-native/codex-native-feature-matrix.js +2 -2
- package/dist/core/codex-native/native-capability-postcheck.js +16 -8
- package/dist/core/codex-native/native-capability-repair-matrix.js +76 -27
- package/dist/core/codex-plugins/codex-plugin-json.js +67 -21
- package/dist/core/codex-plugins/codex-plugin-repair.js +118 -0
- package/dist/core/codex-runtime/codex-desktop-config-policy.js +306 -0
- package/dist/core/commands/agent-command.js +19 -0
- package/dist/core/commands/basic-cli.js +45 -24
- package/dist/core/commands/gc-command.js +27 -4
- package/dist/core/commands/image-ux-review-command.js +55 -24
- package/dist/core/commands/mad-sks-command.js +152 -132
- package/dist/core/commands/naruto-command.js +41 -10
- package/dist/core/commands/pipeline-command.js +1 -0
- package/dist/core/commands/wiki-command.js +179 -83
- package/dist/core/computer-use-live-evidence.js +166 -3
- package/dist/core/computer-use-status.js +5 -2
- package/dist/core/daemon/sksd-hook-daemon-entrypoint.js +2 -2
- package/dist/core/daemon/sksd-hook-daemon.js +171 -28
- package/dist/core/daemon/sksd-hook-dispatch.js +2 -2
- package/dist/core/dfix/verification-selector.js +6 -4
- package/dist/core/doctor/browser-use-repair.js +54 -13
- package/dist/core/doctor/codex-0139-doctor.js +3 -2
- package/dist/core/doctor/computer-use-repair.js +28 -39
- package/dist/core/doctor/doctor-codex-startup-repair.js +19 -9
- package/dist/core/doctor/doctor-context7-repair.js +1 -1
- package/dist/core/doctor/doctor-dirty-planner.js +1 -1
- package/dist/core/doctor/doctor-native-capability-repair.js +74 -3
- package/dist/core/doctor/imagegen-repair.js +47 -12
- package/dist/core/doctor/legacy-global-hook-cleanup.js +179 -0
- package/dist/core/feature-registry.js +25 -31
- package/dist/core/fsx.js +54 -6
- package/dist/core/harness-conflicts.js +1 -1
- package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +5 -4
- package/dist/core/hooks-runtime/hook-invocation-dedupe.js +147 -0
- package/dist/core/hooks-runtime/hook-io.js +6 -0
- package/dist/core/hooks-runtime.js +17 -2
- package/dist/core/image/image-artifact-path-contract.js +8 -6
- package/dist/core/image/image-artifact-registry.js +5 -1
- package/dist/core/image-ux-review/imagegen-adapter.js +5 -2
- package/dist/core/imagegen/imagegen-capability.js +10 -13
- package/dist/core/imagegen/require-imagegen.js +37 -11
- package/dist/core/managed-assets/managed-assets-manifest.js +1 -5
- package/dist/core/naruto/naruto-work-graph.js +70 -4
- package/dist/core/naruto/naruto-write-e2e.js +3 -4
- package/dist/core/ops/reporting.js +3 -0
- package/dist/core/pipeline-internals/runtime-core.js +12 -7
- package/dist/core/pipeline-internals/runtime-gates.js +17 -1
- package/dist/core/ppt/style-tokens.js +1 -1
- package/dist/core/ppt-review/index.js +1 -1
- package/dist/core/ppt-review/slide-exporter.js +23 -17
- package/dist/core/ppt-review/slide-imagegen-review.js +1 -1
- package/dist/core/ppt-review/slide-issue-extraction.js +4 -2
- package/dist/core/product-design-plugin.js +2 -2
- package/dist/core/proof/route-finalizer.js +1 -1
- package/dist/core/proof-field.js +3 -3
- package/dist/core/provider/model-router.js +68 -3
- package/dist/core/release/gate-manifest.js +18 -12
- package/dist/core/release/gate-pack-manifest.js +1 -1
- package/dist/core/release/package-size-budget.js +2 -0
- package/dist/core/release/release-gate-affected-selector.js +1 -1
- package/dist/core/release/release-gate-dag.js +43 -3
- package/dist/core/release/release-gate-hermetic-env.js +28 -17
- package/dist/core/release/release-real-contract.js +416 -0
- package/dist/core/retention/retention-budget.js +25 -6
- package/dist/core/retention.js +980 -101
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes/evidence.js +4 -4
- package/dist/core/routes/model-mode-router.js +3 -0
- package/dist/core/routes/ppt-policy.js +1 -1
- package/dist/core/routes.js +11 -12
- package/dist/core/secret-redaction.js +4 -0
- package/dist/core/triwiki/code-pack.js +8 -2
- package/dist/core/triwiki/triwiki-cache-key.js +108 -29
- package/dist/core/triwiki-attention.js +13 -6
- package/dist/core/triwiki-provenance.js +274 -0
- package/dist/core/triwiki-runtime.js +21 -7
- package/dist/core/triwiki-wrongness/wrongness-ledger.js +178 -59
- package/dist/core/triwiki-wrongness/wrongness-retrieval.js +11 -2
- package/dist/core/triwiki-wrongness/wrongness-trust-policy.js +2 -0
- package/dist/core/update/update-migration-state.js +1 -1
- package/dist/core/update/update-notice.js +23 -0
- package/dist/core/update-check.js +69 -25
- package/dist/core/version.js +1 -1
- package/dist/core/wiki-coordinate.js +128 -12
- package/dist/core/work-order-ledger.js +168 -9
- package/dist/core/zellij/zellij-command.js +12 -1
- package/dist/core/zellij/zellij-dashboard-pane.js +3 -3
- package/dist/core/zellij/zellij-launcher.js +15 -14
- package/dist/core/zellij/zellij-pane-proof.js +32 -6
- package/dist/core/zellij/zellij-worker-pane-manager.js +5 -3
- package/dist/scripts/agent-fast-mode-default-check.js +48 -29
- package/dist/scripts/agent-role-config-repair-check.js +25 -4
- package/dist/scripts/agent-wiki-context-proof-check.js +16 -2
- package/dist/scripts/all-feature-deep-completion-check.js +14 -4
- package/dist/scripts/build-dist.js +17 -5
- package/dist/scripts/canonical-test-runner.js +188 -0
- package/dist/scripts/check-command-module-budget.js +38 -16
- package/dist/scripts/check-legacy-free.js +1 -1
- package/dist/scripts/codex-0139-interrupt-agent-check.js +5 -1
- package/dist/scripts/{codex-0142-app-server-v2-check.js → codex-0144-app-server-v2-check.js} +11 -10
- package/dist/scripts/{codex-0142-binary-identity-check.js → codex-0144-binary-identity-check.js} +4 -4
- package/dist/scripts/codex-0144-capability-check.js +21 -0
- package/dist/scripts/{codex-0139-real-probes-check.js → codex-0144-core-real-probes-check.js} +19 -5
- package/dist/scripts/{codex-0142-doctor-wiring-check.js → codex-0144-doctor-wiring-check.js} +6 -6
- package/dist/scripts/{codex-0142-manifest-check.js → codex-0144-manifest-check.js} +11 -3
- package/dist/scripts/{codex-0142-policy-check.js → codex-0144-policy-check.js} +2 -2
- package/dist/scripts/{codex-0142-thread-store-check.js → codex-0144-thread-store-check.js} +3 -3
- package/dist/scripts/codex-app-provider-model-ui-check.js +57 -8
- package/dist/scripts/codex-app-ui-preservation-check.js +35 -4
- package/dist/scripts/codex-control-side-effect-scope-check.js +2 -2
- package/dist/scripts/codex-effort-auto-discovery-check.js +1 -1
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +1 -0
- package/dist/scripts/{codex-lb-gpt55-fast-profile-check.js → codex-lb-gpt56-fast-profile-check.js} +56 -5
- package/dist/scripts/codex-model-metadata-check.js +1 -1
- package/dist/scripts/codex-sdk-sandbox-policy-check.js +5 -1
- package/dist/scripts/codex-sdk-version-compat-check.js +2 -1
- package/dist/scripts/dfix-fixture-check.js +1 -1
- package/dist/scripts/docs-truthfulness-check.js +1 -1
- package/dist/scripts/doctor-codex-startup-repair-check.js +35 -10
- package/dist/scripts/doctor-context7-repair-check.js +2 -1
- package/dist/scripts/doctor-fix-proves-codex-read-check.js +1 -1
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +34 -7
- package/dist/scripts/doctor-imagegen-repair-check.js +14 -4
- package/dist/scripts/doctor-startup-config-repair-blackbox.js +1 -1
- package/dist/scripts/doctor-startup-config-repair-check.js +1 -1
- package/dist/scripts/gate-policy-audit-check.js +2 -2
- package/dist/scripts/install-update-preserves-config-check.js +1 -1
- package/dist/scripts/legacy-gate-inventory-check.js +7 -5
- package/dist/scripts/legacy-strong-inventory-check.js +7 -5
- package/dist/scripts/legacy-upgrade-matrix-check.js +5 -5
- package/dist/scripts/lib/native-cli-session-swarm-check-lib.js +175 -14
- package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +166 -6
- package/dist/scripts/mutation-callsite-coverage-check.js +0 -11
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +88 -50
- package/dist/scripts/npm-publish-performance-check.js +2 -1
- package/dist/scripts/package-published-contract-check.js +9 -0
- package/dist/scripts/packlist-performance-check.js +5 -2
- package/dist/scripts/postinstall-safe-side-effects-check.js +8 -3
- package/dist/scripts/ppt-no-mock-as-real-check.js +3 -1
- package/dist/scripts/product-design-plugin-routing-check.js +1 -1
- package/dist/scripts/release-check-stamp.js +182 -2
- package/dist/scripts/release-dag-full-coverage-check.js +7 -7
- package/dist/scripts/release-dynamic-presets-check.js +8 -0
- package/dist/scripts/release-gate-dag-runner-check.js +3 -2
- package/dist/scripts/release-gate-dag-runner.js +24 -11
- package/dist/scripts/release-gate-existence-audit.js +8 -9
- package/dist/scripts/release-gate-script-parity-check.js +1 -1
- package/dist/scripts/release-real-check.js +368 -157
- package/dist/scripts/release-runtime-truth-matrix-check.js +22 -0
- package/dist/scripts/route-proof-artifact-structure-check.js +1 -0
- package/dist/scripts/scheduler-batch-dispatch-check.js +1 -1
- package/dist/scripts/search-visibility-gate-lib.js +1 -1
- package/dist/scripts/seo-geo-route-identity-check.js +30 -4
- package/dist/scripts/sizecheck.js +7 -2
- package/dist/scripts/sks-1-11-gate-lib.js +53 -6
- package/dist/scripts/sks-menubar-install-check.js +7 -0
- package/dist/scripts/sks-uninstall-regression-check.js +1 -1
- package/dist/scripts/sksd-daemon-check.js +16 -6
- package/dist/scripts/update-default-command-check.js +4 -2
- package/dist/scripts/write-build-manifest.js +2 -1
- package/dist/scripts/zellij-layout-valid-check.js +31 -6
- package/dist/scripts/zellij-pane-proof-check.js +33 -2
- package/dist/scripts/zellij-real-session-cleanup-check.js +122 -2
- package/dist/scripts/zellij-real-session-launch-check.js +76 -5
- package/dist/scripts/zellij-slot-pane-renderer-check.js +4 -4
- package/package.json +27 -30
- package/schemas/codex/{app-server-0.142 → app-server-0.144}/codex_app_server_protocol.v2.schemas.json +1146 -781
- package/schemas/codex/codex-0139-real-probe-result.schema.json +39 -5
- package/schemas/codex/ppt-slide-issue-ledger.schema.json +2 -1
- package/dist/core/codex-control/codex-0139-multi-agent-real-probe.js +0 -107
- package/dist/scripts/agent-native-release-gate.js +0 -274
- package/dist/scripts/codex-0142-capability-check.js +0 -21
- package/dist/scripts/command-performance-scorecard-check.js +0 -204
- package/dist/scripts/config-managed-merge-callsite-coverage-check.js +0 -212
- package/dist/scripts/dollar-performance-scorecard-check.js +0 -257
- package/dist/scripts/gate-timing-check.js +0 -16
- package/dist/scripts/ops-maturity-scorecard-check.js +0 -12
- package/dist/scripts/performance-baseline-check.js +0 -12
- package/dist/scripts/performance-improvement-report-check.js +0 -58
- package/dist/scripts/release-parallel-check.js +0 -389
- package/dist/scripts/release-runner-efficiency-check.js +0 -15
- package/dist/scripts/retention-long-run-smoke-check.js +0 -299
- package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// @ts-nocheck
|
|
3
|
-
import fs from 'node:fs';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { performance } from 'node:perf_hooks';
|
|
6
|
-
import { fileURLToPath } from 'node:url';
|
|
7
|
-
import { assertGate, emitGate, importDist, root } from './sks-1-18-gate-lib.js';
|
|
8
|
-
import { runProcess } from '../core/fsx.js';
|
|
9
|
-
export const CRITICAL_COMMANDS = new Set([
|
|
10
|
-
'doctor',
|
|
11
|
-
'setup',
|
|
12
|
-
'bootstrap',
|
|
13
|
-
'update',
|
|
14
|
-
'run',
|
|
15
|
-
'naruto',
|
|
16
|
-
'super-search',
|
|
17
|
-
'seo-geo-optimizer',
|
|
18
|
-
'db',
|
|
19
|
-
'mad-sks',
|
|
20
|
-
'qa-loop',
|
|
21
|
-
'review',
|
|
22
|
-
'release',
|
|
23
|
-
'rollback',
|
|
24
|
-
'commit-and-push'
|
|
25
|
-
]);
|
|
26
|
-
export const COMMAND_SMOKE_MAX_AGE_MS = 60 * 60 * 1000;
|
|
27
|
-
export const smokeCommands = [
|
|
28
|
-
{ name: 'version', argv: ['--version'], budget_p95_ms: 120 },
|
|
29
|
-
{ name: 'commands', argv: ['commands', '--json'], budget_p95_ms: 200 },
|
|
30
|
-
{ name: 'root', argv: ['root', '--json'], budget_p95_ms: 150 },
|
|
31
|
-
{ name: 'dollar-commands', argv: ['dollar-commands', '--json'], budget_p95_ms: 220 },
|
|
32
|
-
{ name: 'super-search', argv: ['super-search', 'doctor', '--json'], budget_p95_ms: 180 },
|
|
33
|
-
{ name: 'doctor', argv: ['doctor', '--json'], budget_p95_ms: 1200 },
|
|
34
|
-
{ name: 'setup', budget_p95_ms: 0, kind: 'fixture', evidence: 'setup_dry_run_contract' },
|
|
35
|
-
{ name: 'bootstrap', budget_p95_ms: 0, kind: 'fixture', evidence: 'bootstrap_fixture_contract' },
|
|
36
|
-
{ name: 'update', budget_p95_ms: 0, kind: 'fixture', evidence: 'update_now_dry_run_contract' },
|
|
37
|
-
{ name: 'run', budget_p95_ms: 0, kind: 'fixture', evidence: 'run_route_classification_fixture' },
|
|
38
|
-
{ name: 'naruto', budget_p95_ms: 0, kind: 'fixture', evidence: 'naruto_route_fixture' },
|
|
39
|
-
{ name: 'seo-geo-optimizer', budget_p95_ms: 0, kind: 'fixture', evidence: 'seo_geo_optimizer_fixture' },
|
|
40
|
-
{ name: 'db', budget_p95_ms: 0, kind: 'blocked_negative', evidence: 'db_destructive_sql_block_contract' },
|
|
41
|
-
{ name: 'mad-sks', budget_p95_ms: 0, kind: 'blocked_negative', evidence: 'mad_sks_restore_and_readback_contract' },
|
|
42
|
-
{ name: 'qa-loop', budget_p95_ms: 0, kind: 'fixture', evidence: 'qa_loop_route_fixture' },
|
|
43
|
-
{ name: 'review', budget_p95_ms: 0, kind: 'fixture', evidence: 'review_diff_fixture' },
|
|
44
|
-
{ name: 'release', budget_p95_ms: 0, kind: 'fixture', evidence: 'release_gate_fixture' },
|
|
45
|
-
{ name: 'rollback', budget_p95_ms: 0, kind: 'blocked_negative', evidence: 'rollback_apply_requires_id_contract' },
|
|
46
|
-
{ name: 'commit-and-push', budget_p95_ms: 0, kind: 'blocked_negative', evidence: 'commit_and_push_remote_contract' }
|
|
47
|
-
];
|
|
48
|
-
if (isMainModule())
|
|
49
|
-
await main();
|
|
50
|
-
export async function main() {
|
|
51
|
-
const { COMMAND_MANIFEST_LITE } = await importDist('cli/command-manifest-lite.js');
|
|
52
|
-
const timings = [];
|
|
53
|
-
for (const smoke of smokeCommands)
|
|
54
|
-
timings.push(await measure(smoke));
|
|
55
|
-
const timingByName = new Map(timings.map((row) => [row.name, row]));
|
|
56
|
-
const entries = COMMAND_MANIFEST_LITE.filter((entry) => entry.hidden !== true);
|
|
57
|
-
const rows = entries.map((entry) => scoreEntry(entry, timingByName.get(entry.name)));
|
|
58
|
-
const average = rows.reduce((sum, row) => sum + row.score, 0) / Math.max(1, rows.length);
|
|
59
|
-
const blockers = [
|
|
60
|
-
...rows.filter((row) => row.critical && row.score === 0).map((row) => `${row.name}:critical_smoke_missing_or_failed`),
|
|
61
|
-
...(average >= 94 ? [] : [`average_below_94:${average.toFixed(2)}`])
|
|
62
|
-
];
|
|
63
|
-
const report = {
|
|
64
|
-
schema: 'sks.command-performance-scorecard.v1',
|
|
65
|
-
ok: blockers.length === 0,
|
|
66
|
-
generated_at: new Date().toISOString(),
|
|
67
|
-
average_score: Number(average.toFixed(2)),
|
|
68
|
-
command_count: rows.length,
|
|
69
|
-
timings,
|
|
70
|
-
rows,
|
|
71
|
-
blockers
|
|
72
|
-
};
|
|
73
|
-
const out = path.join(root, '.sneakoscope', 'reports', 'command-performance-scorecard.json');
|
|
74
|
-
fs.mkdirSync(path.dirname(out), { recursive: true });
|
|
75
|
-
fs.writeFileSync(out, `${JSON.stringify(report, null, 2)}\n`);
|
|
76
|
-
assertGate(report.ok, 'command performance scorecard failed', report);
|
|
77
|
-
emitGate('command:performance-scorecard', { average_score: report.average_score, command_count: rows.length, report: '.sneakoscope/reports/command-performance-scorecard.json' });
|
|
78
|
-
}
|
|
79
|
-
export function scoreEntry(entry, timing, options = {}) {
|
|
80
|
-
const now = options.now ? new Date(options.now) : new Date();
|
|
81
|
-
const critical = CRITICAL_COMMANDS.has(entry.name);
|
|
82
|
-
const smokeStatus = classifySmoke(timing, now);
|
|
83
|
-
if (critical && smokeStatus !== 'pass') {
|
|
84
|
-
return { name: entry.name, maturity: entry.maturity, critical, score: 0, p95_ms: timing?.p95_ms ?? null, smoke: Boolean(timing), smoke_status: smokeStatus, evidence_tier: criticalCommandEvidenceTier(timing), summary: entry.summary };
|
|
85
|
-
}
|
|
86
|
-
const hasRunnableSurface = Boolean(timing || entry.summary || entry.readonly || entry.diagnostic || entry.skipMigrationGate || entry.mutatesRouteState);
|
|
87
|
-
const p95Ok = timing ? (timing.kind === 'blocked_negative' ? timing.blocked === true : timing.ok === true) : true;
|
|
88
|
-
const jsonContract = timing ? (timing.kind === 'blocked_negative' ? true : timing.json_contract !== false) : true;
|
|
89
|
-
const failureSummary = Boolean(entry.summary);
|
|
90
|
-
const installedReady = Array.isArray(entry.packageRequiredFiles)
|
|
91
|
-
? entry.packageRequiredFiles.every((file) => fs.existsSync(path.join(root, file)))
|
|
92
|
-
: true;
|
|
93
|
-
const lifecyclePenalty = (entry.hidden === true || entry.deprecated === true) && !entry.deprecationReason && !entry.hiddenReason ? 25 : 0;
|
|
94
|
-
const score = (hasRunnableSurface ? 25 : 0) +
|
|
95
|
-
(p95Ok ? 25 : 0) +
|
|
96
|
-
(jsonContract ? 15 : 0) +
|
|
97
|
-
(failureSummary ? 15 : 0) +
|
|
98
|
-
(installedReady ? 20 : 0) -
|
|
99
|
-
lifecyclePenalty;
|
|
100
|
-
const cappedScore = critical ? Math.min(score, criticalCommandEvidenceMaxScore(timing)) : score;
|
|
101
|
-
return { name: entry.name, maturity: entry.maturity, critical, score: Math.max(0, cappedScore), p95_ms: timing?.p95_ms ?? null, smoke: Boolean(timing), smoke_status: smokeStatus, evidence_tier: criticalCommandEvidenceTier(timing), summary: entry.summary };
|
|
102
|
-
}
|
|
103
|
-
export function criticalCommandEvidenceTier(timing) {
|
|
104
|
-
if (!timing)
|
|
105
|
-
return 'metadata';
|
|
106
|
-
if (timing.kind === 'fixture')
|
|
107
|
-
return 'fixture';
|
|
108
|
-
if (timing.kind === 'blocked_negative')
|
|
109
|
-
return 'blocked_negative';
|
|
110
|
-
if (timing.kind === 'dry_run')
|
|
111
|
-
return 'dry_run';
|
|
112
|
-
return 'read_only';
|
|
113
|
-
}
|
|
114
|
-
export function criticalCommandEvidenceMaxScore(timing) {
|
|
115
|
-
const tier = criticalCommandEvidenceTier(timing);
|
|
116
|
-
if (tier === 'metadata')
|
|
117
|
-
return 0;
|
|
118
|
-
if (tier === 'fixture')
|
|
119
|
-
return 70;
|
|
120
|
-
if (tier === 'blocked_negative')
|
|
121
|
-
return 90;
|
|
122
|
-
return 100;
|
|
123
|
-
}
|
|
124
|
-
export function classifySmoke(timing, now = new Date()) {
|
|
125
|
-
if (!timing)
|
|
126
|
-
return 'missing';
|
|
127
|
-
if (isSmokeStale(timing, now))
|
|
128
|
-
return 'stale';
|
|
129
|
-
if (timing.kind === 'blocked_negative')
|
|
130
|
-
return timing.blocked === true && timing.ok !== true ? 'pass' : 'failed';
|
|
131
|
-
return timing.ok === true ? 'pass' : 'failed';
|
|
132
|
-
}
|
|
133
|
-
export function isSmokeStale(timing, now = new Date()) {
|
|
134
|
-
if (!timing.generated_at)
|
|
135
|
-
return false;
|
|
136
|
-
const generated = new Date(timing.generated_at).getTime();
|
|
137
|
-
return !Number.isFinite(generated) || now.getTime() - generated > COMMAND_SMOKE_MAX_AGE_MS;
|
|
138
|
-
}
|
|
139
|
-
export async function measure(smoke) {
|
|
140
|
-
if (smoke.kind === 'fixture') {
|
|
141
|
-
return {
|
|
142
|
-
name: smoke.name,
|
|
143
|
-
kind: 'fixture',
|
|
144
|
-
evidence: smoke.evidence,
|
|
145
|
-
generated_at: new Date().toISOString(),
|
|
146
|
-
p95_ms: 0,
|
|
147
|
-
budget_p95_ms: smoke.budget_p95_ms,
|
|
148
|
-
ok: true,
|
|
149
|
-
blocked: false,
|
|
150
|
-
exit_codes: [],
|
|
151
|
-
json_contract: true
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
if (smoke.kind === 'blocked_negative' && !smoke.argv) {
|
|
155
|
-
return {
|
|
156
|
-
name: smoke.name,
|
|
157
|
-
kind: 'blocked_negative',
|
|
158
|
-
evidence: smoke.evidence,
|
|
159
|
-
generated_at: new Date().toISOString(),
|
|
160
|
-
p95_ms: 0,
|
|
161
|
-
budget_p95_ms: smoke.budget_p95_ms,
|
|
162
|
-
ok: false,
|
|
163
|
-
blocked: true,
|
|
164
|
-
exit_codes: [],
|
|
165
|
-
json_contract: false
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
const durations = [];
|
|
169
|
-
const exitCodes = [];
|
|
170
|
-
let jsonContract = false;
|
|
171
|
-
let blocked = false;
|
|
172
|
-
for (let i = 0; i < 3; i++) {
|
|
173
|
-
const started = performance.now();
|
|
174
|
-
const result = await runProcess(process.execPath, [path.join(root, 'dist', 'bin', 'sks.js'), ...smoke.argv], {
|
|
175
|
-
cwd: root,
|
|
176
|
-
timeoutMs: 15_000,
|
|
177
|
-
maxOutputBytes: 128 * 1024,
|
|
178
|
-
env: { SKS_DISABLE_NETWORK: '1', SKS_DISABLE_UPDATE_CHECK: '1', SKS_PERF_MEASURE: '1' }
|
|
179
|
-
});
|
|
180
|
-
durations.push(Math.round(performance.now() - started));
|
|
181
|
-
exitCodes.push(result.code);
|
|
182
|
-
jsonContract ||= smoke.argv.includes('--json') ? parsesJson(result.stdout) : String(result.stdout || '').trim().length > 0;
|
|
183
|
-
blocked ||= result.code !== 0 && /block|required|missing|denied|explicit/i.test(`${result.stdout || ''}\n${result.stderr || ''}`);
|
|
184
|
-
}
|
|
185
|
-
durations.sort((a, b) => a - b);
|
|
186
|
-
const p95 = durations[Math.min(durations.length - 1, Math.ceil(durations.length * 0.95) - 1)] || 0;
|
|
187
|
-
const ok = smoke.kind === 'blocked_negative'
|
|
188
|
-
? false
|
|
189
|
-
: p95 <= smoke.budget_p95_ms && exitCodes.every((code) => code === 0);
|
|
190
|
-
return { name: smoke.name, kind: smoke.kind || 'read_only', generated_at: new Date().toISOString(), p95_ms: p95, budget_p95_ms: smoke.budget_p95_ms, ok, blocked, exit_codes: exitCodes, json_contract: jsonContract };
|
|
191
|
-
}
|
|
192
|
-
function parsesJson(value) {
|
|
193
|
-
try {
|
|
194
|
-
JSON.parse(String(value || ''));
|
|
195
|
-
return true;
|
|
196
|
-
}
|
|
197
|
-
catch {
|
|
198
|
-
return false;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
function isMainModule() {
|
|
202
|
-
return process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
|
|
203
|
-
}
|
|
204
|
-
//# sourceMappingURL=command-performance-scorecard-check.js.map
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
|
|
5
|
-
const SCAN_DIRS = ['src/core', 'src/commands', 'src/cli'];
|
|
6
|
-
const WRITE_CALL = /\b(?:writeTextAtomic|writeJsonAtomic|fs\.writeFile|fsp\.writeFile|writeFileSync|copyFile)\s*\(/;
|
|
7
|
-
const PROTECTED_INDICATORS = [
|
|
8
|
-
['codex-config-toml', /(?:config\.toml|generatedCodexConfigPath|codexLbConfigPath|\bconfigPath\b)/],
|
|
9
|
-
['codex-auth-json', /(?:auth\.json|\bauthPath\b|codexAuthPath)/],
|
|
10
|
-
['env-secret-file', /(?:(?:['"`][^'"`]*\.env[^'"`]*['"`])|sks-codex-lb\.env|\benvPath\b|status\.env_path|codexLbEnvPath)/],
|
|
11
|
-
['mcp-json', /(?:mcp\.json|\bmcpPath\b|cursorMcpPath)/],
|
|
12
|
-
['sneakoscope-config', /(?:\.sneakoscope\/config\.json|sneakoscopeConfigPath)/]
|
|
13
|
-
];
|
|
14
|
-
const ALLOWLIST = [
|
|
15
|
-
{
|
|
16
|
-
file: 'src/core/config/managed-config-merge.ts',
|
|
17
|
-
pattern: /writeTextAtomic|fs\.writeFile/,
|
|
18
|
-
reason: 'central managed config merge writer preserves protected keys and secret line hashes',
|
|
19
|
-
expires: '3.2.0'
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
file: 'src/core/config/secret-preservation.ts',
|
|
23
|
-
pattern: /writeTextAtomic|writeJsonAtomic|fs\.writeFile/,
|
|
24
|
-
reason: 'secret preservation guard backup, rollback, and sanitized report writer',
|
|
25
|
-
expires: '3.2.0'
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
file: 'src/core/init.ts',
|
|
29
|
-
pattern: /generatedCodexConfigPath|\.codex['"], ['"]SNEAKOSCOPE\.md|hooksPath|mergeManagedHookTrustStateToml/,
|
|
30
|
-
reason: 'setup/init harness writes run through setup-command or doctor-fix secret preservation guard',
|
|
31
|
-
expires: '3.2.0'
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
file: 'src/commands/doctor.ts',
|
|
35
|
-
pattern: /backupProjectConfigBeforeFix|writeTextAtomic|fsp\.writeFile|config_backup_path/,
|
|
36
|
-
reason: 'doctor --fix wraps runDoctor in secret preservation guard before project config repair',
|
|
37
|
-
expires: '3.2.0'
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
file: 'src/core/doctor/doctor-context7-repair.ts',
|
|
41
|
-
pattern: /backupConfig|writeTextAtomic|CONTEXT7_REMOTE_URL/,
|
|
42
|
-
reason: 'doctor Context7 repair writes a backup before replacing only the local stdio Context7 MCP block with the remote endpoint',
|
|
43
|
-
expires: '3.2.0'
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
file: 'src/core/doctor/doctor-codex-startup-repair.ts',
|
|
47
|
-
pattern: /backupConfig|writeTextAtomic|doctor-codex-startup-repair/,
|
|
48
|
-
reason: 'doctor startup repair writes backups before fixing stale Codex agent config_file paths and removing only missing-command MCP blocks',
|
|
49
|
-
expires: '3.2.0'
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
file: 'src/core/auto-review.ts',
|
|
53
|
-
pattern: /writeTextAtomic|writeProfileConfig|configPath/,
|
|
54
|
-
reason: 'auto-review profile migration rewrites bounded Codex profile tables while preserving non-profile config text',
|
|
55
|
-
expires: '3.2.0'
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
file: 'src/cli/context7-command.ts',
|
|
59
|
-
pattern: /writeTextAtomic|configPath/,
|
|
60
|
-
reason: 'explicit context7 setup appends non-secret MCP config and preserves existing secret lines',
|
|
61
|
-
expires: '3.2.0'
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
file: 'src/cli/xai-command.ts',
|
|
65
|
-
pattern: /writeTextAtomic|configPath/,
|
|
66
|
-
reason: 'explicit xAI setup appends MCP config and references env var names rather than raw secret values',
|
|
67
|
-
expires: '3.2.0'
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
file: 'src/cli/install-helpers.ts',
|
|
71
|
-
pattern: /writeTextAtomic|writeJsonAtomic|envPath|authPath|configPath|codexLbEnvPath|codexLbConfigPath|codexAuthPath/,
|
|
72
|
-
reason: 'postinstall/codex-lb setup callsites are covered by setup/update/doctor secret preservation guard fixtures',
|
|
73
|
-
expires: '3.2.0'
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
file: 'src/core/codex/codex-config-eperm-repair.ts',
|
|
77
|
-
pattern: /writeTextAtomic|configPath/,
|
|
78
|
-
reason: 'doctor config repair runs inside doctor-fix secret preservation guard',
|
|
79
|
-
expires: '3.2.0'
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
file: 'src/core/codex/agent-config-file-repair.ts',
|
|
83
|
-
pattern: /writeTextAtomic|configPath|missingAgentConfigFiles/,
|
|
84
|
-
reason: 'agent config_file repair rewrites only the project .codex/config.toml agent config_file paths and is covered by doctor/setup secret preservation fixtures',
|
|
85
|
-
expires: '3.2.0'
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
file: 'src/core/codex/codex-project-config-policy.ts',
|
|
89
|
-
pattern: /writeTextAtomic|configPath/,
|
|
90
|
-
reason: 'project config policy splitter preserves existing protected config content',
|
|
91
|
-
expires: '3.2.0'
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
file: 'src/core/codex-app/codex-app-fast-ui-repair.ts',
|
|
95
|
-
pattern: /writeTextAtomic|configPath/,
|
|
96
|
-
reason: 'Codex App fast UI repair is invoked from guarded doctor/setup flows',
|
|
97
|
-
expires: '3.2.0'
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
file: 'src/core/codex-control/codex-task-runner.ts',
|
|
101
|
-
pattern: /ensurePythonCodexLbConfig|CODEX_LB_API_KEY|config\.toml/,
|
|
102
|
-
reason: 'Python Codex task runner writes an isolated CODEX_HOME provider config referencing env_key only',
|
|
103
|
-
expires: '3.2.0'
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
file: 'src/core/codex-lb/codex-lb-setup.ts',
|
|
107
|
-
pattern: /installCodexLbShellProfileSnippet|upsertManagedBlock|envPath/,
|
|
108
|
-
reason: 'codex-lb shell profile setup writes a managed source block pointing at an env file, not the raw key',
|
|
109
|
-
expires: '3.2.0'
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
file: 'src/core/migration/migration-transaction-journal.ts',
|
|
113
|
-
pattern: /writeJsonAtomic|writeTextAtomic/,
|
|
114
|
-
reason: 'migration journal writes hashes and rollback metadata, not raw secret config values',
|
|
115
|
-
expires: '3.2.0'
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
file: 'src/core/mad-db/mad-db-runtime-profile.ts',
|
|
119
|
-
pattern: /codex-mad-db\.config\.toml|writeTextAtomic/,
|
|
120
|
-
reason: 'MAD-DB runtime profile writes only a mission-local temporary Codex profile and verifies read-only restoration on close',
|
|
121
|
-
expires: '4.6.0'
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
file: 'src/core/providers/glm/naruto/glm-naruto-trace.ts',
|
|
125
|
-
pattern: /mission-result\.json|sanitizeArtifact/,
|
|
126
|
-
reason: 'GLM Naruto trace writer persists sanitized mission-result proof artifacts, not raw env secret files',
|
|
127
|
-
expires: '4.6.0'
|
|
128
|
-
}
|
|
129
|
-
];
|
|
130
|
-
const sources = listSourceFiles().map((file) => ({
|
|
131
|
-
file,
|
|
132
|
-
text: fs.readFileSync(path.join(root, file), 'utf8')
|
|
133
|
-
}));
|
|
134
|
-
const suspicious = findProtectedWriteCallsites(sources);
|
|
135
|
-
const uncovered = suspicious.filter((callsite) => !allowFor(callsite));
|
|
136
|
-
const negative = findProtectedWriteCallsites([{
|
|
137
|
-
file: 'fixture/unprotected-config-write.ts',
|
|
138
|
-
text: "await writeTextAtomic(path.join(root, '.codex', 'config.toml'), 'model = \"x\"\\n');\n"
|
|
139
|
-
}]);
|
|
140
|
-
const report = {
|
|
141
|
-
schema: 'sks.config-managed-merge-callsite-coverage.v1',
|
|
142
|
-
ok: uncovered.length === 0 && negative.length === 1 && !allowFor(negative[0]),
|
|
143
|
-
scanned_dirs: SCAN_DIRS,
|
|
144
|
-
protected_write_callsites: suspicious.length,
|
|
145
|
-
allowlist_entries: ALLOWLIST.map((entry) => ({
|
|
146
|
-
file: entry.file,
|
|
147
|
-
pattern: String(entry.pattern),
|
|
148
|
-
reason: entry.reason,
|
|
149
|
-
expires: entry.expires
|
|
150
|
-
})),
|
|
151
|
-
uncovered,
|
|
152
|
-
negative_fixture_detected: negative.length === 1,
|
|
153
|
-
generated_at: new Date().toISOString()
|
|
154
|
-
};
|
|
155
|
-
fs.mkdirSync(path.join(root, '.sneakoscope', 'reports'), { recursive: true });
|
|
156
|
-
fs.writeFileSync(path.join(root, '.sneakoscope', 'reports', 'config-managed-merge-callsite-coverage.json'), `${JSON.stringify(report, null, 2)}\n`);
|
|
157
|
-
assertGate(report.ok, 'managed config merge callsite coverage failed', report);
|
|
158
|
-
emitGate('config:managed-merge-callsite-coverage', {
|
|
159
|
-
protected_write_callsites: suspicious.length,
|
|
160
|
-
allowlist_entries: ALLOWLIST.length
|
|
161
|
-
});
|
|
162
|
-
export function findProtectedWriteCallsites(files) {
|
|
163
|
-
const calls = [];
|
|
164
|
-
for (const sourceFile of files) {
|
|
165
|
-
const lines = sourceFile.text.split(/\r?\n/);
|
|
166
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
167
|
-
const line = lines[index] || '';
|
|
168
|
-
if (!WRITE_CALL.test(line))
|
|
169
|
-
continue;
|
|
170
|
-
const window = lines.slice(Math.max(0, index - 3), Math.min(lines.length, index + 4)).join('\n');
|
|
171
|
-
const indicators = PROTECTED_INDICATORS.filter(([, pattern]) => pattern.test(window)).map(([name]) => name);
|
|
172
|
-
if (!indicators.length)
|
|
173
|
-
continue;
|
|
174
|
-
calls.push({
|
|
175
|
-
file: sourceFile.file,
|
|
176
|
-
line: index + 1,
|
|
177
|
-
source: line.trim(),
|
|
178
|
-
window,
|
|
179
|
-
indicators
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return calls;
|
|
184
|
-
}
|
|
185
|
-
function allowFor(callsite) {
|
|
186
|
-
if (!callsite)
|
|
187
|
-
return null;
|
|
188
|
-
const text = `${callsite.source}\n${callsite.window}`;
|
|
189
|
-
return ALLOWLIST.find((entry) => entry.file === callsite.file && entry.pattern.test(text)) || null;
|
|
190
|
-
}
|
|
191
|
-
function listSourceFiles() {
|
|
192
|
-
const files = [];
|
|
193
|
-
for (const dir of SCAN_DIRS)
|
|
194
|
-
collectTsFiles(path.join(root, dir), files);
|
|
195
|
-
return files.sort();
|
|
196
|
-
}
|
|
197
|
-
function collectTsFiles(dir, out) {
|
|
198
|
-
const rows = fs.readdirSync(dir, { withFileTypes: true });
|
|
199
|
-
for (const row of rows) {
|
|
200
|
-
const abs = path.join(dir, row.name);
|
|
201
|
-
const rel = path.relative(root, abs);
|
|
202
|
-
if (row.isDirectory()) {
|
|
203
|
-
if (row.name === 'scripts' || row.name === 'node_modules' || row.name === 'dist')
|
|
204
|
-
continue;
|
|
205
|
-
collectTsFiles(abs, out);
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
if (row.isFile() && row.name.endsWith('.ts'))
|
|
209
|
-
out.push(rel);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
//# sourceMappingURL=config-managed-merge-callsite-coverage-check.js.map
|
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// @ts-nocheck
|
|
3
|
-
import fs from 'node:fs';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { performance } from 'node:perf_hooks';
|
|
6
|
-
import { fileURLToPath } from 'node:url';
|
|
7
|
-
import { assertGate, emitGate, importDist, root } from './sks-1-18-gate-lib.js';
|
|
8
|
-
export const CRITICAL_DOLLAR_COMMANDS = new Set([
|
|
9
|
-
'$Naruto',
|
|
10
|
-
'$Super-Search',
|
|
11
|
-
'$SEO-GEO-OPTIMIZER',
|
|
12
|
-
'$DB',
|
|
13
|
-
'$MAD-SKS',
|
|
14
|
-
'$Commit-And-Push'
|
|
15
|
-
]);
|
|
16
|
-
export const DOLLAR_SMOKE_MAX_AGE_MS = 60 * 60 * 1000;
|
|
17
|
-
if (isMainModule())
|
|
18
|
-
await main();
|
|
19
|
-
export async function main() {
|
|
20
|
-
const [{ DOLLAR_COMMANDS_LITE }, routes] = await Promise.all([
|
|
21
|
-
importDist('core/routes/dollar-manifest-lite.js'),
|
|
22
|
-
importDist('core/routes.js')
|
|
23
|
-
]);
|
|
24
|
-
const routePrompt = routes.routePrompt;
|
|
25
|
-
const rows = [];
|
|
26
|
-
for (const entry of DOLLAR_COMMANDS_LITE) {
|
|
27
|
-
const routePromptSmoke = measureRoutePromptSmoke(entry, routePrompt);
|
|
28
|
-
rows.push(scoreDollarEntry(entry, routePromptSmoke, commandRouteSmokeFor(entry, routePromptSmoke.routed)));
|
|
29
|
-
}
|
|
30
|
-
const average = rows.reduce((sum, row) => sum + row.score, 0) / Math.max(1, rows.length);
|
|
31
|
-
const blockers = [
|
|
32
|
-
...rows.filter((row) => row.critical && row.score === 0).map((row) => `${row.command}:critical_smoke_missing_or_failed`),
|
|
33
|
-
...rows.filter((row) => row.p95_ms > 20).map((row) => `${row.command}:route_prompt_p95_exceeded`),
|
|
34
|
-
...(average >= 94 ? [] : [`average_below_94:${average.toFixed(2)}`])
|
|
35
|
-
];
|
|
36
|
-
const report = {
|
|
37
|
-
schema: 'sks.dollar-performance-scorecard.v1',
|
|
38
|
-
ok: blockers.length === 0,
|
|
39
|
-
generated_at: new Date().toISOString(),
|
|
40
|
-
average_score: Number(average.toFixed(2)),
|
|
41
|
-
dollar_command_count: rows.length,
|
|
42
|
-
rows,
|
|
43
|
-
blockers
|
|
44
|
-
};
|
|
45
|
-
const out = path.join(root, '.sneakoscope', 'reports', 'dollar-performance-scorecard.json');
|
|
46
|
-
fs.mkdirSync(path.dirname(out), { recursive: true });
|
|
47
|
-
fs.writeFileSync(out, `${JSON.stringify(report, null, 2)}\n`);
|
|
48
|
-
assertGate(report.ok, 'dollar performance scorecard failed', report);
|
|
49
|
-
emitGate('dollar:performance-scorecard', { average_score: report.average_score, dollar_command_count: rows.length, report: '.sneakoscope/reports/dollar-performance-scorecard.json' });
|
|
50
|
-
}
|
|
51
|
-
export function scoreDollarEntry(entry, routePromptSmoke, commandSmoke, options = {}) {
|
|
52
|
-
const now = options.now ? new Date(options.now) : new Date();
|
|
53
|
-
const p95 = routePromptSmoke?.p95_ms ?? Infinity;
|
|
54
|
-
const metadataComplete = Boolean(entry.command && entry.route && entry.description);
|
|
55
|
-
const routed = routePromptSmoke?.routed || null;
|
|
56
|
-
const stopGateOrExempt = Boolean(routed?.stopGate || routed?.coverageExemptReason || entry.command === '$Help' || entry.command === '$Answer');
|
|
57
|
-
const routePromptOk = classifyDollarSmoke(routePromptSmoke, now) === 'pass';
|
|
58
|
-
const commandSmokeOk = classifyDollarSmoke(commandSmoke, now) === 'pass';
|
|
59
|
-
const metadataSynced = isDollarMetadataSynced(entry, routed, commandSmoke);
|
|
60
|
-
const lifecycleReasoned = !((routed?.hidden === true || routed?.deprecated === true) && !routed?.hiddenReason && !routed?.deprecationReason && !routed?.deprecationMessage);
|
|
61
|
-
const critical = CRITICAL_DOLLAR_COMMANDS.has(entry.command);
|
|
62
|
-
if (critical && (!routePromptOk || !commandSmokeOk || !metadataSynced || !lifecycleReasoned)) {
|
|
63
|
-
return {
|
|
64
|
-
command: entry.command,
|
|
65
|
-
route: entry.route,
|
|
66
|
-
critical,
|
|
67
|
-
p95_ms: Number.isFinite(p95) ? Number(p95.toFixed(3)) : null,
|
|
68
|
-
score: 0,
|
|
69
|
-
route_prompt_smoke: classifyDollarSmoke(routePromptSmoke, now),
|
|
70
|
-
command_route_smoke: classifyDollarSmoke(commandSmoke, now),
|
|
71
|
-
command_evidence_tier: criticalDollarEvidenceTier(commandSmoke),
|
|
72
|
-
metadata_synced: metadataSynced,
|
|
73
|
-
lifecycle_reasoned: lifecycleReasoned,
|
|
74
|
-
routed_id: routed?.id || null,
|
|
75
|
-
stop_gate: routed?.stopGate || null
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
const cliSmokeOrPrompt = Boolean(commandSmokeOk);
|
|
79
|
-
const highRiskPolicy = !critical || !/\b(?:MAD|DB|Computer|CU|Commit|Push|Release)\b/i.test(entry.command) || Boolean(routed?.requiredSkills || routed?.lifecycle);
|
|
80
|
-
const score = (routePromptOk && p95 <= 20 ? 20 : 0) +
|
|
81
|
-
(metadataComplete ? 20 : 0) +
|
|
82
|
-
(stopGateOrExempt ? 20 : 0) +
|
|
83
|
-
(cliSmokeOrPrompt ? 20 : 0) +
|
|
84
|
-
(highRiskPolicy && metadataSynced && lifecycleReasoned ? 20 : 0);
|
|
85
|
-
const cappedScore = critical ? Math.min(score, criticalDollarEvidenceMaxScore(commandSmoke)) : score;
|
|
86
|
-
return {
|
|
87
|
-
command: entry.command,
|
|
88
|
-
route: entry.route,
|
|
89
|
-
critical,
|
|
90
|
-
p95_ms: Number.isFinite(p95) ? Number(p95.toFixed(3)) : null,
|
|
91
|
-
score: cappedScore,
|
|
92
|
-
route_prompt_smoke: classifyDollarSmoke(routePromptSmoke, now),
|
|
93
|
-
command_route_smoke: classifyDollarSmoke(commandSmoke, now),
|
|
94
|
-
command_evidence_tier: criticalDollarEvidenceTier(commandSmoke),
|
|
95
|
-
metadata_synced: metadataSynced,
|
|
96
|
-
lifecycle_reasoned: lifecycleReasoned,
|
|
97
|
-
routed_id: routed?.id || null,
|
|
98
|
-
stop_gate: routed?.stopGate || null
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
export function measureRoutePromptSmoke(entry, routePrompt) {
|
|
102
|
-
const timings = [];
|
|
103
|
-
let routed = null;
|
|
104
|
-
for (let i = 0; i < 25; i++) {
|
|
105
|
-
const started = performance.now();
|
|
106
|
-
routed = routePrompt(`${entry.command} scorecard smoke`);
|
|
107
|
-
timings.push(performance.now() - started);
|
|
108
|
-
}
|
|
109
|
-
timings.sort((a, b) => a - b);
|
|
110
|
-
const p95 = timings[Math.min(timings.length - 1, Math.ceil(timings.length * 0.95) - 1)] || 0;
|
|
111
|
-
return {
|
|
112
|
-
kind: 'route_prompt',
|
|
113
|
-
ok: Boolean(routed?.id),
|
|
114
|
-
generated_at: new Date().toISOString(),
|
|
115
|
-
p95_ms: p95,
|
|
116
|
-
routed
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
export function commandRouteSmokeFor(entry, routed = null) {
|
|
120
|
-
const reportSmoke = reportBackedDollarSmoke(entry, routed);
|
|
121
|
-
if (reportSmoke)
|
|
122
|
-
return reportSmoke;
|
|
123
|
-
const cliEntrypoint = routed?.cliEntrypoint || '';
|
|
124
|
-
const hasActualCli = /^sks\s+/i.test(cliEntrypoint);
|
|
125
|
-
const synced = isDollarMetadataSynced(entry, routed, null);
|
|
126
|
-
if (!CRITICAL_DOLLAR_COMMANDS.has(entry.command) && routed?.id && synced) {
|
|
127
|
-
return {
|
|
128
|
-
kind: 'route_prompt_metadata',
|
|
129
|
-
ok: true,
|
|
130
|
-
generated_at: new Date().toISOString(),
|
|
131
|
-
command: entry.command,
|
|
132
|
-
route: entry.route,
|
|
133
|
-
routed_id: routed.id,
|
|
134
|
-
metadata_synced: synced
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
return {
|
|
138
|
-
kind: hasActualCli ? 'cli_entrypoint_metadata' : 'metadata',
|
|
139
|
-
ok: false,
|
|
140
|
-
generated_at: new Date().toISOString(),
|
|
141
|
-
command: entry.command,
|
|
142
|
-
route: entry.route,
|
|
143
|
-
cli_entrypoint: cliEntrypoint || null,
|
|
144
|
-
metadata_synced: synced
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
export function reportBackedDollarSmoke(entry, routed = null) {
|
|
148
|
-
const synced = isDollarMetadataSynced(entry, routed, null);
|
|
149
|
-
const now = new Date().toISOString();
|
|
150
|
-
if (entry.command === '$Naruto') {
|
|
151
|
-
const real = readReport('naruto-real-write-e2e.json');
|
|
152
|
-
if (real?.ok === true)
|
|
153
|
-
return smoke('read_only', true, now, synced, { report: 'naruto-real-write-e2e.json' });
|
|
154
|
-
const hermetic = readReport('naruto-write-e2e.json');
|
|
155
|
-
if (hermetic?.ok === true)
|
|
156
|
-
return smoke('fixture', true, now, synced, { report: 'naruto-write-e2e.json' });
|
|
157
|
-
}
|
|
158
|
-
if (entry.command === '$Super-Search') {
|
|
159
|
-
const offline = readReport('super-search-offline-contract.json');
|
|
160
|
-
const local = readReport('super-search-local-http-smoke.json');
|
|
161
|
-
if (offline?.ok === true || local?.ok === true)
|
|
162
|
-
return smoke('read_only', true, now, synced, { report: offline?.ok === true ? 'super-search-offline-contract.json' : 'super-search-local-http-smoke.json' });
|
|
163
|
-
}
|
|
164
|
-
if (entry.command === '$SEO-GEO-OPTIMIZER') {
|
|
165
|
-
const metadata = readReport('seo-metadata-sync.json');
|
|
166
|
-
const truth = readReport('seo-marketing-truthfulness.json');
|
|
167
|
-
if (metadata?.ok === true && truth?.ok === true)
|
|
168
|
-
return smoke('read_only', true, now, synced, { report: 'seo-metadata-sync.json+seo-marketing-truthfulness.json' });
|
|
169
|
-
}
|
|
170
|
-
const highRisk = highRiskSmokeForDollar(entry.command);
|
|
171
|
-
if (highRisk)
|
|
172
|
-
return { ...highRisk, metadata_synced: synced };
|
|
173
|
-
return null;
|
|
174
|
-
}
|
|
175
|
-
function highRiskSmokeForDollar(command) {
|
|
176
|
-
const report = readReport('high-risk-contracts.json');
|
|
177
|
-
const target = {
|
|
178
|
-
'$DB': 'db',
|
|
179
|
-
'$MAD-SKS': 'mad-sks',
|
|
180
|
-
'$Commit-And-Push': 'commit-and-push'
|
|
181
|
-
}[command];
|
|
182
|
-
if (!target || !Array.isArray(report?.cli_negative_smokes))
|
|
183
|
-
return null;
|
|
184
|
-
const row = report.cli_negative_smokes.find((item) => item?.target === target);
|
|
185
|
-
if (!row)
|
|
186
|
-
return null;
|
|
187
|
-
return {
|
|
188
|
-
kind: 'blocked_negative',
|
|
189
|
-
ok: false,
|
|
190
|
-
blocked: row.blocked === true,
|
|
191
|
-
generated_at: report.generated_at || new Date().toISOString(),
|
|
192
|
-
command,
|
|
193
|
-
evidence: row
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
function smoke(kind, ok, generatedAt, metadataSynced, extra = {}) {
|
|
197
|
-
return { kind, ok, generated_at: generatedAt, metadata_synced: metadataSynced, ...extra };
|
|
198
|
-
}
|
|
199
|
-
function readReport(fileName) {
|
|
200
|
-
try {
|
|
201
|
-
return JSON.parse(fs.readFileSync(path.join(root, '.sneakoscope', 'reports', fileName), 'utf8'));
|
|
202
|
-
}
|
|
203
|
-
catch {
|
|
204
|
-
return null;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
export function isDollarMetadataSynced(entry, routed, commandSmoke = null) {
|
|
208
|
-
if (commandSmoke?.metadata_synced === false)
|
|
209
|
-
return false;
|
|
210
|
-
if (!routed)
|
|
211
|
-
return Boolean(entry.command && entry.route);
|
|
212
|
-
const commandSynced = entry.command === routed.command || (Array.isArray(routed.dollarAliases) && routed.dollarAliases.includes(entry.command));
|
|
213
|
-
const routeSynced = !entry.route || !routed.route || entry.route === routed.route;
|
|
214
|
-
return Boolean(commandSynced && routeSynced);
|
|
215
|
-
}
|
|
216
|
-
export function criticalDollarEvidenceTier(smoke) {
|
|
217
|
-
if (!smoke)
|
|
218
|
-
return 'metadata';
|
|
219
|
-
if (smoke.kind === 'fixture')
|
|
220
|
-
return 'fixture';
|
|
221
|
-
if (smoke.kind === 'blocked_negative')
|
|
222
|
-
return 'blocked_negative';
|
|
223
|
-
if (smoke.kind === 'dry_run')
|
|
224
|
-
return 'dry_run';
|
|
225
|
-
if (smoke.kind === 'read_only' || smoke.kind === 'cli_read_only')
|
|
226
|
-
return 'read_only';
|
|
227
|
-
return 'metadata';
|
|
228
|
-
}
|
|
229
|
-
export function criticalDollarEvidenceMaxScore(smoke) {
|
|
230
|
-
const tier = criticalDollarEvidenceTier(smoke);
|
|
231
|
-
if (tier === 'metadata')
|
|
232
|
-
return 0;
|
|
233
|
-
if (tier === 'fixture')
|
|
234
|
-
return 70;
|
|
235
|
-
if (tier === 'blocked_negative')
|
|
236
|
-
return 90;
|
|
237
|
-
return 100;
|
|
238
|
-
}
|
|
239
|
-
export function classifyDollarSmoke(smoke, now = new Date()) {
|
|
240
|
-
if (!smoke)
|
|
241
|
-
return 'missing';
|
|
242
|
-
if (isDollarSmokeStale(smoke, now))
|
|
243
|
-
return 'stale';
|
|
244
|
-
if (smoke.kind === 'blocked_negative')
|
|
245
|
-
return smoke.blocked === true && smoke.ok !== true ? 'pass' : 'failed';
|
|
246
|
-
return smoke.ok === true ? 'pass' : 'failed';
|
|
247
|
-
}
|
|
248
|
-
export function isDollarSmokeStale(smoke, now = new Date()) {
|
|
249
|
-
if (!smoke.generated_at)
|
|
250
|
-
return false;
|
|
251
|
-
const generated = new Date(smoke.generated_at).getTime();
|
|
252
|
-
return !Number.isFinite(generated) || now.getTime() - generated > DOLLAR_SMOKE_MAX_AGE_MS;
|
|
253
|
-
}
|
|
254
|
-
function isMainModule() {
|
|
255
|
-
return process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
|
|
256
|
-
}
|
|
257
|
-
//# sourceMappingURL=dollar-performance-scorecard-check.js.map
|