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
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import fsp from 'node:fs/promises';
|
|
2
1
|
import path from 'node:path';
|
|
3
|
-
import { appendJsonl, exists, nowIso, readJson, readText, writeJsonAtomic
|
|
2
|
+
import { appendJsonl, exists, nowIso, readJson, readText, writeJsonAtomic } from '../fsx.js';
|
|
4
3
|
import { containsUserQuestion, noQuestionContinuationReason } from '../no-question-guard.js';
|
|
5
|
-
import { createMission, missionDir, setCurrent } from '../mission.js';
|
|
4
|
+
import { createMission, getOrCreateSessionMission, missionDir, sessionStateKey, setCurrent } from '../mission.js';
|
|
6
5
|
import { buildQuestionSchemaForRoute, buildRequestIntake, REQUEST_INTAKE_ARTIFACT, writeQuestions } from '../questions.js';
|
|
7
6
|
import { sealContract } from '../decision-contract.js';
|
|
8
7
|
import { scanDbSafety } from '../db-safety.js';
|
|
9
8
|
import { GOAL_WORKFLOW_ARTIFACT, writeGoalWorkflow } from '../goal-workflow.js';
|
|
9
|
+
import { createAndWriteWorkOrderLedgerForPrompt } from '../work-order-ledger.js';
|
|
10
10
|
import { writeCodeStructureReport } from '../code-structure.js';
|
|
11
11
|
import { writeMemorySweepReport } from '../memory-governor.js';
|
|
12
12
|
import { writeMistakeMemoryReport } from '../mistake-memory.js';
|
|
13
13
|
import { MISTAKE_RECALL_ARTIFACT, mistakeRecallGateStatus } from '../mistake-recall.js';
|
|
14
14
|
import { recordSkillDreamEvent, SKILL_DREAM_POLICY, skillDreamPolicyText, writeSkillForgeReport } from '../skill-forge.js';
|
|
15
|
-
import { evaluateResearchGate, writeResearchPlan } from '../research.js';
|
|
15
|
+
import { evaluateResearchGate, researchPaperArtifactForPlan, writeResearchPlan } from '../research.js';
|
|
16
16
|
import { PPT_REQUIRED_GATE_FIELDS, writePptRouteArtifacts } from '../ppt.js';
|
|
17
17
|
import { writeQaLoopArtifacts } from '../qa-loop.js';
|
|
18
18
|
import { IMAGE_UX_REVIEW_GATE_ARTIFACT, IMAGE_UX_REVIEW_POLICY_ARTIFACT, IMAGE_UX_REVIEW_SCREEN_INVENTORY_ARTIFACT, IMAGE_UX_REVIEW_GENERATED_REVIEW_LEDGER_ARTIFACT, IMAGE_UX_REVIEW_ISSUE_LEDGER_ARTIFACT, IMAGE_UX_REVIEW_ITERATION_REPORT_ARTIFACT, IMAGE_UX_REVIEW_REQUIRED_GATE_FIELDS, writeImageUxReviewRouteArtifacts } from '../image-ux-review.js';
|
|
@@ -23,13 +23,17 @@ import { validateRouteCompletionProof } from '../proof/route-proof-gate.js';
|
|
|
23
23
|
import { routeFromState, routeRequiresCompletionProof } from '../proof/route-proof-policy.js';
|
|
24
24
|
import { permissionGateSummary } from '../permission-gates.js';
|
|
25
25
|
import { prepareMadDbMission } from '../mad-db/mad-db-coordinator.js';
|
|
26
|
-
import { AGENT_INTAKE_STAGE_ID
|
|
26
|
+
import { AGENT_INTAKE_STAGE_ID } from '../agents/agent-schema.js';
|
|
27
27
|
import { normalizeAgentPolicy, routeRequiresAgentIntake, agentPipelineStage } from '../agents/agent-plan.js';
|
|
28
28
|
import { readAgentGateStatus } from '../agents/agent-gate.js';
|
|
29
29
|
import { CODEX_APP_IMAGE_GENERATION_DOC_URL, CODEX_COMPUTER_USE_EVIDENCE_SOURCE, CODEX_COMPUTER_USE_ONLY_POLICY, CODEX_IMAGEGEN_REQUIRED_POLICY, CODEX_WEB_VERIFICATION_POLICY, FROM_CHAT_IMG_CHECKLIST_ARTIFACT, FROM_CHAT_IMG_COVERAGE_ARTIFACT, FROM_CHAT_IMG_QA_LOOP_ARTIFACT, FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT, FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS, SOLUTION_SCOUT_STAGE_ID, chatCaptureIntakeText, context7RequirementText, dollarCommand, evidenceMentionsForbiddenBrowserAutomation, getdesignReferencePolicyText, hasFromChatImgSignal, hasMadSksSignal, imageUxReviewPipelinePolicyText, leanEngineeringCompactText, looksLikeProblemSolvingRequest, pptPipelineAllowlistPolicyText, reflectionRequiredForRoute, reasoningInstruction, routeNeedsContext7, routePrompt, routeReasoning, routeRequiresSubagents, solutionScoutPolicyText, stripDollarCommand, stripMadSksSignal, stripVisibleDecisionAnswerBlocks, subagentExecutionPolicyText, stackCurrentDocsPolicyText, triwikiContextTracking, triwikiContextTrackingText, triwikiStagePolicyText } from '../routes.js';
|
|
30
30
|
import { normalizeLeanDecision, validateLeanDecision } from '../lean-engineering-policy.js';
|
|
31
31
|
import { MIN_TEAM_REVIEWER_LANES, MIN_TEAM_REVIEW_POLICY_TEXT } from '../team-review-policy.js';
|
|
32
|
-
import {
|
|
32
|
+
import { classifyTaskProfile, gateProfileForTask } from '../runtime/task-profile.js';
|
|
33
|
+
import { chooseVerificationBudget } from '../runtime/verification-budget.js';
|
|
34
|
+
import { NARUTO_PARENT_MODEL } from '../subagents/model-policy.js';
|
|
35
|
+
import { NARUTO_GATE_FILENAME, NARUTO_SUMMARY_FILENAME, SUBAGENT_PLAN_FILENAME, prepareOfficialSubagentMission } from '../subagents/official-subagent-preparation.js';
|
|
36
|
+
import { buildSubagentEvidence, readSubagentEvents, recordSubagentEvent, SUBAGENT_EVIDENCE_FILENAME, SUBAGENT_EVENT_LOG_FILENAME, SUBAGENT_PARENT_SUMMARY_FILENAME } from '../subagents/subagent-evidence.js';
|
|
33
37
|
export { routePrompt };
|
|
34
38
|
export const PIPELINE_PLAN_ARTIFACT = 'pipeline-plan.json';
|
|
35
39
|
export const PIPELINE_PLAN_SCHEMA_VERSION = 1;
|
|
@@ -54,52 +58,79 @@ const DEFAULT_COMPLIANCE_LOOP_LIMIT = 3;
|
|
|
54
58
|
const CLARIFICATION_BYPASS_ROUTES = new Set(['Answer', 'DFix', 'Help', 'Wiki', 'ComputerUse', 'Goal']);
|
|
55
59
|
const QUESTION_GATE_ROUTES = new Set(['QALoop', 'PPT']);
|
|
56
60
|
const LIGHTWEIGHT_ROUTES = new Set(['Answer', 'DFix', 'Help', 'Wiki']);
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
'
|
|
61
|
-
'ambiguity_gate',
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
'
|
|
67
|
-
|
|
68
|
-
'
|
|
69
|
-
'
|
|
70
|
-
'
|
|
71
|
-
'
|
|
72
|
-
'
|
|
73
|
-
'
|
|
74
|
-
'
|
|
75
|
-
'
|
|
76
|
-
'
|
|
77
|
-
'
|
|
78
|
-
|
|
61
|
+
const GATE_PROFILE_STAGES = Object.freeze({
|
|
62
|
+
none: [],
|
|
63
|
+
minimal: ['route_classification', 'listed_verification'],
|
|
64
|
+
scoped: ['route_classification', 'ownership', 'listed_verification', 'honest_summary'],
|
|
65
|
+
full: ['route_classification', 'ambiguity_gate', 'safety_gate', 'ownership', 'listed_verification', 'honest_summary']
|
|
66
|
+
});
|
|
67
|
+
const STAGE_BLOCKING_GATE = Object.freeze({
|
|
68
|
+
ambiguity_gate: 'scope',
|
|
69
|
+
safety_gate: 'safety',
|
|
70
|
+
ssot_guard: 'safety',
|
|
71
|
+
context7_evidence: 'safety',
|
|
72
|
+
mistake_recall: 'safety',
|
|
73
|
+
ownership: 'ownership',
|
|
74
|
+
pipeline_plan: 'ownership',
|
|
75
|
+
focused_implementation: 'ownership',
|
|
76
|
+
[SOLUTION_SCOUT_STAGE_ID]: 'ownership',
|
|
77
|
+
triwiki_use_first: 'ownership',
|
|
78
|
+
subagent_plan: 'ownership',
|
|
79
|
+
official_subagent_execution: 'ownership',
|
|
80
|
+
parent_integration: 'ownership',
|
|
81
|
+
[AGENT_INTAKE_STAGE_ID]: 'ownership',
|
|
82
|
+
route_materialization: 'ownership',
|
|
83
|
+
work_order_coverage: 'ownership',
|
|
84
|
+
listed_verification: 'verification',
|
|
85
|
+
triwiki_validate_before_final: 'verification',
|
|
86
|
+
completion_proof: 'verification',
|
|
87
|
+
reflection: 'verification',
|
|
88
|
+
honest_summary: 'verification'
|
|
89
|
+
});
|
|
90
|
+
const BLOCKING_GATE_LIMITS = Object.freeze({
|
|
91
|
+
passthrough: 0,
|
|
92
|
+
answer: 0,
|
|
93
|
+
'tiny-change': 1,
|
|
94
|
+
'bounded-work': 2,
|
|
95
|
+
'parallel-read': 2,
|
|
96
|
+
'parallel-write': 3,
|
|
97
|
+
'high-risk': 4
|
|
98
|
+
});
|
|
79
99
|
function reflectionInstructionText(commandPrefix = 'sks') {
|
|
80
100
|
return `Post-route reflection: full routes load \`reflection\` after work/tests and before final; DFix/Answer/Help/Wiki/SKS discovery are exempt. Write ${REFLECTION_ARTIFACT}; record only real misses/gaps, or no_issue_acknowledged. For lessons, append TriWiki claim rows to ${REFLECTION_MEMORY_PATH}. Run "${commandPrefix} wiki refresh" or pack, validate, then pass ${REFLECTION_GATE}.`;
|
|
81
101
|
}
|
|
82
102
|
export function buildPipelinePlan(input = {}) {
|
|
83
103
|
const route = input.route || routePrompt(input.task || '$SKS');
|
|
84
104
|
const task = String(input.task || '').trim();
|
|
105
|
+
const taskProfile = input.taskProfile || taskProfileForRoute(route, task, classifyTaskProfile(task));
|
|
106
|
+
const gateProfile = gateProfileForTask(taskProfile);
|
|
85
107
|
const requestIntake = input.requestIntake || null;
|
|
86
108
|
const executionPrompt = String(requestIntake?.transformed_prompt || task || '').trim();
|
|
87
109
|
const ambiguity = normalizeAmbiguity(input.ambiguity, route);
|
|
88
110
|
const proof = normalizeProofField(input.proofField);
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
const
|
|
111
|
+
const subagentsRequired = routeRequiresSubagents(route, task, taskProfile);
|
|
112
|
+
const lane = selectPipelineLane(route, task, proof, taskProfile);
|
|
113
|
+
const normalizedAgentPolicy = normalizeAgentPolicy(route, task, input.agents === undefined ? {} : input.agents);
|
|
114
|
+
const agentPolicy = subagentsRequired
|
|
115
|
+
? { ...normalizedAgentPolicy, required: false, subagents_required: false, reason: 'official_codex_subagent_workflow_replaces_legacy_agent_intake' }
|
|
116
|
+
: normalizedAgentPolicy;
|
|
117
|
+
const verificationBudget = input.verificationBudget || chooseVerificationBudget({
|
|
118
|
+
taskProfile,
|
|
119
|
+
changedFiles: Array.isArray(input.changedFiles) ? input.changedFiles : []
|
|
120
|
+
});
|
|
121
|
+
const stages = buildPipelineStages(route, task, taskProfile, gateProfile, ambiguity, lane, Boolean(input.required), agentPolicy);
|
|
122
|
+
const verification = planVerification(route, proof, verificationBudget);
|
|
93
123
|
const skipped = stages.filter((stage) => stage.status === 'skipped').map((stage) => stage.id);
|
|
94
124
|
const kept = stages.filter((stage) => stage.status !== 'skipped' && stage.status !== 'not_applicable').map((stage) => stage.id);
|
|
95
125
|
const routeEconomy = routeEconomyPlan(proof);
|
|
96
126
|
const leanDecision = normalizeLeanDecision(input.leanDecision, {
|
|
97
|
-
selected_rung:
|
|
98
|
-
task_requires_change: !['
|
|
127
|
+
selected_rung: gateProfile === 'none' ? 'skip' : 'minimal-custom',
|
|
128
|
+
task_requires_change: !['passthrough', 'answer'].includes(taskProfile),
|
|
99
129
|
root_cause_target: route?.id ? `${route.id} route selected implementation surface` : null,
|
|
100
130
|
expected_changed_paths: input.expectedChangedPaths || input.touchedFiles || [],
|
|
101
131
|
verification_minimum: verification.slice(0, 3).map((item) => String(item || '').trim()).filter(Boolean)
|
|
102
132
|
});
|
|
133
|
+
const invariants = pipelineInvariants({ taskProfile, gateProfile, stages, verificationBudget });
|
|
103
134
|
return {
|
|
104
135
|
schema_version: PIPELINE_PLAN_SCHEMA_VERSION,
|
|
105
136
|
generated_at: nowIso(),
|
|
@@ -111,10 +142,18 @@ export function buildPipelinePlan(input = {}) {
|
|
|
111
142
|
stop_gate: route?.stopGate || 'honest_mode',
|
|
112
143
|
required_skills: route?.requiredSkills || [],
|
|
113
144
|
context7_required: Boolean(input.required),
|
|
114
|
-
subagents_required:
|
|
115
|
-
native_sessions_required:
|
|
145
|
+
subagents_required: subagentsRequired,
|
|
146
|
+
native_sessions_required: false,
|
|
116
147
|
reflection_required: reflectionRequiredForRoute(route)
|
|
117
148
|
},
|
|
149
|
+
task_profile: taskProfile,
|
|
150
|
+
gate_profile: gateProfile,
|
|
151
|
+
gate_budget: {
|
|
152
|
+
blocking_gate_limit: BLOCKING_GATE_LIMITS[taskProfile],
|
|
153
|
+
blocking_gate_count: countBlockingGateStages(stages),
|
|
154
|
+
blocking_stage_count: countBlockingStages(stages),
|
|
155
|
+
blocking_gate_ids: blockingGateIds(stages)
|
|
156
|
+
},
|
|
118
157
|
task,
|
|
119
158
|
request_intake: requestIntake ? {
|
|
120
159
|
artifact: REQUEST_INTAKE_ARTIFACT,
|
|
@@ -139,8 +178,9 @@ export function buildPipelinePlan(input = {}) {
|
|
|
139
178
|
},
|
|
140
179
|
skipped_stages: skipped,
|
|
141
180
|
kept_stages: kept,
|
|
181
|
+
verification_budget: verificationBudget,
|
|
142
182
|
verification,
|
|
143
|
-
invariants
|
|
183
|
+
invariants,
|
|
144
184
|
proof_field: proof,
|
|
145
185
|
lean_decision: leanDecision,
|
|
146
186
|
ssot_guard: buildSsotGuard({ route: route?.id || 'SKS', mode: route?.mode || 'SKS', task }),
|
|
@@ -148,13 +188,28 @@ export function buildPipelinePlan(input = {}) {
|
|
|
148
188
|
agent_intake: agentPolicy,
|
|
149
189
|
skill_dream: input.skillDream || { attached: false, reason: 'skill dreaming uses cheap counters and only runs inventory at threshold' },
|
|
150
190
|
goal_continuation: ambientGoalContinuation(),
|
|
151
|
-
next_actions: planNextActions(route, task, ambiguity, lane, agentPolicy),
|
|
191
|
+
next_actions: planNextActions(route, task, taskProfile, ambiguity, lane, agentPolicy, input.missionId),
|
|
152
192
|
no_unrequested_fallback_code: true
|
|
153
193
|
};
|
|
154
194
|
}
|
|
195
|
+
function taskProfileForRoute(route, task, classified) {
|
|
196
|
+
if (classified !== 'answer' && classified !== 'passthrough')
|
|
197
|
+
return classified;
|
|
198
|
+
const routeId = String(route?.id || '');
|
|
199
|
+
if (['DB', 'MadDB', 'ReleaseReview'].includes(routeId) && /\b(apply|execute|run|fix|change|migrate|deploy|release|publish)\b|적용|실행|수정|변경|마이그레이션|배포|릴리즈|출시/i.test(task))
|
|
200
|
+
return 'high-risk';
|
|
201
|
+
if (['Research', 'AutoResearch', 'QALoop', 'PPT', 'ImageUXReview', 'GX', 'DB', 'MadDB', 'ReleaseReview'].includes(routeId))
|
|
202
|
+
return 'bounded-work';
|
|
203
|
+
return classified;
|
|
204
|
+
}
|
|
155
205
|
export async function writePipelinePlan(dir, input = {}) {
|
|
206
|
+
const route = input.route || routePrompt(input.task || '$SKS');
|
|
207
|
+
const taskProfile = input.taskProfile || taskProfileForRoute(route, String(input.task || ''), classifyTaskProfile(input.task || ''));
|
|
208
|
+
if ((taskProfile === 'passthrough' || taskProfile === 'answer') && input.forceLightweightPlan !== true) {
|
|
209
|
+
return buildPipelinePlan({ ...input, taskProfile, requestIntake: input.requestIntake || null });
|
|
210
|
+
}
|
|
156
211
|
const requestIntake = input.requestIntake || await writeRequestIntakeArtifact(dir, input);
|
|
157
|
-
const plan = buildPipelinePlan({ ...input, requestIntake });
|
|
212
|
+
const plan = buildPipelinePlan({ ...input, taskProfile, requestIntake });
|
|
158
213
|
await writeJsonAtomic(path.join(dir, PIPELINE_PLAN_ARTIFACT), plan);
|
|
159
214
|
return plan;
|
|
160
215
|
}
|
|
@@ -186,15 +241,38 @@ function rootFromMissionDir(dir) {
|
|
|
186
241
|
}
|
|
187
242
|
export function validatePipelinePlan(plan = {}) {
|
|
188
243
|
const issues = [];
|
|
244
|
+
const taskProfile = plan.task_profile || classifyTaskProfile(plan.task || '');
|
|
245
|
+
const expectedGateProfile = gateProfileForTask(taskProfile);
|
|
246
|
+
const gateProfile = plan.gate_profile || expectedGateProfile;
|
|
247
|
+
const verificationBudget = plan.verification_budget || chooseVerificationBudget({ taskProfile, changedFiles: [] });
|
|
248
|
+
const expectedBlockingGateLimit = BLOCKING_GATE_LIMITS[taskProfile];
|
|
249
|
+
const declaredBlockingGateLimit = Number(plan.gate_budget?.blocking_gate_limit);
|
|
250
|
+
const actualBlockingGateCount = countBlockingGateStages(plan.stages);
|
|
189
251
|
if (plan.schema_version !== PIPELINE_PLAN_SCHEMA_VERSION)
|
|
190
252
|
issues.push('schema_version');
|
|
191
253
|
if (!plan.route?.id || !plan.route?.command)
|
|
192
254
|
issues.push('route');
|
|
193
255
|
if (!plan.runtime_lane?.lane)
|
|
194
256
|
issues.push('runtime_lane');
|
|
195
|
-
if (
|
|
257
|
+
if (gateProfile !== expectedGateProfile)
|
|
258
|
+
issues.push('gate_profile');
|
|
259
|
+
if (!Number.isInteger(declaredBlockingGateLimit) || declaredBlockingGateLimit !== expectedBlockingGateLimit)
|
|
260
|
+
issues.push('gate_budget.blocking_gate_limit');
|
|
261
|
+
if (actualBlockingGateCount > expectedBlockingGateLimit)
|
|
262
|
+
issues.push(`gate_budget.blocking_gate_limit_exceeded:${actualBlockingGateCount}>${expectedBlockingGateLimit}`);
|
|
263
|
+
if (plan.gate_budget?.blocking_gate_count !== undefined && Number(plan.gate_budget.blocking_gate_count) !== actualBlockingGateCount)
|
|
264
|
+
issues.push('gate_budget.blocking_gate_count');
|
|
265
|
+
if (plan.gate_budget?.blocking_stage_count !== undefined && Number(plan.gate_budget.blocking_stage_count) !== countBlockingStages(plan.stages))
|
|
266
|
+
issues.push('gate_budget.blocking_stage_count');
|
|
267
|
+
if (!sameStringArray(plan.gate_budget?.blocking_gate_ids, blockingGateIds(plan.stages)))
|
|
268
|
+
issues.push('gate_budget.blocking_gate_ids');
|
|
269
|
+
if (!Array.isArray(plan.stages) || (gateProfile !== 'none' && !plan.stages.length))
|
|
196
270
|
issues.push('stages');
|
|
197
|
-
|
|
271
|
+
else {
|
|
272
|
+
issues.push(...validateRequiredGateProfileStages(plan, expectedGateProfile));
|
|
273
|
+
issues.push(...validateStageBlockingMetadata(plan.stages));
|
|
274
|
+
}
|
|
275
|
+
if (!Array.isArray(plan.verification) || (verificationBudget !== 'none' && !plan.verification.length))
|
|
198
276
|
issues.push('verification');
|
|
199
277
|
if (!plan.route_economy?.mode)
|
|
200
278
|
issues.push('route_economy');
|
|
@@ -206,16 +284,79 @@ export function validatePipelinePlan(plan = {}) {
|
|
|
206
284
|
issues.push(...leanDecision.issues.map((issue) => `lean_decision:${issue}`));
|
|
207
285
|
if (plan.no_unrequested_fallback_code !== true || !plan.invariants?.includes('no_unrequested_fallback_code'))
|
|
208
286
|
issues.push('fallback_guard');
|
|
209
|
-
if (
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
287
|
+
if (plan.invariants?.includes('ssot_guard')) {
|
|
288
|
+
if (!plan.ssot_guard?.required)
|
|
289
|
+
issues.push('ssot_guard');
|
|
290
|
+
if (!plan.stages?.some((stage) => stage.id === 'ssot_guard' && !['skipped', 'not_applicable'].includes(stage.status)))
|
|
291
|
+
issues.push('ssot_guard_stage');
|
|
292
|
+
}
|
|
293
|
+
if (gateProfile !== 'none' && !plan.next_actions?.length)
|
|
214
294
|
issues.push('next_actions');
|
|
215
|
-
if (plan.agent_intake?.required && !plan.stages?.some((stage) => stage.id === AGENT_INTAKE_STAGE_ID
|
|
295
|
+
if (plan.agent_intake?.required && !plan.stages?.some((stage) => stage.id === AGENT_INTAKE_STAGE_ID
|
|
296
|
+
&& stage.workflow === 'official_codex_subagent'
|
|
297
|
+
&& Number(stage.requested_subagents || 0) === Number(plan.agent_intake.requested_subagents || 0)
|
|
298
|
+
&& Number(stage.requested_subagents || 0) > 0
|
|
299
|
+
&& Number(stage.max_threads || 0) > 0
|
|
300
|
+
&& Number(stage.max_depth || 0) === 1
|
|
301
|
+
&& Array.isArray(stage.outputs)
|
|
302
|
+
&& stage.outputs.includes(SUBAGENT_EVIDENCE_FILENAME)))
|
|
216
303
|
issues.push('agent_intake_stage');
|
|
217
304
|
return { ok: issues.length === 0, issues };
|
|
218
305
|
}
|
|
306
|
+
function validateRequiredGateProfileStages(plan, gateProfile) {
|
|
307
|
+
const issues = [];
|
|
308
|
+
const stages = Array.isArray(plan.stages) ? plan.stages : [];
|
|
309
|
+
const activeStatuses = new Set(['keep', 'required', 'passed', 'completed']);
|
|
310
|
+
for (const id of GATE_PROFILE_STAGES[gateProfile]) {
|
|
311
|
+
const matches = stages.filter((stage) => String(stage?.id || '') === id);
|
|
312
|
+
if (matches.length !== 1) {
|
|
313
|
+
issues.push(`stages.required_count:${id}:${matches.length}`);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
const status = String(matches[0]?.status || '');
|
|
317
|
+
const validNotApplicable = id === 'ambiguity_gate'
|
|
318
|
+
&& plan.ambiguity_gate?.required === false
|
|
319
|
+
&& status === 'not_applicable';
|
|
320
|
+
if (!activeStatuses.has(status) && !validNotApplicable) {
|
|
321
|
+
issues.push(`stages.required_inactive:${id}:${status || 'missing'}`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return issues;
|
|
325
|
+
}
|
|
326
|
+
function countBlockingGateStages(stages) {
|
|
327
|
+
return blockingGateIds(stages).length;
|
|
328
|
+
}
|
|
329
|
+
function countBlockingStages(stages) {
|
|
330
|
+
if (!Array.isArray(stages))
|
|
331
|
+
return 0;
|
|
332
|
+
return stages.filter((stage) => stage?.blocking === true && !['skipped', 'not_applicable'].includes(String(stage?.status || ''))).length;
|
|
333
|
+
}
|
|
334
|
+
function blockingGateIds(stages) {
|
|
335
|
+
if (!Array.isArray(stages))
|
|
336
|
+
return [];
|
|
337
|
+
return [...new Set(stages
|
|
338
|
+
.filter((stage) => stage?.blocking === true && !['skipped', 'not_applicable'].includes(String(stage?.status || '')))
|
|
339
|
+
.map((stage) => String(stage?.blocking_gate || '').trim())
|
|
340
|
+
.filter(Boolean))].sort();
|
|
341
|
+
}
|
|
342
|
+
function validateStageBlockingMetadata(stages) {
|
|
343
|
+
const issues = [];
|
|
344
|
+
for (const stage of stages) {
|
|
345
|
+
const id = String(stage?.id || 'missing');
|
|
346
|
+
if (typeof stage?.blocking !== 'boolean')
|
|
347
|
+
issues.push(`stages.blocking_metadata_missing:${id}`);
|
|
348
|
+
if (stage?.blocking === true && !String(stage?.blocking_gate || '').trim())
|
|
349
|
+
issues.push(`stages.blocking_gate_missing:${id}`);
|
|
350
|
+
if (stage?.blocking !== true && stage?.blocking_gate != null)
|
|
351
|
+
issues.push(`stages.nonblocking_gate_present:${id}`);
|
|
352
|
+
}
|
|
353
|
+
return issues;
|
|
354
|
+
}
|
|
355
|
+
function sameStringArray(left, right) {
|
|
356
|
+
return Array.isArray(left)
|
|
357
|
+
&& left.length === right.length
|
|
358
|
+
&& left.every((value, index) => String(value) === right[index]);
|
|
359
|
+
}
|
|
219
360
|
function validateRouteEconomyDecisionLattice(routeEconomy = {}, proof = {}) {
|
|
220
361
|
const lattice = routeEconomy.decision_lattice;
|
|
221
362
|
if (!lattice)
|
|
@@ -316,7 +457,7 @@ function routeEconomyPlan(proof = {}) {
|
|
|
316
457
|
deletion_policy: 'do_not_delete_or_skip_pipeline_stages_until_report_only_metrics_are_calibrated'
|
|
317
458
|
};
|
|
318
459
|
}
|
|
319
|
-
function selectPipelineLane(route, task, proof) {
|
|
460
|
+
function selectPipelineLane(route, task, proof, taskProfile = classifyTaskProfile(task)) {
|
|
320
461
|
if (proof.attached && proof.lane) {
|
|
321
462
|
return {
|
|
322
463
|
lane: proof.lane,
|
|
@@ -328,65 +469,101 @@ function selectPipelineLane(route, task, proof) {
|
|
|
328
469
|
keep: proof.keep || SPEED_LANE_POLICY.always_keep
|
|
329
470
|
};
|
|
330
471
|
}
|
|
472
|
+
if (taskProfile === 'passthrough' || taskProfile === 'answer')
|
|
473
|
+
return { lane: 'no_pipeline', source: 'task_profile', fast_lane_allowed: true, reason: 'Light conversation does not create an execution pipeline.', blockers: [], skip_when_fast: [], keep: [] };
|
|
331
474
|
if (route?.id === 'ComputerUse')
|
|
332
475
|
return { lane: 'computer_use_fast_lane', source: 'route_policy', fast_lane_allowed: true, reason: 'Computer Use route is intentionally direct and defers wiki/honest checks to closeout.', blockers: [], skip_when_fast: ['native_agent_intake', 'planning_debate', 'fresh_executor_team'], keep: ['focused_implementation', 'triwiki_validate_before_final', 'honest_mode'] };
|
|
476
|
+
if (taskProfile === 'tiny-change')
|
|
477
|
+
return { lane: 'minimal_change_lane', source: 'task_profile', fast_lane_allowed: true, reason: 'Tiny change uses one blocking gate and one focused check at most.', blockers: [], skip_when_fast: SPEED_LANE_POLICY.skip_when_fast, keep: ['listed_verification'] };
|
|
333
478
|
if (LIGHTWEIGHT_ROUTES.has(route?.id))
|
|
334
479
|
return { lane: `${String(route.id).toLowerCase()}_lightweight_lane`, source: 'route_policy', fast_lane_allowed: true, reason: 'Lightweight route bypasses full mission orchestration by design.', blockers: [], skip_when_fast: SPEED_LANE_POLICY.skip_when_fast, keep: ['focused_implementation', 'listed_verification', 'honest_mode'] };
|
|
335
|
-
if (routeRequiresSubagents(route, task))
|
|
336
|
-
return { lane:
|
|
480
|
+
if (routeRequiresSubagents(route, task, taskProfile))
|
|
481
|
+
return { lane: 'official_subagent_lane', source: 'task_profile', fast_lane_allowed: false, reason: 'Explicit Naruto or parallel work uses the Codex subagent workflow.', blockers: [], skip_when_fast: [], keep: ['subagent_plan', 'official_subagent_execution', 'parent_integration', 'listed_verification', 'honest_summary'] };
|
|
482
|
+
if (taskProfile === 'high-risk')
|
|
483
|
+
return { lane: SPEED_LANE_POLICY.full_lane, source: 'task_profile', fast_lane_allowed: false, reason: 'High-risk work uses the full risk gate profile.', blockers: [], skip_when_fast: [], keep: SPEED_LANE_POLICY.always_keep };
|
|
337
484
|
return { lane: SPEED_LANE_POLICY.balanced_lane, source: 'route_policy', fast_lane_allowed: false, reason: 'Balanced parent-owned route until Proof Field proves a narrower lane.', blockers: ['proof_field_not_attached'], skip_when_fast: [], keep: SPEED_LANE_POLICY.always_keep };
|
|
338
485
|
}
|
|
339
|
-
function buildPipelineStages(route, task, ambiguity, lane, context7Required, agentPolicy = normalizeAgentPolicy(route, task, {})) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
486
|
+
function buildPipelineStages(route, task, taskProfile, gateProfile, ambiguity, lane, context7Required, agentPolicy = normalizeAgentPolicy(route, task, {})) {
|
|
487
|
+
if (gateProfile === 'none')
|
|
488
|
+
return [];
|
|
489
|
+
const ids = [...GATE_PROFILE_STAGES[gateProfile]];
|
|
490
|
+
const specializedRoute = Boolean(route?.id && !LIGHTWEIGHT_ROUTES.has(route.id) && route.id !== 'SKS');
|
|
491
|
+
if (looksLikeProblemSolvingRequest(task) && !['Answer', 'Help', 'Wiki'].includes(route?.id))
|
|
492
|
+
ids.push(SOLUTION_SCOUT_STAGE_ID);
|
|
493
|
+
if (gateProfile === 'scoped' || gateProfile === 'full' || specializedRoute)
|
|
494
|
+
ids.push('pipeline_plan', 'focused_implementation');
|
|
495
|
+
if ((gateProfile === 'full' || specializedRoute) && !ids.includes('ssot_guard'))
|
|
496
|
+
ids.push('ssot_guard');
|
|
497
|
+
if (context7Required)
|
|
498
|
+
ids.push('context7_evidence');
|
|
499
|
+
if ((gateProfile === 'scoped' || gateProfile === 'full') && !LIGHTWEIGHT_ROUTES.has(route?.id)) {
|
|
500
|
+
ids.push('triwiki_use_first', 'triwiki_validate_before_final', 'mistake_recall', 'work_order_coverage');
|
|
501
|
+
}
|
|
502
|
+
if (routeRequiresSubagents(route, task, taskProfile))
|
|
503
|
+
ids.push('subagent_plan', 'official_subagent_execution', 'parent_integration');
|
|
504
|
+
if (agentPolicy.required)
|
|
505
|
+
ids.push(AGENT_INTAKE_STAGE_ID);
|
|
506
|
+
if (specializedRoute)
|
|
507
|
+
ids.push('route_materialization');
|
|
508
|
+
if (specializedRoute)
|
|
509
|
+
ids.push('completion_proof');
|
|
510
|
+
if (reflectionRequiredForRoute(route))
|
|
511
|
+
ids.push('reflection');
|
|
512
|
+
return [...new Set(ids)].map((id) => {
|
|
513
|
+
const configuredGate = STAGE_BLOCKING_GATE[id] || null;
|
|
514
|
+
const blockingGate = configuredGate === 'safety' && gateProfile !== 'full'
|
|
515
|
+
? 'ownership'
|
|
516
|
+
: configuredGate;
|
|
517
|
+
const blocking = Boolean(blockingGate);
|
|
518
|
+
const metadata = { blocking, blocking_gate: blocking ? blockingGate : null };
|
|
519
|
+
if (id === AGENT_INTAKE_STAGE_ID)
|
|
520
|
+
return { ...agentPipelineStage(agentPolicy), status: 'required', reason: agentPolicy.reason, ...metadata };
|
|
521
|
+
if (id === 'ambiguity_gate' && ambiguity?.required === false)
|
|
522
|
+
return { id, status: 'not_applicable', reason: 'ambiguity_gate_not_required_for_entrypoint', ...metadata };
|
|
523
|
+
if (id === 'ambiguity_gate' && ambiguity?.passed)
|
|
524
|
+
return { id, status: 'passed', reason: 'ambiguity_contract_already_sealed', ...metadata };
|
|
525
|
+
return { id, status: 'keep', reason: lane.fast_lane_allowed ? 'task_profile_minimal_lane' : 'required_by_task_and_route_profile', ...metadata };
|
|
354
526
|
});
|
|
355
527
|
}
|
|
356
|
-
function
|
|
357
|
-
if (
|
|
358
|
-
return
|
|
359
|
-
if (id === AGENT_INTAKE_STAGE_ID)
|
|
360
|
-
return { skip: false, reason: 'serious_route_requires_five_agent_intake' };
|
|
361
|
-
if (id === SOLUTION_SCOUT_STAGE_ID && !looksLikeProblemSolvingRequest(task))
|
|
362
|
-
return { skip: true, notApplicable: true, reason: 'no_problem_solving_signal' };
|
|
363
|
-
if (id === SOLUTION_SCOUT_STAGE_ID && ['Answer', 'Help', 'Wiki'].includes(route?.id))
|
|
364
|
-
return { skip: true, notApplicable: true, reason: 'route_not_code_repair' };
|
|
365
|
-
if (id === SOLUTION_SCOUT_STAGE_ID)
|
|
366
|
-
return { skip: false, reason: 'problem_solving_request_requires_web_similarity_agent' };
|
|
367
|
-
if (id === 'ambiguity_gate' && ambiguity?.required === false)
|
|
368
|
-
return { skip: true, notApplicable: true, reason: 'ambiguity_gate_not_required_for_entrypoint' };
|
|
369
|
-
if (id === 'ambiguity_gate' && CLARIFICATION_BYPASS_ROUTES.has(route?.id))
|
|
370
|
-
return { skip: true, notApplicable: true, reason: 'route_bypasses_clarification' };
|
|
371
|
-
if (id === 'context7_evidence' && !context7Required)
|
|
372
|
-
return { skip: true, notApplicable: true, reason: 'context7_not_required_by_route' };
|
|
373
|
-
if (id === 'reflection' && !reflectionRequiredForRoute(route))
|
|
374
|
-
return { skip: true, notApplicable: true, reason: 'reflection_not_required_for_route' };
|
|
375
|
-
if (['native_agent_intake', 'planning_debate', 'fresh_executor_team'].includes(id) && !routeRequiresSubagents(route, task))
|
|
376
|
-
return { skip: true, notApplicable: true, reason: 'native_session_team_not_required_by_route' };
|
|
377
|
-
return { skip: false, reason: 'required_by_lane' };
|
|
378
|
-
}
|
|
379
|
-
function planVerification(route, proof) {
|
|
528
|
+
function planVerification(route, proof, budget) {
|
|
529
|
+
if (budget === 'none')
|
|
530
|
+
return [];
|
|
380
531
|
const out = new Set(proof.verification || []);
|
|
532
|
+
if (budget === 'single-check')
|
|
533
|
+
out.add('run one focused check for the changed surface');
|
|
534
|
+
if (budget === 'affected')
|
|
535
|
+
out.add('run affected tests or checks for changed files');
|
|
536
|
+
if (budget === 'confidence') {
|
|
537
|
+
out.add('run the focused build or typecheck for the affected package');
|
|
538
|
+
out.add('run affected regression tests and the risk-specific safety check');
|
|
539
|
+
}
|
|
540
|
+
if (budget === 'release') {
|
|
541
|
+
out.add('npm run packcheck');
|
|
542
|
+
out.add('sks selftest --mock --json');
|
|
543
|
+
}
|
|
544
|
+
if (route?.id === 'Naruto' || route?.id === 'Team')
|
|
545
|
+
out.add('validate official subagent evidence and the parent integration summary');
|
|
381
546
|
if (route?.id === 'Team')
|
|
382
547
|
out.add('sks validate-artifacts latest --json');
|
|
383
548
|
if (reflectionRequiredForRoute(route))
|
|
384
549
|
out.add('sks wiki validate .sneakoscope/wiki/context-pack.json');
|
|
385
|
-
out.add('npm run packcheck');
|
|
386
|
-
out.add('npm run selftest -- --mock');
|
|
387
550
|
return [...out];
|
|
388
551
|
}
|
|
389
|
-
function
|
|
552
|
+
function pipelineInvariants(input) {
|
|
553
|
+
const out = ['no_unrequested_fallback_code'];
|
|
554
|
+
if (input.verificationBudget !== 'none')
|
|
555
|
+
out.push('listed_verification');
|
|
556
|
+
if (input.stages.some((stage) => stage.id === 'ssot_guard' && stage.status !== 'not_applicable'))
|
|
557
|
+
out.push('ssot_guard');
|
|
558
|
+
if (input.stages.some((stage) => stage.id === 'triwiki_validate_before_final'))
|
|
559
|
+
out.push('triwiki_validate_before_final');
|
|
560
|
+
if (input.gateProfile !== 'none')
|
|
561
|
+
out.push('honest_summary');
|
|
562
|
+
return out;
|
|
563
|
+
}
|
|
564
|
+
function planNextActions(route, task, taskProfile, ambiguity, lane, agentPolicy = normalizeAgentPolicy(route, task, {}), missionId = null) {
|
|
565
|
+
if (taskProfile === 'passthrough' || taskProfile === 'answer')
|
|
566
|
+
return [];
|
|
390
567
|
if (ambiguity.required && !ambiguity.passed) {
|
|
391
568
|
return [
|
|
392
569
|
`read ${REQUEST_INTAKE_ARTIFACT} and preserve its source-order requirements`,
|
|
@@ -396,21 +573,29 @@ function planNextActions(route, task, ambiguity, lane, agentPolicy = normalizeAg
|
|
|
396
573
|
];
|
|
397
574
|
}
|
|
398
575
|
const actions = [`read ${REQUEST_INTAKE_ARTIFACT} and use its transformed_prompt`, 'read pipeline-plan.json before work', 'execute kept stages only', 'run listed verification'];
|
|
399
|
-
if (agentPolicy.required)
|
|
400
|
-
|
|
401
|
-
|
|
576
|
+
if (agentPolicy.required) {
|
|
577
|
+
const missionArg = String(missionId || '').trim() || '<mission-id>';
|
|
578
|
+
const routeArg = String(route?.command || route?.id || '$Agent');
|
|
579
|
+
actions.splice(1, 0, `run sks agent run --mission ${shellQuote(missionArg)} --route ${shellQuote(routeArg)} --agents ${Number(agentPolicy.requested_subagents || agentPolicy.agent_count || 1)} --json before implementation`);
|
|
580
|
+
}
|
|
581
|
+
if (!lane.fast_lane_allowed && routeRequiresSubagents(route, task, taskProfile)) {
|
|
402
582
|
actions.splice(1, 0, route?.id === 'Naruto'
|
|
403
|
-
? '
|
|
404
|
-
: 'materialize
|
|
583
|
+
? 'read subagent-plan.json, create independent disjoint slices, run the official Codex subagent workflow, wait for all requested agent threads, and integrate their results'
|
|
584
|
+
: 'materialize the route-specific subagent plan before implementation');
|
|
405
585
|
}
|
|
406
586
|
if (looksLikeProblemSolvingRequest(task))
|
|
407
587
|
actions.splice(1, 0, 'run Solution Scout web search for similar fixes before editing');
|
|
408
588
|
actions.push('refresh/validate TriWiki when required', 'finish with completion summary and Honest Mode');
|
|
409
589
|
return actions;
|
|
410
590
|
}
|
|
591
|
+
function shellQuote(value) {
|
|
592
|
+
return `'${String(value ?? '').replace(/'/g, `'"'"'`)}'`;
|
|
593
|
+
}
|
|
411
594
|
export function promptPipelineContext(prompt, route = null) {
|
|
412
595
|
const cleanPrompt = stripVisibleDecisionAnswerBlocks(prompt);
|
|
413
596
|
route = route || routePrompt(cleanPrompt);
|
|
597
|
+
if (!route)
|
|
598
|
+
return '';
|
|
414
599
|
const required = routeNeedsContext7(route, cleanPrompt);
|
|
415
600
|
const reasoning = routeReasoning(route, cleanPrompt);
|
|
416
601
|
const directFix = route?.id === 'DFix';
|
|
@@ -434,7 +619,7 @@ export function promptPipelineContext(prompt, route = null) {
|
|
|
434
619
|
'Question-shaped directive policy: before using Answer, decide whether a question is a real information request or an implicit instruction/complaint about broken behavior. Rhetorical bug reports, mandatory-policy statements, and "why is this not happening?" execution complaints must route to Naruto, not Answer.',
|
|
435
620
|
'Best-practice prompt shape: extract Goal, Context, Constraints, and Done-when before implementation; keep questions compact and only ask for answers that can change scope, safety, user-facing behavior, or acceptance criteria.',
|
|
436
621
|
chatCaptureIntakeText(),
|
|
437
|
-
'Default execution routing: general implementation/code-changing prompts
|
|
622
|
+
'Default execution routing: general implementation/code-changing prompts use the profile-selected parent-owned path; explicit Naruto or parallel work uses the Codex subagent workflow with disjoint slices, official agent threads, parent integration, and scoped verification. Answer, DFix, Help, Wiki maintenance, and safety-specific routes remain intentional exceptions.',
|
|
438
623
|
'Stance: infer the user intent aggressively from rough wording, local context, TriWiki, and conservative defaults; do not surface prequestion sheets before work.',
|
|
439
624
|
subagentExecutionPolicyText(route, cleanPrompt),
|
|
440
625
|
solutionScoutPolicyText(cleanPrompt),
|
|
@@ -443,7 +628,7 @@ export function promptPipelineContext(prompt, route = null) {
|
|
|
443
628
|
skillDreamPolicyText(),
|
|
444
629
|
route?.id === 'PPT'
|
|
445
630
|
? `${pptPipelineAllowlistPolicyText()} ${getdesignReferencePolicyText()}`
|
|
446
|
-
: `Design routing: UI/UX uses the Codex App Product Design plugin first for get-context/user-context, research/ideate,
|
|
631
|
+
: `Design routing: UI/UX uses the Codex App Product Design plugin first for get-context/user-context, research/ideate, index/image-to-code/url-to-code, audit/design-qa, and share when available. Treat design.md, design-system-builder, design-ui-editor, design-artifact-expert, and getdesign-reference as compatibility fallback only when the Product Design plugin is unavailable or an existing local design.md must be preserved. Image/logo/raster assets use imagegen, which must prefer Codex App built-in image generation documented at ${CODEX_APP_IMAGE_GENERATION_DOC_URL}. ${CODEX_IMAGEGEN_REQUIRED_POLICY} ${getdesignReferencePolicyText()}`,
|
|
447
632
|
triwikiContextTrackingText(),
|
|
448
633
|
triwikiStagePolicyText(),
|
|
449
634
|
stackCurrentDocsPolicyText(),
|
|
@@ -455,7 +640,7 @@ export function promptPipelineContext(prompt, route = null) {
|
|
|
455
640
|
if (reflectionRequiredForRoute(route))
|
|
456
641
|
lines.push(reflectionInstructionText());
|
|
457
642
|
if (route?.id === 'Naruto')
|
|
458
|
-
lines.push(
|
|
643
|
+
lines.push('Naruto route: prepare subagent-plan.json, delegate independent slices through official Codex worker/expert agent threads, record SubagentStart/SubagentStop events, wait for every requested thread, integrate the parent summary, run scoped verification, and pass naruto-gate.json. Process counts, PID evidence, clone rosters, custom active pools, and verification DAGs are not completion evidence.');
|
|
459
644
|
if (route?.id === 'Team')
|
|
460
645
|
lines.push(`Team route is a deprecated compatibility surface; use $Naruto for new execution missions. Existing Team mission observation commands remain available.`);
|
|
461
646
|
if (route?.id === 'Goal')
|
|
@@ -511,50 +696,74 @@ export function answerOnlyContext(prompt, route = routePrompt(prompt)) {
|
|
|
511
696
|
export async function prepareRoute(root, prompt, state = {}, opts = {}) {
|
|
512
697
|
const cleanPrompt = stripVisibleDecisionAnswerBlocks(prompt);
|
|
513
698
|
const route = routePrompt(cleanPrompt);
|
|
514
|
-
const
|
|
699
|
+
const codexThreadId = String(process.env.CODEX_THREAD_ID || '').trim();
|
|
700
|
+
const sessionKey = opts.sessionKey || codexThreadId || state?._session_key || null;
|
|
515
701
|
const madSksAuthorization = hasMadSksSignal(cleanPrompt);
|
|
516
702
|
const task = stripDollarCommand(stripMadSksSignal(cleanPrompt)) || stripMadSksSignal(stripDollarCommand(cleanPrompt)) || String(cleanPrompt || '').trim();
|
|
517
703
|
const explicit = Boolean(dollarCommand(cleanPrompt));
|
|
518
704
|
if (!route)
|
|
519
705
|
return { route: null, additionalContext: promptPipelineContext(prompt, null) };
|
|
520
706
|
const dreamContext = await routeSkillDreamContext(root, route, task);
|
|
707
|
+
const required = routeNeedsContext7(route, cleanPrompt);
|
|
708
|
+
const reasoning = routeReasoning(route, cleanPrompt);
|
|
709
|
+
const subagentsRequired = routeRequiresSubagents(route, cleanPrompt);
|
|
710
|
+
const finish = async (prepared) => {
|
|
711
|
+
const materialized = subagentsRequired && !['Naruto', 'Team', 'Goal'].includes(route.id)
|
|
712
|
+
? await materializeOfficialSubagentOverlay(root, prepared, route, task, { sessionKey, parentModel: opts.parentModel || null })
|
|
713
|
+
: prepared;
|
|
714
|
+
return withSkillDreamContext(materialized, dreamContext);
|
|
715
|
+
};
|
|
521
716
|
if (route.id === 'DFix')
|
|
522
|
-
return
|
|
717
|
+
return finish(await prepareDfixQuickRoute(route, task));
|
|
523
718
|
if (route.id === 'Answer')
|
|
524
|
-
return
|
|
719
|
+
return finish(await prepareAnswerOnlyRoute(route, task));
|
|
525
720
|
if (route.id === 'ComputerUse')
|
|
526
|
-
return
|
|
721
|
+
return finish(await prepareComputerUseFastRoute(route, task));
|
|
527
722
|
if (route.id === 'Wiki')
|
|
528
|
-
return
|
|
723
|
+
return finish(await prepareWikiQuickRoute(route, task));
|
|
529
724
|
if (route.id === 'Goal')
|
|
530
|
-
return
|
|
725
|
+
return finish(await prepareGoal(root, route, task, required, { sessionKey }));
|
|
531
726
|
if (route.id === 'ImageUXReview')
|
|
532
|
-
return
|
|
727
|
+
return finish(await prepareImageUxReview(root, route, task, required, { sessionKey }));
|
|
533
728
|
if (route.id === 'MadDB')
|
|
534
|
-
return
|
|
535
|
-
const required = routeNeedsContext7(route, cleanPrompt);
|
|
536
|
-
const reasoning = routeReasoning(route, cleanPrompt);
|
|
537
|
-
const nativeSessionsRequired = routeRequiresSubagents(route, cleanPrompt);
|
|
729
|
+
return finish(await prepareMadDb(root, route, task, required, { sessionKey }));
|
|
538
730
|
if (QUESTION_GATE_ROUTES.has(route.id) || route.id === 'MadSKS')
|
|
539
|
-
return
|
|
731
|
+
return finish(await prepareClarificationGate(root, route, task, required, { madSksAuthorization, sessionKey }));
|
|
732
|
+
if (route.id === 'Naruto' && subagentsRequired)
|
|
733
|
+
return finish(await prepareNaruto(root, route, task, required, { madSksAuthorization, sessionKey, parentModel: opts.parentModel || null }));
|
|
540
734
|
if (route.id === 'Naruto')
|
|
541
|
-
return
|
|
735
|
+
return finish(await prepareLightRoute(root, parentOwnedProfileRoute(route), task, required, { sessionKey }));
|
|
542
736
|
if (route.id === 'Team')
|
|
543
|
-
return
|
|
737
|
+
return finish(await prepareNaruto(root, { ...route, id: 'Naruto', command: '$Naruto', mode: 'NARUTO', stopGate: 'naruto-gate.json', requiredSkills: ['naruto', 'pipeline-runner', 'prompt-pipeline', 'honest-mode'] }, task, required, { madSksAuthorization, teamAlias: true, sessionKey, parentModel: opts.parentModel || null }));
|
|
544
738
|
if (route.id === 'Research')
|
|
545
|
-
return
|
|
739
|
+
return finish(await prepareResearch(root, route, task, required, { sessionKey }));
|
|
546
740
|
if (route.id === 'AutoResearch')
|
|
547
|
-
return
|
|
741
|
+
return finish(await prepareAutoResearch(root, route, task, required, { sessionKey }));
|
|
548
742
|
if (route.id === 'DB')
|
|
549
|
-
return
|
|
743
|
+
return finish(await prepareDb(root, route, task, required, { sessionKey }));
|
|
550
744
|
if (route.id === 'GX')
|
|
551
|
-
return
|
|
745
|
+
return finish(await prepareGx(root, route, task, required, { sessionKey }));
|
|
552
746
|
if (explicit || required)
|
|
553
|
-
return
|
|
554
|
-
return
|
|
747
|
+
return finish(await prepareLightRoute(root, route, task, required, { sessionKey }));
|
|
748
|
+
return finish({
|
|
555
749
|
route,
|
|
556
|
-
additionalContext: `${promptPipelineContext(prompt, route)}\n\nReasoning: ${reasoning.effort} (${reasoning.reason}); temporary profile ${reasoning.profile}.\nRequired skills: ${route.requiredSkills.join(', ')}.\
|
|
557
|
-
}
|
|
750
|
+
additionalContext: `${promptPipelineContext(prompt, route)}\n\nReasoning: ${reasoning.effort} (${reasoning.reason}); temporary profile ${reasoning.profile}.\nRequired skills: ${route.requiredSkills.join(', ')}.\nOfficial subagents required: ${subagentsRequired ? 'yes' : 'no'}.`
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
function parentOwnedProfileRoute(route) {
|
|
754
|
+
return {
|
|
755
|
+
...route,
|
|
756
|
+
id: 'SKS',
|
|
757
|
+
command: '$SKS',
|
|
758
|
+
mode: 'SKS',
|
|
759
|
+
route: 'profiled parent-owned execution',
|
|
760
|
+
description: 'Parent-owned bounded execution selected by the task profile; no subagent workflow is required.',
|
|
761
|
+
requiredSkills: ['pipeline-runner', 'prompt-pipeline', 'honest-mode'],
|
|
762
|
+
lifecycle: ['task_profile', 'ownership', 'focused_implementation', 'listed_verification', 'honest_summary'],
|
|
763
|
+
stopGate: 'honest_mode',
|
|
764
|
+
coverage_required: false,
|
|
765
|
+
explicit_invocation: false
|
|
766
|
+
};
|
|
558
767
|
}
|
|
559
768
|
async function routeSkillDreamContext(root, route, task) {
|
|
560
769
|
try {
|
|
@@ -695,14 +904,13 @@ export async function activeRouteContext(root, state) {
|
|
|
695
904
|
? ' Context7 evidence is still required before completion: use resolve-library-id, then query-docs (or legacy get-library-docs).'
|
|
696
905
|
: '';
|
|
697
906
|
const roles = state.role_counts ? ` Role counts: ${formatLegacyRoleCounts(state.role_counts)}.` : '';
|
|
698
|
-
return `
|
|
907
|
+
return `Legacy Team mission ${state.mission_id || 'latest'} must keep its existing live transcript and compatibility artifacts current.${roles} New Team invocations redirect to the Naruto official Codex subagent workflow; this context is only for finishing a pre-6.1.1 Team mission. Preserve its original minimum ${MIN_TEAM_REVIEWER_LANES}-lane review/integration and ${TEAM_SESSION_CLEANUP_ARTIFACT} contract before reflection/final. ${MIN_TEAM_REVIEW_POLICY_TEXT} Inspect with sks team log/watch ${state.mission_id || 'latest'}.${reasoningNote}${context7}${planNote}`;
|
|
699
908
|
}
|
|
700
909
|
if (state.mode === 'NARUTO') {
|
|
701
|
-
|
|
702
|
-
return `Active Naruto mission ${state.mission_id || 'latest'} must keep clone/worker evidence current.${clones} Use sks naruto status ${state.mission_id || 'latest'} --json, inspect .sneakoscope/missions/${state.mission_id || 'latest'}/naruto-gate.json and agents/agent-proof-evidence.json, then continue until the Naruto gate passes or a hard blocker is recorded.${reasoningNote}${planNote}`;
|
|
910
|
+
return `Active Naruto mission ${state.mission_id || 'latest'} uses the official Codex subagent workflow. Read subagent-plan.json, keep ${SUBAGENT_EVENT_LOG_FILENAME} and ${SUBAGENT_EVIDENCE_FILENAME} current from SubagentStart/SubagentStop, wait for all requested agent threads, then return the exact sks.subagent-parent-summary.v1 JSON result so SKS can persist ${SUBAGENT_PARENT_SUMMARY_FILENAME} and derive naruto-summary.json/naruto-gate.json. Do not substitute process counts, PID evidence, clone artifacts, or a custom active pool.${reasoningNote}${planNote}`;
|
|
703
911
|
}
|
|
704
912
|
if (state.subagents_required && !(await hasSubagentEvidence(root, state))) {
|
|
705
|
-
return `Active SKS route ${id} requires
|
|
913
|
+
return `Active SKS route ${id} requires official subagent evidence before completion. Delegate independent slices to worker/expert custom agents, record matched SubagentStart/SubagentStop thread ids, wait for every requested agent thread, and provide the parent integration summary.${reasoningNote}${planNote}`;
|
|
706
914
|
}
|
|
707
915
|
if (state.mode === 'GOAL')
|
|
708
916
|
return `Active Goal mission ${state.mission_id || 'latest'} uses Codex native /goal continuation. Inspect .sneakoscope/missions/${state.mission_id || 'latest'}/${GOAL_WORKFLOW_ARTIFACT}, then use /goal create, pause, resume, or clear in the Codex runtime as appropriate.${planNote}`;
|
|
@@ -728,7 +936,17 @@ async function prepareGoal(root, route, task, required, opts = {}) {
|
|
|
728
936
|
const { id, dir, mission } = await createMission(root, { mode: 'goal', prompt: task, sessionKey: opts.sessionKey });
|
|
729
937
|
const workflow = await writeGoalWorkflow(dir, mission, { action: 'create', prompt: task });
|
|
730
938
|
await writeJsonAtomic(path.join(dir, 'route-context.json'), { route: route.id, command: route.command, mode: route.mode, task, required_skills: route.requiredSkills, context7_required: required, native_goal: workflow.native_goal, stop_gate: route.stopGate });
|
|
731
|
-
const pipelinePlan = await writePipelinePlan(dir, {
|
|
939
|
+
const pipelinePlan = await writePipelinePlan(dir, {
|
|
940
|
+
missionId: id,
|
|
941
|
+
route,
|
|
942
|
+
task,
|
|
943
|
+
required,
|
|
944
|
+
ambiguity: { required: false, status: 'not_required' },
|
|
945
|
+
// Goal is a lightweight persistence overlay, but its mission still owns the
|
|
946
|
+
// durable request-intake/plan contract. Question-shaped or vague Goal tasks
|
|
947
|
+
// must not be mistaken for answer-only work and skip artifact writes.
|
|
948
|
+
forceLightweightPlan: true
|
|
949
|
+
});
|
|
732
950
|
const executionRoute = routePrompt(task);
|
|
733
951
|
const shouldDelegateExecution = routeRequiresSubagents(route, task)
|
|
734
952
|
&& executionRoute
|
|
@@ -811,6 +1029,7 @@ async function prepareClarificationGate(root, route, task, required, opts = {})
|
|
|
811
1029
|
const materializedLine = materialized.phase ? `\nRoute artifacts were materialized immediately; state advanced to ${materialized.phase}.` : '';
|
|
812
1030
|
return {
|
|
813
1031
|
route,
|
|
1032
|
+
mission_id: id,
|
|
814
1033
|
additionalContext: `${promptPipelineContext(task, route)}
|
|
815
1034
|
|
|
816
1035
|
Route contract auto-sealed for ${route.command}: contract answers were inferred from the prompt, TriWiki/current-code defaults, and conservative SKS safety policy.
|
|
@@ -945,10 +1164,10 @@ async function materializeMadSksAuthorization(dir, id, route, routeContext = {},
|
|
|
945
1164
|
}
|
|
946
1165
|
async function prepareResearch(root, route, task, required, opts = {}) {
|
|
947
1166
|
const { id, dir } = await createMission(root, { mode: 'research', prompt: task, sessionKey: opts.sessionKey });
|
|
948
|
-
await writeResearchPlan(dir, task, {});
|
|
1167
|
+
const researchPlan = await writeResearchPlan(dir, task, {});
|
|
949
1168
|
const pipelinePlan = await writePipelinePlan(dir, { missionId: id, route, task, required, ambiguity: { required: false, status: 'direct_route' } });
|
|
950
1169
|
await setCurrent(root, routeState(id, route, 'RESEARCH_PREPARED', required, { prompt: task, pipeline_plan_ready: validatePipelinePlan(pipelinePlan).ok, pipeline_plan_path: PIPELINE_PLAN_ARTIFACT }), { sessionKey: opts.sessionKey });
|
|
951
|
-
return routeContext(route, id, task, required,
|
|
1170
|
+
return routeContext(route, id, task, required, `Run sks research run latest as a real long-running source-gathering pass, never an automatic mock fallback; do not modify repository source code. Run layered Super Search first and allow only correlated verified-content rows to support real claims. Then run exactly three independent official research_reviewer threads on GPT-5.6 Sol Max. Any objection requires a mission-local research_synthesizer revision and a fresh three-thread review cycle; do not launch a custom scheduler or debate pool. Treat agent-ledger.json and debate-ledger.json as compatibility projections, write research-report.md and ${researchPaperArtifactForPlan(researchPlan)}, and pass the adversarial convergence, Honest Mode, and research-gate.json checks.`);
|
|
952
1171
|
}
|
|
953
1172
|
async function prepareAutoResearch(root, route, task, required, opts = {}) {
|
|
954
1173
|
const { id, dir } = await createMission(root, { mode: 'autoresearch', prompt: task, sessionKey: opts.sessionKey });
|
|
@@ -966,7 +1185,7 @@ async function prepareDb(root, route, task, required, opts = {}) {
|
|
|
966
1185
|
await writeJsonAtomic(path.join(dir, 'db-review.json'), { passed: false, scan_ok: scan.ok, destructive_operation_zero: true, safe_mcp_policy: false, context7_evidence: false, notes: [] });
|
|
967
1186
|
const pipelinePlan = await writePipelinePlan(dir, { missionId: id, route, task, required, ambiguity: { required: false, status: 'direct_route' } });
|
|
968
1187
|
await setCurrent(root, routeState(id, route, 'DB_REVIEW_REQUIRED', required, { prompt: task, pipeline_plan_ready: validatePipelinePlan(pipelinePlan).ok, pipeline_plan_path: PIPELINE_PLAN_ARTIFACT }), { sessionKey: opts.sessionKey });
|
|
969
|
-
return routeContext(route, id, task, required, '
|
|
1188
|
+
return routeContext(route, id, task, required, 'Inspect the automatically materialized db-safety-scan.json, keep database operations read-only, record safe MCP and current-docs evidence, and pass db-review.json. The legacy sks db CLI is removed; explicitly authorized SQL-plane work uses sks mad-sks.');
|
|
970
1189
|
}
|
|
971
1190
|
async function prepareMadDb(root, route, task, required, opts = {}) {
|
|
972
1191
|
const prepared = await prepareMadDbMission({ root, task, verifyTools: false, sessionKey: opts.sessionKey, route: 'MadSKS', routeCommand: '$MAD-SKS' });
|
|
@@ -1018,10 +1237,101 @@ async function prepareLightRoute(root, route, task, required, opts = {}) {
|
|
|
1018
1237
|
await setCurrent(root, routeState(id, route, 'ROUTE_CONTEXT_READY', required, { prompt: task, stop_gate: 'none', pipeline_plan_ready: validatePipelinePlan(pipelinePlan).ok, pipeline_plan_path: PIPELINE_PLAN_ARTIFACT }), { sessionKey: opts.sessionKey });
|
|
1019
1238
|
return routeContext(route, id, task, required, 'Load the route skill context, execute the smallest matching action, and finish with Honest Mode.');
|
|
1020
1239
|
}
|
|
1240
|
+
async function materializeOfficialSubagentOverlay(root, prepared, route, task, opts = {}) {
|
|
1241
|
+
const id = String(prepared?.mission_id || '').trim();
|
|
1242
|
+
if (!id)
|
|
1243
|
+
throw new Error(`official_subagent_overlay_mission_missing:${route?.id || 'unknown'}`);
|
|
1244
|
+
const dir = missionDir(root, id);
|
|
1245
|
+
const cleanTask = stripDollarCommand(task) || String(task || '').trim();
|
|
1246
|
+
await createAndWriteWorkOrderLedgerForPrompt(dir, {
|
|
1247
|
+
missionId: id,
|
|
1248
|
+
route: route?.command || route?.id || 'official-subagent-overlay',
|
|
1249
|
+
prompt: cleanTask
|
|
1250
|
+
});
|
|
1251
|
+
const requestedSubagents = requestedSubagentsFromTask(cleanTask);
|
|
1252
|
+
const observedParentModel = typeof opts.parentModel === 'string' && opts.parentModel.trim()
|
|
1253
|
+
? opts.parentModel.trim()
|
|
1254
|
+
: null;
|
|
1255
|
+
const preparation = await prepareOfficialSubagentMission({
|
|
1256
|
+
root,
|
|
1257
|
+
dir,
|
|
1258
|
+
missionId: id,
|
|
1259
|
+
goal: cleanTask,
|
|
1260
|
+
route: route?.command || route?.id || 'specialized-route',
|
|
1261
|
+
sessionScope: opts.sessionKey || null,
|
|
1262
|
+
...(requestedSubagents === undefined ? {} : { requestedSubagents }),
|
|
1263
|
+
requestedSubagentsExplicit: requestedSubagents !== undefined,
|
|
1264
|
+
mode: 'generic',
|
|
1265
|
+
observedParentModel,
|
|
1266
|
+
preparationOnly: true
|
|
1267
|
+
});
|
|
1268
|
+
const { budget, delegationPrompt, plan } = preparation;
|
|
1269
|
+
await setCurrent(root, {
|
|
1270
|
+
mission_id: id,
|
|
1271
|
+
subagents_required: true,
|
|
1272
|
+
subagents_verified: false,
|
|
1273
|
+
native_sessions_required: false,
|
|
1274
|
+
native_sessions_verified: false,
|
|
1275
|
+
agents_required: false,
|
|
1276
|
+
requested_subagents: budget.requestedSubagents,
|
|
1277
|
+
subagent_max_threads: budget.maxThreads,
|
|
1278
|
+
subagent_max_depth: budget.maxDepth,
|
|
1279
|
+
official_subagent_run_id: plan.workflow_run_id,
|
|
1280
|
+
session_scope: opts.sessionKey || null,
|
|
1281
|
+
subagent_plan_file: SUBAGENT_PLAN_FILENAME,
|
|
1282
|
+
subagent_evidence_file: SUBAGENT_EVIDENCE_FILENAME
|
|
1283
|
+
}, { sessionKey: opts.sessionKey });
|
|
1284
|
+
return {
|
|
1285
|
+
...prepared,
|
|
1286
|
+
mission_id: id,
|
|
1287
|
+
additionalContext: [
|
|
1288
|
+
prepared.additionalContext,
|
|
1289
|
+
`Official Codex subagent overlay for ${route?.command || route?.id || 'this route'}: use ${SUBAGENT_PLAN_FILENAME}, record matched SubagentStart/SubagentStop events in ${SUBAGENT_EVENT_LOG_FILENAME}, and provide the required structured parent thread-outcome summary before this route's own gate can pass. This generic overlay does not create ${NARUTO_SUMMARY_FILENAME}, ${NARUTO_GATE_FILENAME}, or close the work-order ledger.`,
|
|
1290
|
+
delegationPrompt
|
|
1291
|
+
].filter(Boolean).join('\n\n')
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1021
1294
|
async function prepareNaruto(root, route, task, required, opts = {}) {
|
|
1022
1295
|
const cleanTask = stripDollarCommand(task) || String(task || '').trim();
|
|
1023
1296
|
const fromChatImgRequired = hasFromChatImgSignal(cleanTask);
|
|
1024
|
-
const
|
|
1297
|
+
const requestedSubagents = requestedSubagentsFromTask(cleanTask);
|
|
1298
|
+
const observedParentModel = typeof opts.parentModel === 'string' && opts.parentModel.trim()
|
|
1299
|
+
? opts.parentModel.trim()
|
|
1300
|
+
: null;
|
|
1301
|
+
const mission = opts.sessionKey
|
|
1302
|
+
? await getOrCreateSessionMission(root, {
|
|
1303
|
+
mode: 'naruto',
|
|
1304
|
+
prompt: cleanTask,
|
|
1305
|
+
sessionKey: opts.sessionKey,
|
|
1306
|
+
selectMissionId: (state) => {
|
|
1307
|
+
const activeRoute = String(state?.route || state?.route_command || state?.mode || '').replace(/^\$/, '').toUpperCase();
|
|
1308
|
+
const sessionMatches = state?._session_key === sessionStateKey(opts.sessionKey);
|
|
1309
|
+
return sessionMatches && state?.mission_id && state?.route_closed !== true && activeRoute === 'NARUTO'
|
|
1310
|
+
? String(state.mission_id)
|
|
1311
|
+
: null;
|
|
1312
|
+
}
|
|
1313
|
+
})
|
|
1314
|
+
: await createMission(root, { mode: 'naruto', prompt: cleanTask, sessionKey: opts.sessionKey });
|
|
1315
|
+
const { id, dir } = mission;
|
|
1316
|
+
await createAndWriteWorkOrderLedgerForPrompt(dir, {
|
|
1317
|
+
missionId: id,
|
|
1318
|
+
route: 'Naruto',
|
|
1319
|
+
prompt: cleanTask
|
|
1320
|
+
});
|
|
1321
|
+
const preparation = await prepareOfficialSubagentMission({
|
|
1322
|
+
root,
|
|
1323
|
+
dir,
|
|
1324
|
+
missionId: id,
|
|
1325
|
+
goal: cleanTask,
|
|
1326
|
+
route: '$Naruto',
|
|
1327
|
+
sessionScope: opts.sessionKey || null,
|
|
1328
|
+
...(requestedSubagents === undefined ? {} : { requestedSubagents }),
|
|
1329
|
+
requestedSubagentsExplicit: requestedSubagents !== undefined,
|
|
1330
|
+
mode: 'naruto',
|
|
1331
|
+
observedParentModel,
|
|
1332
|
+
preparationOnly: true
|
|
1333
|
+
});
|
|
1334
|
+
const { budget, delegationPrompt, workflowRunId, taskProfile, officialConfig, triwikiAttention, parentModelMatch } = preparation;
|
|
1025
1335
|
const routeContextPayload = {
|
|
1026
1336
|
route: 'Naruto',
|
|
1027
1337
|
command: '$Naruto',
|
|
@@ -1030,34 +1340,34 @@ async function prepareNaruto(root, route, task, required, opts = {}) {
|
|
|
1030
1340
|
required_skills: route.requiredSkills || ['naruto', 'pipeline-runner', 'prompt-pipeline', 'honest-mode'],
|
|
1031
1341
|
context7_required: required,
|
|
1032
1342
|
context_tracking: triwikiContextTracking(),
|
|
1033
|
-
stop_gate:
|
|
1343
|
+
stop_gate: NARUTO_GATE_FILENAME,
|
|
1344
|
+
workflow: 'official_codex_subagent',
|
|
1345
|
+
workflow_run_id: workflowRunId,
|
|
1346
|
+
session_scope: opts.sessionKey || null,
|
|
1347
|
+
requested_subagents: budget.requestedSubagents,
|
|
1348
|
+
requested_subagents_explicit: requestedSubagents !== undefined,
|
|
1349
|
+
max_threads: budget.maxThreads,
|
|
1350
|
+
max_depth: budget.maxDepth,
|
|
1351
|
+
parent_model_policy: NARUTO_PARENT_MODEL,
|
|
1352
|
+
observed_parent_model: observedParentModel,
|
|
1353
|
+
parent_model_match: parentModelMatch,
|
|
1354
|
+
config_sources: officialConfig.sources,
|
|
1355
|
+
config_blockers: officialConfig.blockers,
|
|
1356
|
+
triwiki_attention: triwikiAttention,
|
|
1034
1357
|
team_alias: opts.teamAlias === true,
|
|
1035
1358
|
from_chat_img_required: fromChatImgRequired,
|
|
1036
1359
|
mad_sks_authorization: Boolean(opts.madSksAuthorization)
|
|
1037
1360
|
};
|
|
1038
1361
|
await writeJsonAtomic(path.join(dir, 'route-context.json'), routeContextPayload);
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
concurrency_governor_ready: false,
|
|
1049
|
-
active_pool_ready: false,
|
|
1050
|
-
verification_dag_ready: false,
|
|
1051
|
-
gpt_final_pack_ready: false,
|
|
1052
|
-
zellij_dashboard_ready: false,
|
|
1053
|
-
native_agent_proof: false,
|
|
1054
|
-
final_arbiter_accepted: false,
|
|
1055
|
-
session_cleanup: false,
|
|
1056
|
-
...(fromChatImgRequired ? { from_chat_img_required: true, from_chat_img_request_coverage: false } : {}),
|
|
1057
|
-
blockers: ['naruto_run_not_started'],
|
|
1058
|
-
updated_at: nowIso()
|
|
1059
|
-
});
|
|
1060
|
-
const pipelinePlan = await writePipelinePlan(dir, { missionId: id, route, task: cleanTask, required, ambiguity: { required: false, status: opts.teamAlias ? 'team_alias_to_naruto' : 'direct_naruto' } });
|
|
1362
|
+
if (fromChatImgRequired) {
|
|
1363
|
+
const gate = await readJson(path.join(dir, NARUTO_GATE_FILENAME), {});
|
|
1364
|
+
await writeJsonAtomic(path.join(dir, NARUTO_GATE_FILENAME), {
|
|
1365
|
+
...gate,
|
|
1366
|
+
from_chat_img_required: true,
|
|
1367
|
+
from_chat_img_request_coverage: false
|
|
1368
|
+
});
|
|
1369
|
+
}
|
|
1370
|
+
const pipelinePlan = await writePipelinePlan(dir, { missionId: id, route, task: cleanTask, taskProfile, required, ambiguity: { required: false, status: opts.teamAlias ? 'team_alias_to_naruto' : 'direct_naruto' } });
|
|
1061
1371
|
await setCurrent(root, routeState(id, route, 'NARUTO_READY', required, {
|
|
1062
1372
|
prompt: cleanTask,
|
|
1063
1373
|
route: 'Naruto',
|
|
@@ -1066,26 +1376,45 @@ async function prepareNaruto(root, route, task, required, opts = {}) {
|
|
|
1066
1376
|
implementation_allowed: true,
|
|
1067
1377
|
ambiguity_gate_required: false,
|
|
1068
1378
|
ambiguity_gate_passed: true,
|
|
1069
|
-
stop_gate:
|
|
1379
|
+
stop_gate: NARUTO_GATE_FILENAME,
|
|
1070
1380
|
required_skills: routeContextPayload.required_skills,
|
|
1071
1381
|
subagents_required: true,
|
|
1072
|
-
native_sessions_required:
|
|
1382
|
+
native_sessions_required: false,
|
|
1383
|
+
agents_required: false,
|
|
1384
|
+
requested_subagents: budget.requestedSubagents,
|
|
1385
|
+
subagent_max_threads: budget.maxThreads,
|
|
1386
|
+
subagent_max_depth: budget.maxDepth,
|
|
1387
|
+
subagent_plan_file: SUBAGENT_PLAN_FILENAME,
|
|
1388
|
+
subagent_evidence_file: SUBAGENT_EVIDENCE_FILENAME,
|
|
1389
|
+
official_subagent_run_id: workflowRunId,
|
|
1390
|
+
session_scope: opts.sessionKey || null,
|
|
1391
|
+
observed_parent_model: observedParentModel,
|
|
1392
|
+
parent_model_match: parentModelMatch,
|
|
1073
1393
|
from_chat_img_required: fromChatImgRequired,
|
|
1074
|
-
naruto_gate_file:
|
|
1394
|
+
naruto_gate_file: NARUTO_GATE_FILENAME,
|
|
1075
1395
|
pipeline_plan_ready: validatePipelinePlan(pipelinePlan).ok,
|
|
1076
1396
|
pipeline_plan_path: PIPELINE_PLAN_ARTIFACT
|
|
1077
1397
|
}), { sessionKey: opts.sessionKey });
|
|
1078
|
-
return routeContext(route, id, cleanTask, required, `
|
|
1398
|
+
return routeContext(route, id, cleanTask, required, `Use the delegation context below in the current Codex parent session. First replace parent_required with a defensible independent/disjoint decomposition, then spawn and wait for every requested agent thread. Record official events and integrate the parent summary before passing ${NARUTO_GATE_FILENAME}.\n\n${delegationPrompt}`);
|
|
1399
|
+
}
|
|
1400
|
+
function requestedSubagentsFromTask(task) {
|
|
1401
|
+
const text = String(task || '');
|
|
1402
|
+
const value = text.match(/(?:^|\s)--agents(?:=|\s+)(\d+)\b/i)?.[1];
|
|
1403
|
+
if (!value)
|
|
1404
|
+
return undefined;
|
|
1405
|
+
const parsed = Number.parseInt(value, 10);
|
|
1406
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
1079
1407
|
}
|
|
1080
1408
|
function routeState(id, route, phase, context7Required, extra = {}) {
|
|
1081
1409
|
const reasoning = routeReasoning(route, extra.prompt || '');
|
|
1082
|
-
const
|
|
1083
|
-
return { mission_id: id, route: route.id, route_command: route.command, mode: route.mode, phase, context7_required: context7Required, context7_verified: false, subagents_required:
|
|
1410
|
+
const subagentsRequired = routeRequiresSubagents(route, extra.prompt || '');
|
|
1411
|
+
return { mission_id: id, route: route.id, route_command: route.command, mode: route.mode, phase, context7_required: context7Required, context7_verified: false, subagents_required: subagentsRequired, subagents_verified: !subagentsRequired, native_sessions_required: false, native_sessions_verified: false, agents_required: subagentsRequired ? false : routeRequiresAgentIntake(route, { task: extra.prompt }), reflection_required: reflectionRequiredForRoute(route), visible_progress_required: true, context_tracking: 'triwiki', required_skills: route.requiredSkills, stop_gate: route.stopGate, reasoning_effort: reasoning.effort, reasoning_profile: reasoning.profile, reasoning_temporary: true, goal_continuation: ambientGoalContinuation(), ...extra };
|
|
1084
1412
|
}
|
|
1085
1413
|
function routeContext(route, id, task, required, next) {
|
|
1086
1414
|
const visibleTask = stripVisibleDecisionAnswerBlocks(task);
|
|
1087
1415
|
return {
|
|
1088
1416
|
route,
|
|
1417
|
+
mission_id: id,
|
|
1089
1418
|
additionalContext: `${promptPipelineContext(visibleTask, route)}
|
|
1090
1419
|
|
|
1091
1420
|
${route.command} route prepared.
|
|
@@ -1096,7 +1425,7 @@ Execution prompt: request-intake.transformed_prompt
|
|
|
1096
1425
|
Pipeline plan: .sneakoscope/missions/${id}/${PIPELINE_PLAN_ARTIFACT}
|
|
1097
1426
|
Required skills: ${route.requiredSkills.join(', ')}
|
|
1098
1427
|
Stop gate: ${route.stopGate}
|
|
1099
|
-
|
|
1428
|
+
Official subagents: ${routeRequiresSubagents(route, visibleTask) ? 'required for this explicit Naruto/parallel task; use independent disjoint slices, official agent threads, matched SubagentStart/SubagentStop events, and a parent integration summary.' : 'not required by this task profile; keep the work parent-owned unless a concrete independent decomposition emerges.'}
|
|
1100
1429
|
TriWiki: use only the latest coordinate+voxel-overlay context pack before each route phase, hydrate low-trust claims during the phase, refresh after new findings or artifact changes, and validate before handoffs/final claims. Coordinate-only legacy packs are invalid and must be refreshed before pipeline decisions.
|
|
1101
1430
|
Final closeout: every pipeline final answer must summarize what was done, what changed for the user/repo, what was verified, and any remaining gaps.
|
|
1102
1431
|
${reflectionRequiredForRoute(route) ? `Reflection: ${reflectionInstructionText()}` : 'Reflection: not required for this lightweight route.'}
|
|
@@ -1175,19 +1504,26 @@ export async function recordContext7Evidence(root, state, payload) {
|
|
|
1175
1504
|
return record;
|
|
1176
1505
|
}
|
|
1177
1506
|
export async function recordSubagentEvidence(root, state, payload) {
|
|
1178
|
-
const stage = subagentStage(payload);
|
|
1179
|
-
if (!stage)
|
|
1180
|
-
return null;
|
|
1181
1507
|
if (!await shouldWritePipelineEvidence(root, state))
|
|
1182
1508
|
return null;
|
|
1183
|
-
const record = { ts: nowIso(), stage, tool: subagentToolName(payload), payload_keys: Object.keys(payload || {}).sort() };
|
|
1184
1509
|
const id = state?.mission_id;
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1510
|
+
const dir = id ? missionDir(root, id) : path.join(root, '.sneakoscope', 'state', 'subagents');
|
|
1511
|
+
const explicitEventName = payload?.hook_event_name
|
|
1512
|
+
|| payload?.hookEventName
|
|
1513
|
+
|| payload?.event_name
|
|
1514
|
+
|| payload?.eventName
|
|
1515
|
+
|| payload?.event
|
|
1516
|
+
|| null;
|
|
1517
|
+
const officialEvent = await recordSubagentEvent(dir, payload, explicitEventName);
|
|
1518
|
+
if (officialEvent)
|
|
1519
|
+
return officialEvent;
|
|
1520
|
+
if (!legacySubagentWorkflowEnabled(state))
|
|
1521
|
+
return null;
|
|
1522
|
+
const stage = legacySubagentStage(payload);
|
|
1523
|
+
if (!stage)
|
|
1524
|
+
return null;
|
|
1525
|
+
const record = { ts: nowIso(), stage, tool: legacySubagentToolName(payload), payload_keys: Object.keys(payload || {}).sort(), workflow: 'legacy_process_swarm' };
|
|
1526
|
+
await appendJsonl(path.join(dir, 'subagent-evidence.jsonl'), record);
|
|
1191
1527
|
return record;
|
|
1192
1528
|
}
|
|
1193
1529
|
async function shouldWritePipelineEvidence(root, state = {}) {
|
|
@@ -1195,11 +1531,11 @@ async function shouldWritePipelineEvidence(root, state = {}) {
|
|
|
1195
1531
|
return exists(missionDir(root, state.mission_id));
|
|
1196
1532
|
return exists(path.join(root, '.sneakoscope', 'state', 'current.json'));
|
|
1197
1533
|
}
|
|
1198
|
-
function
|
|
1534
|
+
function legacySubagentToolName(payload) {
|
|
1199
1535
|
const obj = payload || {};
|
|
1200
1536
|
return String(obj.tool_name || obj.name || obj.tool?.name || obj.mcp_tool || obj.command || obj.type || '');
|
|
1201
1537
|
}
|
|
1202
|
-
function
|
|
1538
|
+
function legacySubagentStage(payload) {
|
|
1203
1539
|
const hay = JSON.stringify(payload || {});
|
|
1204
1540
|
// Codex 0.139 renamed multi-agent v2 `close_agent` to `interrupt_agent`;
|
|
1205
1541
|
// accept both so cockpit evidence keeps classifying on newer CLIs.
|
|
@@ -1209,10 +1545,8 @@ function subagentStage(payload) {
|
|
|
1209
1545
|
return 'exception';
|
|
1210
1546
|
if (/spawn_agent/i.test(hay))
|
|
1211
1547
|
return 'spawn_agent';
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
return 'result';
|
|
1215
|
-
}
|
|
1548
|
+
if (/interrupt_agent|close_agent/i.test(hay))
|
|
1549
|
+
return 'result';
|
|
1216
1550
|
if (/wait_agent|completed|final/i.test(hay))
|
|
1217
1551
|
return 'result';
|
|
1218
1552
|
return 'subagent';
|
|
@@ -1220,8 +1554,44 @@ function subagentStage(payload) {
|
|
|
1220
1554
|
export async function subagentEvidence(root, state) {
|
|
1221
1555
|
const id = state?.mission_id;
|
|
1222
1556
|
if (!id)
|
|
1223
|
-
return { spawn: false, result: false, exception: false, ok: false, count: 0 };
|
|
1224
|
-
const
|
|
1557
|
+
return { spawn: false, result: false, exception: false, ok: false, count: 0, workflow: 'official_codex_subagent' };
|
|
1558
|
+
const dir = missionDir(root, id);
|
|
1559
|
+
const plan = await readJson(path.join(dir, 'subagent-plan.json'), null).catch(() => null);
|
|
1560
|
+
if (plan?.workflow === 'official_codex_subagent') {
|
|
1561
|
+
const [events, persistedParentSummary, summary, canonical] = await Promise.all([
|
|
1562
|
+
readSubagentEvents(dir),
|
|
1563
|
+
readJson(path.join(dir, SUBAGENT_PARENT_SUMMARY_FILENAME), null).catch(() => null),
|
|
1564
|
+
readJson(path.join(dir, 'naruto-summary.json'), null).catch(() => null),
|
|
1565
|
+
readJson(path.join(dir, SUBAGENT_EVIDENCE_FILENAME), null).catch(() => null)
|
|
1566
|
+
]);
|
|
1567
|
+
const evidence = buildSubagentEvidence({
|
|
1568
|
+
requestedSubagents: Number(plan.requested_subagents || 0),
|
|
1569
|
+
events,
|
|
1570
|
+
parentSummary: persistedParentSummary,
|
|
1571
|
+
workflowStatus: summary?.status || null,
|
|
1572
|
+
preparationOnly: summary?.status === 'delegation_context_ready' || canonical?.preparation_only === true,
|
|
1573
|
+
additionalBlockers: Array.isArray(plan.config_blockers)
|
|
1574
|
+
? plan.config_blockers.map((item) => `official_subagent_config:${String(item)}`)
|
|
1575
|
+
: []
|
|
1576
|
+
});
|
|
1577
|
+
const canonicalMismatch = canonicalEvidenceMismatch(canonical, evidence);
|
|
1578
|
+
const blockers = [...new Set([
|
|
1579
|
+
...(Array.isArray(evidence.blockers) ? evidence.blockers : []),
|
|
1580
|
+
...(canonicalMismatch ? [canonicalMismatch] : [])
|
|
1581
|
+
])];
|
|
1582
|
+
return {
|
|
1583
|
+
...evidence,
|
|
1584
|
+
ok: evidence.ok === true && blockers.length === 0,
|
|
1585
|
+
blockers,
|
|
1586
|
+
spawn: evidence.started_threads > 0,
|
|
1587
|
+
result: evidence.completed_threads > 0,
|
|
1588
|
+
exception: evidence.failed_threads > 0,
|
|
1589
|
+
count: events.length
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
if (!legacySubagentWorkflowEnabled(state))
|
|
1593
|
+
return { spawn: false, result: false, exception: false, ok: false, count: 0, workflow: 'official_codex_subagent' };
|
|
1594
|
+
const text = await readText(path.join(dir, 'subagent-evidence.jsonl'), '');
|
|
1225
1595
|
const lines = text.split(/\n/).filter(Boolean);
|
|
1226
1596
|
let spawn = false;
|
|
1227
1597
|
let result = false;
|
|
@@ -1238,11 +1608,39 @@ export async function subagentEvidence(root, state) {
|
|
|
1238
1608
|
}
|
|
1239
1609
|
catch { }
|
|
1240
1610
|
}
|
|
1241
|
-
return { spawn, result, exception, ok: spawn || exception, count: lines.length };
|
|
1611
|
+
return { spawn, result, exception, ok: spawn || exception, count: lines.length, workflow: 'legacy_process_swarm' };
|
|
1612
|
+
}
|
|
1613
|
+
function canonicalEvidenceMismatch(canonical, recomputed) {
|
|
1614
|
+
if (canonical?.schema !== 'sks.subagent-evidence.v1' || canonical?.workflow !== 'official_codex_subagent') {
|
|
1615
|
+
return 'persisted_subagent_evidence_schema_invalid';
|
|
1616
|
+
}
|
|
1617
|
+
const scalarKeys = [
|
|
1618
|
+
'requested_subagents', 'started_threads', 'completed_threads', 'failed_threads',
|
|
1619
|
+
'parent_summary_present', 'parent_summary_trustworthy', 'parent_summary_status',
|
|
1620
|
+
'preparation_only', 'status', 'ok'
|
|
1621
|
+
];
|
|
1622
|
+
for (const key of scalarKeys) {
|
|
1623
|
+
if (canonical?.[key] !== recomputed?.[key])
|
|
1624
|
+
return `persisted_subagent_evidence_mismatch:${key}`;
|
|
1625
|
+
}
|
|
1626
|
+
const arrayKeys = [
|
|
1627
|
+
'started_thread_ids', 'completed_thread_ids', 'failed_thread_ids', 'open_thread_ids',
|
|
1628
|
+
'unmatched_stop_thread_ids', 'ambiguous_stop_thread_ids', 'event_sources', 'blockers'
|
|
1629
|
+
];
|
|
1630
|
+
for (const key of arrayKeys) {
|
|
1631
|
+
if (JSON.stringify(canonical?.[key] || []) !== JSON.stringify(recomputed?.[key] || [])) {
|
|
1632
|
+
return `persisted_subagent_evidence_mismatch:${key}`;
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
return null;
|
|
1242
1636
|
}
|
|
1243
1637
|
export async function hasSubagentEvidence(root, state) {
|
|
1244
1638
|
return (await subagentEvidence(root, state)).ok;
|
|
1245
1639
|
}
|
|
1640
|
+
function legacySubagentWorkflowEnabled(state = {}) {
|
|
1641
|
+
return state?.legacy_subagent_workflow === true
|
|
1642
|
+
|| state?.workflow === 'legacy_process_swarm';
|
|
1643
|
+
}
|
|
1246
1644
|
function context7ToolName(payload) {
|
|
1247
1645
|
const obj = payload || {};
|
|
1248
1646
|
return String(obj.tool_name || obj.name || obj.tool?.name || obj.mcp_tool || obj.command || obj.type || '');
|