sneakoscope 4.8.6 → 5.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -726
- package/bench/tasks/t01-off-by-one/repo/package.json +9 -0
- package/bench/tasks/t01-off-by-one/repo/src/pagination.js +5 -0
- package/bench/tasks/t01-off-by-one/repo/test.js +5 -0
- package/bench/tasks/t01-off-by-one/task.json +13 -0
- package/bench/tasks/t02-signature-cochange/repo/package.json +9 -0
- package/bench/tasks/t02-signature-cochange/repo/src/admin.js +5 -0
- package/bench/tasks/t02-signature-cochange/repo/src/audit.js +5 -0
- package/bench/tasks/t02-signature-cochange/repo/src/labels.js +3 -0
- package/bench/tasks/t02-signature-cochange/repo/src/profile.js +5 -0
- package/bench/tasks/t02-signature-cochange/repo/test.js +9 -0
- package/bench/tasks/t02-signature-cochange/task.json +12 -0
- package/bench/tasks/t03-type-puzzle/repo/package.json +9 -0
- package/bench/tasks/t03-type-puzzle/repo/src/config.js +4 -0
- package/bench/tasks/t03-type-puzzle/repo/test.js +6 -0
- package/bench/tasks/t03-type-puzzle/task.json +13 -0
- package/bench/tasks/t04-refactor-preserve/repo/package.json +9 -0
- package/bench/tasks/t04-refactor-preserve/repo/src/cart.js +8 -0
- package/bench/tasks/t04-refactor-preserve/repo/test.js +4 -0
- package/bench/tasks/t04-refactor-preserve/task.json +12 -0
- package/bench/tasks/t05-performance/repo/package.json +9 -0
- package/bench/tasks/t05-performance/repo/src/pairs.js +9 -0
- package/bench/tasks/t05-performance/repo/test.js +11 -0
- package/bench/tasks/t05-performance/task.json +12 -0
- package/bench/tasks/t06-mistake-rule/repo/package.json +9 -0
- package/bench/tasks/t06-mistake-rule/repo/src/loader.js +6 -0
- package/bench/tasks/t06-mistake-rule/repo/test.js +7 -0
- package/bench/tasks/t06-mistake-rule/task.json +12 -0
- package/config/bench-baseline.json +7 -0
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/bin/install.js +35 -0
- package/dist/bin/sks.js +1 -1
- package/dist/cli/cli-theme.js +51 -0
- package/dist/cli/command-registry.js +75 -42
- package/dist/cli/help-fast.js +18 -8
- package/dist/cli/insane-search-command.js +36 -8
- package/dist/cli/install-helpers.js +147 -47
- package/dist/cli/router.js +58 -2
- package/dist/commands/codex-lb.js +6 -4
- package/dist/commands/doctor.js +146 -8
- package/dist/commands/proof.js +6 -3
- package/dist/commands/zellij-monitor-pane.js +25 -0
- package/dist/commands/zellij-slot-pane.js +39 -2
- package/dist/commands/zellij-viewport-pane.js +56 -0
- package/dist/commands/zellij.js +55 -2
- package/dist/config/skills-manifest.json +493 -0
- package/dist/core/agents/agent-conflict-graph.js +5 -0
- package/dist/core/agents/agent-lease.js +5 -0
- package/dist/core/agents/agent-ledger-schemas.js +1 -0
- package/dist/core/agents/agent-lifecycle.js +86 -35
- package/dist/core/agents/agent-orchestrator.js +287 -72
- package/dist/core/agents/agent-output-validator.js +14 -3
- package/dist/core/agents/agent-patch-queue-store.js +108 -4
- package/dist/core/agents/agent-patch-queue.js +10 -3
- package/dist/core/agents/agent-patch-schema.js +13 -0
- package/dist/core/agents/agent-proof-evidence.js +6 -1
- package/dist/core/agents/agent-runner-fake.js +40 -0
- package/dist/core/agents/agent-scheduler.js +2 -3
- package/dist/core/agents/agent-worker-pipeline.js +36 -2
- package/dist/core/agents/codex-exec-worker-adapter.js +2 -0
- package/dist/core/agents/native-cli-session-swarm.js +30 -13
- package/dist/core/agents/native-cli-worker.js +2 -1
- package/dist/core/agents/native-worker-backend-router.js +58 -1
- package/dist/core/auto-review.js +25 -4
- package/dist/core/codex/agent-config-file-repair.js +15 -2
- package/dist/core/codex/codex-config-eperm-repair.js +8 -2
- package/dist/core/codex/codex-config-guard.js +289 -0
- package/dist/core/codex/codex-config-toml.js +122 -0
- package/dist/core/codex/codex-project-config-policy.js +59 -7
- package/dist/core/codex-app/sks-menubar.js +780 -122
- package/dist/core/codex-app.js +1 -0
- package/dist/core/codex-control/codex-fake-sdk-adapter.js +6 -4
- package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
- package/dist/core/codex-control/codex-sdk-env-policy.js +1 -1
- package/dist/core/codex-control/codex-task-runner.js +32 -14
- package/dist/core/codex-control/python-codex-sdk-adapter.js +4 -1
- package/dist/core/codex-control/schemas/agent-worker-result.schema.js +12 -3
- package/dist/core/codex-hooks/codex-hook-managed-install.js +5 -0
- package/dist/core/codex-hooks/codex-hook-state-writer.js +70 -11
- package/dist/core/codex-hooks/codex-hook-trust-doctor.js +2 -2
- package/dist/core/codex-lb/codex-lb-env.js +20 -1
- package/dist/core/codex-lb/codex-lb-setup.js +2 -5
- package/dist/core/codex-native/skill-registry-ledger.js +24 -5
- package/dist/core/commands/basic-cli.js +21 -2
- package/dist/core/commands/check-command.js +37 -5
- package/dist/core/commands/command-utils.js +22 -2
- package/dist/core/commands/computer-use-command.js +62 -7
- package/dist/core/commands/db-command.js +31 -5
- package/dist/core/commands/fast-mode-command.js +39 -11
- package/dist/core/commands/gate-result-contract.js +43 -0
- package/dist/core/commands/gates-command.js +6 -1
- package/dist/core/commands/gc-command.js +29 -2
- package/dist/core/commands/goal-command.js +9 -2
- package/dist/core/commands/gx-command.js +79 -7
- package/dist/core/commands/image-ux-review-command.js +188 -13
- package/dist/core/commands/mad-db-command.js +85 -176
- package/dist/core/commands/mad-sks-command.js +248 -34
- package/dist/core/commands/menubar-command.js +146 -0
- package/dist/core/commands/naruto-command.js +64 -10
- package/dist/core/commands/pipeline-command.js +21 -2
- package/dist/core/commands/plan-command.js +76 -0
- package/dist/core/commands/ppt-command.js +159 -24
- package/dist/core/commands/qa-loop-command.js +6 -2
- package/dist/core/commands/release-command.js +55 -2
- package/dist/core/commands/research-command.js +1 -1
- package/dist/core/commands/review-command.js +217 -0
- package/dist/core/commands/route-command.js +62 -0
- package/dist/core/commands/route-success-helpers.js +59 -0
- package/dist/core/commands/run-command.js +19 -7
- package/dist/core/commands/seo-command.js +49 -1
- package/dist/core/commands/status-command.js +21 -1
- package/dist/core/commands/team-legacy-observe-command.js +221 -3
- package/dist/core/commands/ui-command.js +161 -0
- package/dist/core/commands/uninstall-command.js +312 -0
- package/dist/core/db-safety.js +7 -3
- package/dist/core/doctor/codex-startup-config-repair.js +14 -3
- package/dist/core/doctor/confirm-repair.js +27 -0
- package/dist/core/doctor/context7-mcp-repair.js +35 -7
- package/dist/core/doctor/doctor-codex-startup-repair.js +10 -3
- package/dist/core/doctor/doctor-context7-repair.js +17 -4
- package/dist/core/doctor/doctor-dirty-planner.js +27 -9
- package/dist/core/doctor/doctor-native-capability-repair.js +12 -2
- package/dist/core/doctor/doctor-readiness-matrix.js +27 -2
- package/dist/core/doctor/doctor-repair-postcheck.js +4 -0
- package/dist/core/doctor/doctor-transaction.js +21 -5
- package/dist/core/doctor/doctor-zellij-repair.js +1 -0
- package/dist/core/doctor/imagegen-repair.js +161 -0
- package/dist/core/doctor/supabase-mcp-repair.js +23 -5
- package/dist/core/feature-fixture-runner.js +2 -2
- package/dist/core/feature-fixtures.js +65 -37
- package/dist/core/feature-registry.js +106 -3
- package/dist/core/fsx.js +91 -2
- package/dist/core/hooks-runtime/skill-reconcile-preflight.js +43 -0
- package/dist/core/hooks-runtime.js +86 -46
- package/dist/core/image-ux-review/imagegen-adapter.js +48 -11
- package/dist/core/image-ux-review.js +16 -0
- package/dist/core/imagegen/imagegen-capability.js +11 -5
- package/dist/core/imagegen/require-imagegen.js +57 -0
- package/dist/core/init/skills.js +271 -14
- package/dist/core/init.js +13 -10
- package/dist/core/mad-db/mad-db-coordinator.js +96 -20
- package/dist/core/mad-db/mad-db-policy.js +12 -10
- package/dist/core/mad-sks/executors/executor-base.js +8 -2
- package/dist/core/mad-sks/executors/index.js +4 -0
- package/dist/core/mad-sks/executors/sql-plane-executor.js +194 -0
- package/dist/core/mission.js +138 -5
- package/dist/core/naruto/naruto-active-pool.js +84 -30
- package/dist/core/naruto/naruto-backpressure.js +5 -1
- package/dist/core/naruto/naruto-real-worker-child.js +10 -0
- package/dist/core/naruto/naruto-real-worker-runtime.js +9 -7
- package/dist/core/naruto/naruto-role-policy.js +3 -0
- package/dist/core/naruto/naruto-task-hints.js +10 -0
- package/dist/core/naruto/naruto-work-graph.js +8 -2
- package/dist/core/naruto/naruto-work-item.js +6 -0
- package/dist/core/naruto/resource-pressure-monitor.js +33 -15
- package/dist/core/naruto/solution-tournament.js +101 -0
- package/dist/core/permission-gates.js +30 -0
- package/dist/core/pipeline-internals/runtime-core.js +72 -222
- package/dist/core/pipeline-internals/runtime-gates.js +140 -24
- package/dist/core/ppt-review/index.js +6 -1
- package/dist/core/ppt-review/slide-imagegen-review.js +75 -10
- package/dist/core/ppt.js +70 -2
- package/dist/core/proof/auto-finalize.js +70 -11
- package/dist/core/proof/proof-schema.js +2 -0
- package/dist/core/proof/route-adapter.js +5 -1
- package/dist/core/proof/route-finalizer.js +8 -5
- package/dist/core/proof/selftest-proof-fixtures.js +18 -5
- package/dist/core/proof/validation.js +2 -0
- package/dist/core/provider/model-router.js +53 -0
- package/dist/core/questions.js +1 -1
- package/dist/core/recallpulse.js +1 -1
- package/dist/core/release/gate-manifest.js +2 -2
- package/dist/core/release/release-gate-affected-selector.js +3 -10
- package/dist/core/release/release-gate-batch-runner.js +4 -2
- package/dist/core/release/release-gate-cache-v2.js +27 -14
- package/dist/core/release/release-gate-dag.js +6 -1
- package/dist/core/release/release-gate-hermetic-env.js +10 -0
- package/dist/core/release/release-gate-node.js +3 -0
- package/dist/core/release/release-gate-resource-governor.js +1 -0
- package/dist/core/retention.js +89 -4
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes/diagnostic-allowlist.js +55 -0
- package/dist/core/routes.js +83 -33
- package/dist/core/safety/mutation-guard.js +5 -1
- package/dist/core/skill-forge.js +9 -4
- package/dist/core/stop-gate/gate-evaluator.js +102 -0
- package/dist/core/stop-gate/stop-gate-check.js +26 -4
- package/dist/core/stop-gate/stop-gate-resolver.js +19 -3
- package/dist/core/stop-gate/stop-gate-writer.js +20 -1
- package/dist/core/team-dag.js +12 -465
- package/dist/core/team-dashboard-renderer.js +13 -94
- package/dist/core/team-live.js +68 -804
- package/dist/core/triwiki/agents-md-projector.js +184 -0
- package/dist/core/triwiki-wrongness/wrongness-schema.js +3 -1
- package/dist/core/trust-kernel/trust-kernel-schema.js +1 -0
- package/dist/core/trust-kernel/trust-report.js +1 -1
- package/dist/core/trust-kernel/trust-status.js +2 -0
- package/dist/core/ui/dashboard-html.js +111 -0
- package/dist/core/update/update-migration-state.js +383 -42
- package/dist/core/update-check.js +201 -78
- package/dist/core/verification/diff-quality.js +100 -0
- package/dist/core/verification/impact-scan.js +164 -0
- package/dist/core/verification/machine-feedback.js +146 -0
- package/dist/core/verification/mistake-rule-compiler.js +195 -0
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-layout-builder.js +44 -16
- package/dist/core/zellij/zellij-monitor-renderer.js +53 -0
- package/dist/core/zellij/zellij-self-heal.js +27 -32
- package/dist/core/zellij/zellij-slot-pane-renderer.js +162 -153
- package/dist/core/zellij/zellij-slot-telemetry.js +2 -0
- package/dist/core/zellij/zellij-theme.js +67 -0
- package/dist/core/zellij/zellij-ui-mode.js +16 -0
- package/dist/core/zellij/zellij-viewport-binder.js +59 -0
- package/dist/core/zellij/zellij-worker-pane-manager.js +53 -5
- package/dist/scripts/agent-patch-swarm-gate-lib.js +2 -2
- package/dist/scripts/build-dist.js +8 -0
- package/dist/scripts/check-feature-quality.js +2 -2
- package/dist/scripts/cli-output-consistency-check.js +57 -0
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +106 -0
- package/dist/scripts/codex-lb-gpt55-fast-profile-check.js +105 -0
- package/dist/scripts/codex-lb-missing-env-regression.js +2 -3
- package/dist/scripts/codex-project-config-policy-merge-regression.js +3 -3
- package/dist/scripts/coding-bench-check.js +136 -0
- package/dist/scripts/concurrent-session-collision-check.js +67 -0
- package/dist/scripts/docs-truthfulness-check.js +1 -1
- package/dist/scripts/doctor-imagegen-repair-check.js +62 -0
- package/dist/scripts/ensure-bin-executable.js +11 -3
- package/dist/scripts/gate-policy-audit-check.js +130 -0
- package/dist/scripts/harness-benchmark-check.js +104 -0
- package/dist/scripts/hook-latency-budget-check.js +45 -0
- package/dist/scripts/legacy-update-e2e-check.js +228 -0
- package/dist/scripts/lib/codex-sdk-gate-lib.js +2 -2
- package/dist/scripts/lib/real-codex-parallel-gate.js +2 -2
- package/dist/scripts/loop-directive-check-lib.js +1 -1
- package/dist/scripts/mad-db-command-check.js +11 -8
- package/dist/scripts/mad-db-real-supabase-e2e.js +2 -2
- package/dist/scripts/mad-db-route-identity-check.js +8 -6
- package/dist/scripts/mad-db-safety-conflict-matrix-check.js +31 -8
- package/dist/scripts/mad-db-skill-policy-snapshot-check.js +4 -5
- package/dist/scripts/mad-sks-zellij-default-pane-worker-check.js +3 -2
- package/dist/scripts/mad-sks-zellij-launch-check.js +1 -1
- package/dist/scripts/naruto-zellij-dynamic-right-column-check.js +7 -7
- package/dist/scripts/parallel-claim-enforcement-check.js +14 -5
- package/dist/scripts/ppt-real-imagegen-wiring-check.js +5 -1
- package/dist/scripts/project-skill-dedupe-check.js +23 -5
- package/dist/scripts/proof-root-cause-policy-check.js +2 -0
- package/dist/scripts/release-affected-selector-check.js +2 -2
- package/dist/scripts/release-cache-glob-hashing-check.js +1 -0
- package/dist/scripts/release-dag-full-coverage-check.js +13 -4
- package/dist/scripts/release-gate-dag-runner-check.js +10 -2
- package/dist/scripts/release-gate-dag-runner.js +22 -0
- package/dist/scripts/release-gate-existence-audit.js +2 -1
- package/dist/scripts/release-gate-planner.js +2 -1
- package/dist/scripts/release-gate-script-parity-check.js +1 -1
- package/dist/scripts/release-metadata-1-19-check.js +2 -1
- package/dist/scripts/release-readiness-report.js +38 -7
- package/dist/scripts/release-stability-report-check.js +12 -8
- package/dist/scripts/search-visibility-gate-lib.js +2 -2
- package/dist/scripts/seo-geo-feature-fixture-quality-check.js +1 -1
- package/dist/scripts/skills-manifest-continuity-check.js +46 -0
- package/dist/scripts/sks-1-11-gate-lib.js +8 -6
- package/dist/scripts/sks-menubar-install-check.js +87 -21
- package/dist/scripts/sks-uninstall-regression-check.js +54 -0
- package/dist/scripts/uninstall-inventory-check.js +3 -0
- package/dist/scripts/ux-review-real-loop-fixture-check.js +9 -4
- package/dist/scripts/ux-review-run-wires-imagegen-check.js +4 -0
- package/dist/scripts/zellij-layout-valid-check.js +18 -11
- package/dist/scripts/zellij-right-column-geometry-proof.js +2 -4
- package/dist/scripts/zellij-slot-pane-renderer-check.js +9 -9
- package/dist/scripts/zellij-slot-pane-stale-detection-check.js +3 -4
- package/dist/scripts/zellij-slot-pane-telemetry-renderer-check.js +3 -2
- package/dist/scripts/zellij-slot-telemetry-renderer-check.js +4 -2
- package/dist/scripts/zellij-spawn-on-demand-layout-check.js +8 -2
- package/dist/scripts/zellij-viewport-binder-check.js +9 -0
- package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
- package/docs/demo.tape +28 -0
- package/package.json +70 -3
- package/schemas/codex/completion-proof.schema.json +3 -2
- package/schemas/release/release-gate-node.schema.json +2 -1
- package/dist/scripts/agent-backfill-route-blackbox.js +0 -5
- package/dist/scripts/agent-dynamic-pool-route-blackbox.js +0 -5
- package/dist/scripts/agent-parallel-write-blackbox.js +0 -56
- package/dist/scripts/agent-patch-swarm-route-blackbox.js +0 -10
- package/dist/scripts/agent-route-blackbox-lib.js +0 -132
- package/dist/scripts/blackbox-command-import-smoke.js +0 -143
- package/dist/scripts/blackbox-global-shim.js +0 -77
- package/dist/scripts/blackbox-matrix.js +0 -70
- package/dist/scripts/blackbox-npx-one-shot.js +0 -69
- package/dist/scripts/blackbox-pack-install.js +0 -174
- package/dist/scripts/brand-neutrality-zero-leakage-blackbox.js +0 -4
- package/dist/scripts/build-once-runner-blackbox.js +0 -34
- package/dist/scripts/codex-0140-integration-blackbox.js +0 -13
- package/dist/scripts/codex-agent-type-blackbox.js +0 -4
- package/dist/scripts/codex-app-harness-blackbox.js +0 -4
- package/dist/scripts/codex-app-skill-agent-blackbox.js +0 -4
- package/dist/scripts/codex-hook-approval-blackbox.js +0 -4
- package/dist/scripts/codex-init-deep-directory-local-blackbox.js +0 -4
- package/dist/scripts/codex-native-feature-broker-blackbox.js +0 -4
- package/dist/scripts/codex-native-pattern-analysis-blackbox.js +0 -4
- package/dist/scripts/codex-native-read-repair-split-blackbox.js +0 -55
- package/dist/scripts/codex-native-reference-cache-blackbox.js +0 -41
- package/dist/scripts/core-skill-integrity-blackbox.js +0 -33
- package/dist/scripts/dfix-fast-blackbox-check.js +0 -37
- package/dist/scripts/dfix-parallel-write-blackbox.js +0 -48
- package/dist/scripts/dfix-patch-swarm-route-blackbox.js +0 -10
- package/dist/scripts/doctor-context7-mcp-repair-blackbox.js +0 -16
- package/dist/scripts/doctor-dirty-repair-blackbox.js +0 -22
- package/dist/scripts/doctor-dirty-semantic-blackbox.js +0 -8
- package/dist/scripts/doctor-fix-production-blackbox.js +0 -26
- package/dist/scripts/doctor-native-capability-repair-blackbox.js +0 -39
- package/dist/scripts/doctor-startup-config-repair-blackbox.js +0 -13
- package/dist/scripts/doctor-supabase-mcp-repair-blackbox.js +0 -14
- package/dist/scripts/doctor-transaction-engine-blackbox.js +0 -28
- package/dist/scripts/doctor-zellij-fix-blackbox.js +0 -4
- package/dist/scripts/doctor-zellij-no-homebrew-blackbox.js +0 -4
- package/dist/scripts/doctor-zellij-upgrade-blackbox.js +0 -4
- package/dist/scripts/gate-pack-runner-blackbox.js +0 -27
- package/dist/scripts/gate-pack-v2-blackbox.js +0 -18
- package/dist/scripts/geo-cli-blackbox-check.js +0 -18
- package/dist/scripts/loop-collision-blackbox.js +0 -3
- package/dist/scripts/loop-concurrency-oversubscription-blackbox.js +0 -3
- package/dist/scripts/loop-fixture-production-misuse-blackbox.js +0 -3
- package/dist/scripts/loop-kill-interrupt-real-blackbox.js +0 -3
- package/dist/scripts/loop-merge-strategy-blackbox.js +0 -3
- package/dist/scripts/loop-mesh-production-e2e-blackbox.js +0 -3
- package/dist/scripts/loop-side-effect-blackbox.js +0 -3
- package/dist/scripts/mad-db-operation-lifecycle-blackbox.js +0 -29
- package/dist/scripts/mad-sks-actual-executor-blackbox.js +0 -5
- package/dist/scripts/mad-zellij-headless-fallback-blackbox.js +0 -4
- package/dist/scripts/mad-zellij-self-heal-blackbox.js +0 -4
- package/dist/scripts/naruto-loop-mesh-blackbox.js +0 -3
- package/dist/scripts/naruto-real-parallelism-blackbox.js +0 -307
- package/dist/scripts/naruto-worktree-coding-blackbox.js +0 -29
- package/dist/scripts/parallel-runtime-real-blackbox.js +0 -44
- package/dist/scripts/pipeline-codex-native-doctor-mad-routing-real-blackbox.js +0 -77
- package/dist/scripts/pipeline-codex-native-e2e-blackbox.js +0 -13
- package/dist/scripts/pipeline-codex-native-image-routing-real-blackbox.js +0 -50
- package/dist/scripts/pipeline-codex-native-loop-routing-real-blackbox.js +0 -74
- package/dist/scripts/pipeline-codex-native-qa-routing-real-blackbox.js +0 -51
- package/dist/scripts/pipeline-codex-native-research-routing-real-blackbox.js +0 -45
- package/dist/scripts/pipeline-execution-profile-routing-blackbox.js +0 -4
- package/dist/scripts/postinstall-global-doctor-blackbox.js +0 -12
- package/dist/scripts/ppt-full-e2e-blackbox-check.js +0 -109
- package/dist/scripts/ppt-imagegen-blackbox-check.js +0 -46
- package/dist/scripts/project-skill-dedupe-blackbox.js +0 -36
- package/dist/scripts/qa-backfill-route-blackbox.js +0 -5
- package/dist/scripts/qa-patch-swarm-route-blackbox.js +0 -10
- package/dist/scripts/release-full-parallelism-blackbox.js +0 -41
- package/dist/scripts/release-triwiki-first-runner-blackbox.js +0 -48
- package/dist/scripts/release-wiring-3110-blackbox.js +0 -27
- package/dist/scripts/release-wiring-3112-blackbox.js +0 -17
- package/dist/scripts/release-wiring-3113-blackbox.js +0 -17
- package/dist/scripts/research-backfill-route-blackbox.js +0 -5
- package/dist/scripts/research-final-reviewer-blackbox.js +0 -70
- package/dist/scripts/research-stage-cycle-runtime-blackbox.js +0 -40
- package/dist/scripts/research-synthesis-writer-blackbox.js +0 -24
- package/dist/scripts/route-blackbox-realism-check.js +0 -21
- package/dist/scripts/scheduler-resource-claim-blackbox.js +0 -24
- package/dist/scripts/seo-cli-blackbox-check.js +0 -18
- package/dist/scripts/sks-3110-all-feature-regression-blackbox.js +0 -116
- package/dist/scripts/sks-3112-all-feature-regression-blackbox.js +0 -29
- package/dist/scripts/sks-3113-all-feature-regression-blackbox.js +0 -17
- package/dist/scripts/sks-400-all-feature-regression-blackbox.js +0 -21
- package/dist/scripts/sks-400-extreme-parallel-blackbox.js +0 -8
- package/dist/scripts/sks-400-five-minute-blackbox.js +0 -9
- package/dist/scripts/sks-400-legacy-purge-blackbox.js +0 -8
- package/dist/scripts/sks-401-all-feature-regression-blackbox.js +0 -46
- package/dist/scripts/sks-401-five-minute-actual-blackbox.js +0 -23
- package/dist/scripts/sks-402-all-feature-regression-blackbox.js +0 -9
- package/dist/scripts/sks-402-five-minute-real-blackbox.js +0 -22
- package/dist/scripts/sksd-warm-cache-blackbox.js +0 -12
- package/dist/scripts/supabase-secret-preservation-blackbox.js +0 -29
- package/dist/scripts/team-backfill-route-blackbox.js +0 -5
- package/dist/scripts/team-parallel-write-blackbox.js +0 -55
- package/dist/scripts/team-patch-swarm-route-blackbox.js +0 -10
- package/dist/scripts/triwiki-affected-graph-blackbox.js +0 -28
- package/dist/scripts/triwiki-proof-bank-blackbox.js +0 -30
- package/dist/scripts/triwiki-proof-bank-lock-blackbox.js +0 -7
- package/dist/scripts/update-preserves-supabase-keys-blackbox.js +0 -27
- package/dist/scripts/ux-patch-swarm-route-blackbox.js +0 -10
- package/dist/scripts/ux-review-imagegen-blackbox-check.js +0 -67
- package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -28
- package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -80
- package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -137
- package/dist/scripts/zellij-self-heal-typed-blackbox.js +0 -4
- package/dist/scripts/zellij-slot-telemetry-real-blackbox.js +0 -20
- package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -81
- package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -202
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { projectRoot, readJson, readText, writeJsonAtomic, appendJsonl, readStdin, nowIso, runProcess, sha256, packageRoot, tmpdir } from './fsx.js';
|
|
3
3
|
import { looksInteractiveCommand, interactiveCommandReason } from './no-question-guard.js';
|
|
4
|
-
import { missionDir, setCurrent
|
|
4
|
+
import { loadStateForSession, missionDir, setCurrent } from './mission.js';
|
|
5
5
|
import { checkDbOperation, dbBlockReason, handleMadSksUserConfirmation } from './db-safety.js';
|
|
6
6
|
import { maybeRecordMadDbToolResultFromToolUse } from './mad-db/mad-db-result-lifecycle.js';
|
|
7
7
|
import { checkHarnessModification, harnessGuardBlockReason, isHarnessSourceProject } from './harness-guard.js';
|
|
@@ -16,6 +16,8 @@ import { leanEngineeringCompactText } from './lean-engineering-policy.js';
|
|
|
16
16
|
import { appendMissionStatus } from './recallpulse.js';
|
|
17
17
|
import { scanAgentTextForRecursion } from './agents/agent-recursion-guard.js';
|
|
18
18
|
import { evaluateLoopContinuation } from './loops/loop-continuation-enforcer.js';
|
|
19
|
+
import { diagnosticPromptAllowedDuringNoQuestions } from './routes/diagnostic-allowlist.js';
|
|
20
|
+
import { maybeReconcileProjectSkillsPreflight } from './hooks-runtime/skill-reconcile-preflight.js';
|
|
19
21
|
import { buildCompactContinue, buildPermissionRequestAllow, buildPermissionRequestDeny, buildPostToolUseBlock, buildPostToolUseContinue, buildPreToolUseContinue, buildPreToolUseDeny, buildSessionStartContinue, buildStopBlock, buildStopContinue, buildSubagentStartContinue, buildSubagentStopBlock, buildSubagentStopContinue, buildUserPromptSubmitBlock, buildUserPromptSubmitContinue } from './codex-compat/codex-hook-output-builders.js';
|
|
20
22
|
import { joinSystemMessages, teamLiveDigest } from './hooks-runtime/team-digest.js';
|
|
21
23
|
const STOP_REPEAT_GUARD_ARTIFACT = 'stop-hook-repeat-guard.json';
|
|
@@ -38,8 +40,8 @@ async function loadHookPayload() {
|
|
|
38
40
|
return { raw };
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
|
-
async function loadState(root) {
|
|
42
|
-
return
|
|
43
|
+
async function loadState(root, payload = {}) {
|
|
44
|
+
return loadStateForSession(root, conversationId(payload));
|
|
43
45
|
}
|
|
44
46
|
function isNoQuestionRunning(state) {
|
|
45
47
|
return (state.mode === 'RESEARCH' && state.phase === 'RESEARCH_RUNNING_NO_QUESTIONS')
|
|
@@ -61,6 +63,9 @@ function extractUserPrompt(payload) {
|
|
|
61
63
|
function conversationId(payload) {
|
|
62
64
|
return String(payload.conversation_id || payload.thread_id || payload.session_id || payload.chat_id || payload.cwd || 'default');
|
|
63
65
|
}
|
|
66
|
+
function explicitConversationId(payload = {}) {
|
|
67
|
+
return payload.conversation_id || payload.thread_id || payload.session_id || payload.chat_id || null;
|
|
68
|
+
}
|
|
64
69
|
function extractCommand(payload) {
|
|
65
70
|
return payload.command || payload.tool_input?.command || payload.toolInput?.command || payload.input?.command || payload.tool?.input?.command || '';
|
|
66
71
|
}
|
|
@@ -176,27 +181,39 @@ export async function hookMain(name) {
|
|
|
176
181
|
}
|
|
177
182
|
export async function evaluateHookPayload(name, payload = {}, opts = {}) {
|
|
178
183
|
const root = opts.root || await projectRoot(payload.cwd || process.cwd());
|
|
179
|
-
const
|
|
184
|
+
const sessionKey = conversationId(payload);
|
|
185
|
+
if (!explicitConversationId(payload)) {
|
|
186
|
+
await appendJsonl(path.join(root, '.sneakoscope', 'state', 'session-id-fallback-warning.jsonl'), {
|
|
187
|
+
ts: nowIso(),
|
|
188
|
+
warning: 'hook_payload_missing_explicit_session_id',
|
|
189
|
+
conversation_id: sessionKey,
|
|
190
|
+
cwd_hash: sha256(String(payload.cwd || root)).slice(0, 12),
|
|
191
|
+
hook: name
|
|
192
|
+
}).catch(() => null);
|
|
193
|
+
}
|
|
194
|
+
const loadedState = opts.state || payload.state || await loadState(root, payload);
|
|
195
|
+
const state = { ...loadedState, _session_key: loadedState?._session_key || sessionKey };
|
|
180
196
|
const noQuestion = isNoQuestionRunning(state);
|
|
181
197
|
if (name === 'user-prompt-submit') {
|
|
182
198
|
const modelBlock = blockForbiddenClientModel(payload);
|
|
183
199
|
if (modelBlock)
|
|
184
200
|
return modelBlock;
|
|
185
|
-
return hookUserPrompt(root, state, payload, noQuestion);
|
|
201
|
+
return hookUserPrompt(root, state, payload, noQuestion, sessionKey);
|
|
186
202
|
}
|
|
187
203
|
if (name === 'pre-tool')
|
|
188
|
-
return hookPreTool(root, state, payload, noQuestion);
|
|
204
|
+
return hookPreTool(root, state, payload, noQuestion, sessionKey);
|
|
189
205
|
if (name === 'post-tool')
|
|
190
|
-
return hookPostTool(root, state, payload, noQuestion);
|
|
206
|
+
return hookPostTool(root, state, payload, noQuestion, sessionKey);
|
|
191
207
|
if (name === 'permission-request')
|
|
192
|
-
return hookPermission(root, state, payload, noQuestion);
|
|
208
|
+
return hookPermission(root, state, payload, noQuestion, sessionKey);
|
|
193
209
|
if (name === 'stop')
|
|
194
|
-
return hookStop(root, state, payload, noQuestion);
|
|
210
|
+
return hookStop(root, state, payload, noQuestion, sessionKey);
|
|
195
211
|
if (name === 'subagent-start')
|
|
196
|
-
return hookSubagentStart(root, state);
|
|
212
|
+
return hookSubagentStart(root, state, sessionKey);
|
|
197
213
|
return { continue: true };
|
|
198
214
|
}
|
|
199
|
-
async function hookSubagentStart(root, state) {
|
|
215
|
+
async function hookSubagentStart(root, state, sessionKey = null) {
|
|
216
|
+
void sessionKey;
|
|
200
217
|
const active = await activeRouteContext(root, state).catch(() => '');
|
|
201
218
|
const additionalContext = [leanEngineeringCompactText(), active].filter(Boolean).join('\n\n');
|
|
202
219
|
return { continue: true, additionalContext };
|
|
@@ -265,7 +282,7 @@ function clientModelCandidates(value, depth = 0) {
|
|
|
265
282
|
}
|
|
266
283
|
return out;
|
|
267
284
|
}
|
|
268
|
-
async function hookUserPrompt(root, state, payload, noQuestion) {
|
|
285
|
+
async function hookUserPrompt(root, state, payload, noQuestion, sessionKey = null) {
|
|
269
286
|
if (looksLikeCodexGitAction(payload)) {
|
|
270
287
|
await armCodexGitActionStopBypass(root, payload).catch(() => null);
|
|
271
288
|
return {
|
|
@@ -279,6 +296,7 @@ async function hookUserPrompt(root, state, payload, noQuestion) {
|
|
|
279
296
|
systemMessage: 'SKS: Codex App settings/profile event ignored; route gates unchanged.'
|
|
280
297
|
};
|
|
281
298
|
}
|
|
299
|
+
await maybeReconcileProjectSkillsPreflight(root).catch(() => null);
|
|
282
300
|
if (!noQuestion) {
|
|
283
301
|
const prompt = stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload));
|
|
284
302
|
const madSksConfirmation = await handleMadSksUserConfirmation(root, state, prompt);
|
|
@@ -311,12 +329,13 @@ async function hookUserPrompt(root, state, payload, noQuestion) {
|
|
|
311
329
|
return { continue: true, additionalContext, systemMessage: joinSystemMessages(visibleHookMessage('user-prompt-submit', additionalContext), teamDigest?.system) };
|
|
312
330
|
}
|
|
313
331
|
const teamDigest = (bypassActiveRoute || command || prepareFreshRoute) ? null : await teamLiveDigest(root, state);
|
|
314
|
-
const
|
|
332
|
+
const shouldLoadActiveContext = !command && !bypassActiveRoute && !goalOverlay && !prepareFreshRoute;
|
|
333
|
+
const activeContext = shouldLoadActiveContext ? await activeRouteContext(root, state) : '';
|
|
315
334
|
const contexts = [updateContext];
|
|
316
|
-
if (activeContext &&
|
|
335
|
+
if (activeContext && shouldLoadActiveContext)
|
|
317
336
|
contexts.push(routePipelineContext(prompt), activeContext);
|
|
318
337
|
else
|
|
319
|
-
contexts.push((await prepareRoute(root, prompt, state)).additionalContext);
|
|
338
|
+
contexts.push((await prepareRoute(root, prompt, state, { sessionKey })).additionalContext);
|
|
320
339
|
if (goalOverlay)
|
|
321
340
|
contexts.push(goalOverlay);
|
|
322
341
|
if (teamDigest?.context)
|
|
@@ -324,6 +343,13 @@ async function hookUserPrompt(root, state, payload, noQuestion) {
|
|
|
324
343
|
const additionalContext = contexts.filter(Boolean).join('\n\n');
|
|
325
344
|
return { continue: true, additionalContext, systemMessage: joinSystemMessages(visibleHookMessage('user-prompt-submit', additionalContext), teamDigest?.system) };
|
|
326
345
|
}
|
|
346
|
+
const prompt = stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload));
|
|
347
|
+
if (diagnosticPromptAllowedDuringNoQuestions(prompt)) {
|
|
348
|
+
return {
|
|
349
|
+
continue: true,
|
|
350
|
+
systemMessage: 'SKS: diagnostic command allowed during no-question mode by command registry contract.'
|
|
351
|
+
};
|
|
352
|
+
}
|
|
327
353
|
const id = state.mission_id;
|
|
328
354
|
if (id)
|
|
329
355
|
await appendJsonl(path.join(missionDir(root, id), 'user_queue.jsonl'), { ts: nowIso(), payload });
|
|
@@ -380,18 +406,21 @@ function activeGoalOverlayContext(state = {}, route = null) {
|
|
|
380
406
|
`Goal artifact: .sneakoscope/missions/${state.mission_id}/goal-workflow.json. Use Codex native /goal controls only if the user explicitly returns to $Goal.`
|
|
381
407
|
].join('\n');
|
|
382
408
|
}
|
|
383
|
-
async function hookPreTool(root, state, payload, noQuestion) {
|
|
384
|
-
|
|
385
|
-
if (
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
409
|
+
async function hookPreTool(root, state, payload, noQuestion, sessionKey = null) {
|
|
410
|
+
void sessionKey;
|
|
411
|
+
if (needsMutationSafetyCheck(payload)) {
|
|
412
|
+
const madSksImmutableDecision = await checkMadSksImmutableModification(root, state, payload);
|
|
413
|
+
if (madSksImmutableDecision.action === 'block') {
|
|
414
|
+
return { decision: 'block', permissionDecision: 'deny', reason: madSksImmutableBlockReason(madSksImmutableDecision) };
|
|
415
|
+
}
|
|
416
|
+
const harnessDecision = await checkHarnessModification(root, payload, { phase: 'pre-tool' });
|
|
417
|
+
if (harnessDecision.action === 'block') {
|
|
418
|
+
return { decision: 'block', permissionDecision: 'deny', reason: harnessGuardBlockReason(harnessDecision) };
|
|
419
|
+
}
|
|
420
|
+
const dbDecision = await checkDbOperation(root, state, payload, { duringNoQuestion: noQuestion });
|
|
421
|
+
if (dbDecision.action === 'block' || dbDecision.action === 'confirm') {
|
|
422
|
+
return { decision: 'block', permissionDecision: 'deny', reason: dbBlockReason(dbDecision) };
|
|
423
|
+
}
|
|
395
424
|
}
|
|
396
425
|
if (clarificationGateLocked(state) && !clarificationAnswerToolAllowed(payload)) {
|
|
397
426
|
return { decision: 'block', permissionDecision: 'deny', reason: clarificationPauseBlockReason(state) };
|
|
@@ -430,12 +459,14 @@ function agentWorkerHookContext(state = {}, payload = {}) {
|
|
|
430
459
|
|| payload.agent_worker === true
|
|
431
460
|
|| payload.agentWorker === true);
|
|
432
461
|
}
|
|
433
|
-
async function hookPostTool(root, state, payload, noQuestion) {
|
|
434
|
-
|
|
435
|
-
await
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
462
|
+
async function hookPostTool(root, state, payload, noQuestion, sessionKey = null) {
|
|
463
|
+
state = { ...state, _session_key: state?._session_key || sessionKey };
|
|
464
|
+
await Promise.all([
|
|
465
|
+
recordMadDbPostToolLifecycle(root, state, payload).catch(() => null),
|
|
466
|
+
recordContext7Evidence(root, state, payload).catch(() => null),
|
|
467
|
+
recordSubagentEvidence(root, state, payload).catch(() => null),
|
|
468
|
+
toolFailed(payload) ? recordToolErrorTaxonomy(root, state, payload).catch(() => null) : Promise.resolve(null)
|
|
469
|
+
]);
|
|
439
470
|
const teamDigest = await teamLiveDigest(root, state);
|
|
440
471
|
if (!noQuestion) {
|
|
441
472
|
return teamDigest?.context
|
|
@@ -455,6 +486,17 @@ async function hookPostTool(root, state, payload, noQuestion) {
|
|
|
455
486
|
? { continue: true, additionalContext: teamDigest.context, systemMessage: joinSystemMessages(visibleHookMessage('post-tool'), teamDigest.system) }
|
|
456
487
|
: { continue: true };
|
|
457
488
|
}
|
|
489
|
+
function needsMutationSafetyCheck(payload = {}) {
|
|
490
|
+
const toolName = String(payload.tool_name || payload.toolName || payload.name || payload.tool?.name || '');
|
|
491
|
+
const knownReadOnly = /^(Read|Grep|Glob|LS|TodoRead|WebFetch|WebSearch|BashOutput|NotebookRead|ListMcpResources|ReadMcpResource)$/i;
|
|
492
|
+
if (knownReadOnly.test(toolName))
|
|
493
|
+
return /\b(sql|supabase|db|migration)\b/i.test(JSON.stringify(payload || {}));
|
|
494
|
+
if (/^(Edit|Write|MultiEdit|NotebookEdit|Bash|Shell|ApplyPatch)$/i.test(toolName))
|
|
495
|
+
return true;
|
|
496
|
+
if (/\b(sql|supabase|db|migration)\b/i.test(toolName))
|
|
497
|
+
return true;
|
|
498
|
+
return true;
|
|
499
|
+
}
|
|
458
500
|
async function recordMadDbPostToolLifecycle(root, state = {}, payload = {}) {
|
|
459
501
|
if (!state?.mission_id)
|
|
460
502
|
return null;
|
|
@@ -508,7 +550,8 @@ async function recordToolErrorTaxonomy(root, state = {}, payload = {}) {
|
|
|
508
550
|
await appendJsonl(path.join(missionDir(root, state.mission_id), 'tool-errors.jsonl'), record);
|
|
509
551
|
return record;
|
|
510
552
|
}
|
|
511
|
-
async function hookPermission(root, state, payload, noQuestion) {
|
|
553
|
+
async function hookPermission(root, state, payload, noQuestion, sessionKey = null) {
|
|
554
|
+
void sessionKey;
|
|
512
555
|
const madSksImmutableDecision = await checkMadSksImmutableModification(root, state, payload);
|
|
513
556
|
if (madSksImmutableDecision.action === 'block') {
|
|
514
557
|
return { decision: 'deny', permissionDecision: 'deny', reason: madSksImmutableBlockReason(madSksImmutableDecision) };
|
|
@@ -610,7 +653,7 @@ function clarificationPauseBlockReason(state = {}) {
|
|
|
610
653
|
const route = state.route_command || state.route || state.mode || 'route';
|
|
611
654
|
return `SKS ${route} ambiguity gate is paused and waiting for explicit user answers. Do not run implementation, tests, route materialization, or unrelated tools yet. The only allowed action is sealing the user's reply with "sks pipeline answer ${id} --stdin"; elapsed time or repeated hook resumes never count as answers.`;
|
|
612
655
|
}
|
|
613
|
-
async function hookStop(root, state, payload, noQuestion) {
|
|
656
|
+
async function hookStop(root, state, payload, noQuestion, sessionKey = null) {
|
|
614
657
|
const last = extractLastMessage(payload);
|
|
615
658
|
if (state?.mode === 'LOOP' || state?.route === 'Loop' || state?.route_command === '$Loop') {
|
|
616
659
|
const missionId = state?.mission_id;
|
|
@@ -664,14 +707,14 @@ async function hookStop(root, state, payload, noQuestion) {
|
|
|
664
707
|
};
|
|
665
708
|
}
|
|
666
709
|
if (shouldLoopBackAfterHonestMode(state) && hasHonestModeUnresolvedGap(last)) {
|
|
667
|
-
const loopback = await recordHonestModeLoopback(root, state, last);
|
|
710
|
+
const loopback = await recordHonestModeLoopback(root, state, last, sessionKey);
|
|
668
711
|
return {
|
|
669
712
|
decision: 'block',
|
|
670
713
|
reason: `${localizedFinalizationReason('honest_loopback', languageBasis)} Loopback: ${loopback.relative_file}`
|
|
671
714
|
};
|
|
672
715
|
}
|
|
673
716
|
if (state?.honest_loop_required)
|
|
674
|
-
await resolveHonestModeLoopback(root, state);
|
|
717
|
+
await resolveHonestModeLoopback(root, state, sessionKey);
|
|
675
718
|
return { continue: true };
|
|
676
719
|
}
|
|
677
720
|
return {
|
|
@@ -691,7 +734,7 @@ async function consumeLightRouteStop(root, payload = {}) {
|
|
|
691
734
|
if (!Number.isFinite(expiresMs) || expiresMs < nowMs)
|
|
692
735
|
return false;
|
|
693
736
|
const currentConversation = conversationId(payload);
|
|
694
|
-
if (record.conversation_id &&
|
|
737
|
+
if (record.conversation_id && record.conversation_id !== currentConversation)
|
|
695
738
|
return false;
|
|
696
739
|
await writeJsonAtomic(file, {
|
|
697
740
|
...record,
|
|
@@ -712,9 +755,6 @@ function hasDfixLightCompletion(text) {
|
|
|
712
755
|
const gap = /(미검증|남은|문제|gap|remaining|not verified|not run|blocker|차단|불가|없음|none)/i.test(s);
|
|
713
756
|
return verification && gap;
|
|
714
757
|
}
|
|
715
|
-
function explicitConversationId(payload = {}) {
|
|
716
|
-
return payload.conversation_id || payload.thread_id || payload.session_id || payload.chat_id || null;
|
|
717
|
-
}
|
|
718
758
|
function looksLikeCodexGitAction(payload = {}) {
|
|
719
759
|
const prompt = stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload));
|
|
720
760
|
const metadataText = codexGitActionMetadataText(payload);
|
|
@@ -824,7 +864,7 @@ async function consumeCodexGitActionStopBypass(root, payload = {}) {
|
|
|
824
864
|
if (!Number.isFinite(expiresMs) || expiresMs < Date.now())
|
|
825
865
|
return false;
|
|
826
866
|
const currentConversation = conversationId(payload);
|
|
827
|
-
if (record.conversation_id &&
|
|
867
|
+
if (record.conversation_id && record.conversation_id !== currentConversation)
|
|
828
868
|
return false;
|
|
829
869
|
await writeJsonAtomic(file, {
|
|
830
870
|
...record,
|
|
@@ -971,7 +1011,7 @@ function shouldLoopBackAfterHonestMode(state = {}) {
|
|
|
971
1011
|
return false;
|
|
972
1012
|
return Boolean(state.ambiguity_gate_passed || state.clarification_passed || /CONTRACT_SEALED|HONEST_LOOPBACK/i.test(String(state.phase || '')));
|
|
973
1013
|
}
|
|
974
|
-
async function recordHonestModeLoopback(root, state = {}, lastMessage = '') {
|
|
1014
|
+
async function recordHonestModeLoopback(root, state = {}, lastMessage = '', sessionKey = null) {
|
|
975
1015
|
const id = state.mission_id;
|
|
976
1016
|
const dir = missionDir(root, id);
|
|
977
1017
|
const previousPhase = state.phase || null;
|
|
@@ -999,10 +1039,10 @@ async function recordHonestModeLoopback(root, state = {}, lastMessage = '') {
|
|
|
999
1039
|
questions_allowed: false,
|
|
1000
1040
|
ambiguity_gate_required: true,
|
|
1001
1041
|
ambiguity_gate_passed: true
|
|
1002
|
-
});
|
|
1042
|
+
}, { sessionKey: sessionKey || state._session_key });
|
|
1003
1043
|
return { file, relative_file: path.relative(root, file).split(path.sep).join('/') };
|
|
1004
1044
|
}
|
|
1005
|
-
async function resolveHonestModeLoopback(root, state = {}) {
|
|
1045
|
+
async function resolveHonestModeLoopback(root, state = {}, sessionKey = null) {
|
|
1006
1046
|
const id = state.mission_id;
|
|
1007
1047
|
const mode = String(state.mode || state.route || 'SKS').toUpperCase();
|
|
1008
1048
|
if (id)
|
|
@@ -1012,7 +1052,7 @@ async function resolveHonestModeLoopback(root, state = {}) {
|
|
|
1012
1052
|
honest_loop_required: false,
|
|
1013
1053
|
honest_loop_resolved_at: nowIso(),
|
|
1014
1054
|
questions_allowed: true
|
|
1015
|
-
});
|
|
1055
|
+
}, { sessionKey: sessionKey || state._session_key });
|
|
1016
1056
|
}
|
|
1017
1057
|
export async function emitHook(name) {
|
|
1018
1058
|
const result = await hookMain(name);
|
|
@@ -107,6 +107,7 @@ export function createCodexAppImagegenAdapter(opts = {}) {
|
|
|
107
107
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
108
108
|
created_at: nowIso(),
|
|
109
109
|
provider: 'codex_app_imagegen',
|
|
110
|
+
evidence_class: 'codex_app_imagegen',
|
|
110
111
|
model: 'gpt-image-2',
|
|
111
112
|
ok: false,
|
|
112
113
|
status: 'blocked',
|
|
@@ -131,11 +132,13 @@ export function createCodexAppImagegenAdapter(opts = {}) {
|
|
|
131
132
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
132
133
|
created_at: nowIso(),
|
|
133
134
|
provider: 'codex_app_imagegen',
|
|
135
|
+
evidence_class: 'codex_app_imagegen',
|
|
134
136
|
model: 'gpt-image-2',
|
|
135
137
|
ok: true,
|
|
136
138
|
status: 'generated',
|
|
137
139
|
output_image_path: dest,
|
|
138
140
|
output_image_sha256: meta.sha256,
|
|
141
|
+
output_sha256: meta.sha256,
|
|
139
142
|
output_id: meta.output_id,
|
|
140
143
|
output_source: outputSource,
|
|
141
144
|
image_artifact_path_contract: imageContract?.artifact_path || null,
|
|
@@ -161,6 +164,7 @@ export function createCodexAppImagegenAdapter(opts = {}) {
|
|
|
161
164
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
162
165
|
created_at: nowIso(),
|
|
163
166
|
provider: 'codex_app_imagegen',
|
|
167
|
+
evidence_class: 'codex_app_imagegen',
|
|
164
168
|
model: 'gpt-image-2',
|
|
165
169
|
ok: false,
|
|
166
170
|
status: 'blocked',
|
|
@@ -196,6 +200,22 @@ export function createFakeImagegenAdapter(opts = {}) {
|
|
|
196
200
|
await ensureDir(input.output_dir);
|
|
197
201
|
const requestArtifact = path.join(input.output_dir, 'image-ux-gpt-image-2-request.json');
|
|
198
202
|
const responseArtifact = path.join(input.output_dir, 'image-ux-gpt-image-2-response.json');
|
|
203
|
+
if (!imagegenMockContext(opts)) {
|
|
204
|
+
await writeJsonAtomic(responseArtifact, {
|
|
205
|
+
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
206
|
+
created_at: nowIso(),
|
|
207
|
+
provider: 'fake_imagegen_adapter',
|
|
208
|
+
fake_adapter: true,
|
|
209
|
+
execution_class: 'mock_fixture',
|
|
210
|
+
evidence_class: 'mock_fixture',
|
|
211
|
+
model: 'gpt-image-2',
|
|
212
|
+
ok: false,
|
|
213
|
+
status: 'blocked',
|
|
214
|
+
blocker: 'fake_imagegen_requires_test_or_mock_context',
|
|
215
|
+
local_only: true
|
|
216
|
+
});
|
|
217
|
+
return { ok: false, status: 'blocked', generated_image_path: null, output_id: null, blocker: 'fake_imagegen_requires_test_or_mock_context', provider: 'fake_imagegen_adapter', request_artifact: null, response_artifact: responseArtifact, latency_ms: Date.now() - started };
|
|
218
|
+
}
|
|
199
219
|
const validation = await validateGptImage2Request({
|
|
200
220
|
provider: 'fake_imagegen_adapter',
|
|
201
221
|
endpoint: 'local hermetic fixture',
|
|
@@ -227,6 +247,9 @@ export function createFakeImagegenAdapter(opts = {}) {
|
|
|
227
247
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
228
248
|
created_at: nowIso(),
|
|
229
249
|
provider: 'fake_imagegen_adapter',
|
|
250
|
+
fake_adapter: true,
|
|
251
|
+
execution_class: 'mock_fixture',
|
|
252
|
+
evidence_class: 'mock_fixture',
|
|
230
253
|
model: 'gpt-image-2',
|
|
231
254
|
ok: false,
|
|
232
255
|
status: 'blocked',
|
|
@@ -251,16 +274,20 @@ export function createFakeImagegenAdapter(opts = {}) {
|
|
|
251
274
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
252
275
|
created_at: nowIso(),
|
|
253
276
|
provider: 'fake_imagegen_adapter',
|
|
277
|
+
fake_adapter: true,
|
|
278
|
+
execution_class: 'mock_fixture',
|
|
279
|
+
evidence_class: 'mock_fixture',
|
|
254
280
|
model: 'gpt-image-2',
|
|
255
281
|
ok: true,
|
|
256
282
|
status: 'generated',
|
|
257
283
|
output_image_path: out,
|
|
258
284
|
output_image_sha256: meta.sha256,
|
|
285
|
+
output_sha256: meta.sha256,
|
|
259
286
|
output_id: meta.output_id,
|
|
287
|
+
output_source: 'mock_fixture',
|
|
260
288
|
image_artifact_path_contract: imageContract?.artifact_path || null,
|
|
261
289
|
dimensions: { width: meta.width, height: meta.height, format: meta.format },
|
|
262
290
|
latency_ms: Date.now() - started,
|
|
263
|
-
fake_adapter: true,
|
|
264
291
|
source: 'mock_like_fixture',
|
|
265
292
|
real_generated: false,
|
|
266
293
|
mock: true,
|
|
@@ -320,6 +347,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
320
347
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
321
348
|
created_at: nowIso(),
|
|
322
349
|
provider: 'openai_images_api',
|
|
350
|
+
evidence_class: 'non_codex_api_fallback',
|
|
323
351
|
model: 'gpt-image-2',
|
|
324
352
|
ok: false,
|
|
325
353
|
status: 'blocked',
|
|
@@ -334,6 +362,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
334
362
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
335
363
|
created_at: nowIso(),
|
|
336
364
|
provider: 'openai_images_api',
|
|
365
|
+
evidence_class: 'non_codex_api_fallback',
|
|
337
366
|
model: 'gpt-image-2',
|
|
338
367
|
ok: false,
|
|
339
368
|
status: 'blocked',
|
|
@@ -397,6 +426,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
397
426
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
398
427
|
created_at: nowIso(),
|
|
399
428
|
provider: 'openai_responses_image_generation',
|
|
429
|
+
evidence_class: 'non_codex_api_fallback',
|
|
400
430
|
model: 'gpt-image-2',
|
|
401
431
|
responses_model: responsesImagegenModel(opts),
|
|
402
432
|
auth_source: auth.auth_source,
|
|
@@ -404,6 +434,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
404
434
|
status: 'generated',
|
|
405
435
|
output_image_path: out,
|
|
406
436
|
output_image_sha256: meta.sha256,
|
|
437
|
+
output_sha256: meta.sha256,
|
|
407
438
|
output_id: meta.output_id,
|
|
408
439
|
image_artifact_path_contract: imageContract?.artifact_path || null,
|
|
409
440
|
dimensions: { width: meta.width, height: meta.height, format: meta.format },
|
|
@@ -454,12 +485,14 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
|
|
|
454
485
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
455
486
|
created_at: nowIso(),
|
|
456
487
|
provider: 'openai_images_api',
|
|
488
|
+
evidence_class: 'non_codex_api_fallback',
|
|
457
489
|
model: 'gpt-image-2',
|
|
458
490
|
auth_source: auth.auth_source,
|
|
459
491
|
ok: true,
|
|
460
492
|
status: 'generated',
|
|
461
493
|
output_image_path: out,
|
|
462
494
|
output_image_sha256: meta.sha256,
|
|
495
|
+
output_sha256: meta.sha256,
|
|
463
496
|
output_id: meta.output_id,
|
|
464
497
|
image_artifact_path_contract: imageContract?.artifact_path || null,
|
|
465
498
|
dimensions: { width: meta.width, height: meta.height, format: meta.format },
|
|
@@ -511,24 +544,17 @@ async function resolveImageArtifactRoot(input) {
|
|
|
511
544
|
return projectRoot(input.output_dir || process.cwd()).catch(() => cwdRoot);
|
|
512
545
|
}
|
|
513
546
|
export async function generateGptImage2CalloutReview(input, opts = {}) {
|
|
514
|
-
if (opts.fake === true || process.env.SKS_TEST_FAKE_IMAGEGEN === '1') {
|
|
515
|
-
return createFakeImagegenAdapter(opts.fakeAdapter || {}).generateCalloutReview(input);
|
|
547
|
+
if ((opts.fake === true || process.env.SKS_TEST_FAKE_IMAGEGEN === '1') && imagegenMockContext(opts)) {
|
|
548
|
+
return createFakeImagegenAdapter({ ...(opts.fakeAdapter || {}), mockContext: true }).generateCalloutReview(input);
|
|
516
549
|
}
|
|
517
550
|
const capability = await detectImagegenCapability(opts.capability || {}).catch(() => null);
|
|
518
|
-
// Auto-enable the OpenAI direct-key API fallback whenever an OPENAI_API_KEY is
|
|
519
|
-
// available, so a missing/failed Codex App $imagegen surface still produces a
|
|
520
|
-
// real image instead of a hard block. Explicit opt-out wins: pass
|
|
521
|
-
// allowApiFallback:false or SKS_IMAGEGEN_ALLOW_API_FALLBACK=0.
|
|
522
|
-
const openAiKeyPresent = Boolean(opts.openai?.apiKey || process.env.OPENAI_API_KEY);
|
|
523
|
-
const explicitDisableApiFallback = opts.allowApiFallback === false || process.env.SKS_IMAGEGEN_ALLOW_API_FALLBACK === '0';
|
|
524
551
|
// codex-lb imagegen is a direct API fallback, not Codex App imagegen evidence.
|
|
525
552
|
// It must be explicitly enabled by the caller or environment.
|
|
526
553
|
const explicitDisableCodexLbFallback = opts.allowCodexLbApiFallback === false || process.env.SKS_IMAGEGEN_ALLOW_CODEX_LB_API_FALLBACK === '0';
|
|
527
554
|
const allowCodexLbApiFallback = !explicitDisableCodexLbFallback && (opts.allowCodexLbApiFallback === true
|
|
528
555
|
|| process.env.SKS_IMAGEGEN_ALLOW_CODEX_LB_API_FALLBACK === '1');
|
|
529
|
-
const allowApiFallback =
|
|
556
|
+
const allowApiFallback = (opts.allowApiFallback === true
|
|
530
557
|
|| process.env.SKS_IMAGEGEN_ALLOW_API_FALLBACK === '1'
|
|
531
|
-
|| openAiKeyPresent
|
|
532
558
|
|| allowCodexLbApiFallback);
|
|
533
559
|
const openaiOptions = {
|
|
534
560
|
...(opts.openai || {}),
|
|
@@ -544,6 +570,13 @@ export async function generateGptImage2CalloutReview(input, opts = {}) {
|
|
|
544
570
|
return codexResult;
|
|
545
571
|
return createOpenAIImagesApiAdapter(openaiOptions).generateCalloutReview(input);
|
|
546
572
|
}
|
|
573
|
+
function imagegenMockContext(opts = {}) {
|
|
574
|
+
return opts.mockContext === true
|
|
575
|
+
|| opts.testContext === true
|
|
576
|
+
|| process.env.NODE_ENV === 'test'
|
|
577
|
+
|| process.env.SKS_SELFTEST_MOCK === '1'
|
|
578
|
+
|| process.env.SKS_MOCK === '1';
|
|
579
|
+
}
|
|
547
580
|
export function imagegenCapabilityBlocker(surface = 'Codex App $imagegen') {
|
|
548
581
|
return {
|
|
549
582
|
schema: 'sks.image-ux-imagegen-blocker.v1',
|
|
@@ -705,6 +738,9 @@ export async function generatedImageMetadata(root, imagePath, opts = {}) {
|
|
|
705
738
|
source_screen_id: opts.source_screen_id || null,
|
|
706
739
|
provider_model: 'gpt-image-2',
|
|
707
740
|
provider_surface: opts.provider_surface || 'codex_app_imagegen',
|
|
741
|
+
evidence_class: opts.evidence_class || (opts.mock ? 'mock_fixture' : 'codex_app_imagegen'),
|
|
742
|
+
output_source: opts.output_source || (opts.mock ? 'mock_fixture' : 'manual_attach'),
|
|
743
|
+
output_sha256: opts.output_sha256 || await sha256File(absolute),
|
|
708
744
|
requested_fidelity: 'high_fidelity_automatic',
|
|
709
745
|
image_input_fidelity_note: 'high_fidelity_automatic',
|
|
710
746
|
privacy: 'local-only',
|
|
@@ -729,6 +765,7 @@ function redactedImagegenResponse(payload, ok, latencyMs, provider = 'openai_ima
|
|
|
729
765
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
730
766
|
created_at: nowIso(),
|
|
731
767
|
provider,
|
|
768
|
+
evidence_class: provider === 'codex_app_imagegen' ? 'codex_app_imagegen' : 'non_codex_api_fallback',
|
|
732
769
|
model: 'gpt-image-2',
|
|
733
770
|
ok,
|
|
734
771
|
status: ok ? 'generated' : 'blocked',
|
|
@@ -790,11 +790,14 @@ function buildImagegenResponseArtifact(generatedReviewLedger = {}) {
|
|
|
790
790
|
schema: 'sks.image-ux-gpt-image-2-response.v1',
|
|
791
791
|
created_at: nowIso(),
|
|
792
792
|
provider: image?.provider_surface || generatedReviewLedger.provider?.preferred_surface || 'none',
|
|
793
|
+
evidence_class: image?.evidence_class || (image?.mock ? 'mock_fixture' : image?.real_generated ? 'codex_app_imagegen' : null),
|
|
793
794
|
model: 'gpt-image-2',
|
|
794
795
|
ok: generatedReviewLedger.passed === true,
|
|
795
796
|
status: generatedReviewLedger.passed === true ? 'generated' : 'blocked_or_pending',
|
|
796
797
|
output_image_path: image?.path || null,
|
|
797
798
|
output_image_sha256: image?.sha256 || null,
|
|
799
|
+
output_sha256: image?.output_sha256 || image?.sha256 || null,
|
|
800
|
+
output_source: image?.output_source || (image?.mock ? 'mock_fixture' : image?.real_generated ? 'manual_attach' : null),
|
|
798
801
|
output_id: image?.output_id || null,
|
|
799
802
|
dimensions: image ? { width: image.width || null, height: image.height || null, format: image.format || null } : null,
|
|
800
803
|
latency_ms: image?.latency_ms || null,
|
|
@@ -863,6 +866,19 @@ function generatedImageEvidenceBlockers(image = {}, evidence = {}) {
|
|
|
863
866
|
if (image.real_generated !== true || image.mock === true || image.source === 'mock_fixture')
|
|
864
867
|
return [];
|
|
865
868
|
const blockers = [];
|
|
869
|
+
const evidenceClass = String(image.evidence_class || '');
|
|
870
|
+
const outputSource = String(image.output_source || '');
|
|
871
|
+
const outputSha = String(image.output_sha256 || image.output_image_sha256 || '');
|
|
872
|
+
if (!evidenceClass)
|
|
873
|
+
blockers.push('generated_review_image_evidence_class_missing');
|
|
874
|
+
else if (evidenceClass !== 'codex_app_imagegen')
|
|
875
|
+
blockers.push(`generated_review_image_evidence_class_not_codex_app:${evidenceClass}`);
|
|
876
|
+
if (outputSource && !['manual_attach', 'auto_discovered_generated_images'].includes(outputSource))
|
|
877
|
+
blockers.push(`generated_review_image_output_source_invalid:${outputSource}`);
|
|
878
|
+
if (!outputSha)
|
|
879
|
+
blockers.push('generated_review_image_output_sha256_missing');
|
|
880
|
+
else if (evidence.sha256 && outputSha !== evidence.sha256)
|
|
881
|
+
blockers.push('generated_review_image_output_sha256_mismatch');
|
|
866
882
|
if (!image.path)
|
|
867
883
|
blockers.push('generated_review_image_missing');
|
|
868
884
|
if (!evidence.sha256)
|
|
@@ -18,8 +18,13 @@ export async function detectImagegenCapability(opts = {}) {
|
|
|
18
18
|
}).catch(() => null);
|
|
19
19
|
const apiFallbackAvailable = openaiApiKeyPresent;
|
|
20
20
|
const fakeAdapterEnabled = opts.fake === true || env.SKS_TEST_FAKE_IMAGEGEN === '1';
|
|
21
|
-
const
|
|
22
|
-
|
|
21
|
+
const fakeAdapterAcceptedForRoute = fakeAdapterEnabled && (opts.mockContext === true
|
|
22
|
+
|| opts.testContext === true
|
|
23
|
+
|| env.NODE_ENV === 'test'
|
|
24
|
+
|| env.SKS_SELFTEST_MOCK === '1'
|
|
25
|
+
|| env.SKS_MOCK === '1');
|
|
26
|
+
const realGenerationAvailable = codexAppBuiltInAvailable;
|
|
27
|
+
const routeGenerationAvailable = codexAppBuiltInAvailable || fakeAdapterAcceptedForRoute;
|
|
23
28
|
const coreReady = codexAppBuiltInAvailable;
|
|
24
29
|
const coreBlockers = coreReady ? [] : ['codex_app_builtin_imagegen_capability_missing'];
|
|
25
30
|
const routeGenerationBlockers = routeGenerationAvailable ? [] : ['imagegen_capability_missing'];
|
|
@@ -68,16 +73,17 @@ export async function detectImagegenCapability(opts = {}) {
|
|
|
68
73
|
},
|
|
69
74
|
fake_adapter: {
|
|
70
75
|
available: fakeAdapterEnabled,
|
|
76
|
+
accepted_for_route_readiness: fakeAdapterAcceptedForRoute,
|
|
71
77
|
env: 'SKS_TEST_FAKE_IMAGEGEN=1',
|
|
72
78
|
source: 'mock_like_fixture',
|
|
73
79
|
real_generation_claim_allowed: false
|
|
74
80
|
},
|
|
75
|
-
supports_reference_image: codexAppBuiltInAvailable ||
|
|
81
|
+
supports_reference_image: codexAppBuiltInAvailable || fakeAdapterAcceptedForRoute,
|
|
76
82
|
gpt_image_2_input_fidelity_automatic: true,
|
|
77
83
|
input_fidelity_must_be_omitted: true,
|
|
78
84
|
supported_workflows: {
|
|
79
|
-
ux_review_callouts: codexAppBuiltInAvailable ||
|
|
80
|
-
ppt_slide_callouts: codexAppBuiltInAvailable ||
|
|
85
|
+
ux_review_callouts: codexAppBuiltInAvailable || fakeAdapterAcceptedForRoute,
|
|
86
|
+
ppt_slide_callouts: codexAppBuiltInAvailable || fakeAdapterAcceptedForRoute,
|
|
81
87
|
structured_extraction_required_after_generation: true,
|
|
82
88
|
full_verification_requires_codex_app_output: true
|
|
83
89
|
},
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { detectImagegenCapability } from './imagegen-capability.js';
|
|
2
|
+
import { repairCodexImagegen } from '../doctor/imagegen-repair.js';
|
|
3
|
+
export async function requireCodexImagegen(root, opts = {}) {
|
|
4
|
+
const capability = await detectImagegenCapability({
|
|
5
|
+
codexBin: opts.codexBin || undefined,
|
|
6
|
+
timeoutMs: opts.timeoutMs || 5000
|
|
7
|
+
}).catch((err) => ({
|
|
8
|
+
ok: false,
|
|
9
|
+
core_ready: false,
|
|
10
|
+
blockers: [err instanceof Error ? err.message : String(err)]
|
|
11
|
+
}));
|
|
12
|
+
if (capability.core_ready === true) {
|
|
13
|
+
return { ok: true, capability, repair: null, blocker: null, blockers: [] };
|
|
14
|
+
}
|
|
15
|
+
const repair = opts.autoRepair === true
|
|
16
|
+
? await repairCodexImagegen({
|
|
17
|
+
root,
|
|
18
|
+
apply: opts.applyRepair === true,
|
|
19
|
+
codexBin: opts.codexBin || null,
|
|
20
|
+
timeoutMs: opts.timeoutMs || 5000
|
|
21
|
+
}).catch((err) => ({
|
|
22
|
+
ok: false,
|
|
23
|
+
recovered: false,
|
|
24
|
+
blockers: [err instanceof Error ? err.message : String(err)]
|
|
25
|
+
}))
|
|
26
|
+
: null;
|
|
27
|
+
const finalCapability = repair
|
|
28
|
+
? repair.after || capability
|
|
29
|
+
: capability;
|
|
30
|
+
const ok = finalCapability.core_ready === true || repair?.recovered === true;
|
|
31
|
+
const blockers = ok ? [] : [
|
|
32
|
+
...new Set([
|
|
33
|
+
...((finalCapability?.core_blockers || []).map(String)),
|
|
34
|
+
...((finalCapability?.blockers || []).map(String)),
|
|
35
|
+
...((repair?.blockers || []).map(String)),
|
|
36
|
+
'codex_imagegen_unavailable'
|
|
37
|
+
])
|
|
38
|
+
];
|
|
39
|
+
return {
|
|
40
|
+
ok,
|
|
41
|
+
capability: finalCapability,
|
|
42
|
+
repair,
|
|
43
|
+
blocker: ok ? null : {
|
|
44
|
+
schema: 'sks.codex-imagegen-required-blocker.v1',
|
|
45
|
+
blocker: 'codex_imagegen_unavailable',
|
|
46
|
+
status: 'blocked',
|
|
47
|
+
blockers,
|
|
48
|
+
next_actions: repair?.manual_actions || [
|
|
49
|
+
'Install/update Codex CLI: npm i -g @openai/codex@latest',
|
|
50
|
+
'Open Codex App settings and enable image_generation / $imagegen.',
|
|
51
|
+
'Verify with: codex features list --json'
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
blockers
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=require-imagegen.js.map
|