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,1232 +1,722 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
1
|
import path from 'node:path';
|
|
3
2
|
import { ui as cliUi } from '../../cli/cli-theme.js';
|
|
4
|
-
import { createMission, findLatestMission, loadMission, setCurrent } from '../mission.js';
|
|
5
|
-
import {
|
|
6
|
-
import { nowIso, readJson, sksRoot, writeJsonAtomic } from '../fsx.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import { runNarutoRealActivePool } from '../naruto/naruto-active-pool.js';
|
|
19
|
-
import { collectActualNarutoWorker, killAllActiveNarutoWorkers, spawnActualNarutoWorker } from '../naruto/naruto-real-worker-runtime.js';
|
|
20
|
-
import { runZellij } from '../zellij/zellij-command.js';
|
|
21
|
-
import { allocateNarutoTasksToWorkers } from '../naruto/naruto-allocation-policy.js';
|
|
22
|
-
import { rebalanceNarutoReadyWork } from '../naruto/naruto-rebalance-policy.js';
|
|
23
|
-
import { buildNarutoVerificationDag } from '../naruto/naruto-verification-dag.js';
|
|
24
|
-
import { runNarutoVerificationPool } from '../naruto/naruto-verification-pool.js';
|
|
25
|
-
import { evaluateNarutoFinalizer } from '../naruto/naruto-finalizer.js';
|
|
26
|
-
import { buildNarutoGptFinalPack } from '../naruto/naruto-gpt-final-pack.js';
|
|
27
|
-
import { planNarutoZellijDashboard } from '../zellij/zellij-naruto-dashboard.js';
|
|
28
|
-
import { checkPromptPlaceholders } from '../prompt/prompt-placeholder-guard.js';
|
|
29
|
-
import { evaluateGitWorktreeCapability } from '../git/git-worktree-capability.js';
|
|
30
|
-
import { buildNarutoRealWriteProof } from '../naruto/naruto-real-write-proof.js';
|
|
31
|
-
import { buildRuntimeProofSummary, renderRuntimeProofSummary } from '../agents/runtime-proof-summary.js';
|
|
32
|
-
import { writeCodex0138CapabilityArtifacts } from '../codex-control/codex-0138-capability.js';
|
|
33
|
-
import { writeCodex0139CapabilityArtifacts } from '../codex-control/codex-0139-capability.js';
|
|
34
|
-
import { writeFinalStopGate } from '../stop-gate/stop-gate-writer.js';
|
|
35
|
-
import { extractNarutoPromptPaths } from '../naruto/naruto-task-hints.js';
|
|
36
|
-
const NARUTO_RESULT_SCHEMA = 'sks.naruto-command-result.v1';
|
|
37
|
-
const NARUTO_ROUTE = '$Naruto';
|
|
38
|
-
// $Naruto — Shadow Clone Swarm (影分身 / Kage Bunshin no Jutsu).
|
|
39
|
-
// A high-scale variant of the native agent orchestrator that fans out up to
|
|
40
|
-
// MAX_NARUTO_AGENT_COUNT (100) identical clone sessions in parallel, reusing the
|
|
41
|
-
// proven scheduler / work-queue / patch-swarm machinery (lease-based safe parallel
|
|
42
|
-
// writes). The standard 20-agent ceiling is lifted only for this route.
|
|
3
|
+
import { createMission, findLatestMission, getOrCreateSessionMission, loadStateForSession, loadMission, sessionStateKey, setCurrent } from '../mission.js';
|
|
4
|
+
import { closeWorkOrderLedgerForRouteResult, createAndWriteWorkOrderLedgerForPrompt } from '../work-order-ledger.js';
|
|
5
|
+
import { appendJsonl, exists, nowIso, readJson, sksRoot, writeJsonAtomic } from '../fsx.js';
|
|
6
|
+
import { SUBAGENT_EVENT_LOG_FILENAME, SUBAGENT_PARENT_SUMMARY_FILENAME, bindTrustworthySubagentParentSummaryToRun, persistOrReuseTrustworthySubagentParentSummary, readSubagentEvents, writeSubagentEvidence } from '../subagents/subagent-evidence.js';
|
|
7
|
+
import { buildNarutoHelpResult } from '../subagents/naruto-help-contract.js';
|
|
8
|
+
import { withFileLock } from '../locks/file-lock.js';
|
|
9
|
+
import { resolveSubagentThreadBudget } from '../subagents/thread-budget.js';
|
|
10
|
+
import { codexAppSessionKey, detectCodexAppSession, runOfficialSubagentWorkflow } from '../subagents/official-subagent-runner.js';
|
|
11
|
+
import { NARUTO_GATE_FILENAME, NARUTO_RESULT_SCHEMA, NARUTO_SUMMARY_FILENAME, SUBAGENT_PLAN_FILENAME, buildNarutoGateResult, buildNarutoSummary, prepareOfficialSubagentMission, writeNarutoGate } from '../subagents/official-subagent-preparation.js';
|
|
12
|
+
import { recordOfficialSubagentParentOutcomesTelemetry } from '../zellij/zellij-official-subagent-telemetry.js';
|
|
13
|
+
export { buildNarutoGateResult } from '../subagents/official-subagent-preparation.js';
|
|
14
|
+
const LEGACY_FLAG_WARNING = 'SKS: --clones is deprecated; use --agents. Naruto now uses Codex subagents.';
|
|
15
|
+
const LEGACY_WORKERS_WARNING = 'SKS: naruto workers is deprecated; use naruto subagents.';
|
|
16
|
+
const REMOVED_LEGACY_SUBCOMMANDS = new Set(['dashboard']);
|
|
43
17
|
export async function narutoCommand(commandOrArgs = 'naruto', maybeArgs = []) {
|
|
44
|
-
const args = Array.isArray(commandOrArgs) ? commandOrArgs : maybeArgs;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// `sks --mad --glm --naruto` global mode; a command-local --glm flag must
|
|
48
|
-
// never bypass the Luna/Terra/Sol catalog and backend guards below.
|
|
49
|
-
if (args.includes('--glm')) {
|
|
50
|
-
const result = {
|
|
51
|
-
schema: 'sks.naruto-command-result.v1',
|
|
52
|
-
ok: false,
|
|
53
|
-
mode: 'NARUTO',
|
|
54
|
-
status: 'blocked',
|
|
55
|
-
reason: 'naruto_gpt_5_6_family_only_glm_override_forbidden',
|
|
56
|
-
blockers: ['naruto_gpt_5_6_family_only_glm_override_forbidden'],
|
|
57
|
-
hint: 'Use normal sks naruto for Luna/Terra/Sol. The separate legacy GLM route requires: sks --mad --glm --naruto.'
|
|
58
|
-
};
|
|
59
|
-
process.exitCode = 1;
|
|
60
|
-
if (args.includes('--json'))
|
|
61
|
-
console.log(JSON.stringify(result, null, 2));
|
|
62
|
-
else
|
|
63
|
-
console.error(`$Naruto blocked: ${result.reason}. ${result.hint}`);
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
18
|
+
const args = Array.isArray(commandOrArgs) ? commandOrArgs.map(String) : maybeArgs.map(String);
|
|
19
|
+
if (args.some((arg) => arg === '--glm' || arg.startsWith('--glm=')))
|
|
20
|
+
return blockGlmOverride(args.includes('--json'));
|
|
66
21
|
const parsed = parseNarutoArgs(args);
|
|
22
|
+
if (parsed.clonesAliasUsed)
|
|
23
|
+
console.warn(LEGACY_FLAG_WARNING);
|
|
24
|
+
if (parsed.workersAliasUsed)
|
|
25
|
+
console.warn(LEGACY_WORKERS_WARNING);
|
|
26
|
+
if (parsed.argumentErrors.length) {
|
|
27
|
+
return emit(parsed, argumentBlock(parsed.argumentErrors), () => {
|
|
28
|
+
console.error(`$Naruto argument error: ${parsed.argumentErrors.join(', ')}`);
|
|
29
|
+
}, true);
|
|
30
|
+
}
|
|
31
|
+
if (parsed.unsupportedLegacyFlags.length) {
|
|
32
|
+
return emit(parsed, legacyFlagBlock(parsed.unsupportedLegacyFlags), () => {
|
|
33
|
+
console.error('$Naruto uses only the Codex official subagent workflow. Legacy process, scheduler, pool, backend, and model flags were removed.');
|
|
34
|
+
}, true);
|
|
35
|
+
}
|
|
67
36
|
if (!parsed.json)
|
|
68
|
-
cliUi.banner(parsed.action === 'run' ? '
|
|
69
|
-
if (!parsed.json && parsed.action !== 'run')
|
|
70
|
-
cliUi.ok('naruto command surface ready');
|
|
37
|
+
cliUi.banner(parsed.action === 'run' ? 'naruto subagents' : `naruto ${parsed.action}`);
|
|
71
38
|
if (parsed.action === 'help')
|
|
72
39
|
return narutoHelp(parsed);
|
|
73
40
|
if (parsed.action === 'status')
|
|
74
41
|
return narutoStatus(parsed);
|
|
75
|
-
if (parsed.action === '
|
|
76
|
-
return
|
|
77
|
-
if (parsed.action === 'workers')
|
|
78
|
-
return narutoWorkers(parsed);
|
|
42
|
+
if (parsed.action === 'subagents')
|
|
43
|
+
return narutoSubagents(parsed);
|
|
79
44
|
if (parsed.action === 'proof')
|
|
80
45
|
return narutoProof(parsed);
|
|
81
|
-
// Like the Codex CLI update prompt: check the installed zellij version and
|
|
82
|
-
// offer an upgrade to the latest stable release before the live session
|
|
83
|
-
// opens. Never blocks the run.
|
|
84
|
-
if (!parsed.json && !parsed.mock && !parsed.noOpenZellij) {
|
|
85
|
-
await maybePromptZellijUpdateForLaunch(args, { label: '$Naruto launch' }).catch(() => undefined);
|
|
86
|
-
}
|
|
87
46
|
return narutoRun(parsed);
|
|
88
47
|
}
|
|
89
48
|
async function narutoRun(parsed) {
|
|
90
|
-
// 20차 P0-2: a real (non---mock) run must never be silently downgraded to
|
|
91
|
-
// the fake Codex SDK adapter by a stray inherited env var (leaked shell
|
|
92
|
-
// export, leftover CI job config, etc). Clear the escape hatches for this
|
|
93
|
-
// process before any codex task executes; --mock runs and NODE_ENV=test
|
|
94
|
-
// are unaffected since they set/rely on these independently downstream.
|
|
95
|
-
if (!parsed.mock && process.env.NODE_ENV !== 'test') {
|
|
96
|
-
delete process.env.SKS_CODEX_SDK_FAKE;
|
|
97
|
-
delete process.env.SKS_CODEX_SDK_FIXTURE;
|
|
98
|
-
}
|
|
99
49
|
const root = await sksRoot();
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
: []
|
|
115
|
-
});
|
|
116
|
-
if (!placeholderGuard.ok) {
|
|
117
|
-
process.exitCode = 1;
|
|
50
|
+
const appSession = detectCodexAppSession();
|
|
51
|
+
const sessionKey = appSession ? codexAppSessionKey() : null;
|
|
52
|
+
if (appSession && sessionKey) {
|
|
53
|
+
return withFileLock({
|
|
54
|
+
lockPath: path.join(root, '.sneakoscope', 'state', `naruto-session-${sessionStateKey(sessionKey)}.lock`),
|
|
55
|
+
timeoutMs: 20_000,
|
|
56
|
+
staleMs: 120_000
|
|
57
|
+
}, () => narutoRunTransaction(parsed, root, appSession, sessionKey));
|
|
58
|
+
}
|
|
59
|
+
return narutoRunTransaction(parsed, root, appSession, sessionKey);
|
|
60
|
+
}
|
|
61
|
+
async function narutoRunTransaction(parsed, root, appSession, sessionKey) {
|
|
62
|
+
const mission = await resolveRunMission(root, parsed, sessionKey);
|
|
63
|
+
if (!mission) {
|
|
118
64
|
return emit(parsed, {
|
|
119
65
|
schema: NARUTO_RESULT_SCHEMA,
|
|
120
66
|
ok: false,
|
|
121
|
-
mode: 'NARUTO',
|
|
122
|
-
action: 'run',
|
|
123
67
|
status: 'blocked',
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
hint: placeholderGuard.blockers.includes('write_capable_prompt_target_paths_empty')
|
|
127
|
-
? 'Name the target source path(s), or run Naruto read-only discovery before starting a write-capable worker swarm.'
|
|
128
|
-
: null
|
|
129
|
-
}, () => {
|
|
130
|
-
console.log('$Naruto blocked before work graph creation: unresolved prompt placeholder or empty write target path.');
|
|
131
|
-
for (const blocker of placeholderGuard.blockers)
|
|
132
|
-
console.log('- ' + blocker);
|
|
133
|
-
});
|
|
68
|
+
blockers: [`naruto_mission_not_found:${parsed.missionId}`]
|
|
69
|
+
}, () => console.error(`Naruto mission not found: ${parsed.missionId}`), true);
|
|
134
70
|
}
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const gitWorktreeCapability = writeCapable
|
|
146
|
-
? await evaluateGitWorktreeCapability({ root, missionId: mission.id })
|
|
147
|
-
: null;
|
|
148
|
-
const worktreePolicy = gitWorktreeCapability?.mode === 'git-worktree'
|
|
149
|
-
? {
|
|
150
|
-
mode: 'git-worktree',
|
|
151
|
-
required: true,
|
|
152
|
-
main_repo_root: gitWorktreeCapability.detection.root,
|
|
153
|
-
worktree_root: gitWorktreeCapability.root_resolution?.root || null,
|
|
154
|
-
fallback_reason: null
|
|
155
|
-
}
|
|
156
|
-
: {
|
|
157
|
-
mode: 'patch-envelope-only',
|
|
158
|
-
required: false,
|
|
159
|
-
main_repo_root: gitWorktreeCapability?.detection.root || null,
|
|
160
|
-
worktree_root: null,
|
|
161
|
-
fallback_reason: writeCapable ? (gitWorktreeCapability?.blockers.join(';') || 'not_git_repo_or_worktree_unavailable') : 'readonly_or_write_disabled'
|
|
162
|
-
};
|
|
163
|
-
// The clone roster is the full work fan-out; live concurrency is throttled to a
|
|
164
|
-
// system-safe number so naruto never spawns the whole count at once unless an
|
|
165
|
-
// explicit operator override asks for a higher target.
|
|
166
|
-
const localWorker = await resolveNarutoLocalWorkerMode(parsed);
|
|
167
|
-
const schedulerBackend = parsed.backend;
|
|
168
|
-
const safe = systemSafeNarutoConcurrency({ backend: schedulerBackend });
|
|
169
|
-
const baseWorkGraph = buildNarutoWorkGraph({
|
|
170
|
-
prompt: parsed.prompt,
|
|
171
|
-
requestedClones: roster.agent_count,
|
|
172
|
-
totalWorkItems: parsed.workItems,
|
|
173
|
-
honorExplicitTotalWorkItems: parsed.workItemsExplicit,
|
|
174
|
-
readonly: parsed.readonly,
|
|
175
|
-
writeCapable,
|
|
176
|
-
targetPaths,
|
|
177
|
-
leaseBasePath: patchEnvelopeBasePath,
|
|
178
|
-
maxActiveWorkers: parsed.concurrency || safe.cap,
|
|
179
|
-
worktreePolicy,
|
|
180
|
-
tournament: parsed.tournament
|
|
181
|
-
});
|
|
182
|
-
const baseRoleDistribution = buildNarutoRoleDistribution(baseWorkGraph.work_items, { readonly: parsed.readonly });
|
|
183
|
-
const allocationWorkers = buildNarutoAllocationWorkers(baseWorkGraph, baseRoleDistribution, roster);
|
|
184
|
-
const allocationAssignments = allocateNarutoTasksToWorkers(baseWorkGraph.work_items, allocationWorkers);
|
|
185
|
-
const workGraph = buildNarutoWorkGraph({
|
|
186
|
-
prompt: parsed.prompt,
|
|
187
|
-
requestedClones: roster.agent_count,
|
|
188
|
-
totalWorkItems: parsed.workItems,
|
|
189
|
-
honorExplicitTotalWorkItems: parsed.workItemsExplicit,
|
|
190
|
-
readonly: parsed.readonly,
|
|
191
|
-
writeCapable,
|
|
192
|
-
targetPaths,
|
|
193
|
-
leaseBasePath: patchEnvelopeBasePath,
|
|
194
|
-
maxActiveWorkers: parsed.concurrency || safe.cap,
|
|
195
|
-
worktreePolicy,
|
|
196
|
-
allocationAssignments,
|
|
197
|
-
tournament: parsed.tournament
|
|
198
|
-
});
|
|
199
|
-
const roleDistribution = buildNarutoRoleDistribution(workGraph.work_items, { readonly: parsed.readonly });
|
|
200
|
-
const allocationPolicy = {
|
|
201
|
-
schema: 'sks.naruto-allocation-policy.v1',
|
|
202
|
-
generated_at: nowIso(),
|
|
203
|
-
ok: allocationWorkers.length > 0 && allocationAssignments.length === workGraph.work_items.length,
|
|
204
|
-
scoring_model: {
|
|
205
|
-
same_primary_role: 18,
|
|
206
|
-
declared_role: 12,
|
|
207
|
-
same_path_lane: 12,
|
|
208
|
-
overlap_each: 4,
|
|
209
|
-
assigned_task_penalty_each: -4,
|
|
210
|
-
write_conflict_penalty: -20,
|
|
211
|
-
dependency_incomplete: '-Infinity'
|
|
212
|
-
},
|
|
213
|
-
workers: allocationWorkers,
|
|
214
|
-
assignments: allocationAssignments.map((row) => ({
|
|
215
|
-
task_id: row.id,
|
|
216
|
-
owner: row.owner,
|
|
217
|
-
score: Number.isFinite(row.allocation_score) ? row.allocation_score : '-Infinity',
|
|
218
|
-
reason: row.allocation_reason,
|
|
219
|
-
role: row.required_role,
|
|
220
|
-
kind: row.kind,
|
|
221
|
-
paths: row.hints.paths,
|
|
222
|
-
domains: row.hints.domains,
|
|
223
|
-
write_paths: row.hints.writePaths
|
|
224
|
-
})),
|
|
225
|
-
blockers: allocationWorkers.length ? [] : ['naruto_allocation_workers_missing']
|
|
226
|
-
};
|
|
227
|
-
const rebalanceDecisions = rebalanceNarutoReadyWork({
|
|
228
|
-
tasks: workGraph.work_items.map((item) => ({ ...item, status: 'pending' })),
|
|
229
|
-
workers: allocationWorkers.map((worker) => ({ ...worker, alive: true, state: 'idle' })),
|
|
230
|
-
completedTaskIds: [],
|
|
231
|
-
reclaimedTaskIds: []
|
|
232
|
-
});
|
|
233
|
-
const rebalancePolicy = {
|
|
234
|
-
schema: 'sks.naruto-rebalance-policy.v1',
|
|
235
|
-
generated_at: nowIso(),
|
|
236
|
-
ok: true,
|
|
237
|
-
trigger: 'idle_worker_ready_queue',
|
|
238
|
-
decisions: rebalanceDecisions,
|
|
239
|
-
blocked_by_dependency_count: workGraph.work_items.filter((item) => item.dependencies.length > 0).length,
|
|
240
|
-
blockers: []
|
|
241
|
-
};
|
|
242
|
-
const governor = decideNarutoConcurrency({
|
|
243
|
-
requestedClones: roster.agent_count,
|
|
244
|
-
totalWorkItems: workGraph.total_work_items,
|
|
245
|
-
pendingWorkQueueSize: workGraph.total_work_items,
|
|
246
|
-
backend: schedulerBackend,
|
|
247
|
-
parallelismMode: parsed.parallelism
|
|
248
|
-
});
|
|
249
|
-
const activeCap = Math.min(safe.cap, governor.safe_active_workers);
|
|
250
|
-
const activeSlots = Math.max(1, Math.min(roster.agent_count, parsed.concurrency || activeCap, activeCap));
|
|
251
|
-
const zellijVisiblePanes = Math.max(1, Math.min(activeSlots, governor.safe_zellij_visible_panes));
|
|
252
|
-
const runPreRunSmoke = parsed.smoke === true || process.env.SKS_NARUTO_PRE_RUN_SMOKE === '1';
|
|
253
|
-
const realActivePoolSmoke = runPreRunSmoke
|
|
254
|
-
? await runNarutoControlPlaneSmoke({
|
|
255
|
-
root,
|
|
256
|
-
missionId: mission.id,
|
|
257
|
-
prompt: parsed.prompt,
|
|
258
|
-
rosterCount: roster.agent_count,
|
|
259
|
-
totalWorkItems: workGraph.total_work_items,
|
|
260
|
-
patchEnvelopeBasePath,
|
|
261
|
-
worktreePolicy,
|
|
262
|
-
governor,
|
|
263
|
-
activeSlots,
|
|
264
|
-
zellijVisiblePanes
|
|
265
|
-
})
|
|
266
|
-
: {
|
|
267
|
-
schema: 'sks.naruto-active-pool.v1',
|
|
268
|
-
ok: false,
|
|
269
|
-
status: 'skipped',
|
|
270
|
-
runtime_source_of_truth: 'agent-orchestrator-scheduler',
|
|
271
|
-
production_runtime_source_of_truth: 'agent-orchestrator-scheduler',
|
|
272
|
-
fallback_reason: 'pre_run_smoke_never_owns_production_runtime',
|
|
273
|
-
reason: 'pre_run_smoke_disabled_for_production',
|
|
274
|
-
active_cap: 0,
|
|
275
|
-
max_observed_active_workers: 0,
|
|
276
|
-
average_active_workers: 0,
|
|
277
|
-
active_pool_utilization: 0,
|
|
278
|
-
refill_latency_ms_p95: 0,
|
|
279
|
-
visible_workers: 0,
|
|
280
|
-
headless_workers: 0,
|
|
281
|
-
worker_lifecycle: [],
|
|
282
|
-
smoke_graph_total_work_items: 0
|
|
283
|
-
};
|
|
284
|
-
const verificationCommand = resolveNarutoVerificationCommand(root);
|
|
285
|
-
const verificationDag = buildNarutoVerificationDag(workGraph, { cwd: root, command: verificationCommand });
|
|
286
|
-
const gptFinalPack = buildNarutoGptFinalPack({
|
|
287
|
-
missionId: mission.id,
|
|
288
|
-
graph: workGraph,
|
|
289
|
-
roleDistribution,
|
|
290
|
-
localLlmMetrics: localWorker,
|
|
291
|
-
worktreePolicy,
|
|
292
|
-
worktreeDiffs: []
|
|
293
|
-
});
|
|
294
|
-
const zellijDashboard = planNarutoZellijDashboard({
|
|
295
|
-
targetActiveWorkers: activeSlots,
|
|
296
|
-
visiblePaneCap: governor.safe_zellij_visible_panes,
|
|
297
|
-
backpressure: governor.backpressure,
|
|
298
|
-
roles: roleDistribution.work_item_roles.map((row) => row.role),
|
|
299
|
-
backend: schedulerBackend,
|
|
300
|
-
worktreePolicy
|
|
301
|
-
});
|
|
302
|
-
const ledgerRoot = path.join(mission.dir, 'agents');
|
|
303
|
-
await writeNarutoArtifacts(ledgerRoot, {
|
|
304
|
-
workGraph,
|
|
305
|
-
roleDistribution,
|
|
306
|
-
governor,
|
|
307
|
-
realActivePool: realActivePoolSmoke,
|
|
308
|
-
allocationPolicy,
|
|
309
|
-
rebalancePolicy,
|
|
310
|
-
verificationDag,
|
|
311
|
-
gptFinalPack,
|
|
312
|
-
zellijDashboard,
|
|
313
|
-
placeholderGuard,
|
|
314
|
-
gitWorktreeCapability
|
|
315
|
-
});
|
|
316
|
-
await writeJsonAtomic(path.join(mission.dir, 'naruto-gate.json'), {
|
|
317
|
-
schema: 'sks.naruto-gate.v1',
|
|
318
|
-
passed: false,
|
|
319
|
-
mission_id: mission.id,
|
|
320
|
-
clone_roster_built: true,
|
|
321
|
-
clone_count: roster.agent_count,
|
|
322
|
-
work_graph_ready: workGraph.ok === true,
|
|
323
|
-
role_distribution_ready: roleDistribution.ok === true,
|
|
324
|
-
allocation_ready: allocationPolicy.ok === true,
|
|
325
|
-
rebalance_ready: rebalancePolicy.ok === true,
|
|
326
|
-
concurrency_governor_ready: true,
|
|
327
|
-
active_pool_ready: true,
|
|
328
|
-
verification_dag_ready: verificationDag.configured,
|
|
329
|
-
verification_dag_unconfigured_reason: verificationDag.unconfigured_reason,
|
|
330
|
-
verification_dag_executed: false,
|
|
331
|
-
gpt_final_pack_ready: Boolean(gptFinalPack?.schema),
|
|
332
|
-
zellij_dashboard_ready: zellijDashboard.ok === true,
|
|
333
|
-
native_agent_proof: false,
|
|
334
|
-
final_arbiter_accepted: false,
|
|
335
|
-
session_cleanup: false,
|
|
336
|
-
blockers: [...(workGraph.blockers || []), ...(allocationPolicy.blockers || [])],
|
|
337
|
-
updated_at: nowIso()
|
|
71
|
+
const { id, dir } = mission;
|
|
72
|
+
if (appSession && sessionKey) {
|
|
73
|
+
const pending = await readPendingAppNarutoRun(root, { id, dir }, sessionKey);
|
|
74
|
+
if (pending)
|
|
75
|
+
return emit(parsed, pending, () => renderRunResult(pending));
|
|
76
|
+
}
|
|
77
|
+
await createAndWriteWorkOrderLedgerForPrompt(dir, {
|
|
78
|
+
missionId: id,
|
|
79
|
+
route: 'Naruto',
|
|
80
|
+
prompt: parsed.prompt
|
|
338
81
|
});
|
|
82
|
+
const preparation = await withFileLock({
|
|
83
|
+
lockPath: path.join(dir, '.naruto-preparation.lock'),
|
|
84
|
+
timeoutMs: 5_000,
|
|
85
|
+
staleMs: 60_000
|
|
86
|
+
}, () => prepareOfficialSubagentMission({
|
|
87
|
+
root,
|
|
88
|
+
dir,
|
|
89
|
+
missionId: id,
|
|
90
|
+
goal: parsed.prompt,
|
|
91
|
+
route: '$Naruto',
|
|
92
|
+
sessionScope: sessionKey,
|
|
93
|
+
...(parsed.requestedSubagents === undefined ? {} : { requestedSubagents: parsed.requestedSubagents }),
|
|
94
|
+
requestedSubagentsExplicit: parsed.requestedSubagents !== undefined,
|
|
95
|
+
...(parsed.maxThreads === undefined ? {} : { maxThreads: parsed.maxThreads }),
|
|
96
|
+
mode: 'naruto',
|
|
97
|
+
readOnly: parsed.readOnly,
|
|
98
|
+
preparationOnly: true
|
|
99
|
+
}));
|
|
100
|
+
const { plan, evidence: preparationEvidence, budget, verification, delegationPrompt, workflowRunId, configBlockers } = preparation;
|
|
339
101
|
await setCurrent(root, {
|
|
340
|
-
mission_id:
|
|
102
|
+
mission_id: id,
|
|
341
103
|
route: 'Naruto',
|
|
342
104
|
route_command: '$Naruto',
|
|
343
105
|
mode: 'NARUTO',
|
|
344
|
-
phase: '
|
|
106
|
+
phase: 'NARUTO_DELEGATION_CONTEXT_READY',
|
|
345
107
|
questions_allowed: false,
|
|
346
108
|
implementation_allowed: true,
|
|
347
|
-
context7_required: false,
|
|
348
|
-
context7_verified: parsed.mock,
|
|
349
109
|
subagents_required: true,
|
|
350
110
|
subagents_verified: false,
|
|
351
|
-
native_sessions_required:
|
|
111
|
+
native_sessions_required: false,
|
|
352
112
|
native_sessions_verified: false,
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
naruto_gate_file:
|
|
113
|
+
agents_required: false,
|
|
114
|
+
requested_subagents: budget.requestedSubagents,
|
|
115
|
+
max_threads: budget.maxThreads,
|
|
116
|
+
max_depth: budget.maxDepth,
|
|
117
|
+
official_subagent_run_id: workflowRunId,
|
|
118
|
+
session_scope: sessionKey,
|
|
119
|
+
stop_gate: NARUTO_GATE_FILENAME,
|
|
120
|
+
naruto_gate_file: NARUTO_GATE_FILENAME,
|
|
361
121
|
prompt: parsed.prompt
|
|
122
|
+
}, { sessionKey });
|
|
123
|
+
const run = await runOfficialSubagentWorkflow({
|
|
124
|
+
root,
|
|
125
|
+
prompt: delegationPrompt,
|
|
126
|
+
requestedSubagents: budget.requestedSubagents,
|
|
127
|
+
maxThreads: budget.maxThreads,
|
|
128
|
+
appSession,
|
|
129
|
+
missionId: id,
|
|
130
|
+
sessionKey
|
|
362
131
|
});
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
liveZellij = await launchZellijLayout({
|
|
132
|
+
const completedPlan = await readJson(path.join(dir, SUBAGENT_PLAN_FILENAME), plan).catch(() => plan);
|
|
133
|
+
const finalBudget = resolveSubagentThreadBudget({
|
|
134
|
+
requested: Number(completedPlan?.requested_subagents || budget.requestedSubagents),
|
|
135
|
+
configuredMaxThreads: Number(completedPlan?.max_threads || budget.maxThreads)
|
|
136
|
+
});
|
|
137
|
+
const runBoundParentSummary = bindTrustworthySubagentParentSummaryToRun(run.parent_summary, workflowRunId);
|
|
138
|
+
const effectiveParentSummary = await persistOrReuseTrustworthySubagentParentSummary(dir, runBoundParentSummary, {
|
|
139
|
+
workflowStatus: run.status,
|
|
140
|
+
runId: workflowRunId
|
|
141
|
+
});
|
|
142
|
+
const evidence = await writeSubagentEvidence(dir, {
|
|
143
|
+
requestedSubagents: finalBudget.requestedSubagents,
|
|
144
|
+
parentSummary: effectiveParentSummary,
|
|
145
|
+
workflowStatus: run.status,
|
|
146
|
+
preparationOnly: appSession,
|
|
147
|
+
runId: workflowRunId,
|
|
148
|
+
additionalBlockers: configBlockers
|
|
149
|
+
});
|
|
150
|
+
if (!appSession) {
|
|
151
|
+
const parentTelemetry = await recordOfficialSubagentParentOutcomesTelemetry({
|
|
384
152
|
root,
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
153
|
+
routeMissionId: id,
|
|
154
|
+
parentSummary: effectiveParentSummary,
|
|
155
|
+
plan: completedPlan
|
|
156
|
+
}).catch(async (error) => {
|
|
157
|
+
await appendJsonl(path.join(dir, 'zellij-telemetry-warnings.jsonl'), {
|
|
158
|
+
ts: nowIso(),
|
|
159
|
+
warning: 'official_subagent_parent_outcome_telemetry_failed',
|
|
160
|
+
error: String(error?.message || error)
|
|
161
|
+
}).catch(() => undefined);
|
|
162
|
+
return null;
|
|
391
163
|
});
|
|
392
|
-
if (
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
initial_panes: 'main-only',
|
|
401
|
-
dashboard_created: false,
|
|
402
|
-
worker_panes_created: 0,
|
|
403
|
-
right_column_mode: 'spawn-on-first-worker',
|
|
404
|
-
visible_pane_cap: zellijVisiblePanes
|
|
405
|
-
});
|
|
406
|
-
console.log('Zellij: started main-only session ' + liveZellij.session_name + '; right column opens on first visible worker spawn. Attach with: ' + (liveZellij.attach_command_with_env || liveZellij.attach_command));
|
|
407
|
-
if (parsed.attach)
|
|
408
|
-
attachZellijSessionInteractive(liveZellij.session_name, { cwd: process.cwd(), configPath: liveZellij.clipboard_config_path });
|
|
409
|
-
}
|
|
410
|
-
else if (liveZellij?.ok) {
|
|
411
|
-
console.log('Zellij: optional live panes unavailable (' + ((liveZellij.warnings || []).join('; ') || liveZellij.capability?.status || 'unknown') + ')');
|
|
412
|
-
}
|
|
413
|
-
else {
|
|
414
|
-
console.log('Zellij: blocked (' + Array.from(new Set(liveZellij?.blockers || [])).join('; ') + ')');
|
|
164
|
+
if (parentTelemetry?.blocker) {
|
|
165
|
+
await appendJsonl(path.join(dir, 'zellij-telemetry-warnings.jsonl'), {
|
|
166
|
+
ts: nowIso(),
|
|
167
|
+
warning: 'official_subagent_parent_outcome_telemetry_incomplete',
|
|
168
|
+
blocker: parentTelemetry.blocker,
|
|
169
|
+
failed_mission_ids: 'failed_mission_ids' in parentTelemetry ? parentTelemetry.failed_mission_ids : [],
|
|
170
|
+
skipped_thread_ids: 'skipped_thread_ids' in parentTelemetry ? parentTelemetry.skipped_thread_ids : []
|
|
171
|
+
}).catch(() => undefined);
|
|
415
172
|
}
|
|
416
173
|
}
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
workerPlacement: parsed.json || parsed.noOpenZellij ? 'process' : 'zellij-pane',
|
|
444
|
-
zellijPaneWorker: true,
|
|
445
|
-
zellijVisiblePaneCap: zellijVisiblePanes,
|
|
446
|
-
...(parsed.fastMode === undefined ? {} : { fastMode: parsed.fastMode }),
|
|
447
|
-
...(parsed.serviceTier === undefined ? {} : { serviceTier: parsed.serviceTier }),
|
|
448
|
-
noFast: parsed.noFast,
|
|
449
|
-
writeMode: writeCapable ? parsed.writeMode || 'parallel' : 'off',
|
|
450
|
-
applyPatches: parsed.applyPatches,
|
|
451
|
-
dryRunPatches: parsed.dryRunPatches,
|
|
452
|
-
maxWriteAgents: parsed.maxWriteAgents,
|
|
453
|
-
gitWorktreePolicy: worktreePolicy,
|
|
454
|
-
narutoWorkGraph: workGraph,
|
|
455
|
-
narutoAllocationPolicy: allocationPolicy,
|
|
456
|
-
narutoRebalancePolicy: rebalancePolicy,
|
|
457
|
-
json: parsed.json
|
|
458
|
-
}));
|
|
459
|
-
const realWriteProof = await maybeWriteNarutoRealWriteProof(mission.dir, mission.id, parsed, result);
|
|
460
|
-
const parallelRuntime = result.parallel_runtime_proof || null;
|
|
461
|
-
const nativeProofOk = result.proof?.ok === true || result.proof?.status === 'passed';
|
|
462
|
-
const finalAccepted = result.proof?.status === 'passed' || result.proof?.gpt_final_status === 'approved';
|
|
463
|
-
// Real backends must actually prove parallel runtime; mock backends (no real
|
|
464
|
-
// process fan-out to observe) and small rosters below the 16-worker proof
|
|
465
|
-
// threshold are exempt. Previously this was inverted (`!parsed.mock`), which
|
|
466
|
-
// skipped the proof precisely when it mattered most — real execution.
|
|
467
|
-
const parallelRuntimeOk = parsed.mock || roster.agent_count < 16 || (parallelRuntime?.passed === true
|
|
468
|
-
&& Number(parallelRuntime.max_observed_active_workers || 0) >= Math.min(16, activeSlots));
|
|
469
|
-
// Verification starts only after clone workers finish so two process pools do
|
|
470
|
-
// not compete for CPU, memory, and disk at the same time.
|
|
471
|
-
const verificationDagResult = verificationDag.configured && verificationDag.tasks.length > 0
|
|
472
|
-
? await runNarutoVerificationPool(verificationDag, governor, { cwd: root, logDir: path.join(mission.dir, 'agents', 'verification-logs') })
|
|
473
|
-
: null;
|
|
474
|
-
if (verificationDagResult)
|
|
475
|
-
await writeJsonAtomic(path.join(mission.dir, 'naruto-verification-dag-result.json'), verificationDagResult);
|
|
476
|
-
const verificationDagOk = !verificationDag.configured || verificationDagResult === null ? true : verificationDagResult.ok === true;
|
|
477
|
-
const regressionProof = summarizeRegressionProof(workGraph, result);
|
|
478
|
-
await writeJsonAtomic(path.join(mission.dir, 'regression-proof-summary.json'), regressionProof);
|
|
479
|
-
const tddOk = !regressionProof.required || (regressionProof.regression_test_added && regressionProof.regression_test_failed_before_fix && regressionProof.regression_test_passed_after_fix);
|
|
480
|
-
const narutoGateFullPassed = result.ok === true && nativeProofOk && finalAccepted && (realWriteProof ? realWriteProof.ok === true : true) && parallelRuntimeOk && tddOk && workGraph.ok === true && allocationPolicy.ok === true && verificationDagOk;
|
|
481
|
-
const narutoGateFullBlockers = [...(result.proof?.blockers || []), ...(realWriteProof && !realWriteProof.ok ? realWriteProof.blockers : []), ...(parallelRuntimeOk ? [] : ['naruto_parallel_runtime_proof_below_gate']), ...(tddOk ? [] : ['tdd_evidence_missing']), ...(verificationDagOk ? [] : ['naruto_verification_dag_failed']), ...(workGraph.blockers || []), ...(allocationPolicy.blockers || [])];
|
|
482
|
-
await writeJsonAtomic(path.join(mission.dir, 'naruto-gate.json'), {
|
|
483
|
-
schema: 'sks.naruto-gate.v1',
|
|
484
|
-
passed: narutoGateFullPassed,
|
|
485
|
-
mission_id: mission.id,
|
|
486
|
-
clone_roster_built: true,
|
|
487
|
-
clone_count: roster.agent_count,
|
|
488
|
-
work_graph_ready: workGraph.ok === true,
|
|
489
|
-
role_distribution_ready: roleDistribution.ok === true,
|
|
490
|
-
allocation_ready: allocationPolicy.ok === true,
|
|
491
|
-
rebalance_ready: rebalancePolicy.ok === true,
|
|
492
|
-
concurrency_governor_ready: true,
|
|
493
|
-
active_pool_ready: true,
|
|
494
|
-
verification_dag_ready: verificationDagOk,
|
|
495
|
-
verification_dag_configured: verificationDag.configured,
|
|
496
|
-
verification_dag_unconfigured_reason: verificationDag.unconfigured_reason,
|
|
497
|
-
verification_dag_executed: verificationDagResult !== null,
|
|
498
|
-
verification_dag_result: verificationDagResult ? 'naruto-verification-dag-result.json' : null,
|
|
499
|
-
gpt_final_pack_ready: Boolean(gptFinalPack?.schema),
|
|
500
|
-
zellij_dashboard_ready: zellijDashboard.ok === true,
|
|
501
|
-
native_agent_proof: nativeProofOk,
|
|
502
|
-
naruto_real_write_proof: realWriteProof ? 'naruto-real-write-proof.json' : null,
|
|
503
|
-
parallel_runtime_proof: parallelRuntimeOk,
|
|
504
|
-
regression_test_added: regressionProof.regression_test_added,
|
|
505
|
-
regression_test_failed_before_fix: regressionProof.regression_test_failed_before_fix,
|
|
506
|
-
regression_test_passed_after_fix: regressionProof.regression_test_passed_after_fix,
|
|
507
|
-
regression_proof: 'regression-proof-summary.json',
|
|
508
|
-
final_arbiter_accepted: finalAccepted,
|
|
509
|
-
session_cleanup: result.proof?.all_sessions_closed === true || nativeProofOk,
|
|
510
|
-
blockers: narutoGateFullBlockers,
|
|
511
|
-
updated_at: nowIso()
|
|
512
|
-
});
|
|
513
|
-
await closeWorkOrderLedgerForRouteResult(mission.dir, { ok: narutoGateFullPassed, blockers: narutoGateFullBlockers });
|
|
514
|
-
const clones = result.roster?.agent_count ?? roster.agent_count;
|
|
515
|
-
const localWorkerSummary = summarizeNarutoLocalWorkerResult(localWorker, result);
|
|
516
|
-
// Finalizer policy: when local LLM workers contributed patches, the GPT
|
|
517
|
-
// final arbiter must have accepted before patches are considered final.
|
|
518
|
-
const finalizer = evaluateNarutoFinalizer({
|
|
519
|
-
localParticipated: Number(localWorkerSummary?.selected_worker_count || 0) > 0,
|
|
520
|
-
gptFinalStatus: result.proof?.gpt_final_status || null,
|
|
521
|
-
applyPatches: parsed.applyPatches
|
|
522
|
-
});
|
|
523
|
-
await writeJsonAtomic(path.join(mission.dir, 'naruto-finalizer.json'), {
|
|
524
|
-
...finalizer,
|
|
525
|
-
generated_at: nowIso(),
|
|
526
|
-
mission_id: mission.id
|
|
174
|
+
const passed = run.ok === true && evidence.ok === true && appSession === false;
|
|
175
|
+
const blockers = uniqueStrings([
|
|
176
|
+
...(Array.isArray(evidence.blockers) ? evidence.blockers : []),
|
|
177
|
+
...configBlockers,
|
|
178
|
+
...(!appSession && run.ok !== true ? [`codex_parent_exit:${String(run.codex_exit_code ?? 'unknown')}`] : []),
|
|
179
|
+
...(appSession ? ['official_subagent_execution_pending_in_current_parent'] : [])
|
|
180
|
+
]);
|
|
181
|
+
const status = passed
|
|
182
|
+
? 'completed'
|
|
183
|
+
: appSession
|
|
184
|
+
? 'delegation_context_ready'
|
|
185
|
+
: run.ok === true
|
|
186
|
+
? 'incomplete'
|
|
187
|
+
: 'blocked';
|
|
188
|
+
const summary = buildNarutoSummary({
|
|
189
|
+
missionId: id,
|
|
190
|
+
workflowRunId,
|
|
191
|
+
budget: finalBudget,
|
|
192
|
+
evidence,
|
|
193
|
+
verification,
|
|
194
|
+
status,
|
|
195
|
+
ok: passed,
|
|
196
|
+
parentSummary: effectiveParentSummary,
|
|
197
|
+
blockers,
|
|
198
|
+
appSession,
|
|
199
|
+
sessionKey
|
|
527
200
|
});
|
|
528
|
-
|
|
201
|
+
await writeJsonAtomic(path.join(dir, NARUTO_SUMMARY_FILENAME), summary);
|
|
202
|
+
await writeNarutoGate(dir, { missionId: id, workflowRunId, evidence, passed, blockers });
|
|
529
203
|
await setCurrent(root, {
|
|
530
|
-
mission_id:
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
204
|
+
mission_id: id,
|
|
205
|
+
official_subagent_run_id: workflowRunId,
|
|
206
|
+
session_scope: sessionKey,
|
|
207
|
+
phase: passed ? 'NARUTO_COMPLETE' : appSession ? 'NARUTO_DELEGATION_CONTEXT_READY' : 'NARUTO_BLOCKED',
|
|
208
|
+
subagents_verified: evidence.ok === true,
|
|
209
|
+
requested_subagents: finalBudget.requestedSubagents,
|
|
210
|
+
max_threads: finalBudget.maxThreads,
|
|
211
|
+
naruto_gate_passed: passed,
|
|
212
|
+
route_closed: false
|
|
213
|
+
}, { sessionKey });
|
|
214
|
+
if (!appSession) {
|
|
215
|
+
await closeWorkOrderLedgerForRouteResult(dir, { ok: passed, blockers });
|
|
216
|
+
if (!passed)
|
|
217
|
+
process.exitCode = 1;
|
|
218
|
+
}
|
|
219
|
+
const result = {
|
|
220
|
+
...summary,
|
|
221
|
+
mission_id: id,
|
|
222
|
+
attached_to_pending_run: false,
|
|
223
|
+
additionalContext: appSession ? run.additionalContext : undefined,
|
|
224
|
+
artifacts: narutoArtifactLinks(evidence)
|
|
225
|
+
};
|
|
226
|
+
return emit(parsed, result, () => renderRunResult(result));
|
|
227
|
+
}
|
|
228
|
+
async function readPendingAppNarutoRun(root, mission, sessionKey) {
|
|
229
|
+
const [plan, evidence, summary, gate, state] = await Promise.all([
|
|
230
|
+
readJson(path.join(mission.dir, SUBAGENT_PLAN_FILENAME), null),
|
|
231
|
+
readJson(path.join(mission.dir, 'subagent-evidence.json'), null),
|
|
232
|
+
readJson(path.join(mission.dir, NARUTO_SUMMARY_FILENAME), null),
|
|
233
|
+
readJson(path.join(mission.dir, NARUTO_GATE_FILENAME), null),
|
|
234
|
+
loadStateForSession(root, sessionKey).catch(() => null)
|
|
235
|
+
]);
|
|
236
|
+
const workflowRunId = String(plan?.workflow_run_id || '').trim();
|
|
237
|
+
const sessionMatches = state?._session_key === sessionStateKey(sessionKey);
|
|
238
|
+
const pending = Boolean(workflowRunId
|
|
239
|
+
&& plan?.schema === 'sks.subagent-plan.v1'
|
|
240
|
+
&& plan?.workflow === 'official_codex_subagent'
|
|
241
|
+
&& plan?.mission_id === mission.id
|
|
242
|
+
&& plan?.session_scope === sessionKey
|
|
243
|
+
&& evidence?.run_id === workflowRunId
|
|
244
|
+
&& evidence?.preparation_only === true
|
|
245
|
+
&& evidence?.ok !== true
|
|
246
|
+
&& summary?.workflow_run_id === workflowRunId
|
|
247
|
+
&& summary?.mission_id === mission.id
|
|
248
|
+
&& summary?.app_session === true
|
|
249
|
+
&& summary?.session_scope === sessionKey
|
|
250
|
+
&& summary?.status === 'delegation_context_ready'
|
|
251
|
+
&& summary?.ok !== true
|
|
252
|
+
&& summary?.completion_evidence !== true
|
|
253
|
+
&& gate?.workflow_run_id === workflowRunId
|
|
254
|
+
&& gate?.mission_id === mission.id
|
|
255
|
+
&& gate?.passed !== true
|
|
256
|
+
&& sessionMatches
|
|
257
|
+
&& state?.mission_id === mission.id
|
|
258
|
+
&& state?.official_subagent_run_id === workflowRunId
|
|
259
|
+
&& state?.session_scope === sessionKey
|
|
260
|
+
&& state?.route_closed !== true
|
|
261
|
+
&& state?.phase === 'NARUTO_DELEGATION_CONTEXT_READY');
|
|
262
|
+
if (!pending)
|
|
263
|
+
return null;
|
|
264
|
+
return {
|
|
265
|
+
...summary,
|
|
567
266
|
schema: NARUTO_RESULT_SCHEMA,
|
|
568
|
-
ok:
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
pre_run_real_active_pool_source: runPreRunSmoke ? 'smoke_only' : 'skipped',
|
|
579
|
-
concurrency_capped: clones > (result.target_active_slots ?? activeSlots),
|
|
580
|
-
system: { cores: safe.cores, free_gb: safe.free_gb, safe_concurrency: safe.cap, heavy_backend: safe.heavy },
|
|
581
|
-
work_graph: {
|
|
582
|
-
total_work_items: workGraph.total_work_items,
|
|
583
|
-
mixed_work_kinds: workGraph.mixed_work_kinds,
|
|
584
|
-
write_allowed_count: workGraph.write_allowed_count,
|
|
585
|
-
active_wave_count: workGraph.active_waves.length,
|
|
586
|
-
parallel_write_wave_count: workGraph.active_waves.filter((wave) => wave.write_paths.length > 1).length,
|
|
587
|
-
ok: workGraph.ok,
|
|
588
|
-
worktree_policy: workGraph.worktree_policy
|
|
589
|
-
},
|
|
590
|
-
git_worktree: gitWorktreeCapability,
|
|
591
|
-
role_distribution: roleDistribution,
|
|
592
|
-
allocation_policy: allocationPolicy,
|
|
593
|
-
rebalance_policy: rebalancePolicy,
|
|
594
|
-
concurrency_governor: governor,
|
|
595
|
-
active_pool: {
|
|
596
|
-
ok: realActivePoolSmoke.ok,
|
|
597
|
-
runtime_source_of_truth: realActivePoolSmoke.runtime_source_of_truth,
|
|
598
|
-
production_runtime_source_of_truth: realActivePoolSmoke.production_runtime_source_of_truth,
|
|
599
|
-
active_cap: realActivePoolSmoke.active_cap,
|
|
600
|
-
max_observed_active_workers: realActivePoolSmoke.max_observed_active_workers,
|
|
601
|
-
average_active_workers: realActivePoolSmoke.average_active_workers,
|
|
602
|
-
active_pool_utilization: realActivePoolSmoke.active_pool_utilization,
|
|
603
|
-
refill_latency_ms_p95: realActivePoolSmoke.refill_latency_ms_p95,
|
|
604
|
-
visible_workers: realActivePoolSmoke.visible_workers,
|
|
605
|
-
headless_workers: realActivePoolSmoke.headless_workers,
|
|
606
|
-
worker_lifecycle_count: realActivePoolSmoke.worker_lifecycle.length,
|
|
607
|
-
worker_lifecycle_sample: realActivePoolSmoke.worker_lifecycle.slice(0, 5)
|
|
608
|
-
},
|
|
609
|
-
parallel_runtime: parallelRuntime ? {
|
|
610
|
-
proof_path: path.join(result.ledger_root || '', 'parallel-runtime-proof.json'),
|
|
611
|
-
max_observed_active_workers: parallelRuntime.max_observed_active_workers,
|
|
612
|
-
unique_worker_pids: parallelRuntime.unique_worker_pids,
|
|
613
|
-
speedup_ratio: parallelRuntime.speedup_ratio,
|
|
614
|
-
visible_panes: parallelRuntime.visible_panes,
|
|
615
|
-
headless_workers: parallelRuntime.headless_workers,
|
|
616
|
-
passed: parallelRuntime.passed
|
|
617
|
-
} : null,
|
|
618
|
-
parallel_write_policy: result.parallel_write_policy || null,
|
|
619
|
-
local_worker: localWorkerSummary,
|
|
620
|
-
fast_mode_policy: result.fast_mode_policy || null,
|
|
621
|
-
fast_mode_propagation: result.fast_mode_propagation ? {
|
|
622
|
-
ok: result.fast_mode_propagation.ok === true,
|
|
623
|
-
fast_mode: result.fast_mode_propagation.fast_mode,
|
|
624
|
-
service_tier: result.fast_mode_propagation.service_tier,
|
|
625
|
-
worker_process_report_count: result.fast_mode_propagation.worker_process_report_count || 0,
|
|
626
|
-
blockers: result.fast_mode_propagation.blockers || []
|
|
627
|
-
} : null,
|
|
628
|
-
finalizer,
|
|
629
|
-
regression_proof: regressionProof,
|
|
630
|
-
proof: result.proof?.status || 'missing',
|
|
631
|
-
run: compactNarutoRunResult(result),
|
|
632
|
-
zellij: null
|
|
267
|
+
ok: false,
|
|
268
|
+
completion_evidence: false,
|
|
269
|
+
status: 'delegation_context_ready',
|
|
270
|
+
workflow_run_id: workflowRunId,
|
|
271
|
+
mission_id: mission.id,
|
|
272
|
+
app_session: true,
|
|
273
|
+
session_scope: sessionKey,
|
|
274
|
+
attached_to_pending_run: true,
|
|
275
|
+
additionalContext: plan.delegation_prompt,
|
|
276
|
+
artifacts: narutoArtifactLinks(evidence)
|
|
633
277
|
};
|
|
634
|
-
summary.zellij = liveZellij;
|
|
635
|
-
return emit(parsed, summary, () => {
|
|
636
|
-
console.log('🍥 Shadow Clone Jutsu — Kage Bunshin no Jutsu');
|
|
637
|
-
console.log('Mission: ' + result.mission_id);
|
|
638
|
-
console.log('Clones: ' + summary.clones + ' / max ' + MAX_NARUTO_AGENT_COUNT + ', running ' + summary.target_active_slots + ' at a time' + (summary.concurrency_capped ? ` (throttled to host capacity: ${safe.cores} cores, ${safe.free_gb} GB free)` : ''));
|
|
639
|
-
console.log('Backend: ' + result.backend);
|
|
640
|
-
console.log('Roles: ' + roleDistribution.entries.map((entry) => `${entry.role}:${entry.count}`).join(', '));
|
|
641
|
-
console.log('Proof: ' + summary.proof);
|
|
642
|
-
if (!finalizer.ok)
|
|
643
|
-
console.log('Finalizer: blocked — ' + finalizer.blockers.join(', '));
|
|
644
|
-
if (summary.parallel_runtime) {
|
|
645
|
-
console.log('$Naruto parallel proof:');
|
|
646
|
-
console.log(' max active workers: ' + summary.parallel_runtime.max_observed_active_workers);
|
|
647
|
-
console.log(' unique PIDs: ' + summary.parallel_runtime.unique_worker_pids);
|
|
648
|
-
console.log(' speedup: ' + summary.parallel_runtime.speedup_ratio + 'x');
|
|
649
|
-
console.log(' result: ' + (summary.parallel_runtime.passed ? 'passed' : 'blocked'));
|
|
650
|
-
}
|
|
651
|
-
if (summary.zellij?.ok && summary.zellij.capability?.status === 'ok')
|
|
652
|
-
console.log('Zellij: prepared ' + zellijVisiblePanes + ' visible active clone lane(s) in ' + summary.zellij.session_name + '; dashboard tracks ' + Math.max(0, activeSlots - zellijVisiblePanes) + ' headless active worker(s)');
|
|
653
|
-
else if (summary.zellij?.ok)
|
|
654
|
-
console.log('Zellij: optional live panes unavailable (' + ((summary.zellij.warnings || []).join('; ') || summary.zellij.capability?.status || 'unknown') + ')');
|
|
655
|
-
});
|
|
656
278
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
279
|
+
function narutoArtifactLinks(evidence) {
|
|
280
|
+
return {
|
|
281
|
+
plan: SUBAGENT_PLAN_FILENAME,
|
|
282
|
+
events: SUBAGENT_EVENT_LOG_FILENAME,
|
|
283
|
+
parent_summary: evidence?.parent_summary_trustworthy === true ? SUBAGENT_PARENT_SUMMARY_FILENAME : null,
|
|
284
|
+
evidence: 'subagent-evidence.json',
|
|
285
|
+
summary: NARUTO_SUMMARY_FILENAME,
|
|
286
|
+
gate: NARUTO_GATE_FILENAME
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
async function narutoStatus(parsed) {
|
|
290
|
+
const resolved = await resolveReadMission(parsed);
|
|
291
|
+
if (!resolved)
|
|
292
|
+
return missingMission(parsed, 'status');
|
|
293
|
+
const [plan, evidence, summary, gate] = await Promise.all([
|
|
294
|
+
readJson(path.join(resolved.dir, SUBAGENT_PLAN_FILENAME), null),
|
|
295
|
+
readJson(path.join(resolved.dir, 'subagent-evidence.json'), null),
|
|
296
|
+
readJson(path.join(resolved.dir, NARUTO_SUMMARY_FILENAME), null),
|
|
297
|
+
readJson(path.join(resolved.dir, NARUTO_GATE_FILENAME), null)
|
|
669
298
|
]);
|
|
670
|
-
const
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
299
|
+
const result = {
|
|
300
|
+
schema: NARUTO_RESULT_SCHEMA,
|
|
301
|
+
ok: Boolean(plan || evidence || summary || gate),
|
|
302
|
+
action: 'status',
|
|
303
|
+
mission_id: resolved.id,
|
|
304
|
+
status: summary?.status || evidence?.status || 'prepared',
|
|
305
|
+
requested_subagents: plan?.requested_subagents ?? evidence?.requested_subagents ?? null,
|
|
306
|
+
max_threads: plan?.max_threads ?? null,
|
|
307
|
+
started_subagents: evidence?.started_threads ?? 0,
|
|
308
|
+
completed_subagents: evidence?.completed_threads ?? 0,
|
|
309
|
+
failed_subagents: evidence?.failed_threads ?? 0,
|
|
310
|
+
gate_passed: gate?.passed === true,
|
|
311
|
+
blockers: gate?.blockers || evidence?.blockers || []
|
|
312
|
+
};
|
|
313
|
+
return emit(parsed, result, () => renderStatusResult(result));
|
|
314
|
+
}
|
|
315
|
+
async function narutoSubagents(parsed) {
|
|
316
|
+
const resolved = await resolveReadMission(parsed);
|
|
317
|
+
if (!resolved)
|
|
318
|
+
return missingMission(parsed, 'subagents');
|
|
319
|
+
const [evidence, events] = await Promise.all([
|
|
320
|
+
readJson(path.join(resolved.dir, 'subagent-evidence.json'), null),
|
|
321
|
+
readSubagentEvents(resolved.dir)
|
|
685
322
|
]);
|
|
686
|
-
const
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
blockers: [
|
|
700
|
-
...(entries.length ? [] : ['patch_queue_entries_missing']),
|
|
701
|
-
...(applyRows.length ? [] : ['patch_apply_results_missing']),
|
|
702
|
-
...(result?.patch_swarm?.blockers || [])
|
|
703
|
-
]
|
|
704
|
-
});
|
|
705
|
-
await writeJsonAtomic(path.join(missionDir, 'naruto-real-write-proof.json'), proof);
|
|
706
|
-
return proof;
|
|
707
|
-
}
|
|
708
|
-
function uniqueRelValues(values) {
|
|
709
|
-
return [...new Set((Array.isArray(values) ? values : []).map((value) => String(value || '').replace(/\\/g, '/').replace(/^\.\/+/, '').trim()).filter(Boolean))].sort();
|
|
710
|
-
}
|
|
711
|
-
function compactNarutoRunResult(result) {
|
|
712
|
-
return {
|
|
713
|
-
schema: result?.schema || 'sks.agent-run.v1',
|
|
714
|
-
ok: result?.ok === true,
|
|
715
|
-
mission_id: result?.mission_id || null,
|
|
716
|
-
route: result?.route || NARUTO_ROUTE,
|
|
717
|
-
backend: result?.backend || null,
|
|
718
|
-
parallel_write_policy: result?.parallel_write_policy || null,
|
|
719
|
-
target_active_slots: result?.target_active_slots ?? null,
|
|
720
|
-
proof: result?.proof ? {
|
|
721
|
-
ok: result.proof.ok === true,
|
|
722
|
-
status: result.proof.status || null,
|
|
723
|
-
blockers: result.proof.blockers || []
|
|
724
|
-
} : null,
|
|
725
|
-
scheduler: result?.scheduler ? {
|
|
726
|
-
state: {
|
|
727
|
-
completed_count: result.scheduler.state?.completed_count ?? result.scheduler.completed_count ?? null,
|
|
728
|
-
failed_count: result.scheduler.state?.failed_count ?? result.scheduler.failed_count ?? null,
|
|
729
|
-
blocked_count: result.scheduler.state?.blocked_count ?? result.scheduler.blocked_count ?? null,
|
|
730
|
-
max_observed_active_slots: result.scheduler.state?.max_observed_active_slots ?? result.scheduler.max_observed_active_slots ?? null
|
|
731
|
-
}
|
|
732
|
-
} : null,
|
|
733
|
-
artifacts: {
|
|
734
|
-
ledger_root: result?.ledger_root || null,
|
|
735
|
-
proof: 'agent-proof-evidence.json',
|
|
736
|
-
scheduler: 'agent-scheduler-state.json',
|
|
737
|
-
native_cli_session_swarm: 'agent-native-cli-session-swarm.json',
|
|
738
|
-
naruto_real_active_pool: 'naruto-real-active-pool.json'
|
|
739
|
-
}
|
|
323
|
+
const result = {
|
|
324
|
+
schema: NARUTO_RESULT_SCHEMA,
|
|
325
|
+
ok: Boolean(evidence),
|
|
326
|
+
action: 'subagents',
|
|
327
|
+
mission_id: resolved.id,
|
|
328
|
+
requested_subagents: evidence?.requested_subagents ?? null,
|
|
329
|
+
started_subagents: evidence?.started_threads ?? 0,
|
|
330
|
+
completed_subagents: evidence?.completed_threads ?? 0,
|
|
331
|
+
failed_subagents: evidence?.failed_threads ?? 0,
|
|
332
|
+
started_thread_ids: evidence?.started_thread_ids || [],
|
|
333
|
+
completed_thread_ids: evidence?.completed_thread_ids || [],
|
|
334
|
+
failed_thread_ids: evidence?.failed_thread_ids || [],
|
|
335
|
+
events
|
|
740
336
|
};
|
|
337
|
+
return emit(parsed, result, () => renderStatusResult(result));
|
|
741
338
|
}
|
|
742
|
-
async function
|
|
743
|
-
const
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
mode: 'patch-envelope-only',
|
|
761
|
-
required: false,
|
|
762
|
-
main_repo_root: input.worktreePolicy.main_repo_root,
|
|
763
|
-
worktree_root: null,
|
|
764
|
-
fallback_reason: 'pre_run_smoke_never_owns_production_runtime'
|
|
339
|
+
async function narutoProof(parsed) {
|
|
340
|
+
const resolved = await resolveReadMission(parsed);
|
|
341
|
+
if (!resolved)
|
|
342
|
+
return missingMission(parsed, 'proof');
|
|
343
|
+
const [evidence, summary, gate] = await Promise.all([
|
|
344
|
+
readJson(path.join(resolved.dir, 'subagent-evidence.json'), null),
|
|
345
|
+
readJson(path.join(resolved.dir, NARUTO_SUMMARY_FILENAME), null),
|
|
346
|
+
readJson(path.join(resolved.dir, NARUTO_GATE_FILENAME), null)
|
|
347
|
+
]);
|
|
348
|
+
const result = {
|
|
349
|
+
schema: NARUTO_RESULT_SCHEMA,
|
|
350
|
+
ok: gate?.passed === true && evidence?.ok === true,
|
|
351
|
+
action: 'proof',
|
|
352
|
+
mission_id: resolved.id,
|
|
353
|
+
workflow: 'official_codex_subagent',
|
|
354
|
+
evidence,
|
|
355
|
+
summary,
|
|
356
|
+
gate
|
|
765
357
|
};
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
root: input.root,
|
|
771
|
-
missionId: input.missionId,
|
|
772
|
-
item,
|
|
773
|
-
placement,
|
|
774
|
-
backend: 'fake',
|
|
775
|
-
parentPrompt: input.prompt,
|
|
776
|
-
worktreePolicy: smokeWorktreePolicy,
|
|
777
|
-
zellijSessionName: `sks-${input.missionId}`,
|
|
778
|
-
visiblePaneCap: input.zellijVisiblePanes
|
|
779
|
-
}),
|
|
780
|
-
collectWorker: async (handle) => collectActualNarutoWorker(handle),
|
|
781
|
-
enqueueVerification: async () => undefined,
|
|
782
|
-
updateDashboard: async () => undefined
|
|
358
|
+
return emit(parsed, result, () => {
|
|
359
|
+
console.log(`Naruto proof ${resolved.id}: ${result.ok ? 'passed' : 'incomplete'}`);
|
|
360
|
+
if (Array.isArray(gate?.blockers) && gate.blockers.length)
|
|
361
|
+
console.log(`Blockers: ${gate.blockers.join(', ')}`);
|
|
783
362
|
});
|
|
784
|
-
return {
|
|
785
|
-
...realActivePool,
|
|
786
|
-
status: 'smoke_completed',
|
|
787
|
-
runtime_source_of_truth: 'pre_run_smoke_only',
|
|
788
|
-
production_runtime_source_of_truth: 'agent-orchestrator-scheduler',
|
|
789
|
-
fallback_reason: 'pre_run_smoke_never_owns_production_runtime',
|
|
790
|
-
smoke_graph_total_work_items: smokeGraph.total_work_items
|
|
791
|
-
};
|
|
792
363
|
}
|
|
793
|
-
function
|
|
794
|
-
const
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
const
|
|
801
|
-
const
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
};
|
|
364
|
+
function narutoHelp(parsed) {
|
|
365
|
+
const result = buildNarutoHelpResult();
|
|
366
|
+
return emit(parsed, result, () => {
|
|
367
|
+
console.log('$Naruto — Codex official subagent workflow');
|
|
368
|
+
for (const line of result.usage)
|
|
369
|
+
console.log(` ${line}`);
|
|
370
|
+
console.log(`Parent: ${result.parent.model} / ${result.parent.model_reasoning_effort}`);
|
|
371
|
+
const worker = result.agents.worker;
|
|
372
|
+
const expert = result.agents.expert;
|
|
373
|
+
if (worker)
|
|
374
|
+
console.log(`Worker: ${worker.model} / ${worker.model_reasoning_effort}`);
|
|
375
|
+
if (expert)
|
|
376
|
+
console.log(`Expert: ${expert.model} / ${expert.model_reasoning_effort}`);
|
|
377
|
+
console.log(`Default children: ${result.default_requested_subagents}; use explicit --agents N for wider parallelism`);
|
|
378
|
+
console.log(`Nesting: max_depth=${result.max_depth}; subagents must not spawn subagents`);
|
|
379
|
+
console.log('Context: bounded TriWiki attention.use_first anchors with on-demand source hydration');
|
|
380
|
+
console.log('Evidence: SubagentStop is lifecycle-only; completion requires subagent-parent-summary.json with one structured outcome per thread.');
|
|
807
381
|
});
|
|
808
382
|
}
|
|
809
|
-
function
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
383
|
+
async function resolveRunMission(root, parsed, sessionKey = null) {
|
|
384
|
+
if (parsed.missionId && parsed.missionId !== 'latest') {
|
|
385
|
+
const loaded = await loadMission(root, parsed.missionId).catch(() => null);
|
|
386
|
+
return loaded ? { id: parsed.missionId, dir: loaded.dir } : null;
|
|
387
|
+
}
|
|
388
|
+
if (sessionKey) {
|
|
389
|
+
const resolved = await getOrCreateSessionMission(root, {
|
|
390
|
+
mode: 'naruto',
|
|
391
|
+
prompt: parsed.prompt,
|
|
392
|
+
sessionKey,
|
|
393
|
+
selectMissionId: (state) => {
|
|
394
|
+
const route = String(state?.route || state?.route_command || state?.mode || '').replace(/^\$/, '').toUpperCase();
|
|
395
|
+
const sessionMatches = state?._session_key === sessionStateKey(sessionKey);
|
|
396
|
+
return sessionMatches && state?.mission_id && state?.route_closed !== true && route === 'NARUTO'
|
|
397
|
+
? String(state.mission_id)
|
|
398
|
+
: null;
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
return { id: resolved.id, dir: resolved.dir };
|
|
402
|
+
}
|
|
403
|
+
const created = await createMission(root, { mode: 'naruto', prompt: parsed.prompt, sessionKey });
|
|
404
|
+
return { id: created.id, dir: created.dir };
|
|
813
405
|
}
|
|
814
|
-
function
|
|
815
|
-
const
|
|
816
|
-
const
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
406
|
+
async function resolveReadMission(parsed) {
|
|
407
|
+
const root = await sksRoot();
|
|
408
|
+
const explicitId = parsed.missionId && parsed.missionId !== 'latest' ? parsed.missionId : null;
|
|
409
|
+
const sessionKey = detectCodexAppSession() ? codexAppSessionKey() : null;
|
|
410
|
+
let id = explicitId;
|
|
411
|
+
if (!id && sessionKey) {
|
|
412
|
+
const state = await loadStateForSession(root, sessionKey).catch(() => null);
|
|
413
|
+
const route = String(state?.route || state?.route_command || state?.mode || '').replace(/^\$/, '').toUpperCase();
|
|
414
|
+
if (state?._session_key === sessionStateKey(sessionKey) && state?.route_closed !== true && route === 'NARUTO') {
|
|
415
|
+
id = String(state.mission_id || '') || null;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (!id && !sessionKey)
|
|
419
|
+
id = await findLatestMission(root, { mode: 'naruto' });
|
|
420
|
+
if (!id)
|
|
421
|
+
return null;
|
|
422
|
+
const loaded = await loadMission(root, id).catch(() => null);
|
|
423
|
+
return loaded ? { root, id, dir: loaded.dir } : null;
|
|
424
|
+
}
|
|
425
|
+
export function parseNarutoArgs(args) {
|
|
426
|
+
const helpRequested = args.includes('--help') || args.includes('-h');
|
|
427
|
+
const validationArgs = [...args];
|
|
428
|
+
const normalized = helpRequested
|
|
429
|
+
? ['help', ...(args.includes('--json') ? ['--json'] : [])]
|
|
430
|
+
: args;
|
|
431
|
+
const first = normalized[0] && !normalized[0].startsWith('-') ? normalized[0] : '';
|
|
432
|
+
const workersAliasUsed = first === 'workers';
|
|
433
|
+
const actionName = workersAliasUsed ? 'subagents' : first;
|
|
434
|
+
const actions = new Set(['run', 'status', 'subagents', 'proof', 'help']);
|
|
435
|
+
const action = (actions.has(actionName) ? actionName : 'run');
|
|
436
|
+
const explicitAction = actions.has(actionName) || workersAliasUsed;
|
|
437
|
+
const rest = explicitAction ? normalized.slice(1) : normalized;
|
|
438
|
+
const optionArgs = validationArgs.includes('--') ? validationArgs.slice(0, validationArgs.indexOf('--')) : validationArgs;
|
|
439
|
+
const agentsOption = optionValue(optionArgs, '--agents');
|
|
440
|
+
const clonesOption = optionValue(optionArgs, '--clones');
|
|
441
|
+
const maxThreadsOption = optionValue(optionArgs, '--max-threads');
|
|
442
|
+
const missionOption = optionValue(optionArgs, '--mission');
|
|
443
|
+
const missionIdOption = optionValue(optionArgs, '--mission-id');
|
|
444
|
+
const argumentErrors = uniqueStrings([
|
|
445
|
+
...optionErrors('--agents', agentsOption, true),
|
|
446
|
+
...optionErrors('--clones', clonesOption, true),
|
|
447
|
+
...optionErrors('--max-threads', maxThreadsOption, true),
|
|
448
|
+
...optionErrors('--mission', missionOption, false),
|
|
449
|
+
...optionErrors('--mission-id', missionIdOption, false),
|
|
450
|
+
...(agentsOption.present && clonesOption.present ? ['conflicting_options:--agents,--clones'] : []),
|
|
451
|
+
...booleanOptionErrors(validationArgs),
|
|
452
|
+
...unknownOptionErrors(validationArgs)
|
|
453
|
+
]);
|
|
454
|
+
if (REMOVED_LEGACY_SUBCOMMANDS.has(String(first || '').toLowerCase())) {
|
|
455
|
+
argumentErrors.push(`removed_legacy_subcommand:${String(first).toLowerCase()}`);
|
|
456
|
+
}
|
|
457
|
+
const requestedSubagents = strictPositiveInteger(agentsOption.value ?? clonesOption.value);
|
|
458
|
+
const maxThreads = strictPositiveInteger(maxThreadsOption.value);
|
|
459
|
+
const missionFlag = missionOption.value ?? missionIdOption.value;
|
|
460
|
+
const positional = positionalValues(rest);
|
|
461
|
+
const positionalMission = action === 'status' || action === 'subagents' || action === 'proof'
|
|
462
|
+
? positional.find((value) => value === 'latest' || /^M-/.test(value))
|
|
463
|
+
: undefined;
|
|
464
|
+
const prompt = action === 'run'
|
|
465
|
+
? positional.join(' ').trim()
|
|
466
|
+
: '';
|
|
467
|
+
const positionalHead = String(positional[0] || '').toLowerCase();
|
|
468
|
+
const subcommandNames = new Set(['run', 'status', 'subagents', 'workers', 'proof', 'help']);
|
|
469
|
+
if (explicitAction && action === 'run' && REMOVED_LEGACY_SUBCOMMANDS.has(positionalHead)) {
|
|
470
|
+
argumentErrors.push(`removed_legacy_subcommand:${positionalHead}`);
|
|
471
|
+
}
|
|
472
|
+
else if (explicitAction && action === 'run' && subcommandNames.has(positionalHead)) {
|
|
473
|
+
argumentErrors.push(`misplaced_subcommand:${positionalHead}`);
|
|
820
474
|
}
|
|
475
|
+
else if (!explicitAction && REMOVED_LEGACY_SUBCOMMANDS.has(positionalHead)) {
|
|
476
|
+
argumentErrors.push(`removed_legacy_subcommand:${positionalHead}`);
|
|
477
|
+
}
|
|
478
|
+
else if (!explicitAction && subcommandNames.has(positionalHead)) {
|
|
479
|
+
argumentErrors.push(`misplaced_subcommand:${positionalHead}`);
|
|
480
|
+
}
|
|
481
|
+
if (action !== 'run') {
|
|
482
|
+
let missionConsumed = false;
|
|
483
|
+
for (const value of positional) {
|
|
484
|
+
if (!missionConsumed && positionalMission !== undefined && value === positionalMission) {
|
|
485
|
+
missionConsumed = true;
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
const normalizedValue = String(value || '').toLowerCase();
|
|
489
|
+
if (REMOVED_LEGACY_SUBCOMMANDS.has(normalizedValue)) {
|
|
490
|
+
argumentErrors.push(`removed_legacy_subcommand:${normalizedValue}`);
|
|
491
|
+
}
|
|
492
|
+
else if (subcommandNames.has(normalizedValue)) {
|
|
493
|
+
argumentErrors.push(`misplaced_subcommand:${normalizedValue}`);
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
argumentErrors.push(`unexpected_positional:${value}`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
if (action === 'run' && !prompt)
|
|
501
|
+
argumentErrors.push('empty_task');
|
|
821
502
|
return {
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
503
|
+
action,
|
|
504
|
+
prompt,
|
|
505
|
+
requestedSubagents,
|
|
506
|
+
maxThreads,
|
|
507
|
+
missionId: String(missionFlag || positionalMission || 'latest'),
|
|
508
|
+
json: normalized.includes('--json'),
|
|
509
|
+
readOnly: normalized.includes('--readonly') || normalized.includes('--read-only'),
|
|
510
|
+
clonesAliasUsed: clonesOption.present,
|
|
511
|
+
workersAliasUsed,
|
|
512
|
+
unsupportedLegacyFlags: unsupportedLegacyFlags(validationArgs),
|
|
513
|
+
argumentErrors: uniqueStrings(argumentErrors)
|
|
825
514
|
};
|
|
826
515
|
}
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
516
|
+
function positionalValues(args) {
|
|
517
|
+
const valueFlags = new Set([
|
|
518
|
+
'--agents', '--clones', '--max-threads', '--mission', '--mission-id',
|
|
519
|
+
'--backend', '--concurrency', '--target-active-slots', '--work-items',
|
|
520
|
+
'--write-mode', '--max-write-agents', '--service-tier', '--messages',
|
|
521
|
+
'--parallelism', '--tournament', '--ollama-model', '--local-model-model',
|
|
522
|
+
'--ollama-base-url', '--local-model-base-url', '--scheduler', '--scheduler-mode',
|
|
523
|
+
'--pool', '--pool-size', '--model', '--parent-model', '--worker-model',
|
|
524
|
+
'--expert-model', '--agent-model', '--clone-model', '--reasoning-effort', '--engine'
|
|
525
|
+
]);
|
|
526
|
+
const booleanFlags = new Set([
|
|
527
|
+
'--json', '--readonly', '--read-only', '--real', '--mock', '--no-open-zellij',
|
|
528
|
+
'--no-zellij', '--attach', '--smoke', '--apply-patches', '--dry-run-patches',
|
|
529
|
+
'--dry-run-patch', '--ollama', '--local-model', '--no-ollama', '--no-local-model',
|
|
530
|
+
'--parallel-write', '--fast', '--no-fast'
|
|
531
|
+
]);
|
|
532
|
+
const result = [];
|
|
533
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
534
|
+
const arg = args[index] || '';
|
|
535
|
+
if (arg === '--') {
|
|
536
|
+
result.push(...args.slice(index + 1));
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
if (valueFlags.has(arg)) {
|
|
540
|
+
index += 1;
|
|
541
|
+
continue;
|
|
542
|
+
}
|
|
543
|
+
if ([...valueFlags].some((flag) => arg.startsWith(`${flag}=`)))
|
|
544
|
+
continue;
|
|
545
|
+
if (booleanFlags.has(arg))
|
|
546
|
+
continue;
|
|
547
|
+
if (!arg.startsWith('--'))
|
|
548
|
+
result.push(arg);
|
|
852
549
|
}
|
|
550
|
+
return result;
|
|
853
551
|
}
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
552
|
+
function unsupportedLegacyFlags(args) {
|
|
553
|
+
const optionArgs = args.includes('--') ? args.slice(0, args.indexOf('--')) : args;
|
|
554
|
+
const unsupportedBoolean = [
|
|
555
|
+
'--mock', '--ollama', '--local-model', '--no-ollama', '--no-local-model',
|
|
556
|
+
'--apply-patches', '--dry-run-patches', '--dry-run-patch', '--attach', '--smoke',
|
|
557
|
+
'--parallel-write', '--fast', '--no-fast', '--real', '--no-open-zellij',
|
|
558
|
+
'--no-zellij', '--incremental', '--mad'
|
|
559
|
+
];
|
|
560
|
+
const unsupportedValues = [
|
|
561
|
+
'--backend', '--concurrency', '--target-active-slots', '--work-items', '--write-mode',
|
|
562
|
+
'--max-write-agents', '--service-tier', '--messages', '--parallelism', '--tournament',
|
|
563
|
+
'--ollama-model', '--local-model-model', '--ollama-base-url', '--local-model-base-url',
|
|
564
|
+
'--scheduler', '--scheduler-mode', '--pool', '--pool-size', '--model', '--parent-model',
|
|
565
|
+
'--worker-model', '--expert-model', '--agent-model', '--clone-model', '--reasoning-effort',
|
|
566
|
+
'--engine'
|
|
567
|
+
];
|
|
568
|
+
const flags = unsupportedBoolean.filter((flag) => optionArgs.some((arg) => arg === flag || arg.startsWith(`${flag}=`)));
|
|
569
|
+
for (const flag of unsupportedValues) {
|
|
570
|
+
const option = optionValue(optionArgs, flag);
|
|
571
|
+
if (option.present)
|
|
572
|
+
flags.push(option.value === undefined ? flag : `${flag}=${option.value}`);
|
|
573
|
+
}
|
|
574
|
+
return uniqueStrings(flags);
|
|
575
|
+
}
|
|
576
|
+
function optionValue(args, name) {
|
|
577
|
+
const values = [];
|
|
578
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
579
|
+
const arg = args[index] || '';
|
|
580
|
+
if (arg === name) {
|
|
581
|
+
const next = args[index + 1];
|
|
582
|
+
values.push(next && !next.startsWith('--') ? next : undefined);
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
585
|
+
if (arg.startsWith(`${name}=`))
|
|
586
|
+
values.push(arg.slice(name.length + 1) || undefined);
|
|
878
587
|
}
|
|
879
|
-
return '';
|
|
880
|
-
}
|
|
881
|
-
function summarizeRegressionProof(workGraph, result) {
|
|
882
|
-
const bugfixItems = (Array.isArray(workGraph?.work_items) ? workGraph.work_items : []).filter((item) => String(item?.kind || '') === 'bugfix');
|
|
883
|
-
const proofs = collectRegressionProofs(result).filter(validRegressionProof);
|
|
884
588
|
return {
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
proof_count: proofs.length,
|
|
890
|
-
regression_test_added: bugfixItems.length === 0 ? true : proofs.some((proof) => String(proof.test_file || '').trim().length > 0),
|
|
891
|
-
regression_test_failed_before_fix: bugfixItems.length === 0 ? true : proofs.some((proof) => proof.failed_before === true),
|
|
892
|
-
regression_test_passed_after_fix: bugfixItems.length === 0 ? true : proofs.some((proof) => proof.passed_after === true),
|
|
893
|
-
test_files: [...new Set(proofs.map((proof) => String(proof.test_file || '')).filter(Boolean))],
|
|
894
|
-
blockers: bugfixItems.length === 0 || proofs.length > 0 ? [] : ['tdd_evidence_missing']
|
|
589
|
+
present: values.length > 0,
|
|
590
|
+
value: values.at(-1),
|
|
591
|
+
missing: values.some((value) => value === undefined),
|
|
592
|
+
duplicate: values.length > 1
|
|
895
593
|
};
|
|
896
594
|
}
|
|
897
|
-
function
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
595
|
+
function strictPositiveInteger(value) {
|
|
596
|
+
if (value === undefined || value === null || value === '')
|
|
597
|
+
return undefined;
|
|
598
|
+
if (!/^\d+$/.test(String(value)))
|
|
599
|
+
return undefined;
|
|
600
|
+
const parsed = Number(value);
|
|
601
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined;
|
|
602
|
+
}
|
|
603
|
+
function optionErrors(name, option, numeric) {
|
|
604
|
+
const errors = [];
|
|
605
|
+
if (option.missing)
|
|
606
|
+
errors.push(`missing_option_value:${name}`);
|
|
607
|
+
if (option.duplicate)
|
|
608
|
+
errors.push(`duplicate_option:${name}`);
|
|
609
|
+
if (numeric && option.present && option.value !== undefined && strictPositiveInteger(option.value) === undefined) {
|
|
610
|
+
errors.push(`invalid_positive_integer:${name}=${option.value}`);
|
|
611
|
+
}
|
|
612
|
+
return errors;
|
|
903
613
|
}
|
|
904
|
-
function
|
|
905
|
-
|
|
614
|
+
function unknownOptionErrors(args) {
|
|
615
|
+
const canonical = new Set([
|
|
616
|
+
'--agents', '--clones', '--max-threads', '--mission', '--mission-id',
|
|
617
|
+
'--json', '--readonly', '--read-only', '--help', '-h', '--'
|
|
618
|
+
]);
|
|
619
|
+
const legacy = new Set([
|
|
620
|
+
'--mock', '--ollama', '--local-model', '--no-ollama', '--no-local-model',
|
|
621
|
+
'--apply-patches', '--dry-run-patches', '--dry-run-patch', '--attach', '--smoke',
|
|
622
|
+
'--parallel-write', '--fast', '--no-fast', '--real', '--no-open-zellij',
|
|
623
|
+
'--no-zellij', '--incremental', '--mad', '--glm', '--backend', '--concurrency',
|
|
624
|
+
'--target-active-slots', '--work-items', '--write-mode', '--max-write-agents',
|
|
625
|
+
'--service-tier', '--messages', '--parallelism', '--tournament', '--ollama-model',
|
|
626
|
+
'--local-model-model', '--ollama-base-url', '--local-model-base-url', '--scheduler',
|
|
627
|
+
'--scheduler-mode', '--pool', '--pool-size', '--model', '--parent-model', '--worker-model',
|
|
628
|
+
'--expert-model', '--agent-model', '--clone-model', '--reasoning-effort', '--engine'
|
|
629
|
+
]);
|
|
630
|
+
const errors = [];
|
|
631
|
+
const optionArgs = args.includes('--') ? args.slice(0, args.indexOf('--')) : args;
|
|
632
|
+
for (const arg of optionArgs) {
|
|
633
|
+
if (!arg.startsWith('-') || arg === '-')
|
|
634
|
+
continue;
|
|
635
|
+
const name = arg.includes('=') ? arg.slice(0, arg.indexOf('=')) : arg;
|
|
636
|
+
if (!canonical.has(name) && !legacy.has(name))
|
|
637
|
+
errors.push(`unsupported_argument:${name}`);
|
|
638
|
+
}
|
|
639
|
+
return errors;
|
|
640
|
+
}
|
|
641
|
+
function booleanOptionErrors(args) {
|
|
642
|
+
const booleanNames = new Set(['--json', '--readonly', '--read-only', '--help', '-h']);
|
|
643
|
+
const optionArgs = args.includes('--') ? args.slice(0, args.indexOf('--')) : args;
|
|
644
|
+
const errors = [];
|
|
645
|
+
for (const arg of optionArgs) {
|
|
646
|
+
if (!arg.includes('='))
|
|
647
|
+
continue;
|
|
648
|
+
const name = arg.slice(0, arg.indexOf('='));
|
|
649
|
+
if (booleanNames.has(name))
|
|
650
|
+
errors.push(`boolean_option_value_not_supported:${name}`);
|
|
651
|
+
}
|
|
652
|
+
return errors;
|
|
906
653
|
}
|
|
907
|
-
|
|
908
|
-
const
|
|
909
|
-
const id = parsed.missionId && parsed.missionId !== 'latest' ? parsed.missionId : await findLatestMission(root, { mode: 'naruto' });
|
|
910
|
-
if (!id)
|
|
911
|
-
return emit(parsed, { schema: NARUTO_RESULT_SCHEMA, ok: false, action: 'status', status: 'missing_mission' }, () => console.log('No Naruto mission found.'));
|
|
912
|
-
const { dir } = await loadMission(root, id);
|
|
913
|
-
const proof = await readJson(path.join(dir, 'agents', 'agent-proof-evidence.json'), null);
|
|
914
|
-
const scheduler = await readJson(path.join(dir, 'agents', 'agent-scheduler-state.json'), null);
|
|
915
|
-
const roleDistribution = await readJson(path.join(dir, 'agents', 'naruto-role-distribution.json'), null);
|
|
916
|
-
const workGraph = await readJson(path.join(dir, 'agents', 'naruto-work-graph.json'), null);
|
|
917
|
-
const governor = await readJson(path.join(dir, 'agents', 'naruto-concurrency-governor.json'), null);
|
|
918
|
-
const summary = {
|
|
654
|
+
function blockGlmOverride(json) {
|
|
655
|
+
const result = {
|
|
919
656
|
schema: NARUTO_RESULT_SCHEMA,
|
|
920
|
-
ok:
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
max_active_slots: scheduler?.max_active_slots ?? null,
|
|
926
|
-
completed: scheduler?.completed_count ?? null,
|
|
927
|
-
role_distribution: roleDistribution,
|
|
928
|
-
work_graph: workGraph ? {
|
|
929
|
-
total_work_items: workGraph.total_work_items,
|
|
930
|
-
mixed_work_kinds: workGraph.mixed_work_kinds,
|
|
931
|
-
write_allowed_count: workGraph.write_allowed_count,
|
|
932
|
-
active_wave_count: Array.isArray(workGraph.active_waves) ? workGraph.active_waves.length : null,
|
|
933
|
-
parallel_write_wave_count: Array.isArray(workGraph.active_waves) ? workGraph.active_waves.filter((wave) => Array.isArray(wave.write_paths) && wave.write_paths.length > 1).length : null
|
|
934
|
-
} : null,
|
|
935
|
-
concurrency_governor: governor
|
|
657
|
+
ok: false,
|
|
658
|
+
status: 'blocked',
|
|
659
|
+
reason: 'naruto_gpt_5_6_family_only_glm_override_forbidden',
|
|
660
|
+
blockers: ['naruto_gpt_5_6_family_only_glm_override_forbidden'],
|
|
661
|
+
hint: 'Use normal sks naruto for the official Codex subagent workflow. The separate legacy GLM route requires sks --mad --glm --naruto.'
|
|
936
662
|
};
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
console.log(
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
console.log('Roles: ' + roleDistribution.entries.map((entry) => `${entry.role}:${entry.count}`).join(', '));
|
|
944
|
-
});
|
|
663
|
+
process.exitCode = 1;
|
|
664
|
+
if (json)
|
|
665
|
+
console.log(JSON.stringify(result, null, 2));
|
|
666
|
+
else
|
|
667
|
+
console.error(`$Naruto blocked: ${result.reason}. ${result.hint}`);
|
|
668
|
+
return result;
|
|
945
669
|
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
const id = parsed.missionId && parsed.missionId !== 'latest' ? parsed.missionId : await findLatestMission(root, { mode: 'naruto' });
|
|
949
|
-
if (!id)
|
|
950
|
-
return emit(parsed, { schema: NARUTO_RESULT_SCHEMA, ok: false, action: 'dashboard', status: 'missing_mission' }, () => console.log('No Naruto mission found.'));
|
|
951
|
-
const { dir } = await loadMission(root, id);
|
|
952
|
-
const snapshot = await readJson(path.join(dir, 'zellij-dashboard-snapshot.json'), null);
|
|
953
|
-
const rightColumnState = await readJson(path.join(dir, 'zellij-right-column-state.json'), null);
|
|
954
|
-
const summary = {
|
|
670
|
+
function legacyFlagBlock(flags) {
|
|
671
|
+
return {
|
|
955
672
|
schema: NARUTO_RESULT_SCHEMA,
|
|
956
|
-
ok:
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
right_column_state: rightColumnState,
|
|
961
|
-
blockers: snapshot || rightColumnState ? [] : ['naruto_dashboard_missing']
|
|
673
|
+
ok: false,
|
|
674
|
+
status: 'blocked',
|
|
675
|
+
blockers: flags.map((flag) => `removed_legacy_process_flag:${flag}`),
|
|
676
|
+
hint: 'Naruto supports only the Codex official subagent workflow. Use --agents, --max-threads, --read-only, --mission, or --json.'
|
|
962
677
|
};
|
|
963
|
-
return emit(parsed, summary, () => {
|
|
964
|
-
console.log('🍥 Naruto dashboard: ' + id);
|
|
965
|
-
console.log('Right column: ' + (rightColumnState?.status || 'missing'));
|
|
966
|
-
if (snapshot)
|
|
967
|
-
console.log('Active/visible/headless/queue: ' + [snapshot.active_workers, snapshot.visible_panes, snapshot.headless_workers, snapshot.queue_depth].join('/'));
|
|
968
|
-
});
|
|
969
678
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
const id = parsed.missionId && parsed.missionId !== 'latest' ? parsed.missionId : await findLatestMission(root, { mode: 'naruto' });
|
|
973
|
-
if (!id)
|
|
974
|
-
return emit(parsed, { schema: NARUTO_RESULT_SCHEMA, ok: false, action: 'workers', status: 'missing_mission' }, () => console.log('No Naruto mission found.'));
|
|
975
|
-
const { dir } = await loadMission(root, id);
|
|
976
|
-
const swarm = await readJson(path.join(dir, 'agents', 'agent-native-cli-session-swarm.json'), null);
|
|
977
|
-
const state = await readJson(path.join(dir, 'zellij-right-column-state.json'), null);
|
|
978
|
-
const records = Array.isArray(swarm?.records) ? swarm.records : [];
|
|
979
|
-
const summary = {
|
|
679
|
+
function argumentBlock(errors) {
|
|
680
|
+
return {
|
|
980
681
|
schema: NARUTO_RESULT_SCHEMA,
|
|
981
|
-
ok:
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
failed: records.filter((row) => row.status === 'failed').length,
|
|
987
|
-
visible_worker_panes: state?.visible_worker_panes || [],
|
|
988
|
-
headless_workers: state?.headless_workers || [],
|
|
989
|
-
records,
|
|
990
|
-
blockers: swarm || state ? [] : ['naruto_worker_records_missing']
|
|
682
|
+
ok: false,
|
|
683
|
+
status: 'blocked',
|
|
684
|
+
reason: 'invalid_naruto_arguments',
|
|
685
|
+
blockers: errors.map((error) => `invalid_naruto_argument:${error}`),
|
|
686
|
+
hint: 'Provide a non-empty quoted task and valid positive integers for --agents/--max-threads. Use only official Naruto options.'
|
|
991
687
|
};
|
|
992
|
-
return emit(parsed, summary, () => {
|
|
993
|
-
console.log('🍥 Naruto workers: ' + id);
|
|
994
|
-
console.log(`Active ${summary.active} · completed ${summary.completed} · failed ${summary.failed} · visible ${summary.visible_worker_panes.length} · headless ${summary.headless_workers.length}`);
|
|
995
|
-
});
|
|
996
688
|
}
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
const id = parsed.missionId && parsed.missionId !== 'latest' ? parsed.missionId : await findLatestMission(root, { mode: 'naruto' });
|
|
1000
|
-
if (!id)
|
|
1001
|
-
return emit(parsed, { schema: NARUTO_RESULT_SCHEMA, ok: false, action: 'proof', status: 'missing_mission' }, () => console.log('No Naruto mission found.'));
|
|
1002
|
-
const summary = await buildRuntimeProofSummary(root, id, { maxMessages: parsed.messages });
|
|
1003
|
-
return emit(parsed, { ...summary, action: 'proof' }, () => {
|
|
1004
|
-
console.log(renderRuntimeProofSummary(summary));
|
|
1005
|
-
});
|
|
1006
|
-
}
|
|
1007
|
-
async function narutoHelp(parsed) {
|
|
1008
|
-
const help = {
|
|
689
|
+
function missingMission(parsed, action) {
|
|
690
|
+
return emit(parsed, {
|
|
1009
691
|
schema: NARUTO_RESULT_SCHEMA,
|
|
1010
|
-
ok:
|
|
1011
|
-
action
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
usage: [
|
|
1015
|
-
'sks naruto run "<task>" [--clones N] [--backend codex-sdk|fake|ollama|local-llm] [--local-model|--ollama|--no-ollama] [--work-items N] [--tournament 2-4] [--write-mode parallel|serial|off] [--apply-patches] [--dry-run-patches] [--real] [--readonly] [--json]',
|
|
1016
|
-
'sks naruto status [--mission <id>] [--json]',
|
|
1017
|
-
'sks naruto proof latest [--messages 20] [--json]'
|
|
1018
|
-
],
|
|
1019
|
-
defaults: { clones: DEFAULT_NARUTO_CLONES, max_clones: MAX_NARUTO_AGENT_COUNT, backend: 'codex-sdk' }
|
|
1020
|
-
};
|
|
1021
|
-
return emit(parsed, help, () => {
|
|
1022
|
-
console.log('🍥 $Naruto — Shadow Clone Swarm (影分身)');
|
|
1023
|
-
console.log(help.description);
|
|
1024
|
-
for (const line of help.usage)
|
|
1025
|
-
console.log(' ' + line);
|
|
1026
|
-
});
|
|
1027
|
-
}
|
|
1028
|
-
function parseNarutoArgs(args = []) {
|
|
1029
|
-
if (hasFlag(args, '--help') || hasFlag(args, '-h'))
|
|
1030
|
-
args = ['help', ...args.filter((arg) => arg !== '--help' && arg !== '-h')];
|
|
1031
|
-
const first = args[0] && !String(args[0]).startsWith('--') ? String(args[0]) : '';
|
|
1032
|
-
const actions = new Set(['run', 'status', 'help', 'dashboard', 'workers', 'proof']);
|
|
1033
|
-
const action = (actions.has(first) ? first : 'run');
|
|
1034
|
-
const rest = action === first ? args.slice(1) : args;
|
|
1035
|
-
const json = hasFlag(args, '--json');
|
|
1036
|
-
// Computed early (normally derived further down) so an explicit --clones/
|
|
1037
|
-
// --agents can still override this exactly as before, but the *default*
|
|
1038
|
-
// scales with apparent task size instead of unconditionally requesting
|
|
1039
|
-
// DEFAULT_NARUTO_CLONES for every run, including a one-line typo fix
|
|
1040
|
-
// (20차 P2-3). --work-items defaults to clones*2 below, so this alone
|
|
1041
|
-
// scales that down proportionally too.
|
|
1042
|
-
const promptSizingValueFlags = new Set(['--clones', '--agents', '--work-items', '--concurrency', '--target-active-slots', '--backend', '--write-mode', '--max-write-agents', '--service-tier', '--mission', '--mission-id', '--ollama-model', '--local-model-model', '--ollama-base-url', '--local-model-base-url', '--parallelism', '--messages', '--tournament']);
|
|
1043
|
-
const promptForSizing = positionalArgs(rest, promptSizingValueFlags).join(' ').trim();
|
|
1044
|
-
const requestedClones = Number(readOption(args, '--clones', readOption(args, '--agents', String(estimateNarutoDefaultCloneCount(promptForSizing)))));
|
|
1045
|
-
const clones = clampClones(requestedClones);
|
|
1046
|
-
const workItemsExplicit = hasOption(args, '--work-items');
|
|
1047
|
-
const workItems = clampWorkItems(Number(readOption(args, '--work-items', clones * 2)), clones);
|
|
1048
|
-
const concurrency = normalizeConcurrency(readOption(args, '--concurrency', readOption(args, '--target-active-slots', null)), clones);
|
|
1049
|
-
const useOllamaProtocol = hasFlag(args, '--ollama');
|
|
1050
|
-
const useLocalModel = hasFlag(args, '--local-model');
|
|
1051
|
-
const useOllama = useOllamaProtocol || useLocalModel;
|
|
1052
|
-
const noOllama = hasFlag(args, '--no-ollama') || hasFlag(args, '--no-local-model');
|
|
1053
|
-
const backendExplicit = hasOption(args, '--backend') || useOllama || noOllama;
|
|
1054
|
-
const defaultBackend = hasFlag(args, '--mock')
|
|
1055
|
-
? 'fake'
|
|
1056
|
-
: useLocalModel && !noOllama
|
|
1057
|
-
? 'local-llm'
|
|
1058
|
-
: useOllamaProtocol && !noOllama
|
|
1059
|
-
? 'ollama'
|
|
1060
|
-
: 'codex-sdk';
|
|
1061
|
-
const backend = String(readOption(args, '--backend', defaultBackend));
|
|
1062
|
-
const mock = hasFlag(args, '--mock') || backend === 'fake';
|
|
1063
|
-
const real = hasFlag(args, '--real');
|
|
1064
|
-
const readonly = hasFlag(args, '--readonly') || hasFlag(args, '--read-only');
|
|
1065
|
-
const writeModeRaw = String(readOption(args, '--write-mode', hasFlag(args, '--parallel-write') ? 'parallel' : '') || '');
|
|
1066
|
-
const writeMode = (['proof-safe', 'parallel', 'serial', 'off'].includes(writeModeRaw) ? writeModeRaw : null);
|
|
1067
|
-
const applyPatches = hasFlag(args, '--apply-patches');
|
|
1068
|
-
const dryRunPatches = hasFlag(args, '--dry-run-patches') || hasFlag(args, '--dry-run-patch');
|
|
1069
|
-
const maxWriteAgents = Math.max(0, Math.floor(Number(readOption(args, '--max-write-agents', '0')) || 0));
|
|
1070
|
-
const explicitServiceTier = String(readOption(args, '--service-tier', '') || '');
|
|
1071
|
-
const requestedServiceTier = normalizeServiceTier(explicitServiceTier, null) || undefined;
|
|
1072
|
-
// Naruto clones always run in the fast service tier. The route-level skill and
|
|
1073
|
-
// release docs explicitly treat --no-fast / standard as non-honored for clones.
|
|
1074
|
-
const serviceTier = action === 'run' ? 'fast' : requestedServiceTier;
|
|
1075
|
-
const fastMode = action === 'run'
|
|
1076
|
-
? true
|
|
1077
|
-
: hasFlag(args, '--no-fast') || requestedServiceTier === 'standard'
|
|
1078
|
-
? false
|
|
1079
|
-
: hasFlag(args, '--fast')
|
|
1080
|
-
? true
|
|
1081
|
-
: undefined;
|
|
1082
|
-
const noFast = action === 'run' ? false : hasFlag(args, '--no-fast');
|
|
1083
|
-
const positionalMission = action === 'dashboard' || action === 'workers' || action === 'status' || action === 'proof'
|
|
1084
|
-
? positionalArgs(rest, new Set()).find((arg) => /^latest$|^M-/.test(arg))
|
|
1085
|
-
: null;
|
|
1086
|
-
const missionId = String(readOption(args, '--mission', readOption(args, '--mission-id', positionalMission || 'latest')));
|
|
1087
|
-
const ollamaModel = String(readOption(args, '--ollama-model', readOption(args, '--local-model-model', '')) || '') || null;
|
|
1088
|
-
const ollamaBaseUrl = String(readOption(args, '--ollama-base-url', readOption(args, '--local-model-base-url', '')) || '') || null;
|
|
1089
|
-
const noOpenZellij = hasFlag(args, '--no-open-zellij') || hasFlag(args, '--no-zellij');
|
|
1090
|
-
const attach = hasFlag(args, '--attach');
|
|
1091
|
-
const smoke = hasFlag(args, '--smoke');
|
|
1092
|
-
const parallelism = normalizeParallelism(readOption(args, '--parallelism', 'safe'));
|
|
1093
|
-
const messages = normalizeMessages(readOption(args, '--messages', '8'));
|
|
1094
|
-
const tournament = normalizeTournament(readOption(args, '--tournament', '0'));
|
|
1095
|
-
const prompt = promptForSizing || 'Naruto shadow clone swarm run';
|
|
1096
|
-
return { action, prompt, clones, workItems, workItemsExplicit, concurrency, backend, backendExplicit, mock, real, readonly, ollamaEnabled: useOllama && !noOllama, noOllama, ollamaModel, ollamaBaseUrl, writeMode, applyPatches, dryRunPatches, maxWriteAgents, fastMode, serviceTier, noFast, json, missionId, noOpenZellij, attach, smoke, parallelism, messages, tournament };
|
|
1097
|
-
}
|
|
1098
|
-
function normalizeParallelism(value) {
|
|
1099
|
-
const text = String(value || 'safe').toLowerCase();
|
|
1100
|
-
if (text === 'safe' || text === 'balanced' || text === 'extreme')
|
|
1101
|
-
return text;
|
|
1102
|
-
return 'safe';
|
|
1103
|
-
}
|
|
1104
|
-
function normalizeMessages(value) {
|
|
1105
|
-
const parsed = Number(value);
|
|
1106
|
-
return Math.max(0, Math.min(100, Math.floor(Number.isFinite(parsed) ? parsed : 8)));
|
|
1107
|
-
}
|
|
1108
|
-
function normalizeTournament(value) {
|
|
1109
|
-
const parsed = Number(value);
|
|
1110
|
-
if (!Number.isFinite(parsed) || parsed < 2)
|
|
1111
|
-
return 0;
|
|
1112
|
-
return Math.max(2, Math.min(4, Math.floor(parsed)));
|
|
1113
|
-
}
|
|
1114
|
-
async function writeNarutoArtifacts(ledgerRoot, artifacts) {
|
|
1115
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'naruto-work-graph.json'), artifacts.workGraph);
|
|
1116
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'naruto-role-distribution.json'), artifacts.roleDistribution);
|
|
1117
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'naruto-concurrency-governor.json'), artifacts.governor);
|
|
1118
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'naruto-active-pool.json'), {
|
|
1119
|
-
schema: 'sks.naruto-active-pool.v1',
|
|
1120
|
-
ok: null,
|
|
1121
|
-
status: 'not_computed',
|
|
1122
|
-
reason: 'simulated_active_pool_removed_from_production_path_20cha_p3_5',
|
|
1123
|
-
runtime_source_of_truth: 'agent-orchestrator-scheduler',
|
|
1124
|
-
see: 'naruto-real-active-pool.json'
|
|
1125
|
-
});
|
|
1126
|
-
if (artifacts.realActivePool)
|
|
1127
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'naruto-real-active-pool.json'), artifacts.realActivePool);
|
|
1128
|
-
if (artifacts.allocationPolicy)
|
|
1129
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'naruto-allocation-policy.json'), artifacts.allocationPolicy);
|
|
1130
|
-
if (artifacts.rebalancePolicy)
|
|
1131
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'naruto-rebalance-policy.json'), artifacts.rebalancePolicy);
|
|
1132
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'naruto-verification-dag.json'), artifacts.verificationDag);
|
|
1133
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'naruto-gpt-final-pack.json'), artifacts.gptFinalPack);
|
|
1134
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'naruto-zellij-dashboard.json'), artifacts.zellijDashboard);
|
|
1135
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'prompt-placeholder-guard.json'), artifacts.placeholderGuard);
|
|
1136
|
-
if (artifacts.gitWorktreeCapability)
|
|
1137
|
-
await writeJsonAtomic(path.join(ledgerRoot, 'git-worktree-capability.json'), artifacts.gitWorktreeCapability);
|
|
1138
|
-
}
|
|
1139
|
-
function clampClones(value) {
|
|
1140
|
-
if (!Number.isFinite(value) || value < 1)
|
|
1141
|
-
return DEFAULT_NARUTO_CLONES;
|
|
1142
|
-
return Math.min(MAX_NARUTO_AGENT_COUNT, Math.floor(value));
|
|
1143
|
-
}
|
|
1144
|
-
function clampWorkItems(value, clones) {
|
|
1145
|
-
if (!Number.isFinite(value) || value < 1)
|
|
1146
|
-
return clones;
|
|
1147
|
-
return Math.floor(value);
|
|
1148
|
-
}
|
|
1149
|
-
function normalizeConcurrency(value, clones) {
|
|
1150
|
-
if (value == null || value === '')
|
|
1151
|
-
return null;
|
|
1152
|
-
const parsed = Number(value);
|
|
1153
|
-
if (!Number.isFinite(parsed) || parsed < 1)
|
|
1154
|
-
return null;
|
|
1155
|
-
return Math.min(Math.floor(parsed), clones, MAX_NARUTO_AGENT_COUNT);
|
|
1156
|
-
}
|
|
1157
|
-
function hasFlag(args, flag) {
|
|
1158
|
-
return args.includes(flag);
|
|
692
|
+
ok: false,
|
|
693
|
+
action,
|
|
694
|
+
status: 'missing_mission'
|
|
695
|
+
}, () => console.log('No Naruto mission found.'));
|
|
1159
696
|
}
|
|
1160
|
-
function
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
const prefixed = args.find((arg) => String(arg).startsWith(name + '='));
|
|
1165
|
-
return prefixed ? prefixed.slice(name.length + 1) : fallback;
|
|
1166
|
-
}
|
|
1167
|
-
function hasOption(args, name) {
|
|
1168
|
-
return args.includes(name) || args.some((arg) => String(arg).startsWith(name + '='));
|
|
1169
|
-
}
|
|
1170
|
-
function positionalArgs(args, valueFlags) {
|
|
1171
|
-
const out = [];
|
|
1172
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
1173
|
-
const arg = String(args[i]);
|
|
1174
|
-
if (arg.startsWith('--')) {
|
|
1175
|
-
if (valueFlags.has(arg) && args[i + 1] && !String(args[i + 1]).startsWith('--'))
|
|
1176
|
-
i += 1;
|
|
1177
|
-
continue;
|
|
1178
|
-
}
|
|
1179
|
-
out.push(arg);
|
|
1180
|
-
}
|
|
1181
|
-
return out;
|
|
1182
|
-
}
|
|
1183
|
-
function emit(parsed, result, text) {
|
|
1184
|
-
if (parsed.json) {
|
|
697
|
+
function emit(parsed, result, human, failed = false) {
|
|
698
|
+
if (failed)
|
|
699
|
+
process.exitCode = 1;
|
|
700
|
+
if (parsed.json)
|
|
1185
701
|
console.log(JSON.stringify(result, null, 2));
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
text();
|
|
702
|
+
else
|
|
703
|
+
human();
|
|
1189
704
|
return result;
|
|
1190
705
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
if (
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
const localAutoSelectCandidate = parsed.backend === 'codex-sdk'
|
|
1207
|
-
&& parsed.backendExplicit !== true
|
|
1208
|
-
&& parsed.noOllama !== true
|
|
1209
|
-
&& config?.ok === true
|
|
1210
|
-
&& config.enabled === true
|
|
1211
|
-
&& policy.ok === true;
|
|
1212
|
-
return {
|
|
1213
|
-
schema: 'sks.naruto-local-worker-mode.v1',
|
|
1214
|
-
enabled: config?.enabled === true,
|
|
1215
|
-
provider: config?.provider || 'ollama',
|
|
1216
|
-
model: config?.model || null,
|
|
1217
|
-
requested_backend: parsed.backend,
|
|
1218
|
-
backend_explicit: parsed.backendExplicit,
|
|
1219
|
-
auto_select_eligible: false,
|
|
1220
|
-
worker_only: true,
|
|
1221
|
-
no_strategy_planning_design: true,
|
|
1222
|
-
policy,
|
|
1223
|
-
blockers: [
|
|
1224
|
-
...(config?.blockers || (config ? [] : ['ollama_worker_config_unavailable'])),
|
|
1225
|
-
...(policy.blockers || []),
|
|
1226
|
-
...(localAutoSelectCandidate ? ['naruto_gpt_5_6_family_only_local_auto_select_forbidden'] : []),
|
|
1227
|
-
...(parsed.backendExplicit ? ['backend_explicit'] : []),
|
|
1228
|
-
...(parsed.noOllama ? ['no_ollama_requested'] : [])
|
|
1229
|
-
]
|
|
1230
|
-
};
|
|
706
|
+
function renderRunResult(result) {
|
|
707
|
+
console.log(`$Naruto ${result.status}: ${result.mission_id}`);
|
|
708
|
+
console.log(`Official subagents: requested ${result.requested_subagents}, max threads ${result.max_threads}`);
|
|
709
|
+
console.log(`Started/completed/failed: ${result.started_subagents}/${result.completed_subagents}/${result.failed_subagents}`);
|
|
710
|
+
if (result.status === 'delegation_context_ready')
|
|
711
|
+
console.log('Continue in the current Codex parent and wait for every requested subagent before summarizing.');
|
|
712
|
+
if (Array.isArray(result.blockers) && result.blockers.length)
|
|
713
|
+
console.log(`Blockers: ${result.blockers.join(', ')}`);
|
|
714
|
+
}
|
|
715
|
+
function renderStatusResult(result) {
|
|
716
|
+
console.log(`Naruto ${result.action || 'status'}: ${result.mission_id}`);
|
|
717
|
+
console.log(`Started/completed/failed: ${result.started_subagents || 0}/${result.completed_subagents || 0}/${result.failed_subagents || 0}`);
|
|
718
|
+
}
|
|
719
|
+
function uniqueStrings(values) {
|
|
720
|
+
return [...new Set(values.map((value) => String(value || '').trim()).filter(Boolean))];
|
|
1231
721
|
}
|
|
1232
722
|
//# sourceMappingURL=naruto-command.js.map
|