sneakoscope 6.0.3 → 6.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 +29 -12
- 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/bin/fast-inline.js +18 -14
- package/dist/bin/sks-dispatch.js +2 -4
- package/dist/cli/args.js +2 -0
- package/dist/cli/command-manifest-lite.js +2 -3
- package/dist/cli/command-registry.js +3 -4
- package/dist/cli/help-fast.js +1 -1
- package/dist/cli/install-helpers.js +348 -763
- package/dist/cli/install-tool-helpers.js +287 -0
- package/dist/cli/router.js +91 -6
- package/dist/commands/codex-lb.js +188 -53
- package/dist/commands/codex.js +44 -5
- package/dist/commands/doctor.js +302 -46
- package/dist/commands/tmux.js +5 -1
- package/dist/commands/versioning.js +7 -0
- package/dist/commands/zellij-monitor-pane.js +2 -0
- package/dist/commands/zellij-viewport-pane.js +3 -1
- package/dist/commands/zellij.js +1 -1
- package/dist/config/skills-manifest.json +59 -59
- package/dist/core/agent-bridge/agent-manifest.js +48 -0
- 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 +3 -1
- package/dist/core/agents/agent-effort-policy.js +30 -38
- 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 +25 -3
- package/dist/core/agents/agent-output-validator.js +1 -1
- package/dist/core/agents/agent-plan.js +100 -21
- package/dist/core/agents/agent-role-config.js +43 -49
- package/dist/core/agents/agent-runner-codex-exec.js +18 -3
- package/dist/core/agents/agent-runner-process.js +1 -0
- package/dist/core/agents/agent-schema.js +3 -2
- package/dist/core/agents/fast-mode-policy.js +3 -5
- package/dist/core/agents/native-cli-session-swarm.js +1 -1
- package/dist/core/agents/native-worker-backend-router.js +2 -1
- package/dist/core/agents/work-partition/repo-inventory.js +68 -7
- package/dist/core/agents/zellij-right-lane-cockpit.js +2 -2
- package/dist/core/code-structure.js +5 -4
- package/dist/core/codex/agent-config-file-repair.js +94 -193
- package/dist/core/codex/codex-cli-update.js +723 -0
- package/dist/core/codex/codex-config-guard.js +38 -11
- package/dist/core/codex/codex-project-config-policy.js +3 -6
- package/dist/core/codex/codex-startup-config-postcheck.js +52 -42
- package/dist/core/codex-adapter.js +35 -22
- package/dist/core/codex-app/codex-agent-role-sync.js +13 -54
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +51 -20
- package/dist/core/codex-app/codex-app-launcher.js +48 -17
- package/dist/core/codex-app/codex-app-restart.js +23 -2
- package/dist/core/codex-app/codex-app-ui-state-snapshot.js +11 -3
- package/dist/core/codex-app/sks-menubar.js +136 -5
- package/dist/core/codex-app.js +35 -14
- 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 +29 -12
- 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 +28 -14
- 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-lb-launch-recovery.js +278 -0
- package/dist/core/codex-control/codex-multi-agent-event-normalizer.js +5 -1
- package/dist/core/codex-control/codex-reliability-shield.js +93 -30
- package/dist/core/codex-control/codex-sdk-adapter.js +96 -13
- 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-control/codex-task-runner.js +62 -9
- package/dist/core/codex-control/python-codex-sdk-adapter.js +30 -3
- package/dist/core/codex-exec-output-schema.js +35 -6
- package/dist/core/codex-lb/codex-lb-env.js +30 -1
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +478 -0
- package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +291 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +31 -38
- package/dist/core/codex-native/codex-native-feature-matrix.js +2 -2
- package/dist/core/codex-native/codex-native-repair-transaction.js +1 -1
- package/dist/core/codex-native/core-skill-manifest.js +8 -4
- 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 +305 -0
- package/dist/core/commands/agent-bridge-command.js +23 -2
- package/dist/core/commands/agent-command.js +38 -5
- package/dist/core/commands/basic-cli.js +77 -30
- package/dist/core/commands/command-utils.js +1 -1
- 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 +182 -137
- package/dist/core/commands/naruto-command.js +643 -1153
- package/dist/core/commands/pipeline-command.js +1 -0
- package/dist/core/commands/research-command.js +293 -231
- package/dist/core/commands/run-command.js +100 -23
- package/dist/core/commands/team-command.js +2 -3
- package/dist/core/commands/team-legacy-observe-command.js +94 -359
- 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/db-safety.js +2 -2
- package/dist/core/decision-lattice.js +6 -6
- 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/codex-startup-config-repair.js +8 -3
- package/dist/core/doctor/computer-use-repair.js +28 -39
- package/dist/core/doctor/doctor-codex-startup-repair.js +24 -149
- 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-fixture-executor.js +71 -7
- package/dist/core/feature-fixture-runner.js +53 -12
- package/dist/core/feature-fixtures.js +47 -14
- package/dist/core/feature-registry.js +53 -58
- package/dist/core/fsx.js +54 -6
- package/dist/core/harness-conflicts.js +19 -10
- 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 +14 -4
- package/dist/core/hooks-runtime/light-turn.js +70 -0
- package/dist/core/hooks-runtime/payload-signals.js +270 -0
- package/dist/core/hooks-runtime/team-digest.js +0 -1
- package/dist/core/hooks-runtime/tool-output-quarantine.js +93 -0
- package/dist/core/hooks-runtime.js +418 -250
- 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/init/skills.js +16 -30
- package/dist/core/init.js +144 -36
- package/dist/core/managed-assets/managed-assets-manifest.js +417 -14
- package/dist/core/mission.js +24 -1
- package/dist/core/naruto/naruto-work-graph.js +70 -4
- package/dist/core/ops/reporting.js +3 -0
- package/dist/core/pipeline-internals/runtime-core.js +578 -180
- package/dist/core/pipeline-internals/runtime-gates.js +191 -49
- 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/preflight/parallel-preflight-engine.js +50 -1
- package/dist/core/product-design-plugin.js +2 -2
- package/dist/core/proof/route-finalizer.js +1 -1
- package/dist/core/proof/route-proof-gate.js +7 -2
- package/dist/core/proof-field.js +3 -3
- package/dist/core/provider/model-router.js +38 -32
- package/dist/core/recallpulse/policy.js +12 -28
- package/dist/core/recallpulse.js +11 -6
- package/dist/core/release/gate-manifest.js +18 -12
- package/dist/core/release/gate-pack-manifest.js +1 -1
- package/dist/core/release/npm-pack-proof.js +247 -0
- package/dist/core/release/package-dist-snapshot.js +151 -0
- package/dist/core/release/package-size-budget.js +5 -0
- package/dist/core/release/release-authorization-snapshot.js +115 -0
- package/dist/core/release/release-gate-affected-selector.js +15 -3
- package/dist/core/release/release-gate-cache-v2.js +30 -0
- package/dist/core/release/release-gate-contract.js +161 -0
- package/dist/core/release/release-gate-dag.js +44 -3
- package/dist/core/release/release-gate-hermetic-env.js +28 -17
- package/dist/core/release/release-real-contract.js +496 -0
- package/dist/core/release-parallel-full-coverage.js +31 -143
- package/dist/core/research/claim-evidence-matrix.js +41 -6
- package/dist/core/research/experiment-plan.js +14 -10
- package/dist/core/research/falsification.js +9 -2
- package/dist/core/research/implementation-blueprint-densifier.js +82 -60
- package/dist/core/research/implementation-blueprint.js +32 -26
- package/dist/core/research/mock-result.js +122 -11
- package/dist/core/research/replication-pack.js +15 -8
- package/dist/core/research/research-adversarial-review.js +1068 -0
- package/dist/core/research/research-claim-builder.js +69 -17
- package/dist/core/research/research-claim-synthesizer.js +343 -0
- package/dist/core/research/research-cycle-runner.js +53 -3
- package/dist/core/research/research-falsification-runner.js +176 -0
- package/dist/core/research/research-final-reviewer.js +44 -125
- package/dist/core/research/research-realistic-report.js +14 -6
- package/dist/core/research/research-review-artifact-digest.js +66 -0
- package/dist/core/research/research-source-evidence.js +144 -0
- package/dist/core/research/research-source-layer-catalog.js +68 -0
- package/dist/core/research/research-source-ledger-merge.js +250 -12
- package/dist/core/research/research-source-shards.js +26 -70
- package/dist/core/research/research-stage-runner.js +237 -247
- package/dist/core/research/research-super-search.js +184 -0
- package/dist/core/research/research-synthesis-prompt.js +20 -1
- package/dist/core/research/research-synthesis-writer.js +86 -5
- package/dist/core/research/research-work-graph.js +25 -18
- package/dist/core/research/source-quality-report.js +21 -0
- package/dist/core/research.js +429 -280
- 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/dollar-manifest-lite.js +11 -11
- package/dist/core/routes/evidence.js +4 -4
- package/dist/core/routes/ppt-policy.js +1 -1
- package/dist/core/routes.js +92 -64
- package/dist/core/runtime/task-profile.js +66 -0
- package/dist/core/runtime/verification-budget.js +12 -0
- package/dist/core/secret-redaction.js +4 -0
- package/dist/core/security/high-risk-contracts.js +6 -6
- package/dist/core/stop-gate/stop-gate-check.js +49 -12
- package/dist/core/subagents/agent-catalog.js +215 -0
- package/dist/core/subagents/model-policy.js +118 -0
- package/dist/core/subagents/naruto-help-contract.js +40 -0
- package/dist/core/subagents/official-subagent-config.js +488 -0
- package/dist/core/subagents/official-subagent-preparation.js +251 -0
- package/dist/core/subagents/official-subagent-prompt.js +137 -0
- package/dist/core/subagents/official-subagent-runner.js +129 -0
- package/dist/core/subagents/subagent-evidence.js +663 -0
- package/dist/core/subagents/terminology.js +16 -0
- package/dist/core/subagents/thread-budget.js +21 -0
- package/dist/core/subagents/triwiki-attention.js +65 -0
- package/dist/core/super-search/runtime-helpers.js +173 -19
- package/dist/core/super-search/runtime.js +140 -15
- package/dist/core/super-search/source-records.js +49 -8
- package/dist/core/team-review-policy.js +15 -0
- package/dist/core/triwiki/code-pack.js +8 -2
- package/dist/core/triwiki/triwiki-cache-key.js +108 -29
- package/dist/core/triwiki/triwiki-module-card.js +1 -1
- 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 +187 -61
- 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-check.js +23 -15
- package/dist/core/version-manager.js +51 -1
- package/dist/core/version.js +1 -1
- package/dist/core/wiki-coordinate.js +128 -12
- package/dist/core/work-order-ledger.js +208 -10
- package/dist/core/zellij/zellij-command.js +12 -1
- package/dist/core/zellij/zellij-dashboard-pane.js +3 -3
- package/dist/core/zellij/zellij-fake-adapter.js +3 -1
- package/dist/core/zellij/zellij-launcher.js +51 -21
- package/dist/core/zellij/zellij-layout-builder.js +14 -5
- package/dist/core/zellij/zellij-official-subagent-activity.js +477 -0
- package/dist/core/zellij/zellij-official-subagent-telemetry.js +264 -0
- package/dist/core/zellij/zellij-pane-proof.js +32 -6
- package/dist/core/zellij/zellij-slot-pane-renderer.js +17 -5
- package/dist/core/zellij/zellij-slot-telemetry.js +15 -3
- package/dist/core/zellij/zellij-ui-mode.js +1 -1
- package/dist/core/zellij/zellij-viewport-binder.js +3 -0
- 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 +34 -15
- 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/architecture-guard-check.js +8 -1
- 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/check-route-modularity.js +0 -1
- package/dist/scripts/check-ts-contracts.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 +53 -19
- package/dist/scripts/codex-app-ui-preservation-check.js +35 -4
- package/dist/scripts/codex-control-all-pipelines-check.js +7 -3
- package/dist/scripts/codex-control-side-effect-scope-check.js +2 -2
- package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +27 -0
- 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-native-agent-role-content-check.js +15 -7
- package/dist/scripts/codex-native-repair-transaction-check.js +3 -1
- package/dist/scripts/codex-sdk-all-pipelines-check.js +7 -4
- package/dist/scripts/codex-sdk-research-pipeline-check.js +30 -8
- 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/db-route-materialization-check.js +33 -0
- package/dist/scripts/dfix-fixture-check.js +1 -1
- package/dist/scripts/docs-truthfulness-check.js +4 -2
- package/dist/scripts/doctor-codex-startup-repair-check.js +47 -25
- package/dist/scripts/doctor-context7-repair-check.js +2 -1
- package/dist/scripts/doctor-fix-production-blackbox.js +12 -2
- 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 +9 -3
- package/dist/scripts/doctor-startup-config-repair-check.js +13 -3
- package/dist/scripts/install-update-preserves-config-check.js +7 -2
- 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 +4 -4
- package/dist/scripts/lib/native-cli-session-swarm-check-lib.js +173 -13
- package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +165 -6
- package/dist/scripts/managed-role-manifest-parity-check.js +5 -4
- package/dist/scripts/mutation-callsite-coverage-check.js +0 -11
- package/dist/scripts/naruto-codex-e2e-check.js +14 -7
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +4 -201
- package/dist/scripts/npm-publish-performance-check.js +20 -12
- package/dist/scripts/official-subagent-workflow-check.js +145 -0
- package/dist/scripts/package-published-contract-check.js +6 -20
- package/dist/scripts/packlist-performance-check.js +17 -3
- package/dist/scripts/parallel-verification-engine-check.js +2 -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/prepublish-release-check-or-fast.js +23 -86
- package/dist/scripts/product-design-plugin-routing-check.js +1 -1
- package/dist/scripts/release-affected-selector-check.js +74 -1
- package/dist/scripts/release-check-stamp.js +324 -239
- package/dist/scripts/release-dag-full-coverage-check.js +7 -15
- package/dist/scripts/release-dynamic-presets-check.js +10 -1
- package/dist/scripts/release-gate-dag-runner-check.js +3 -3
- package/dist/scripts/release-gate-dag-runner.js +35 -11
- package/dist/scripts/release-gate-existence-audit.js +1 -2
- package/dist/scripts/release-gate-script-parity-check.js +1 -1
- package/dist/scripts/release-parallel-full-coverage-check.js +12 -6
- package/dist/scripts/release-parallel-speed-budget-check.js +18 -2
- package/dist/scripts/release-real-check.js +390 -157
- package/dist/scripts/release-registry-check.js +61 -16
- package/dist/scripts/release-runtime-truth-matrix-check.js +22 -0
- package/dist/scripts/research-blueprint-densifier-check.js +2 -2
- package/dist/scripts/research-real-cycle-no-legacy-final-md-check.js +11 -7
- package/dist/scripts/route-proof-artifact-structure-check.js +1 -0
- 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 +4 -4
- package/dist/scripts/sks-1-11-gate-lib.js +53 -6
- package/dist/scripts/sks-3-1-4-directive-check-lib.js +8 -2
- package/dist/scripts/sks-3-1-5-directive-check-lib.js +3 -2
- package/dist/scripts/sks-3-1-6-directive-check-lib.js +5 -3
- package/dist/scripts/sks-menubar-install-check.js +8 -0
- package/dist/scripts/sks-uninstall-regression-check.js +1 -1
- package/dist/scripts/sksd-daemon-check.js +16 -6
- package/dist/scripts/trust-fixture-check.js +32 -10
- package/dist/scripts/write-build-manifest.js +2 -1
- package/dist/scripts/wrongness-fixture-check.js +1 -1
- package/dist/scripts/zellij-layout-valid-check.js +36 -11
- 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/dist/scripts/zellij-spawn-on-demand-layout-check.js +3 -3
- package/docs/demo.tape +1 -1
- package/infra-harness-gates.json +1486 -0
- package/package.json +32 -19
- package/release-gates.v2.json +4060 -0
- package/runtime-required-scripts.json +9 -0
- 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/commands/db.js +0 -6
- package/dist/core/codex-control/codex-0139-multi-agent-real-probe.js +0 -107
- package/dist/core/commands/db-command.js +0 -146
- package/dist/core/research/prompt.js +0 -15
- package/dist/scripts/agent-native-release-gate.js +0 -274
- package/dist/scripts/codex-0142-capability-check.js +0 -21
- package/dist/scripts/codex-control-tool-call-sequence-repair-check.js +0 -14
- 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
|
@@ -5,9 +5,14 @@ import crypto from 'node:crypto';
|
|
|
5
5
|
import fs from 'node:fs';
|
|
6
6
|
import path from 'node:path';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { RELEASE_REAL_CHECK_IDS, RELEASE_REAL_OPTIONAL_CHECK_IDS, RELEASE_REAL_REQUIRED_CHECK_IDS } from '../core/release/release-real-contract.js';
|
|
9
|
+
import { RELEASE_AUTHORIZATION_SNAPSHOT_KEYS, releaseAuthorizationSnapshot } from '../core/release/release-authorization-snapshot.js';
|
|
10
|
+
import { releaseGateContractSnapshot } from '../core/release/release-gate-contract.js';
|
|
11
|
+
import { currentDistFreshness } from './lib/ensure-dist-fresh.js';
|
|
8
12
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
9
13
|
const stampPath = process.env.SKS_RELEASE_STAMP_PATH || path.join(root, '.sneakoscope', 'reports', 'release-check-stamp.json');
|
|
10
14
|
const command = process.argv[2] || 'verify';
|
|
15
|
+
const commandArgs = process.argv.slice(3);
|
|
11
16
|
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
12
17
|
function fail(message, detail = '') {
|
|
13
18
|
console.error(`Release check stamp failed: ${message}`);
|
|
@@ -18,147 +23,27 @@ function fail(message, detail = '') {
|
|
|
18
23
|
function readJson(rel) {
|
|
19
24
|
return JSON.parse(fs.readFileSync(path.join(root, rel), 'utf8'));
|
|
20
25
|
}
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
collectFiles(dir, files, { baseDir: dir, include: opts.include });
|
|
29
|
-
const hash = crypto.createHash('sha256');
|
|
30
|
-
for (const file of files.sort()) {
|
|
31
|
-
const rel = path.relative(dir, file).split(path.sep).join('/');
|
|
32
|
-
const stat = fs.statSync(file);
|
|
33
|
-
hash.update(rel);
|
|
34
|
-
hash.update('\0');
|
|
35
|
-
hash.update(String(stat.size));
|
|
36
|
-
hash.update('\0');
|
|
37
|
-
hash.update(sha256(fs.readFileSync(file)));
|
|
38
|
-
hash.update('\0');
|
|
39
|
-
}
|
|
40
|
-
return { digest: hash.digest('hex'), file_count: files.length };
|
|
41
|
-
}
|
|
42
|
-
function fileDigestForPackageFiles(pkg) {
|
|
43
|
-
const hash = crypto.createHash('sha256');
|
|
44
|
-
const { files, missingEntries } = packageFileSnapshot(pkg);
|
|
45
|
-
for (const entry of missingEntries.sort()) {
|
|
46
|
-
hash.update(entry);
|
|
47
|
-
hash.update('\0');
|
|
48
|
-
hash.update('missing\0');
|
|
49
|
-
}
|
|
50
|
-
for (const file of files) {
|
|
51
|
-
const full = path.join(root, file);
|
|
52
|
-
const stat = fs.statSync(full);
|
|
53
|
-
hash.update(file);
|
|
54
|
-
hash.update('\0');
|
|
55
|
-
hash.update(String(stat.size));
|
|
56
|
-
hash.update('\0');
|
|
57
|
-
hash.update(sha256(fs.readFileSync(full)));
|
|
58
|
-
hash.update('\0');
|
|
59
|
-
}
|
|
60
|
-
return sha256(hash.digest('hex'));
|
|
61
|
-
}
|
|
62
|
-
function packageFileSnapshot(pkg) {
|
|
63
|
-
const entries = packageFileEntries(pkg);
|
|
64
|
-
const candidates = new Set();
|
|
65
|
-
const missingEntries = [];
|
|
66
|
-
for (const entry of entries) {
|
|
67
|
-
if (entry.negated || hasGlob(entry.pattern))
|
|
68
|
-
continue;
|
|
69
|
-
const full = path.join(root, entry.pattern);
|
|
70
|
-
if (!fs.existsSync(full)) {
|
|
71
|
-
missingEntries.push(entry.pattern);
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
const stat = fs.statSync(full);
|
|
75
|
-
if (stat.isDirectory()) {
|
|
76
|
-
const found = [];
|
|
77
|
-
collectFiles(full, found, { baseDir: root });
|
|
78
|
-
for (const file of found)
|
|
79
|
-
candidates.add(path.relative(root, file).split(path.sep).join('/'));
|
|
80
|
-
}
|
|
81
|
-
else if (stat.isFile()) {
|
|
82
|
-
candidates.add(entry.pattern);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
const files = [...candidates].filter((file) => packageFileIncluded(file, entries)).sort();
|
|
86
|
-
return { files, missingEntries };
|
|
87
|
-
}
|
|
88
|
-
function packageFileEntries(pkg) {
|
|
89
|
-
return (Array.isArray(pkg.files) ? pkg.files : [])
|
|
90
|
-
.map((raw) => {
|
|
91
|
-
const value = String(raw || '').trim();
|
|
92
|
-
const negated = value.startsWith('!');
|
|
93
|
-
const pattern = normalizeRel(negated ? value.slice(1) : value);
|
|
94
|
-
return pattern ? { negated, pattern } : null;
|
|
95
|
-
})
|
|
26
|
+
function releaseManifestContract() {
|
|
27
|
+
const manifest = readJson('release-gates.v2.json');
|
|
28
|
+
const contract = releaseGateContractSnapshot();
|
|
29
|
+
const allGates = Array.isArray(manifest?.gates) ? manifest.gates : [];
|
|
30
|
+
const releaseGateIds = allGates
|
|
31
|
+
.filter((gate) => Array.isArray(gate?.preset) && gate.preset.includes('release'))
|
|
32
|
+
.map((gate) => String(gate.id || ''))
|
|
96
33
|
.filter(Boolean);
|
|
34
|
+
return {
|
|
35
|
+
schema: manifest?.schema || null,
|
|
36
|
+
totalGateCount: allGates.length,
|
|
37
|
+
releaseGateIds,
|
|
38
|
+
releaseGateIdsSorted: [...new Set(releaseGateIds)].sort(),
|
|
39
|
+
expectedReleaseGateIds: contract.ids,
|
|
40
|
+
missingExpectedGateIds: contract.ids.filter((id) => !releaseGateIds.includes(id)),
|
|
41
|
+
unexpectedReleaseGateIds: [...new Set(releaseGateIds)].filter((id) => !contract.ids.includes(id)).sort(),
|
|
42
|
+
contract
|
|
43
|
+
};
|
|
97
44
|
}
|
|
98
|
-
function
|
|
99
|
-
|
|
100
|
-
for (const entry of entries) {
|
|
101
|
-
if (matchesPackagePattern(file, entry.pattern))
|
|
102
|
-
included = !entry.negated;
|
|
103
|
-
}
|
|
104
|
-
return included;
|
|
105
|
-
}
|
|
106
|
-
function matchesPackagePattern(file, pattern) {
|
|
107
|
-
const rel = normalizeRel(file);
|
|
108
|
-
const normalized = normalizeRel(pattern);
|
|
109
|
-
if (!rel || !normalized)
|
|
110
|
-
return false;
|
|
111
|
-
if (!hasGlob(normalized))
|
|
112
|
-
return rel === normalized || rel.startsWith(`${normalized}/`);
|
|
113
|
-
const re = globPatternToRegExp(normalized);
|
|
114
|
-
if (re.test(rel))
|
|
115
|
-
return true;
|
|
116
|
-
const parts = rel.split('/');
|
|
117
|
-
parts.pop();
|
|
118
|
-
while (parts.length) {
|
|
119
|
-
if (re.test(parts.join('/')))
|
|
120
|
-
return true;
|
|
121
|
-
parts.pop();
|
|
122
|
-
}
|
|
123
|
-
return false;
|
|
124
|
-
}
|
|
125
|
-
function globPatternToRegExp(pattern) {
|
|
126
|
-
let out = '^';
|
|
127
|
-
for (let i = 0; i < pattern.length; i += 1) {
|
|
128
|
-
const char = pattern[i];
|
|
129
|
-
if (char === '*') {
|
|
130
|
-
if (pattern[i + 1] === '*') {
|
|
131
|
-
if (pattern[i + 2] === '/') {
|
|
132
|
-
out += '(?:[^/]+/)*';
|
|
133
|
-
i += 2;
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
out += '.*';
|
|
137
|
-
i += 1;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
out += '[^/]*';
|
|
142
|
-
}
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
if (char === '?') {
|
|
146
|
-
out += '[^/]';
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
out += char.replace(/[|\\{}()[\]^$+?.]/g, '\\$&');
|
|
150
|
-
}
|
|
151
|
-
return new RegExp(`${out}$`);
|
|
152
|
-
}
|
|
153
|
-
function hasGlob(value) {
|
|
154
|
-
return /[*?]/.test(value);
|
|
155
|
-
}
|
|
156
|
-
function normalizeRel(value) {
|
|
157
|
-
return String(value || '').split(path.sep).join('/').replace(/^\.\/+/, '').replace(/\/+$/, '');
|
|
158
|
-
}
|
|
159
|
-
function gitCommit() {
|
|
160
|
-
const result = spawnSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' });
|
|
161
|
-
return result.status === 0 ? result.stdout.trim() : null;
|
|
45
|
+
function sha256(value) {
|
|
46
|
+
return crypto.createHash('sha256').update(value).digest('hex');
|
|
162
47
|
}
|
|
163
48
|
function runRefreshCommand() {
|
|
164
49
|
const override = process.env.SKS_RELEASE_CHECK_REFRESH_COMMAND;
|
|
@@ -178,115 +63,35 @@ function runRefreshCommand() {
|
|
|
178
63
|
stdio: 'inherit'
|
|
179
64
|
});
|
|
180
65
|
}
|
|
181
|
-
function releaseGateHash(pkg) {
|
|
182
|
-
const manifests = ['release-gates.v2.json', 'infra-harness-gates.json'].map((rel) => {
|
|
183
|
-
const file = path.join(root, rel);
|
|
184
|
-
return fs.existsSync(file) ? `${rel}\0${fs.readFileSync(file, 'utf8')}` : `${rel}\0missing`;
|
|
185
|
-
}).join('\0');
|
|
186
|
-
return sha256(`${pkg.scripts?.['release:check'] || ''}\0${pkg.scripts?.['prepublishOnly'] || ''}\0${manifests}`);
|
|
187
|
-
}
|
|
188
|
-
function collectFiles(dir, out, opts = {}) {
|
|
189
|
-
const baseDir = opts.baseDir || dir;
|
|
190
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
191
|
-
const file = path.join(dir, entry.name);
|
|
192
|
-
if (entry.isDirectory())
|
|
193
|
-
collectFiles(file, out, { ...opts, baseDir });
|
|
194
|
-
else if (entry.isFile()) {
|
|
195
|
-
const rel = path.relative(baseDir, file).split(path.sep).join('/');
|
|
196
|
-
if (!opts.include || opts.include(rel, file))
|
|
197
|
-
out.push(file);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
function gitFiles() {
|
|
202
|
-
const result = spawnSync('git', ['ls-files', '-z', '--cached', '--others', '--exclude-standard'], {
|
|
203
|
-
cwd: root,
|
|
204
|
-
encoding: 'utf8',
|
|
205
|
-
maxBuffer: 64 * 1024 * 1024
|
|
206
|
-
});
|
|
207
|
-
if (result.status !== 0)
|
|
208
|
-
fail('unable to list release-relevant files', result.stderr || result.stdout);
|
|
209
|
-
return result.stdout.split('\0').filter(Boolean);
|
|
210
|
-
}
|
|
211
|
-
function releaseRelevant(file) {
|
|
212
|
-
if (!file || file.startsWith('.sneakoscope/') || file.startsWith('.codex/') || file.startsWith('.agents/'))
|
|
213
|
-
return false;
|
|
214
|
-
if (file.startsWith('node_modules/') || file.startsWith('dist/') || file.startsWith('coverage/'))
|
|
215
|
-
return false;
|
|
216
|
-
if (file.startsWith('crates/sks-core/target/'))
|
|
217
|
-
return false;
|
|
218
|
-
if (/\.tgz$|\.log$/i.test(file))
|
|
219
|
-
return false;
|
|
220
|
-
if (/^(package|package-lock)\.json$/.test(file))
|
|
221
|
-
return true;
|
|
222
|
-
if (file === 'release-gates.v2.json' || file === 'infra-harness-gates.json')
|
|
223
|
-
return true;
|
|
224
|
-
if (/^tsconfig.*\.json$/.test(file))
|
|
225
|
-
return true;
|
|
226
|
-
if (/^(README|CHANGELOG|LICENSE)(\.md)?$/i.test(file))
|
|
227
|
-
return true;
|
|
228
|
-
return [
|
|
229
|
-
'bin/',
|
|
230
|
-
'src/',
|
|
231
|
-
'scripts/',
|
|
232
|
-
'test/',
|
|
233
|
-
'docs/',
|
|
234
|
-
'crates/sks-core/Cargo.',
|
|
235
|
-
'crates/sks-core/src/'
|
|
236
|
-
].some((prefix) => file.startsWith(prefix));
|
|
237
|
-
}
|
|
238
|
-
function releaseSnapshot() {
|
|
239
|
-
const files = gitFiles().filter(releaseRelevant).sort();
|
|
240
|
-
const hash = crypto.createHash('sha256');
|
|
241
|
-
for (const file of files) {
|
|
242
|
-
const full = path.join(root, file);
|
|
243
|
-
let stat;
|
|
244
|
-
try {
|
|
245
|
-
stat = fs.statSync(full);
|
|
246
|
-
}
|
|
247
|
-
catch {
|
|
248
|
-
continue;
|
|
249
|
-
}
|
|
250
|
-
if (!stat.isFile())
|
|
251
|
-
continue;
|
|
252
|
-
const contentHash = sha256(fs.readFileSync(full));
|
|
253
|
-
hash.update(file);
|
|
254
|
-
hash.update('\0');
|
|
255
|
-
hash.update(String(stat.size));
|
|
256
|
-
hash.update('\0');
|
|
257
|
-
hash.update(contentHash);
|
|
258
|
-
hash.update('\0');
|
|
259
|
-
}
|
|
260
|
-
return {
|
|
261
|
-
digest: hash.digest('hex'),
|
|
262
|
-
file_count: files.length
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
66
|
function currentStampPayload() {
|
|
266
67
|
const pkg = readJson('package.json');
|
|
267
|
-
const
|
|
268
|
-
const
|
|
269
|
-
const
|
|
270
|
-
include: (rel) => packageFileIncluded(`dist/${rel}`, packageEntries)
|
|
271
|
-
});
|
|
68
|
+
const authorization = releaseAuthorizationSnapshot(root, pkg);
|
|
69
|
+
const freshness = currentDistFreshness();
|
|
70
|
+
const gateContract = releaseGateContractSnapshot();
|
|
272
71
|
return {
|
|
273
|
-
schema: 'sks.release-check-stamp.
|
|
72
|
+
schema: 'sks.release-check-stamp.v2',
|
|
274
73
|
package_name: pkg.name,
|
|
275
74
|
package_version: pkg.version,
|
|
276
|
-
git_commit: gitCommit(),
|
|
277
75
|
package_json_sha256: sha256(fs.readFileSync(path.join(root, 'package.json'))),
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
release_gate_sha256: releaseGateHash(pkg),
|
|
76
|
+
...authorization,
|
|
77
|
+
dist_source_digest: freshness.source_digest,
|
|
78
|
+
dist_source_file_count: freshness.source_file_count,
|
|
282
79
|
release_check_sha256: sha256(pkg.scripts?.['release:check'] || ''),
|
|
283
|
-
|
|
284
|
-
|
|
80
|
+
release_gate_contract_schema: gateContract.schema,
|
|
81
|
+
release_gate_contract_count: gateContract.count,
|
|
82
|
+
release_gate_contract_sha256: gateContract.sha256
|
|
285
83
|
};
|
|
286
84
|
}
|
|
287
85
|
function writeStamp() {
|
|
86
|
+
const before = currentStampPayload();
|
|
87
|
+
const releaseGateProof = fullReleaseGateProofForWrite(before);
|
|
88
|
+
const current = currentStampPayload();
|
|
89
|
+
const changedDuringWrite = stampIdentityKeys().filter((key) => before[key] !== current[key]);
|
|
90
|
+
if (changedDuringWrite.length)
|
|
91
|
+
fail('release inputs changed while writing the stamp', changedDuringWrite.join('\n'));
|
|
288
92
|
const payload = {
|
|
289
|
-
...
|
|
93
|
+
...current,
|
|
94
|
+
release_gate_proof: releaseGateProof,
|
|
290
95
|
generated_at: new Date().toISOString()
|
|
291
96
|
};
|
|
292
97
|
fs.mkdirSync(path.dirname(stampPath), { recursive: true });
|
|
@@ -314,10 +119,13 @@ function inspectStamp() {
|
|
|
314
119
|
}
|
|
315
120
|
const current = currentStampPayload();
|
|
316
121
|
const mismatches = [];
|
|
317
|
-
for (const key of
|
|
122
|
+
for (const key of stampIdentityKeys()) {
|
|
318
123
|
if (stamp[key] !== current[key])
|
|
319
124
|
mismatches.push(`${key}: stamp=${stamp[key] || 'missing'} current=${current[key] || 'missing'}`);
|
|
320
125
|
}
|
|
126
|
+
const proofInspection = inspectFullReleaseGateProof(stamp.release_gate_proof, current);
|
|
127
|
+
if (!proofInspection.ok)
|
|
128
|
+
mismatches.push(...proofInspection.blockers.map((blocker) => `release_gate_proof:${blocker}`));
|
|
321
129
|
if (mismatches.length) {
|
|
322
130
|
return {
|
|
323
131
|
ok: false,
|
|
@@ -328,6 +136,283 @@ function inspectStamp() {
|
|
|
328
136
|
}
|
|
329
137
|
return { ok: true, current };
|
|
330
138
|
}
|
|
139
|
+
function stampIdentityKeys() {
|
|
140
|
+
return [
|
|
141
|
+
'schema',
|
|
142
|
+
'package_name',
|
|
143
|
+
'package_version',
|
|
144
|
+
'package_json_sha256',
|
|
145
|
+
...RELEASE_AUTHORIZATION_SNAPSHOT_KEYS,
|
|
146
|
+
'dist_source_digest',
|
|
147
|
+
'dist_source_file_count',
|
|
148
|
+
'release_check_sha256',
|
|
149
|
+
'release_gate_contract_schema',
|
|
150
|
+
'release_gate_contract_count',
|
|
151
|
+
'release_gate_contract_sha256'
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
function fullReleaseGateProofForWrite(currentPayload) {
|
|
155
|
+
const preset = argValue('--preset');
|
|
156
|
+
const full = commandArgs.includes('--full');
|
|
157
|
+
if (preset !== 'release' || !full) {
|
|
158
|
+
fail('full release proof required to write publish stamp', 'Use `npm run release:check:full`; affected/fast/confidence checks cannot authorize publish.');
|
|
159
|
+
}
|
|
160
|
+
const explicit = argValue('--summary');
|
|
161
|
+
const summaryPath = explicit ? path.resolve(root, explicit) : latestFullReleaseSummaryPath();
|
|
162
|
+
if (!summaryPath)
|
|
163
|
+
fail('full release DAG summary missing', 'Run `npm run release:check:full` before writing the publish stamp.');
|
|
164
|
+
const reportRoot = path.resolve(root, '.sneakoscope', 'reports', 'release-gates');
|
|
165
|
+
const relative = path.relative(reportRoot, summaryPath);
|
|
166
|
+
if (relative.startsWith('..') || path.isAbsolute(relative))
|
|
167
|
+
fail('release DAG summary is outside the managed report root');
|
|
168
|
+
let summary;
|
|
169
|
+
let summaryBytes;
|
|
170
|
+
try {
|
|
171
|
+
summaryBytes = fs.readFileSync(summaryPath);
|
|
172
|
+
summary = JSON.parse(summaryBytes.toString('utf8'));
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
fail('unable to read full release DAG summary', error?.message || String(error));
|
|
176
|
+
}
|
|
177
|
+
const validation = validateFullReleaseSummary(summary);
|
|
178
|
+
if (validation.length)
|
|
179
|
+
fail('release DAG summary is not full publish proof', validation.join('\n'));
|
|
180
|
+
const explicitRealSummary = argValue('--real-summary');
|
|
181
|
+
const realSummaryPath = explicitRealSummary
|
|
182
|
+
? path.resolve(root, explicitRealSummary)
|
|
183
|
+
: path.join(root, '.sneakoscope', 'reports', 'release-real-check.json');
|
|
184
|
+
const managedReports = path.resolve(root, '.sneakoscope', 'reports');
|
|
185
|
+
const realRelative = path.relative(managedReports, realSummaryPath);
|
|
186
|
+
if (realRelative.startsWith('..') || path.isAbsolute(realRelative))
|
|
187
|
+
fail('release real-check summary is outside the managed report root');
|
|
188
|
+
let realSummary;
|
|
189
|
+
try {
|
|
190
|
+
realSummary = JSON.parse(fs.readFileSync(realSummaryPath, 'utf8'));
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
fail('unable to read release real-check summary', error?.message || String(error));
|
|
194
|
+
}
|
|
195
|
+
const summarySha256 = sha256(summaryBytes);
|
|
196
|
+
const realValidation = validateReleaseRealSummary(realSummary, { runId: summary.run_id, summarySha256, currentPayload });
|
|
197
|
+
if (realValidation.length)
|
|
198
|
+
fail('release real-check summary is not publish proof', realValidation.join('\n'));
|
|
199
|
+
if (fs.statSync(realSummaryPath).mtimeMs < fs.statSync(summaryPath).mtimeMs)
|
|
200
|
+
fail('release real-check predates the full release DAG summary');
|
|
201
|
+
return {
|
|
202
|
+
schema: 'sks.release-check-full-proof.v1',
|
|
203
|
+
preset: 'release',
|
|
204
|
+
full: true,
|
|
205
|
+
run_id: summary.run_id,
|
|
206
|
+
summary_path: path.relative(root, summaryPath).split(path.sep).join('/'),
|
|
207
|
+
summary_sha256: summarySha256,
|
|
208
|
+
release_preset_gate_ids_sha256: sha256([...summary.selected_gate_ids].sort().join('\n')),
|
|
209
|
+
release_gate_contract_sha256: currentPayload.release_gate_contract_sha256,
|
|
210
|
+
selected_gates: summary.selected_gates,
|
|
211
|
+
completed: summary.completed,
|
|
212
|
+
failed: summary.failed,
|
|
213
|
+
affected_mode: summary.affected_selection?.mode,
|
|
214
|
+
confidence: summary.completion_certificate?.confidence || null,
|
|
215
|
+
real_check_path: path.relative(root, realSummaryPath).split(path.sep).join('/'),
|
|
216
|
+
real_check_sha256: sha256(fs.readFileSync(realSummaryPath)),
|
|
217
|
+
real_check_count: realSummary.all_checks.length
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function latestFullReleaseSummaryPath() {
|
|
221
|
+
const reportRoot = path.join(root, '.sneakoscope', 'reports', 'release-gates');
|
|
222
|
+
if (!fs.existsSync(reportRoot))
|
|
223
|
+
return null;
|
|
224
|
+
return fs.readdirSync(reportRoot, { withFileTypes: true })
|
|
225
|
+
.filter((entry) => entry.isDirectory())
|
|
226
|
+
.map((entry) => path.join(reportRoot, entry.name, 'summary.json'))
|
|
227
|
+
.filter((file) => fs.existsSync(file))
|
|
228
|
+
.map((file) => ({ file, stat: fs.statSync(file) }))
|
|
229
|
+
.sort((a, b) => b.stat.mtimeMs - a.stat.mtimeMs)
|
|
230
|
+
.map((row) => row.file)
|
|
231
|
+
.find((file) => {
|
|
232
|
+
try {
|
|
233
|
+
return validateFullReleaseSummary(JSON.parse(fs.readFileSync(file, 'utf8'))).length === 0;
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}) || null;
|
|
239
|
+
}
|
|
240
|
+
function validateFullReleaseSummary(summary) {
|
|
241
|
+
const blockers = [];
|
|
242
|
+
const contract = releaseManifestContract();
|
|
243
|
+
const selectedRaw = Array.isArray(summary?.selected_gate_ids) ? summary.selected_gate_ids.map(String).filter(Boolean) : [];
|
|
244
|
+
const selectedUnique = [...new Set(selectedRaw)].sort();
|
|
245
|
+
if (summary?.schema !== 'sks.release-gate-dag-run.v1')
|
|
246
|
+
blockers.push('summary_schema_invalid');
|
|
247
|
+
if (summary?.ok !== true)
|
|
248
|
+
blockers.push('summary_not_ok');
|
|
249
|
+
if (summary?.selected_preset !== 'release')
|
|
250
|
+
blockers.push('preset_not_release');
|
|
251
|
+
if (summary?.affected_selection?.mode !== 'full')
|
|
252
|
+
blockers.push('affected_mode_not_full');
|
|
253
|
+
if (!Number.isInteger(summary?.selected_gates) || summary.selected_gates <= 0)
|
|
254
|
+
blockers.push('selected_gates_empty');
|
|
255
|
+
if (contract.schema !== 'sks.release-gates.v2')
|
|
256
|
+
blockers.push('release_manifest_schema_invalid');
|
|
257
|
+
if (contract.releaseGateIds.length !== contract.releaseGateIdsSorted.length)
|
|
258
|
+
blockers.push('release_manifest_duplicate_gate_ids');
|
|
259
|
+
if (contract.missingExpectedGateIds.length)
|
|
260
|
+
blockers.push(`release_manifest_missing_contract_ids:${contract.missingExpectedGateIds.join(',')}`);
|
|
261
|
+
if (contract.unexpectedReleaseGateIds.length)
|
|
262
|
+
blockers.push(`release_manifest_unexpected_contract_ids:${contract.unexpectedReleaseGateIds.join(',')}`);
|
|
263
|
+
if (summary?.total_gates !== contract.totalGateCount)
|
|
264
|
+
blockers.push('manifest_total_gate_count_mismatch');
|
|
265
|
+
if (summary?.selected_gates !== contract.contract.count)
|
|
266
|
+
blockers.push('release_preset_gate_count_mismatch');
|
|
267
|
+
if (summary?.failed !== 0)
|
|
268
|
+
blockers.push('failed_gates_present');
|
|
269
|
+
if (summary?.completed !== summary?.selected_gates)
|
|
270
|
+
blockers.push('not_all_selected_gates_completed');
|
|
271
|
+
if (!Array.isArray(summary?.selected_gate_ids) || summary.selected_gate_ids.length !== summary.selected_gates)
|
|
272
|
+
blockers.push('selected_gate_ids_incomplete');
|
|
273
|
+
if (selectedRaw.length !== selectedUnique.length)
|
|
274
|
+
blockers.push('selected_gate_ids_duplicate');
|
|
275
|
+
if (!sameStringList(selectedUnique, contract.expectedReleaseGateIds))
|
|
276
|
+
blockers.push('selected_gate_ids_not_release_contract');
|
|
277
|
+
const affectedSelected = [...new Set((Array.isArray(summary?.affected_selection?.selected_gate_ids) ? summary.affected_selection.selected_gate_ids : []).map(String).filter(Boolean))].sort();
|
|
278
|
+
if (!sameStringList(affectedSelected, contract.expectedReleaseGateIds))
|
|
279
|
+
blockers.push('affected_selected_gate_ids_not_release_contract');
|
|
280
|
+
if (Array.isArray(summary?.skipped_by_affected) && summary.skipped_by_affected.length > 0)
|
|
281
|
+
blockers.push('full_release_has_skipped_gates');
|
|
282
|
+
if (summary?.completion_certificate?.confidence !== 'full-release-proof')
|
|
283
|
+
blockers.push('completion_confidence_not_full');
|
|
284
|
+
if (summary?.completion_certificate?.full_release_proof !== 'current_run')
|
|
285
|
+
blockers.push('full_release_proof_not_current_run');
|
|
286
|
+
if (summary?.completion_certificate?.ok !== true)
|
|
287
|
+
blockers.push('completion_certificate_not_ok');
|
|
288
|
+
return blockers;
|
|
289
|
+
}
|
|
290
|
+
function validateReleaseRealSummary(summary, context = {}) {
|
|
291
|
+
const blockers = [];
|
|
292
|
+
if (summary?.schema !== 'sks.release-real-check.v1')
|
|
293
|
+
blockers.push('real_check_schema_invalid');
|
|
294
|
+
if (summary?.ok !== true)
|
|
295
|
+
blockers.push('real_check_not_ok');
|
|
296
|
+
if (!Array.isArray(summary?.blockers) || summary.blockers.length > 0)
|
|
297
|
+
blockers.push('real_check_blockers_present');
|
|
298
|
+
const rows = Array.isArray(summary?.all_checks) ? summary.all_checks : [];
|
|
299
|
+
const rowIds = rows.map((row) => String(row?.id || '')).filter(Boolean);
|
|
300
|
+
const uniqueRowIds = [...new Set(rowIds)];
|
|
301
|
+
const expectedIds = [...RELEASE_REAL_CHECK_IDS];
|
|
302
|
+
if (!rows.length)
|
|
303
|
+
blockers.push('real_check_empty');
|
|
304
|
+
if (rowIds.length !== uniqueRowIds.length)
|
|
305
|
+
blockers.push('real_check_duplicate_ids');
|
|
306
|
+
if (!sameStringList([...uniqueRowIds].sort(), [...expectedIds].sort()))
|
|
307
|
+
blockers.push('real_check_ids_not_contract');
|
|
308
|
+
if (rows.some((row) => row?.ok !== true || row?.contract_ok !== true || row?.release_blocking === true))
|
|
309
|
+
blockers.push('real_check_failures_present');
|
|
310
|
+
const requiredIds = new Set(RELEASE_REAL_REQUIRED_CHECK_IDS);
|
|
311
|
+
const optionalIds = new Set(RELEASE_REAL_OPTIONAL_CHECK_IDS);
|
|
312
|
+
for (const row of rows) {
|
|
313
|
+
const id = String(row?.id || '');
|
|
314
|
+
if (requiredIds.has(id) && !(row?.required_for_release === true && row?.requirement === 'release_authorizing' && row?.outcome === 'passed' && row?.passed === true && row?.process_ok === true)) {
|
|
315
|
+
blockers.push(`real_required_check_not_passed:${id}`);
|
|
316
|
+
}
|
|
317
|
+
if (optionalIds.has(id) && !(row?.required_for_release === false && row?.requirement === 'live_optional'))
|
|
318
|
+
blockers.push(`real_optional_check_contract_invalid:${id}`);
|
|
319
|
+
}
|
|
320
|
+
const authorizingIds = [...new Set((Array.isArray(summary?.release_authorizing_checks) ? summary.release_authorizing_checks : []).map((row) => String(row?.id || '')).filter(Boolean))].sort();
|
|
321
|
+
if (!sameStringList(authorizingIds, [...RELEASE_REAL_REQUIRED_CHECK_IDS].sort()))
|
|
322
|
+
blockers.push('real_authorizing_check_ids_not_contract');
|
|
323
|
+
if (summary?.task_contract?.ok !== true || !sameStringList([...(summary?.task_contract?.actual_ids || [])].sort(), [...expectedIds].sort()))
|
|
324
|
+
blockers.push('real_task_contract_invalid');
|
|
325
|
+
if (!(summary?.release_check?.id === 'release:check' && summary?.release_check?.ok === true && summary?.release_check?.outcome === 'passed' && summary?.release_check?.required_for_release === true))
|
|
326
|
+
blockers.push('real_release_check_invalid');
|
|
327
|
+
const skipProof = summary?.skip_release_check_proof;
|
|
328
|
+
if (!(skipProof?.ok === true && skipProof?.stable_through_real_checks === true && skipProof?.final_revalidation?.ok === true))
|
|
329
|
+
blockers.push('real_skip_proof_invalid');
|
|
330
|
+
if (context.runId && (skipProof?.run_id !== context.runId || skipProof?.final_revalidation?.run_id !== context.runId))
|
|
331
|
+
blockers.push('real_skip_proof_run_mismatch');
|
|
332
|
+
if (context.summarySha256 && (skipProof?.latest_summary_sha256 !== context.summarySha256 || skipProof?.final_revalidation?.latest_summary_sha256 !== context.summarySha256))
|
|
333
|
+
blockers.push('real_skip_proof_summary_hash_mismatch');
|
|
334
|
+
if (context.currentPayload) {
|
|
335
|
+
for (const [label, proof] of [['initial', skipProof], ['final', skipProof?.final_revalidation]]) {
|
|
336
|
+
for (const key of RELEASE_AUTHORIZATION_SNAPSHOT_KEYS) {
|
|
337
|
+
if (proof?.[key] !== context.currentPayload[key])
|
|
338
|
+
blockers.push(`real_skip_${label}_${key}_not_current`);
|
|
339
|
+
}
|
|
340
|
+
if (proof?.dist_source_digest !== context.currentPayload.dist_source_digest)
|
|
341
|
+
blockers.push(`real_skip_${label}_dist_source_digest_not_current`);
|
|
342
|
+
if (proof?.dist_source_file_count !== context.currentPayload.dist_source_file_count)
|
|
343
|
+
blockers.push(`real_skip_${label}_dist_source_file_count_not_current`);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return blockers;
|
|
347
|
+
}
|
|
348
|
+
function sameStringList(left, right) {
|
|
349
|
+
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
350
|
+
}
|
|
351
|
+
function inspectFullReleaseGateProof(proof, currentPayload) {
|
|
352
|
+
const blockers = [];
|
|
353
|
+
let boundSummary = null;
|
|
354
|
+
let boundSummarySha256 = null;
|
|
355
|
+
if (proof?.schema !== 'sks.release-check-full-proof.v1')
|
|
356
|
+
blockers.push('proof_schema_invalid');
|
|
357
|
+
if (proof?.preset !== 'release' || proof?.full !== true)
|
|
358
|
+
blockers.push('proof_not_full_release');
|
|
359
|
+
if (proof?.release_gate_contract_sha256 !== currentPayload.release_gate_contract_sha256)
|
|
360
|
+
blockers.push('release_gate_contract_hash_mismatch');
|
|
361
|
+
const summaryPath = proof?.summary_path ? path.resolve(root, proof.summary_path) : null;
|
|
362
|
+
const reportRoot = path.resolve(root, '.sneakoscope', 'reports', 'release-gates');
|
|
363
|
+
if (!summaryPath || !fs.existsSync(summaryPath))
|
|
364
|
+
blockers.push('summary_missing');
|
|
365
|
+
else {
|
|
366
|
+
const relative = path.relative(reportRoot, summaryPath);
|
|
367
|
+
if (relative.startsWith('..') || path.isAbsolute(relative))
|
|
368
|
+
blockers.push('summary_outside_managed_reports');
|
|
369
|
+
else {
|
|
370
|
+
const bytes = fs.readFileSync(summaryPath);
|
|
371
|
+
if (sha256(bytes) !== proof.summary_sha256)
|
|
372
|
+
blockers.push('summary_hash_mismatch');
|
|
373
|
+
try {
|
|
374
|
+
const summary = JSON.parse(bytes);
|
|
375
|
+
boundSummary = summary;
|
|
376
|
+
boundSummarySha256 = sha256(bytes);
|
|
377
|
+
blockers.push(...validateFullReleaseSummary(summary));
|
|
378
|
+
if (summary.run_id !== proof.run_id || summary.selected_gates !== proof.selected_gates || summary.completed !== proof.completed || summary.failed !== proof.failed)
|
|
379
|
+
blockers.push('summary_identity_mismatch');
|
|
380
|
+
if (sha256([...summary.selected_gate_ids].sort().join('\n')) !== proof.release_preset_gate_ids_sha256)
|
|
381
|
+
blockers.push('release_preset_gate_ids_hash_mismatch');
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
blockers.push('summary_parse_failed');
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
const realCheckPath = proof?.real_check_path ? path.resolve(root, proof.real_check_path) : null;
|
|
389
|
+
if (!realCheckPath || !fs.existsSync(realCheckPath))
|
|
390
|
+
blockers.push('real_check_summary_missing');
|
|
391
|
+
else {
|
|
392
|
+
const relative = path.relative(path.resolve(root, '.sneakoscope', 'reports'), realCheckPath);
|
|
393
|
+
if (relative.startsWith('..') || path.isAbsolute(relative))
|
|
394
|
+
blockers.push('real_check_summary_outside_managed_reports');
|
|
395
|
+
else {
|
|
396
|
+
const bytes = fs.readFileSync(realCheckPath);
|
|
397
|
+
if (sha256(bytes) !== proof.real_check_sha256)
|
|
398
|
+
blockers.push('real_check_summary_hash_mismatch');
|
|
399
|
+
try {
|
|
400
|
+
const realSummary = JSON.parse(bytes);
|
|
401
|
+
blockers.push(...validateReleaseRealSummary(realSummary, { runId: boundSummary?.run_id || proof.run_id, summarySha256: boundSummarySha256 || proof.summary_sha256, currentPayload }));
|
|
402
|
+
if (realSummary.all_checks?.length !== proof.real_check_count)
|
|
403
|
+
blockers.push('real_check_identity_mismatch');
|
|
404
|
+
}
|
|
405
|
+
catch {
|
|
406
|
+
blockers.push('real_check_summary_parse_failed');
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return { ok: blockers.length === 0, blockers: [...new Set(blockers)] };
|
|
411
|
+
}
|
|
412
|
+
function argValue(name) {
|
|
413
|
+
const index = commandArgs.indexOf(name);
|
|
414
|
+
return index >= 0 ? commandArgs[index + 1] || null : null;
|
|
415
|
+
}
|
|
331
416
|
function verifyStamp() {
|
|
332
417
|
const result = inspectStamp();
|
|
333
418
|
if (!result.ok)
|
|
@@ -359,5 +444,5 @@ else if (command === 'verify')
|
|
|
359
444
|
else if (command === 'ensure')
|
|
360
445
|
ensureStamp();
|
|
361
446
|
else
|
|
362
|
-
fail(`unknown command ${command}`, 'Usage: node ./dist/scripts/release-check-stamp.js <write|verify|ensure>');
|
|
447
|
+
fail(`unknown command ${command}`, 'Usage: node ./dist/scripts/release-check-stamp.js <write --preset release --full [--summary path]|verify|ensure>');
|
|
363
448
|
//# sourceMappingURL=release-check-stamp.js.map
|
|
@@ -2,6 +2,7 @@
|
|
|
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
|
+
import { releaseGateContractSnapshot } from '../core/release/release-gate-contract.js';
|
|
5
6
|
const packageJson = readPackageJson(path.join(root, 'package.json'));
|
|
6
7
|
const releaseManifest = readReleaseGateManifest(path.join(root, 'release-gates.v2.json'), 'sks.release-gates.v2');
|
|
7
8
|
const harnessManifest = readReleaseGateManifest(path.join(root, 'infra-harness-gates.json'), 'sks.infra-harness-gates.v1');
|
|
@@ -9,21 +10,8 @@ const releasePreset = releaseManifest.gates.filter((gate) => gate.preset.include
|
|
|
9
10
|
const harnessPreset = harnessManifest.gates.filter((gate) => gate.preset.includes('harness'));
|
|
10
11
|
const releaseIds = new Set(releasePreset.map((gate) => gate.id));
|
|
11
12
|
const harnessIds = new Set(harnessPreset.map((gate) => gate.id));
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
'qa-loop:comprehensive-verification',
|
|
15
|
-
'loop-integration-finalizer-check',
|
|
16
|
-
'naruto:canonical-stop-gate',
|
|
17
|
-
'agent:native-cli-session-swarm-scaling',
|
|
18
|
-
'agent:fast-mode-policy',
|
|
19
|
-
'codex-control:event-stream-ledger',
|
|
20
|
-
'release:dag-runner',
|
|
21
|
-
'release:gate-budget',
|
|
22
|
-
'release:gate-selection-comprehensive',
|
|
23
|
-
'policy:gate-audit',
|
|
24
|
-
'runtime:proof-summary',
|
|
25
|
-
'typecheck'
|
|
26
|
-
];
|
|
13
|
+
const releaseContract = releaseGateContractSnapshot();
|
|
14
|
+
const requiredReleasePresetIds = releaseContract.ids;
|
|
27
15
|
const requiredHarnessPresetIds = [
|
|
28
16
|
'zellij:layout-valid',
|
|
29
17
|
'zellij:compact-slot-renderer',
|
|
@@ -33,6 +21,7 @@ const requiredHarnessPresetIds = [
|
|
|
33
21
|
'zellij:right-column-geometry-proof'
|
|
34
22
|
];
|
|
35
23
|
const missingRequiredReleasePreset = requiredReleasePresetIds.filter((id) => !releaseIds.has(id));
|
|
24
|
+
const unexpectedReleasePreset = [...releaseIds].filter((id) => !requiredReleasePresetIds.includes(id)).sort();
|
|
36
25
|
const missingRequiredHarnessPreset = requiredHarnessPresetIds.filter((id) => !harnessIds.has(id));
|
|
37
26
|
const duplicateAcrossManifests = [...releaseIds].filter((id) => harnessIds.has(id));
|
|
38
27
|
const releaseZellij = [...releaseIds].filter((id) => id.startsWith('zellij:'));
|
|
@@ -44,6 +33,7 @@ const report = {
|
|
|
44
33
|
ok: schemaComplete
|
|
45
34
|
&& releasePreset.length <= 200
|
|
46
35
|
&& missingRequiredReleasePreset.length === 0
|
|
36
|
+
&& unexpectedReleasePreset.length === 0
|
|
47
37
|
&& missingRequiredHarnessPreset.length === 0
|
|
48
38
|
&& duplicateAcrossManifests.length === 0
|
|
49
39
|
&& releaseZellij.length === 0
|
|
@@ -53,6 +43,8 @@ const report = {
|
|
|
53
43
|
harness_gate_count: harnessPreset.length,
|
|
54
44
|
required_release_preset_ids: requiredReleasePresetIds,
|
|
55
45
|
missing_required_release_preset: missingRequiredReleasePreset,
|
|
46
|
+
unexpected_release_preset: unexpectedReleasePreset,
|
|
47
|
+
release_gate_contract: releaseContract,
|
|
56
48
|
required_harness_preset_ids: requiredHarnessPresetIds,
|
|
57
49
|
missing_required_harness_preset: missingRequiredHarnessPreset,
|
|
58
50
|
duplicate_across_manifests: duplicateAcrossManifests,
|