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
|
@@ -16,9 +16,20 @@ import { appendMissionStatus } from './recallpulse.js';
|
|
|
16
16
|
import { scanAgentTextForRecursion } from './agents/agent-recursion-guard.js';
|
|
17
17
|
import { evaluateLoopContinuation } from './loops/loop-continuation-enforcer.js';
|
|
18
18
|
import { diagnosticPromptAllowedDuringNoQuestions } from './routes/diagnostic-allowlist.js';
|
|
19
|
+
import { closeWorkOrderLedgerForRouteResult } from './work-order-ledger.js';
|
|
19
20
|
import { maybeReconcileProjectSkillsPreflight } from './hooks-runtime/skill-reconcile-preflight.js';
|
|
20
21
|
import { codePackFreshnessNote } from './hooks-runtime/code-pack-freshness-preflight.js';
|
|
22
|
+
import { claimHookInvocation } from './hooks-runtime/hook-invocation-dedupe.js';
|
|
21
23
|
import { joinSystemMessages, teamLiveDigest } from './hooks-runtime/team-digest.js';
|
|
24
|
+
import { armLightTurnStopBypass, clearLightTurnStopBypass, consumeLightTurnStopBypass, hasMatchingLightTurnStopBypass } from './hooks-runtime/light-turn.js';
|
|
25
|
+
import { classifyTaskProfile } from './runtime/task-profile.js';
|
|
26
|
+
import { resolveSubagentThreadBudget } from './subagents/thread-budget.js';
|
|
27
|
+
import { readOfficialSubagentConfig } from './subagents/official-subagent-config.js';
|
|
28
|
+
import { withFileLock } from './locks/file-lock.js';
|
|
29
|
+
import { NARUTO_PARENT_EFFORT, NARUTO_PARENT_MODEL } from './subagents/model-policy.js';
|
|
30
|
+
import { officialSubagentRolePlan } from './subagents/agent-catalog.js';
|
|
31
|
+
import { recordOfficialSubagentParentOutcomesTelemetry, recordOfficialSubagentZellijTelemetry } from './zellij/zellij-official-subagent-telemetry.js';
|
|
32
|
+
import { bindTrustworthySubagentParentSummaryToRun, normalizeSubagentParentSummary, persistOrReuseTrustworthySubagentParentSummary, readSubagentEvents, recordSubagentEvent, SUBAGENT_EVIDENCE_FILENAME, SUBAGENT_PARENT_SUMMARY_FILENAME, writeSubagentEvidence } from './subagents/subagent-evidence.js';
|
|
22
33
|
const STOP_REPEAT_GUARD_ARTIFACT = 'stop-hook-repeat-guard.json';
|
|
23
34
|
const LIGHT_ROUTE_STOP_ARTIFACT = 'light-route-stop.json';
|
|
24
35
|
const CODEX_GIT_ACTION_STOP_ARTIFACT = 'codex-git-action-stop-bypass.json';
|
|
@@ -31,6 +42,8 @@ const UPDATE_CHECK_HOOK_INVOCATION_POLICY = 'function-only:no-runSksUpdateCheck-
|
|
|
31
42
|
// by release readiness so ordinary Codex hook flow cannot grow a hidden update
|
|
32
43
|
// prompt path.
|
|
33
44
|
import { loadHookPayload, normalizeHookResult, visibleHookMessage } from './hooks-runtime/hook-io.js';
|
|
45
|
+
import { codexGitActionMetadataSignal, codexGitActionMetadataText, compactAnswerContext, conversationId, explicitConversationId, extractCommand, extractLastMessage, extractUserPrompt, hookTurnId, looksLikeCodexGitAction, looksLikeCodexGitActionStopCompletion, looksLikeCodexUiSettingsEvent, looksLikeMadSksConfirmationPrompt, observedParentModel, observedParentModelMismatch, toolFailed } from './hooks-runtime/payload-signals.js';
|
|
46
|
+
import { interruptedToolOutputRecoveryBlockReason, missingToolOutputCallId, missingToolOutputCallIdFromPayload, quarantineMissingToolOutput, readToolOutputQuarantine } from './hooks-runtime/tool-output-quarantine.js';
|
|
34
47
|
export { loadHookPayload, normalizeHookResult };
|
|
35
48
|
async function loadState(root, payload = {}) {
|
|
36
49
|
return loadStateForSession(root, conversationId(payload));
|
|
@@ -39,142 +52,39 @@ function isNoQuestionRunning(state) {
|
|
|
39
52
|
return (state.mode === 'RESEARCH' && state.phase === 'RESEARCH_RUNNING_NO_QUESTIONS')
|
|
40
53
|
|| (state.mode === 'QALOOP' && state.phase === 'QALOOP_RUNNING_NO_QUESTIONS');
|
|
41
54
|
}
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return payload.prompt
|
|
47
|
-
|| payload.user_prompt
|
|
48
|
-
|| payload.userPrompt
|
|
49
|
-
|| payload.message
|
|
50
|
-
|| payload.input?.prompt
|
|
51
|
-
|| payload.input?.message
|
|
52
|
-
|| payload.raw
|
|
53
|
-
|| '';
|
|
54
|
-
}
|
|
55
|
-
function conversationId(payload) {
|
|
56
|
-
return String(payload.conversation_id || payload.thread_id || payload.session_id || payload.chat_id || payload.cwd || 'default');
|
|
57
|
-
}
|
|
58
|
-
function explicitConversationId(payload = {}) {
|
|
59
|
-
return payload.conversation_id || payload.thread_id || payload.session_id || payload.chat_id || null;
|
|
60
|
-
}
|
|
61
|
-
function extractCommand(payload) {
|
|
62
|
-
return payload.command || payload.tool_input?.command || payload.toolInput?.command || payload.input?.command || payload.tool?.input?.command || '';
|
|
55
|
+
export async function hookMain(name) {
|
|
56
|
+
const payload = await loadHookPayload();
|
|
57
|
+
const root = await projectRoot(payload.cwd || process.cwd());
|
|
58
|
+
return evaluateHookPayloadOnce(name, payload, { root });
|
|
63
59
|
}
|
|
64
|
-
function
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
'action',
|
|
69
|
-
'intent',
|
|
70
|
-
'operation',
|
|
71
|
-
'permission',
|
|
72
|
-
'description',
|
|
73
|
-
'kind',
|
|
74
|
-
'type',
|
|
75
|
-
'feature',
|
|
76
|
-
'tool_name',
|
|
77
|
-
'toolName',
|
|
78
|
-
'name',
|
|
79
|
-
'label',
|
|
80
|
-
'title',
|
|
81
|
-
'source',
|
|
82
|
-
'event',
|
|
83
|
-
'hook',
|
|
84
|
-
'hook_name',
|
|
85
|
-
'hookName',
|
|
86
|
-
'hook_event_name',
|
|
87
|
-
'hookEventName',
|
|
88
|
-
'id',
|
|
89
|
-
'command'
|
|
90
|
-
]);
|
|
91
|
-
const noisy = new Set([
|
|
92
|
-
'prompt',
|
|
93
|
-
'user_prompt',
|
|
94
|
-
'userPrompt',
|
|
95
|
-
'message',
|
|
96
|
-
'assistant_message',
|
|
97
|
-
'last_assistant_message',
|
|
98
|
-
'response',
|
|
99
|
-
'raw',
|
|
100
|
-
'stdout',
|
|
101
|
-
'stderr'
|
|
102
|
-
]);
|
|
103
|
-
function walk(value, depth = 0, parentKey = '') {
|
|
104
|
-
if (!value || typeof value !== 'object' || depth > 5 || seen.has(value))
|
|
105
|
-
return;
|
|
106
|
-
seen.add(value);
|
|
107
|
-
for (const [key, candidate] of Object.entries(value)) {
|
|
108
|
-
if (noisy.has(key))
|
|
109
|
-
continue;
|
|
110
|
-
if (typeof candidate === 'string') {
|
|
111
|
-
if (interesting.has(key) || /\b(?:codex[_\s-]*app|git[_\s-]*actions?|codex_git_|gitCommit|gitPush|pull\s+request)\b/i.test(candidate)) {
|
|
112
|
-
out.push(`${key}:${candidate}`);
|
|
113
|
-
}
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
if (candidate && typeof candidate === 'object') {
|
|
117
|
-
const allowedContainer = interesting.has(key)
|
|
118
|
-
|| /^(?:input|metadata|context|client|thread|session|request|payload|tool|tool_input|toolInput|permission_request|permissionRequest)$/i.test(key)
|
|
119
|
-
|| parentKey;
|
|
120
|
-
if (allowedContainer)
|
|
121
|
-
walk(candidate, depth + 1, key);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
60
|
+
export async function evaluateHookPayloadOnce(name, payload = {}, opts = {}) {
|
|
61
|
+
const root = opts.root || await projectRoot(payload.cwd || process.cwd());
|
|
62
|
+
if (name === 'user-prompt-submit' && hookPayloadIsLightTurnCandidate(payload)) {
|
|
63
|
+
return evaluateHookPayload(name, payload, { root });
|
|
124
64
|
}
|
|
125
|
-
|
|
126
|
-
|
|
65
|
+
const claim = await claimHookInvocation(root, name, payload).catch(() => ({ duplicate: false }));
|
|
66
|
+
if (claim.duplicate)
|
|
67
|
+
return { continue: true, suppressedDuplicate: true };
|
|
68
|
+
return evaluateHookPayload(name, payload, { root });
|
|
127
69
|
}
|
|
128
|
-
function
|
|
129
|
-
const
|
|
130
|
-
if (
|
|
70
|
+
function hookPayloadIsLightTurnCandidate(payload = {}) {
|
|
71
|
+
const prompt = stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload));
|
|
72
|
+
if (dollarCommand(prompt))
|
|
131
73
|
return false;
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
.replace(/[_-]+/g, ' ');
|
|
135
|
-
if (/\bcodex\s*app\b[\s\S]{0,120}\bgit\b[\s\S]{0,120}\b(?:action|actions|commit|push|pr|pull request)\b/i.test(action))
|
|
136
|
-
return true;
|
|
137
|
-
if (/\bgit\s*actions?\b[\s\S]{0,120}\b(?:commit|push|pr|pull request|commit\s*(?:and|&)\s*push)\b/i.test(action))
|
|
138
|
-
return true;
|
|
139
|
-
if (/\bcodex\s*git\s*(?:commit|push|pr|pull request|commit\s*(?:and|&)\s*push)\b/i.test(action))
|
|
140
|
-
return true;
|
|
141
|
-
if (/\b(?:git\s*)?(?:commit|push|commit\s*(?:and|&)\s*push|create\s+(?:a\s+)?pull\s+request|pull\s+request|pr)\b/i.test(action)) {
|
|
142
|
-
return /\b(?:action|intent|operation|permission|feature|tool\s*name|source|event|hook|name|label|title|type|kind|id)\s*:/i.test(action);
|
|
143
|
-
}
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
function toolFailed(payload = {}) {
|
|
147
|
-
const candidates = [
|
|
148
|
-
payload.exit_code,
|
|
149
|
-
payload.exitCode,
|
|
150
|
-
payload.tool_response?.exit_code,
|
|
151
|
-
payload.toolResponse?.exitCode,
|
|
152
|
-
payload.result?.exit_code,
|
|
153
|
-
payload.result?.exitCode
|
|
154
|
-
];
|
|
155
|
-
for (const candidate of candidates) {
|
|
156
|
-
if (candidate === undefined || candidate === null || candidate === '')
|
|
157
|
-
continue;
|
|
158
|
-
const n = Number(candidate);
|
|
159
|
-
if (Number.isFinite(n))
|
|
160
|
-
return n !== 0;
|
|
161
|
-
}
|
|
162
|
-
if (payload.isError === true || payload.tool_response?.isError === true || payload.toolResponse?.isError === true || payload.result?.isError === true)
|
|
163
|
-
return true;
|
|
164
|
-
if (payload.success === false || payload.tool_response?.success === false || payload.toolResponse?.success === false || payload.result?.success === false)
|
|
165
|
-
return true;
|
|
166
|
-
if (payload.executed === false)
|
|
74
|
+
const profile = classifyTaskProfile(prompt);
|
|
75
|
+
if (profile === 'passthrough')
|
|
167
76
|
return true;
|
|
168
|
-
return
|
|
169
|
-
}
|
|
170
|
-
export async function hookMain(name) {
|
|
171
|
-
const payload = await loadHookPayload();
|
|
172
|
-
return evaluateHookPayload(name, payload);
|
|
77
|
+
return routePrompt(prompt)?.id === 'Answer';
|
|
173
78
|
}
|
|
174
79
|
export async function evaluateHookPayload(name, payload = {}, opts = {}) {
|
|
175
80
|
const root = opts.root || await projectRoot(payload.cwd || process.cwd());
|
|
176
81
|
const sessionKey = conversationId(payload);
|
|
177
|
-
|
|
82
|
+
const greetingFastPath = name === 'user-prompt-submit'
|
|
83
|
+
&& !dollarCommand(stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload)))
|
|
84
|
+
&& classifyTaskProfile(stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload))) === 'passthrough';
|
|
85
|
+
const matchingLightStop = name === 'stop'
|
|
86
|
+
&& await hasMatchingLightTurnStopBypass(root, { sessionKey, turnId: hookTurnId(payload) }).catch(() => false);
|
|
87
|
+
if (!explicitConversationId(payload) && !greetingFastPath && !matchingLightStop) {
|
|
178
88
|
await appendJsonl(path.join(root, '.sneakoscope', 'state', 'session-id-fallback-warning.jsonl'), {
|
|
179
89
|
ts: nowIso(),
|
|
180
90
|
warning: 'hook_payload_missing_explicit_session_id',
|
|
@@ -183,7 +93,11 @@ export async function evaluateHookPayload(name, payload = {}, opts = {}) {
|
|
|
183
93
|
hook: name
|
|
184
94
|
}).catch(() => null);
|
|
185
95
|
}
|
|
186
|
-
|
|
96
|
+
// Hook decisions use persisted session state. Codex hook payloads do not
|
|
97
|
+
// define a trusted `state` field; accepting a partial/spoofed value can hide
|
|
98
|
+
// an active mission or bypass route gates. Explicit opts.state remains for
|
|
99
|
+
// internal replay and focused tests.
|
|
100
|
+
const loadedState = opts.state || await loadState(root, payload);
|
|
187
101
|
const state = { ...loadedState, _session_key: loadedState?._session_key || sessionKey };
|
|
188
102
|
const noQuestion = isNoQuestionRunning(state);
|
|
189
103
|
if (name === 'user-prompt-submit') {
|
|
@@ -198,46 +112,166 @@ export async function evaluateHookPayload(name, payload = {}, opts = {}) {
|
|
|
198
112
|
if (name === 'stop')
|
|
199
113
|
return hookStop(root, state, payload, noQuestion, sessionKey);
|
|
200
114
|
if (name === 'subagent-start')
|
|
201
|
-
return hookSubagentStart(root, state, sessionKey);
|
|
115
|
+
return hookSubagentStart(root, state, payload, sessionKey);
|
|
116
|
+
if (name === 'subagent-stop')
|
|
117
|
+
return hookSubagentStop(root, state, payload, sessionKey);
|
|
202
118
|
return { continue: true };
|
|
203
119
|
}
|
|
204
|
-
async function hookSubagentStart(root, state, sessionKey = null) {
|
|
205
|
-
|
|
206
|
-
|
|
120
|
+
async function hookSubagentStart(root, state, payload = {}, sessionKey = null) {
|
|
121
|
+
const artifactDir = officialSubagentArtifactDir(root, state, sessionKey);
|
|
122
|
+
await recordAndRefreshSubagentEvidence(root, artifactDir, state, payload, 'SubagentStart').catch(() => null);
|
|
123
|
+
const config = await readOfficialSubagentConfig(root);
|
|
124
|
+
const budget = resolveSubagentThreadBudget({ configuredMaxThreads: config.maxThreads });
|
|
125
|
+
const active = subagentRouteContext(state);
|
|
207
126
|
const resourceGuard = [
|
|
208
|
-
|
|
209
|
-
'Subagents must not spawn
|
|
210
|
-
'
|
|
127
|
+
`SKS subagent policy: Codex [agents].max_threads is ${budget.maxThreads}.`,
|
|
128
|
+
'Use max_depth=1. Subagents must not spawn subagents.',
|
|
129
|
+
'Do not duplicate an already assigned slice.',
|
|
130
|
+
'Parallel writes require disjoint paths; serialize overlapping paths.',
|
|
131
|
+
'Close completed agent threads when no longer needed.'
|
|
211
132
|
].join(' ');
|
|
212
133
|
const additionalContext = [leanEngineeringCompactText(), resourceGuard, active].filter(Boolean).join('\n\n');
|
|
213
134
|
return { continue: true, additionalContext };
|
|
214
135
|
}
|
|
215
|
-
function
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
return
|
|
136
|
+
function subagentRouteContext(state = {}) {
|
|
137
|
+
if (!state?.route && !state?.mode)
|
|
138
|
+
return '';
|
|
139
|
+
const route = state.route_command || state.route || state.mode;
|
|
140
|
+
const mission = state.mission_id ? ` for mission ${state.mission_id}` : '';
|
|
141
|
+
const artifacts = state.mission_id
|
|
142
|
+
? ` Read only the route artifacts relevant to your assigned slice under .sneakoscope/missions/${state.mission_id}/.`
|
|
143
|
+
: '';
|
|
144
|
+
const databaseBoundary = String(state.mode || state.route || '').toUpperCase() === 'DB'
|
|
145
|
+
? ' Keep database inspection read-only unless the parent supplied a separately sealed mutation contract.'
|
|
146
|
+
: '';
|
|
147
|
+
return `You are a child thread on ${route}${mission}. Execute only the slice assigned by the parent.${artifacts} Do not spawn or delegate other agents, wait for sibling threads, integrate sibling results, close the parent route, or author the sks.subagent-parent-summary.v1 parent result. Return a concise slice result to the parent.${databaseBoundary}`;
|
|
148
|
+
}
|
|
149
|
+
async function hookSubagentStop(root, state, payload = {}, sessionKey = null) {
|
|
150
|
+
const artifactDir = officialSubagentArtifactDir(root, state, sessionKey);
|
|
151
|
+
await recordAndRefreshSubagentEvidence(root, artifactDir, state, payload, 'SubagentStop').catch(() => null);
|
|
152
|
+
// SubagentStop is evidence collection only. It must never reuse the parent
|
|
153
|
+
// Stop hook's route gate or block a child thread from returning its result.
|
|
154
|
+
return { continue: true, silent: true };
|
|
155
|
+
}
|
|
156
|
+
function officialSubagentArtifactDir(root, state = {}, sessionKey = null) {
|
|
157
|
+
if (state?.mission_id)
|
|
158
|
+
return missionDir(root, state.mission_id);
|
|
159
|
+
return path.join(root, '.sneakoscope', 'state', 'subagents', sha256(String(sessionKey || 'default')).slice(0, 32));
|
|
160
|
+
}
|
|
161
|
+
async function recordAndRefreshSubagentEvidence(root, artifactDir, state, payload, eventName) {
|
|
162
|
+
return withFileLock({
|
|
163
|
+
lockPath: path.join(artifactDir, '.subagent-evidence.lock'),
|
|
164
|
+
timeoutMs: 5_000,
|
|
165
|
+
staleMs: 60_000
|
|
166
|
+
}, async () => {
|
|
167
|
+
const plan = await readJson(path.join(artifactDir, 'subagent-plan.json'), {});
|
|
168
|
+
const workflowRunId = String(plan?.workflow_run_id || state?.official_subagent_run_id || '').trim();
|
|
169
|
+
const eventPayload = workflowRunId && payload && typeof payload === 'object' && !Array.isArray(payload)
|
|
170
|
+
? { ...payload, workflow_run_id: workflowRunId }
|
|
171
|
+
: payload;
|
|
172
|
+
const event = await recordSubagentEvent(artifactDir, eventPayload, eventName);
|
|
173
|
+
if (!event)
|
|
174
|
+
return null;
|
|
175
|
+
const zellijTelemetry = await recordOfficialSubagentZellijTelemetry({
|
|
176
|
+
root,
|
|
177
|
+
routeMissionId: plan?.mission_id || state?.mission_id || null,
|
|
178
|
+
event,
|
|
179
|
+
payload: eventPayload,
|
|
180
|
+
plan
|
|
181
|
+
}).catch(async (error) => {
|
|
182
|
+
await appendJsonl(path.join(artifactDir, 'zellij-telemetry-warnings.jsonl'), {
|
|
183
|
+
ts: nowIso(),
|
|
184
|
+
warning: 'official_subagent_zellij_telemetry_failed',
|
|
185
|
+
event_name: eventName,
|
|
186
|
+
thread_id: event.thread_id,
|
|
187
|
+
error: String(error?.message || error)
|
|
188
|
+
}).catch(() => null);
|
|
189
|
+
return null;
|
|
190
|
+
});
|
|
191
|
+
if (zellijTelemetry?.blocker) {
|
|
192
|
+
await appendJsonl(path.join(artifactDir, 'zellij-telemetry-warnings.jsonl'), {
|
|
193
|
+
ts: nowIso(),
|
|
194
|
+
warning: 'official_subagent_zellij_telemetry_incomplete',
|
|
195
|
+
event_name: eventName,
|
|
196
|
+
thread_id: event.thread_id,
|
|
197
|
+
blocker: zellijTelemetry.blocker,
|
|
198
|
+
failed_mission_ids: 'failed_mission_ids' in zellijTelemetry ? zellijTelemetry.failed_mission_ids : []
|
|
199
|
+
}).catch(() => null);
|
|
200
|
+
}
|
|
201
|
+
const existing = await readJson(path.join(artifactDir, SUBAGENT_EVIDENCE_FILENAME), {});
|
|
202
|
+
const parentSummary = await readJson(path.join(artifactDir, SUBAGENT_PARENT_SUMMARY_FILENAME), null);
|
|
203
|
+
const requestedSubagents = Number(plan?.requested_subagents
|
|
204
|
+
|| state?.requested_subagents
|
|
205
|
+
|| existing?.requested_subagents
|
|
206
|
+
|| 0);
|
|
207
|
+
if (!Number.isFinite(requestedSubagents) || requestedSubagents < 1)
|
|
208
|
+
return event;
|
|
209
|
+
await writeSubagentEvidence(artifactDir, {
|
|
210
|
+
requestedSubagents,
|
|
211
|
+
parentSummary,
|
|
212
|
+
parentSummaryPresent: parentSummary !== null,
|
|
213
|
+
workflowStatus: 'running',
|
|
214
|
+
preparationOnly: false,
|
|
215
|
+
runId: workflowRunId || null,
|
|
216
|
+
additionalBlockers: Array.isArray(plan?.config_blockers)
|
|
217
|
+
? plan.config_blockers.map((item) => `official_subagent_config:${String(item)}`)
|
|
218
|
+
: []
|
|
219
|
+
});
|
|
220
|
+
return event;
|
|
221
|
+
});
|
|
239
222
|
}
|
|
240
223
|
async function hookUserPrompt(root, state, payload, noQuestion, sessionKey = null) {
|
|
224
|
+
// A receipt is scoped to exactly one submitted turn. Every later prompt,
|
|
225
|
+
// including Codex App git/settings events, invalidates it before returning.
|
|
226
|
+
await clearLightTurnStopBypass(root, { sessionKey }).catch(() => undefined);
|
|
227
|
+
const submittedPrompt = stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload));
|
|
228
|
+
const explicitSession = explicitConversationId(payload);
|
|
229
|
+
const detectedMissingCallId = missingToolOutputCallId(submittedPrompt)
|
|
230
|
+
|| missingToolOutputCallIdFromPayload(payload);
|
|
231
|
+
let toolOutputQuarantine = explicitSession
|
|
232
|
+
? await readToolOutputQuarantine(root, sessionKey).catch(() => null)
|
|
233
|
+
: null;
|
|
234
|
+
if (detectedMissingCallId && explicitSession) {
|
|
235
|
+
toolOutputQuarantine = await quarantineMissingToolOutput({
|
|
236
|
+
root,
|
|
237
|
+
sessionKey,
|
|
238
|
+
callId: detectedMissingCallId,
|
|
239
|
+
missionId: state?.mission_id,
|
|
240
|
+
turnId: hookTurnId(payload)
|
|
241
|
+
}).catch(() => toolOutputQuarantine);
|
|
242
|
+
}
|
|
243
|
+
if (submittedPrompt && (detectedMissingCallId || toolOutputQuarantine)) {
|
|
244
|
+
return {
|
|
245
|
+
decision: 'block',
|
|
246
|
+
reason: interruptedToolOutputRecoveryBlockReason({
|
|
247
|
+
callId: detectedMissingCallId || toolOutputQuarantine?.call_id,
|
|
248
|
+
missionId: state?.mission_id || toolOutputQuarantine?.mission_id
|
|
249
|
+
})
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
const parentLaunchMissionId = process.env.SKS_NARUTO_PARENT_LAUNCH === '1'
|
|
253
|
+
? String(process.env.SKS_NARUTO_PARENT_MISSION_ID || '').trim()
|
|
254
|
+
: '';
|
|
255
|
+
if (parentLaunchMissionId) {
|
|
256
|
+
const attachedState = {
|
|
257
|
+
...state,
|
|
258
|
+
mission_id: parentLaunchMissionId,
|
|
259
|
+
mode: 'NARUTO',
|
|
260
|
+
route: 'Naruto',
|
|
261
|
+
route_command: '$Naruto',
|
|
262
|
+
route_closed: false,
|
|
263
|
+
subagents_required: true,
|
|
264
|
+
native_sessions_required: false
|
|
265
|
+
};
|
|
266
|
+
await setCurrent(root, attachedState, { sessionKey, replace: true });
|
|
267
|
+
const activeContext = await activeRouteContext(root, attachedState);
|
|
268
|
+
return {
|
|
269
|
+
continue: true,
|
|
270
|
+
additionalContext: activeContext,
|
|
271
|
+
systemMessage: visibleHookMessage('user-prompt-submit', activeContext),
|
|
272
|
+
attached_parent_mission_id: parentLaunchMissionId
|
|
273
|
+
};
|
|
274
|
+
}
|
|
241
275
|
if (looksLikeCodexGitAction(payload)) {
|
|
242
276
|
await armCodexGitActionStopBypass(root, payload).catch(() => null);
|
|
243
277
|
return {
|
|
@@ -251,15 +285,63 @@ async function hookUserPrompt(root, state, payload, noQuestion, sessionKey = nul
|
|
|
251
285
|
systemMessage: 'SKS: Codex App settings/profile event ignored; route gates unchanged.'
|
|
252
286
|
};
|
|
253
287
|
}
|
|
254
|
-
await maybeReconcileProjectSkillsPreflight(root).catch(() => null);
|
|
255
288
|
if (!noQuestion) {
|
|
256
|
-
const prompt =
|
|
257
|
-
const
|
|
289
|
+
const prompt = submittedPrompt;
|
|
290
|
+
const taskProfile = classifyTaskProfile(prompt);
|
|
291
|
+
const explicitCommand = Boolean(dollarCommand(prompt));
|
|
292
|
+
const lightRoute = explicitCommand ? null : routePrompt(prompt);
|
|
293
|
+
const clarificationPending = isBlockingClarificationAwaiting(state);
|
|
294
|
+
const madConfirmationPrompt = looksLikeMadSksConfirmationPrompt(prompt);
|
|
295
|
+
const activeContinuation = Boolean(state?.mission_id && state?.route_closed !== true && looksLikeActiveContinuationPrompt(prompt));
|
|
296
|
+
if (!explicitCommand && !clarificationPending && !madConfirmationPrompt && !activeContinuation && taskProfile === 'passthrough') {
|
|
297
|
+
const turnId = hookTurnId(payload);
|
|
298
|
+
if (turnId) {
|
|
299
|
+
await armLightTurnStopBypass(root, {
|
|
300
|
+
sessionKey,
|
|
301
|
+
turnId,
|
|
302
|
+
prompt,
|
|
303
|
+
profile: 'passthrough',
|
|
304
|
+
ttlMs: 60_000
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
return { continue: true, silent: true, sksTaskProfile: taskProfile };
|
|
308
|
+
}
|
|
309
|
+
if (!explicitCommand && !clarificationPending && !madConfirmationPrompt && !activeContinuation && lightRoute?.id === 'Answer') {
|
|
310
|
+
const turnId = hookTurnId(payload);
|
|
311
|
+
if (turnId) {
|
|
312
|
+
await armLightTurnStopBypass(root, {
|
|
313
|
+
sessionKey,
|
|
314
|
+
turnId,
|
|
315
|
+
prompt,
|
|
316
|
+
profile: 'answer',
|
|
317
|
+
ttlMs: 5 * 60_000
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
const additionalContext = compactAnswerContext(prompt);
|
|
321
|
+
return { continue: true, additionalContext, sksTaskProfile: 'answer' };
|
|
322
|
+
}
|
|
323
|
+
const madSksConfirmation = madConfirmationPrompt
|
|
324
|
+
? await handleMadSksUserConfirmation(root, state, prompt)
|
|
325
|
+
: null;
|
|
258
326
|
if (madSksConfirmation?.handled) {
|
|
259
327
|
const teamDigest = await teamLiveDigest(root, state);
|
|
260
328
|
const additionalContext = [madSksConfirmation.additionalContext, teamDigest?.context].filter(Boolean).join('\n\n');
|
|
261
329
|
return { continue: true, additionalContext, systemMessage: joinSystemMessages(visibleHookMessage('user-prompt-submit', additionalContext), teamDigest?.system) };
|
|
262
330
|
}
|
|
331
|
+
if (activeContinuation) {
|
|
332
|
+
const activeContext = await activeRouteContext(root, state);
|
|
333
|
+
const teamDigest = await teamLiveDigest(root, state);
|
|
334
|
+
const additionalContext = [
|
|
335
|
+
activeContext,
|
|
336
|
+
teamDigest?.context
|
|
337
|
+
].filter(Boolean).join('\n\n');
|
|
338
|
+
return {
|
|
339
|
+
continue: true,
|
|
340
|
+
additionalContext,
|
|
341
|
+
systemMessage: joinSystemMessages(visibleHookMessage('user-prompt-submit', activeContext), teamDigest?.system)
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
await maybeReconcileProjectSkillsPreflight(root).catch(() => null);
|
|
263
345
|
const updateContext = '';
|
|
264
346
|
const command = dollarCommand(prompt);
|
|
265
347
|
const route = routePrompt(prompt);
|
|
@@ -290,7 +372,10 @@ async function hookUserPrompt(root, state, payload, noQuestion, sessionKey = nul
|
|
|
290
372
|
if (activeContext && shouldLoadActiveContext)
|
|
291
373
|
contexts.push(routePipelineContext(prompt), activeContext);
|
|
292
374
|
else
|
|
293
|
-
contexts.push((await prepareRoute(root, prompt, state, {
|
|
375
|
+
contexts.push((await prepareRoute(root, prompt, state, {
|
|
376
|
+
sessionKey,
|
|
377
|
+
parentModel: observedParentModel(payload)
|
|
378
|
+
})).additionalContext);
|
|
294
379
|
if (goalOverlay)
|
|
295
380
|
contexts.push(goalOverlay);
|
|
296
381
|
if (teamDigest?.context)
|
|
@@ -330,10 +415,13 @@ function shouldPrepareFreshRouteOnActivePrompt(prompt, route = null, opts = {})
|
|
|
330
415
|
return routeRequiresSubagents(route, prompt);
|
|
331
416
|
}
|
|
332
417
|
function looksLikeActiveContinuationPrompt(prompt = '') {
|
|
333
|
-
const text = stripVisibleDecisionAnswerBlocks(String(prompt || ''))
|
|
418
|
+
const text = stripVisibleDecisionAnswerBlocks(String(prompt || ''))
|
|
419
|
+
.trim()
|
|
420
|
+
.replace(/[.!?。!?…,:;]+$/u, '')
|
|
421
|
+
.trim();
|
|
334
422
|
if (!text)
|
|
335
423
|
return false;
|
|
336
|
-
return /^(?:keep\s+going|continue|resume|go\s+on|proceed|carry\s+on
|
|
424
|
+
return /^(?:(?:please\s+)?(?:keep\s+going|continue|resume|go\s+on|proceed|carry\s+on)(?:\s+please)?|계속(?:\s*진행)?(?:\s*해\s*줘|\s*해주세요|\s*해)?|이어\s*서(?:\s*해\s*줘|\s*해주세요|\s*진행해)?|이어서(?:\s*해\s*줘|\s*해주세요|\s*진행해)?|진행(?:\s*해\s*줘|\s*해주세요|\s*해)?|마저\s*해(?:\s*줘|\s*주세요)?|다음|next)$/i.test(text);
|
|
337
425
|
}
|
|
338
426
|
function isClarificationAwaiting(state = {}) {
|
|
339
427
|
const phase = String(state.phase || '');
|
|
@@ -613,6 +701,11 @@ function clarificationPauseBlockReason(state = {}) {
|
|
|
613
701
|
}
|
|
614
702
|
async function hookStop(root, state, payload, noQuestion, sessionKey = null) {
|
|
615
703
|
const last = extractLastMessage(payload);
|
|
704
|
+
if (!noQuestion) {
|
|
705
|
+
const lightTurn = await consumeLightTurnStopBypass(root, { sessionKey, turnId: hookTurnId(payload) });
|
|
706
|
+
if (lightTurn.accepted)
|
|
707
|
+
return { continue: true, action: 'light_turn', silent: true };
|
|
708
|
+
}
|
|
616
709
|
if (state?.mode === 'LOOP' || state?.route === 'Loop' || state?.route_command === '$Loop') {
|
|
617
710
|
const missionId = state?.mission_id;
|
|
618
711
|
if (missionId) {
|
|
@@ -643,6 +736,9 @@ async function hookStop(root, state, payload, noQuestion, sessionKey = null) {
|
|
|
643
736
|
systemMessage: 'SKS: DFix ultralight finalization accepted; full-route Honest Mode loopback is not required.'
|
|
644
737
|
};
|
|
645
738
|
}
|
|
739
|
+
if (state?.subagents_required === true) {
|
|
740
|
+
await refreshOfficialSubagentCompletionArtifacts(root, state, last, sessionKey).catch(() => null);
|
|
741
|
+
}
|
|
646
742
|
const routeDecision = await evaluateStop(root, state, payload, { noQuestion });
|
|
647
743
|
if (routeDecision)
|
|
648
744
|
return routeDecision;
|
|
@@ -680,6 +776,163 @@ async function hookStop(root, state, payload, noQuestion, sessionKey = null) {
|
|
|
680
776
|
reason: 'SKS no-question run is not done. Continue autonomously, fix failing checks, update the active gate file, and do not ask the user.'
|
|
681
777
|
};
|
|
682
778
|
}
|
|
779
|
+
async function refreshOfficialSubagentCompletionArtifacts(root, state = {}, parentSummary = '', sessionKey = null) {
|
|
780
|
+
const id = state?.mission_id;
|
|
781
|
+
if (!id)
|
|
782
|
+
return null;
|
|
783
|
+
const dir = missionDir(root, id);
|
|
784
|
+
const plan = await readJson(path.join(dir, 'subagent-plan.json'), null).catch(() => null);
|
|
785
|
+
if (plan?.workflow !== 'official_codex_subagent')
|
|
786
|
+
return null;
|
|
787
|
+
const requestedSubagents = Number(plan.requested_subagents || state.requested_subagents || 0);
|
|
788
|
+
const workflowRunId = String(plan.workflow_run_id || state.official_subagent_run_id || '').trim();
|
|
789
|
+
const events = await readSubagentEvents(dir);
|
|
790
|
+
const runBoundParentSummary = bindTrustworthySubagentParentSummaryToRun(parentSummary, workflowRunId);
|
|
791
|
+
const effectiveParentSummary = await persistOrReuseTrustworthySubagentParentSummary(dir, runBoundParentSummary, {
|
|
792
|
+
workflowStatus: 'parent_completed',
|
|
793
|
+
runId: workflowRunId || null
|
|
794
|
+
});
|
|
795
|
+
const structuredParentSummary = normalizeSubagentParentSummary(effectiveParentSummary);
|
|
796
|
+
const evidence = await writeSubagentEvidence(dir, {
|
|
797
|
+
requestedSubagents,
|
|
798
|
+
events,
|
|
799
|
+
parentSummary: effectiveParentSummary,
|
|
800
|
+
workflowStatus: 'parent_completed',
|
|
801
|
+
preparationOnly: false,
|
|
802
|
+
runId: workflowRunId || null,
|
|
803
|
+
additionalBlockers: Array.isArray(plan.config_blockers)
|
|
804
|
+
? plan.config_blockers.map((item) => `official_subagent_config:${String(item)}`)
|
|
805
|
+
: []
|
|
806
|
+
});
|
|
807
|
+
if (structuredParentSummary.trustworthy) {
|
|
808
|
+
const parentTelemetry = await recordOfficialSubagentParentOutcomesTelemetry({
|
|
809
|
+
root,
|
|
810
|
+
routeMissionId: id,
|
|
811
|
+
parentSummary: structuredParentSummary.raw,
|
|
812
|
+
plan
|
|
813
|
+
}).catch(async (error) => {
|
|
814
|
+
await appendJsonl(path.join(dir, 'zellij-telemetry-warnings.jsonl'), {
|
|
815
|
+
ts: nowIso(),
|
|
816
|
+
warning: 'official_subagent_parent_outcome_telemetry_failed',
|
|
817
|
+
error: String(error?.message || error)
|
|
818
|
+
}).catch(() => null);
|
|
819
|
+
return null;
|
|
820
|
+
});
|
|
821
|
+
if (parentTelemetry?.blocker) {
|
|
822
|
+
await appendJsonl(path.join(dir, 'zellij-telemetry-warnings.jsonl'), {
|
|
823
|
+
ts: nowIso(),
|
|
824
|
+
warning: 'official_subagent_parent_outcome_telemetry_incomplete',
|
|
825
|
+
blocker: parentTelemetry.blocker,
|
|
826
|
+
failed_mission_ids: 'failed_mission_ids' in parentTelemetry ? parentTelemetry.failed_mission_ids : [],
|
|
827
|
+
skipped_thread_ids: 'skipped_thread_ids' in parentTelemetry ? parentTelemetry.skipped_thread_ids : []
|
|
828
|
+
}).catch(() => null);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
const isNaruto = String(state?.mode || '').toUpperCase() === 'NARUTO'
|
|
832
|
+
|| String(state?.route || state?.route_command || '').replace(/^\$/, '').toUpperCase() === 'NARUTO';
|
|
833
|
+
if (!isNaruto) {
|
|
834
|
+
await setCurrent(root, {
|
|
835
|
+
subagents_spawned: evidence.started_threads > 0,
|
|
836
|
+
subagents_reported: evidence.completed_threads > 0,
|
|
837
|
+
subagents_verified: evidence.ok,
|
|
838
|
+
subagent_evidence_file: SUBAGENT_EVIDENCE_FILENAME,
|
|
839
|
+
parent_summary_present: evidence.parent_summary_present
|
|
840
|
+
}, { sessionKey: sessionKey || state._session_key });
|
|
841
|
+
return evidence;
|
|
842
|
+
}
|
|
843
|
+
const previousGate = await readJson(path.join(dir, 'naruto-gate.json'), {}).catch(() => ({}));
|
|
844
|
+
const parentModel = plan.observed_parent_model || state.observed_parent_model || null;
|
|
845
|
+
const parentModelMismatch = previousGate.parent_model_match === false || observedParentModelMismatch(parentModel, NARUTO_PARENT_MODEL);
|
|
846
|
+
const blockers = [...new Set([
|
|
847
|
+
...evidence.blockers,
|
|
848
|
+
...(Array.isArray(previousGate.config_blockers) ? previousGate.config_blockers.map(String) : []),
|
|
849
|
+
...(Array.isArray(plan.config_blockers) ? plan.config_blockers.map((item) => `official_subagent_config:${String(item)}`) : []),
|
|
850
|
+
...(parentModelMismatch ? [`parent_model_mismatch:${String(parentModel || 'unknown')}`] : [])
|
|
851
|
+
])];
|
|
852
|
+
const passed = evidence.ok === true && blockers.length === 0;
|
|
853
|
+
const updatedAt = nowIso();
|
|
854
|
+
const summary = {
|
|
855
|
+
schema: 'sks.naruto-subagent-workflow.v1',
|
|
856
|
+
ok: passed,
|
|
857
|
+
workflow: 'official_codex_subagent',
|
|
858
|
+
workflow_run_id: workflowRunId || null,
|
|
859
|
+
mission_id: id,
|
|
860
|
+
route: '$Naruto',
|
|
861
|
+
status: passed ? 'completed' : evidence.status,
|
|
862
|
+
parent: {
|
|
863
|
+
model: NARUTO_PARENT_MODEL,
|
|
864
|
+
model_reasoning_effort: NARUTO_PARENT_EFFORT,
|
|
865
|
+
observed_model: parentModel,
|
|
866
|
+
observed_model_match: parentModel ? !parentModelMismatch : null
|
|
867
|
+
},
|
|
868
|
+
requested_subagents: requestedSubagents,
|
|
869
|
+
max_threads: Number(plan.max_threads || state.subagent_max_threads || 0),
|
|
870
|
+
max_depth: 1,
|
|
871
|
+
started_subagents: evidence.started_threads,
|
|
872
|
+
completed_subagents: evidence.completed_threads,
|
|
873
|
+
failed_subagents: evidence.failed_threads,
|
|
874
|
+
agents: officialSubagentRolePlan(),
|
|
875
|
+
verification: {
|
|
876
|
+
budget: plan.verification?.budget || plan.verification_budget || 'affected',
|
|
877
|
+
checks: Array.isArray(plan.verification?.checks)
|
|
878
|
+
? plan.verification.checks
|
|
879
|
+
: Array.isArray(plan.verification_checks)
|
|
880
|
+
? plan.verification_checks
|
|
881
|
+
: []
|
|
882
|
+
},
|
|
883
|
+
legacy_process_swarm_used: false,
|
|
884
|
+
parent_summary_present: evidence.parent_summary_present,
|
|
885
|
+
parent_summary: structuredParentSummary.summary,
|
|
886
|
+
parent_thread_outcomes: structuredParentSummary.raw?.thread_outcomes || [],
|
|
887
|
+
subagent_evidence: SUBAGENT_EVIDENCE_FILENAME,
|
|
888
|
+
blockers,
|
|
889
|
+
updated_at: updatedAt
|
|
890
|
+
};
|
|
891
|
+
await writeJsonAtomic(path.join(dir, 'naruto-summary.json'), summary);
|
|
892
|
+
await writeJsonAtomic(path.join(dir, 'naruto-gate.json'), {
|
|
893
|
+
...previousGate,
|
|
894
|
+
schema: 'sks.naruto-gate.v1',
|
|
895
|
+
workflow: 'official_codex_subagent',
|
|
896
|
+
workflow_run_id: workflowRunId || null,
|
|
897
|
+
mission_id: id,
|
|
898
|
+
status: passed ? 'passed' : 'blocked',
|
|
899
|
+
passed,
|
|
900
|
+
terminal: passed,
|
|
901
|
+
terminal_state: passed ? 'completed' : 'blocked',
|
|
902
|
+
subagent_plan_ready: true,
|
|
903
|
+
official_subagent_evidence: evidence.ok === true,
|
|
904
|
+
parent_summary_present: evidence.parent_summary_present,
|
|
905
|
+
session_cleanup: evidence.failed_threads === 0 && evidence.completed_threads >= requestedSubagents,
|
|
906
|
+
subagent_evidence_ready: evidence.ok === true,
|
|
907
|
+
requested_subagents: evidence.requested_subagents,
|
|
908
|
+
started_subagents: evidence.started_threads,
|
|
909
|
+
completed_subagents: evidence.completed_threads,
|
|
910
|
+
failed_subagents: evidence.failed_threads,
|
|
911
|
+
event_sources: evidence.event_sources,
|
|
912
|
+
evidence: {
|
|
913
|
+
...(previousGate.evidence || {}),
|
|
914
|
+
official_subagent_evidence: SUBAGENT_EVIDENCE_FILENAME,
|
|
915
|
+
parent_summary: SUBAGENT_PARENT_SUMMARY_FILENAME,
|
|
916
|
+
requested_subagents: requestedSubagents,
|
|
917
|
+
started_threads: evidence.started_threads,
|
|
918
|
+
completed_threads: evidence.completed_threads,
|
|
919
|
+
failed_threads: evidence.failed_threads
|
|
920
|
+
},
|
|
921
|
+
blockers,
|
|
922
|
+
missing_fields: blockers,
|
|
923
|
+
updated_at: updatedAt
|
|
924
|
+
});
|
|
925
|
+
if (passed)
|
|
926
|
+
await closeWorkOrderLedgerForRouteResult(dir, { ok: true }).catch(() => null);
|
|
927
|
+
await setCurrent(root, {
|
|
928
|
+
subagents_spawned: evidence.started_threads > 0,
|
|
929
|
+
subagents_reported: evidence.completed_threads > 0,
|
|
930
|
+
subagents_verified: evidence.ok,
|
|
931
|
+
subagent_evidence_file: SUBAGENT_EVIDENCE_FILENAME,
|
|
932
|
+
parent_summary_present: evidence.parent_summary_present
|
|
933
|
+
}, { sessionKey: sessionKey || state._session_key });
|
|
934
|
+
return evidence;
|
|
935
|
+
}
|
|
683
936
|
async function consumeLightRouteStop(root, payload = {}) {
|
|
684
937
|
const file = path.join(root, '.sneakoscope', 'state', LIGHT_ROUTE_STOP_ARTIFACT);
|
|
685
938
|
const record = await readJson(file, null).catch(() => null);
|
|
@@ -713,91 +966,6 @@ function hasDfixLightCompletion(text) {
|
|
|
713
966
|
const gap = /(미검증|남은|문제|gap|remaining|not verified|not run|blocker|차단|불가|없음|none)/i.test(s);
|
|
714
967
|
return verification && gap;
|
|
715
968
|
}
|
|
716
|
-
function looksLikeCodexGitAction(payload = {}) {
|
|
717
|
-
const prompt = stripVisibleDecisionAnswerBlocks(extractUserPrompt(payload));
|
|
718
|
-
const metadataText = codexGitActionMetadataText(payload);
|
|
719
|
-
const haystack = [
|
|
720
|
-
metadataText,
|
|
721
|
-
payload.action,
|
|
722
|
-
payload.intent,
|
|
723
|
-
payload.operation,
|
|
724
|
-
payload.permission,
|
|
725
|
-
payload.description,
|
|
726
|
-
payload.kind,
|
|
727
|
-
payload.type,
|
|
728
|
-
payload.feature,
|
|
729
|
-
payload.tool_name,
|
|
730
|
-
payload.toolName,
|
|
731
|
-
payload.source,
|
|
732
|
-
payload.event,
|
|
733
|
-
payload.hook,
|
|
734
|
-
payload.hook_name,
|
|
735
|
-
payload.input?.action,
|
|
736
|
-
payload.input?.intent,
|
|
737
|
-
payload.input?.operation,
|
|
738
|
-
payload.input?.feature,
|
|
739
|
-
payload.input?.source,
|
|
740
|
-
payload.metadata?.action,
|
|
741
|
-
payload.metadata?.intent,
|
|
742
|
-
payload.metadata?.operation,
|
|
743
|
-
payload.metadata?.feature,
|
|
744
|
-
payload.metadata?.source
|
|
745
|
-
].filter(Boolean).join(' ');
|
|
746
|
-
const codexAppGitSignal = /\bcodex[_\s-]*app\b[\s\S]{0,80}\bgit\b[\s\S]{0,80}\b(?:action|actions|commit|push|pr)\b/i.test(haystack);
|
|
747
|
-
const gitActionSignal = /\bgit[_\s-]*actions?\b[\s\S]{0,80}\b(?:commit|push|commit[\s_-]*(?:and|&)?[\s_-]*push)\b/i.test(haystack);
|
|
748
|
-
const appSignal = codexGitActionMetadataSignal(metadataText)
|
|
749
|
-
|| codexAppGitSignal
|
|
750
|
-
|| gitActionSignal
|
|
751
|
-
|| /\b(?:codex[_\s-]*(?:app[_\s-]*)?)?(?:git[_\s-]*)?(?:commit[_\s-]*message|git[_\s-]*commit|git[_\s-]*push|git[_\s-]*pr|codex_git_commit|codex_git_push|codex_git_pr)\b/i.test(haystack)
|
|
752
|
-
|| /커밋\s*메시지\s*생성/i.test(haystack);
|
|
753
|
-
const promptSignal = /\bgenerate(?:\s+a)?(?:\s+git)?\s+commit\s+message\b/i.test(prompt)
|
|
754
|
-
|| /\bcommit\s+message\b[\s\S]{0,80}\b(?:staged|diff|changes?|git)\b/i.test(prompt)
|
|
755
|
-
|| looksLikeStockCodexGitActionPrompt(prompt)
|
|
756
|
-
|| /커밋\s*메시지\s*생성/i.test(prompt);
|
|
757
|
-
if (!appSignal && !promptSignal)
|
|
758
|
-
return false;
|
|
759
|
-
if (looksLikeStockCodexGitActionPrompt(prompt))
|
|
760
|
-
return true;
|
|
761
|
-
if (appSignal)
|
|
762
|
-
return true;
|
|
763
|
-
return !looksLikeUserImplementationRequest(prompt);
|
|
764
|
-
}
|
|
765
|
-
function looksLikeStockCodexGitActionPrompt(prompt = '') {
|
|
766
|
-
const text = String(prompt || '').trim();
|
|
767
|
-
if (!text || text.length > 120)
|
|
768
|
-
return false;
|
|
769
|
-
return /^(?:generate\s+(?:a\s+)?git\s+commit\s+message(?:\s+for\s+(?:the\s+)?(?:staged\s+)?diff)?|commit\s+changes|commit\s+and\s+push\s+changes|push\s+changes|create\s+(?:a\s+)?commit|create\s+(?:a\s+)?pull\s+request)\.?$/i.test(text);
|
|
770
|
-
}
|
|
771
|
-
function looksLikeCodexGitActionStopCompletion(last = '', payload = {}) {
|
|
772
|
-
const text = String(last || '').trim();
|
|
773
|
-
const metadataText = codexGitActionMetadataText(payload);
|
|
774
|
-
const haystack = [
|
|
775
|
-
metadataText,
|
|
776
|
-
payload.action,
|
|
777
|
-
payload.intent,
|
|
778
|
-
payload.operation,
|
|
779
|
-
payload.kind,
|
|
780
|
-
payload.type,
|
|
781
|
-
payload.feature,
|
|
782
|
-
payload.source,
|
|
783
|
-
payload.event,
|
|
784
|
-
payload.metadata?.action,
|
|
785
|
-
payload.metadata?.intent,
|
|
786
|
-
payload.metadata?.operation,
|
|
787
|
-
payload.metadata?.feature,
|
|
788
|
-
payload.metadata?.source
|
|
789
|
-
].filter(Boolean).join(' ');
|
|
790
|
-
if (codexGitActionMetadataSignal(metadataText))
|
|
791
|
-
return true;
|
|
792
|
-
if (/\bcodex[_\s-]*app\b[\s\S]{0,80}\bgit\b[\s\S]{0,80}\b(?:action|commit|push|pr)\b/i.test(haystack))
|
|
793
|
-
return true;
|
|
794
|
-
if (!text || text.length > 180)
|
|
795
|
-
return false;
|
|
796
|
-
return /^(?:commit(?:ted)?(?:\s+and\s+pushed)?(?:\s+changes)?(?:\s+complete[.!]?)?|push(?:ed)?(?:\s+changes)?(?:\s+complete[.!]?)?|created\s+(?:a\s+)?pull\s+request[.!]?)$/i.test(text);
|
|
797
|
-
}
|
|
798
|
-
function looksLikeUserImplementationRequest(text = '') {
|
|
799
|
-
return /(fix|bug|broken|error|issue|implement|change|update|repair|수정|버그|오류|에러|문제|고쳐|고치|해결|변경|수리|패치|안생기|안\s*생기)/i.test(String(text || ''));
|
|
800
|
-
}
|
|
801
969
|
async function armCodexGitActionStopBypass(root, payload = {}) {
|
|
802
970
|
const nowMs = Date.now();
|
|
803
971
|
const record = {
|