sneakoscope 8.0.2 → 8.0.4
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 +150 -37
- package/config/skills-hash-ledger.v1.json +1 -1
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +55 -27
- package/dist/bin/install.js +6 -32
- package/dist/bin/sks-dispatch.js +1 -1
- package/dist/cli/args.js +0 -2
- package/dist/cli/cli-theme.js +18 -9
- package/dist/cli/command-manifest-lite.js +6 -6
- package/dist/cli/command-registry.js +6 -6
- package/dist/cli/feature-commands.js +9 -7
- package/dist/cli/install-helpers-codex-lb-chain.js +198 -7
- package/dist/cli/install-helpers-codex-lb-config.js +78 -10
- package/dist/cli/install-helpers-install-support.js +9 -6
- package/dist/cli/install-helpers.js +101 -49
- package/dist/cli/install-tool-helpers.js +2 -82
- package/dist/cli/output.js +6 -1
- package/dist/cli/router.js +101 -2
- package/dist/commands/codex-lb.js +119 -19
- package/dist/commands/doctor-profile.js +1 -1
- package/dist/commands/doctor.js +727 -144
- package/dist/commands/mad-sks.js +1 -5
- package/dist/config/skills-manifest.json +4 -2
- package/dist/core/agents/agent-codex-cockpit.js +0 -3
- package/dist/core/agents/agent-effort-policy.js +5 -5
- package/dist/core/agents/agent-janitor.js +0 -20
- package/dist/core/agents/agent-orchestrator.js +9 -56
- package/dist/core/agents/agent-output-validator.js +2 -3
- package/dist/core/agents/agent-patch-schema.js +2 -2
- package/dist/core/agents/agent-proof-evidence.js +0 -65
- package/dist/core/agents/agent-recursion-guard.js +1 -1
- package/dist/core/agents/agent-runner-codex-exec.js +5 -3
- package/dist/core/agents/agent-scheduler.js +327 -85
- package/dist/core/agents/agent-schema.js +1 -1
- package/dist/core/agents/agent-trust-report.js +0 -36
- package/dist/core/agents/agent-worker-pipeline.js +0 -1
- package/dist/core/agents/fast-mode-policy.js +1 -3
- package/dist/core/agents/native-cli-worker-runtime-proof.js +1 -1
- package/dist/core/agents/native-cli-worker-runtime.js +69 -647
- package/dist/core/agents/native-cli-worker.js +6 -7
- package/dist/core/agents/native-worker-backend-router.js +2 -32
- package/dist/core/agents/no-subagent-scaling-policy.js +1 -1
- package/dist/core/agents/parallel-runtime-proof.js +1 -6
- package/dist/core/agents/runtime-proof-summary.js +1 -35
- package/dist/core/architecture-hardening/contracts/contracts.js +193 -0
- package/dist/core/architecture-hardening/migration/migration.js +111 -0
- package/dist/core/architecture-hardening/state/state-service.js +155 -0
- package/dist/core/artifact-schemas.js +0 -3
- package/dist/core/codex/codex-config-guard.js +238 -52
- package/dist/core/codex-adapter.js +5 -3
- package/dist/core/codex-app/auxiliary-oauth-policy.js +36 -0
- package/dist/core/codex-app/catalog-compat/catalog-service.js +104 -0
- package/dist/core/codex-app/child-policy/child-policy.js +35 -0
- package/dist/core/codex-app/codex-app-handoff.js +0 -1
- package/dist/core/codex-app/codex-hook-lifecycle.js +1 -1
- package/dist/core/codex-app/codex-init-deep.js +1 -1
- package/dist/core/codex-app/menubar/app-bundle.js +2 -0
- package/dist/core/codex-app/menubar/constants.js +14 -1
- package/dist/core/codex-app/menubar/global-install.js +288 -0
- package/dist/core/codex-app/menubar/installer.js +79 -14
- package/dist/core/codex-app/menubar/launch-agent.js +267 -45
- package/dist/core/codex-app/menubar/paths.js +3 -0
- package/dist/core/codex-app/menubar/rollback.js +55 -7
- package/dist/core/codex-app/menubar/status.js +75 -4
- package/dist/core/codex-app/provider-child-policy.js +64 -0
- package/dist/core/codex-app/provider-mode.js +91 -0
- package/dist/core/codex-app/provider-operation-stages.js +20 -0
- package/dist/core/codex-app/provider-session-policy.js +85 -0
- package/dist/core/codex-app/session-policy/session-pinning.js +68 -0
- package/dist/core/codex-app.js +3 -2
- package/dist/core/codex-control/codex-0139-image-path-real-probe.js +3 -1
- package/dist/core/codex-control/codex-0139-web-search-probe.js +3 -1
- package/dist/core/codex-control/codex-app-server-runtime-env.js +13 -4
- package/dist/core/codex-control/codex-app-server-v2-client.js +3 -3
- package/dist/core/codex-control/codex-control-proof.js +0 -1
- package/dist/core/codex-control/codex-task-runner.js +1 -4
- package/dist/core/codex-exec-output-schema.js +4 -1
- package/dist/core/codex-lb/codex-lb-env.js +63 -72
- package/dist/core/codex-lb/codex-lb-setup.js +15 -2
- package/dist/core/codex-lb/desktop-bridge/header-policy.js +6 -0
- package/dist/core/codex-lb/desktop-bridge/http-forward.js +48 -6
- package/dist/core/codex-lb/desktop-bridge/security.js +134 -0
- package/dist/core/codex-lb/desktop-bridge/server.js +9 -3
- package/dist/core/codex-lb/desktop-bridge/state.js +26 -6
- package/dist/core/codex-lb/desktop-bridge/types.js +1 -0
- package/dist/core/codex-lb/desktop-center-credentials.js +517 -58
- package/dist/core/codex-lb/desktop-controller.js +177 -56
- package/dist/core/codex-lb/desktop-service.js +179 -40
- package/dist/core/codex-lb/legacy-migration.js +1 -3
- package/dist/core/codex-lb/native-openai-transport/transport.js +68 -0
- package/dist/core/codex-lb/probes/cli-image-tool-probe.js +1 -1
- package/dist/core/codex-lb/provider-routing/provider-router.js +58 -0
- package/dist/core/codex-lb/routing-truth.js +327 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +4 -0
- package/dist/core/codex-native/codex-native-pattern-analysis.js +1 -2
- package/dist/core/codex-native/core-skill-manifest.js +1 -1
- package/dist/core/codex-plugins/codex-plugin-json.js +26 -6
- package/dist/core/codex-plugins/codex-plugin-repair.js +32 -6
- package/dist/core/commands/basic-cli.js +9 -7
- package/dist/core/commands/computer-use-command.js +1 -1
- package/dist/core/commands/image-ux-review-command.js +16 -9
- package/dist/core/commands/install-package-command.js +105 -0
- package/dist/core/commands/intent-normalization/normalizer.js +96 -0
- package/dist/core/commands/mad-sks-command.js +23 -274
- package/dist/core/commands/mad-sks-headless.js +11 -30
- package/dist/core/commands/naruto-command.js +0 -25
- package/dist/core/commands/qa-loop-command.js +104 -22
- package/dist/core/commands/remote-command.js +2 -2
- package/dist/core/commands/research-command.js +10 -5
- package/dist/core/commands/telegram-command.js +407 -0
- package/dist/core/config-adopt/config-adopt-command.js +35 -0
- package/dist/core/config-adopt/config-adopt.js +346 -0
- package/dist/core/config-adopt/index.js +3 -0
- package/dist/core/doctor/command-alias-cleanup.js +4 -1
- package/dist/core/doctor/current-project-guidance-nested.js +37 -6
- package/dist/core/doctor/current-project-guidance.js +15 -9
- package/dist/core/doctor/doctor-dirty-planner.js +1 -4
- package/dist/core/doctor/doctor-readiness-matrix.js +15 -18
- package/dist/core/doctor/retired-managed-residue-private.js +4 -3
- package/dist/core/doctor/retired-managed-residue-runtime.js +2 -2
- package/dist/core/doctor/skill-legacy-surface.js +11 -10
- package/dist/core/doctor/sks-menubar-doctor.js +4 -0
- package/dist/core/evaluation.js +0 -19
- package/dist/core/evidence/v2/evidence-key.js +105 -0
- package/dist/core/feature-fixtures.js +12 -7
- package/dist/core/feature-registry.js +52 -21
- package/dist/core/hooks-runtime/hook-context.js +9 -0
- package/dist/core/hooks-runtime/managed-skill-admission.js +54 -4
- package/dist/core/hooks-runtime/official-subagent-lifecycle.js +69 -52
- package/dist/core/hooks-runtime/stop-finalization.js +226 -0
- package/dist/core/hooks-runtime/stop-repeat-guard.js +21 -2
- package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +2 -2
- package/dist/core/hooks-runtime/subagent-skill-availability-evidence.js +3 -3
- package/dist/core/hooks-runtime/subagent-skill-availability-guards.js +43 -5
- package/dist/core/hooks-runtime/subagent-skill-availability.js +64 -30
- package/dist/core/hooks-runtime/subagent-stop-hook.js +15 -2
- package/dist/core/hooks-runtime.js +179 -212
- package/dist/core/image/reference-evidence/reference-registry.js +145 -0
- package/dist/core/image-ux-review/imagegen-adapter.js +21 -9
- package/dist/core/image-ux-review/reference-policy/reference-policy.js +9 -0
- package/dist/core/imagegen/codex-lb-imagegen-target.js +8 -0
- package/dist/core/imagegen/imagegen-capability.js +59 -2
- package/dist/core/imagegen/require-imagegen.js +2 -2
- package/dist/core/init/skills.js +17 -3
- package/dist/core/init.js +3 -3
- package/dist/core/install/installed-package-smoke.js +23 -5
- package/dist/core/json/canonical.js +9 -0
- package/dist/core/locks/file-lock.js +0 -1
- package/dist/core/loops/loop-continuation-enforcer.js +65 -7
- package/dist/core/loops/loop-decomposer.js +0 -1
- package/dist/core/loops/loop-gate-runner.js +65 -4
- package/dist/core/loops/loop-gate-selector.js +0 -2
- package/dist/core/loops/loop-proof-validation.js +38 -0
- package/dist/core/loops/loop-risk-classifier.js +1 -1
- package/dist/core/loops/loop-runtime.js +14 -2
- package/dist/core/loops/loop-scheduler.js +7 -2
- package/dist/core/loops/loop-worker-runtime.js +0 -15
- package/dist/core/loops/loop-worktree-runtime.js +52 -4
- package/dist/core/managed-assets/managed-assets-manifest.js +14 -14
- package/dist/core/naruto/hardware-capacity-probe.js +9 -6
- package/dist/core/naruto/naruto-active-pool.js +2 -14
- package/dist/core/naruto/naruto-concurrency-governor.js +71 -31
- package/dist/core/naruto/naruto-loop-worker-router.js +0 -2
- package/dist/core/naruto/naruto-verification-dag.js +0 -1
- package/dist/core/naruto/naruto-write-e2e.js +1 -2
- package/dist/core/naruto/resource-pressure-monitor.js +0 -4
- package/dist/core/observability/architecture-hardening/safe-projection.js +65 -0
- package/dist/core/perf/import-graph-budget.js +0 -1
- package/dist/core/perf/release-latency-slo.js +3 -2
- package/dist/core/preflight/parallel-preflight-engine.js +2 -15
- package/dist/core/product-design-app-server.js +13 -1
- package/dist/core/proof/fake-real-proof-policy.js +2 -17
- package/dist/core/proof/route-proof-gate.js +2 -10
- package/dist/core/proof/route-proof-policy.js +1 -1
- package/dist/core/proof/runtime-evidence-policy.js +185 -0
- package/dist/core/proof/runtime-truth-matrix.js +64 -39
- package/dist/core/proof/validation.js +27 -11
- package/dist/core/provider/provider-context.js +18 -2
- package/dist/core/providers/openrouter/openrouter-account.js +3 -2
- package/dist/core/python-tools/python-tool-runner.js +1 -1
- package/dist/core/qa-loop/qa-execution-control.js +57 -0
- package/dist/core/questions.js +1 -1
- package/dist/core/release/extreme-parallel-scheduler.js +0 -3
- package/dist/core/release/gate-manifest.js +3 -7
- package/dist/core/release/gate-pack-manifest.js +3 -7
- package/dist/core/release/package-size-budget.js +2 -2
- package/dist/core/release/physical-release-gates.js +189 -0
- package/dist/core/release/publish-preflight.js +113 -0
- package/dist/core/release/release-gate-affected-selector.js +0 -2
- package/dist/core/release/release-gate-batch-runner.js +1 -1
- package/dist/core/release/release-gate-node.js +0 -1
- package/dist/core/release/release-gate-resource-governor.js +0 -1
- package/dist/core/release/release-pack-receipt.js +5 -8
- package/dist/core/release/release-real-contract.js +0 -6
- package/dist/core/release/resource-class-budget.js +0 -1
- package/dist/core/release/stage-publish.js +178 -36
- package/dist/core/research/research-adversarial-review.js +103 -9
- package/dist/core/research.js +1 -1
- package/dist/core/retention.js +0 -1
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes/diagnostic-allowlist.js +0 -1
- package/dist/core/routes/dollar-manifest-lite.js +1 -1
- package/dist/core/routes.js +46 -15
- package/dist/core/runtime/execution-control.js +226 -0
- package/dist/core/runtime/progress-recovery/progress-recovery.js +89 -0
- package/dist/core/runtime/task-profile.js +10 -4
- package/dist/core/runtime/verification-budget.js +10 -1
- package/dist/core/safety/intent-contract/intent-contract.js +94 -0
- package/dist/core/safety/mutation-guard.js +0 -2
- package/dist/core/safety/mutation-ledger.js +0 -2
- package/dist/core/safety/requested-scope-contract.js +0 -0
- package/dist/core/search-visibility/discovery.js +1 -1
- package/dist/core/search-visibility/index.js +12 -0
- package/dist/core/search-visibility/verifier.js +112 -3
- package/dist/core/security/private-credential-file.js +209 -0
- package/dist/core/session/project-namespace.js +0 -5
- package/dist/core/skills/skill-agent-metadata.js +1 -3
- package/dist/core/strategy/adhd-orchestrating-gate.js +0 -1
- package/dist/core/subagents/agent-catalog.js +19 -34
- package/dist/core/subagents/model-policy.js +65 -24
- package/dist/core/subagents/naruto-help-contract.js +8 -8
- package/dist/core/subagents/naruto-host-credentials.js +13 -0
- package/dist/core/subagents/official-subagent-config.js +16 -6
- package/dist/core/subagents/official-subagent-preparation.js +35 -16
- package/dist/core/subagents/official-subagent-prompt.js +7 -7
- package/dist/core/subagents/official-subagent-runner.js +27 -4
- package/dist/core/subagents/role-model-preferences.js +1 -1
- package/dist/core/subagents/thread-budget.js +19 -12
- package/dist/core/subagents/wave-lifecycle.js +18 -6
- package/dist/core/telegram/access.js +58 -0
- package/dist/core/telegram/client.js +157 -0
- package/dist/core/telegram/confirmation.js +37 -0
- package/dist/core/telegram/doctor.js +154 -0
- package/dist/core/telegram/index.js +9 -0
- package/dist/core/telegram/keychain.js +317 -0
- package/dist/core/telegram/liveness.js +118 -0
- package/dist/core/telegram/poller.js +90 -0
- package/dist/core/telegram/redaction.js +15 -0
- package/dist/core/telegram/state-lock.js +416 -0
- package/dist/core/telegram/types.js +1 -0
- package/dist/core/text/strings.js +3 -0
- package/dist/core/triwiki/context-graph/store/evidence-write-lock.js +29 -0
- package/dist/core/triwiki/context-graph/store/fragment-cache.js +24 -0
- package/dist/core/triwiki/context-graph/store/snapshot-store.js +69 -21
- package/dist/core/triwiki/triwiki-gate-impact-map.js +2 -2
- package/dist/core/triwiki/triwiki-module-card.js +1 -2
- package/dist/core/update/installed-cli-resolution.js +170 -0
- package/dist/core/update/update-diagnostics.js +52 -0
- package/dist/core/update/update-migration-state.js +30 -12
- package/dist/core/update/update-operation.js +2 -1
- package/dist/core/update/update-stage-diagnostics.js +38 -0
- package/dist/core/update/update-status.js +2 -9
- package/dist/core/update-check.js +279 -91
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/AppDelegate.swift +19 -1
- package/dist/native/sks-menubar/Sources/AppIdentity.swift +7 -0
- package/dist/native/sks-menubar/Sources/ControlCenterWindowController.swift +6 -2
- package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +159 -92
- package/dist/native/sks-menubar/Sources/OperationModels.swift +389 -0
- package/dist/native/sks-menubar/Sources/OverviewViewController.swift +57 -0
- package/dist/native/sks-menubar/Sources/ProcessClient.swift +3 -1
- package/dist/native/sks-menubar/Sources/ProvidersConnectTest.swift +115 -0
- package/dist/native/sks-menubar/Sources/ProvidersFastMode.swift +17 -0
- package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +3 -0
- package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +58 -17
- package/dist/native/sks-menubar/Sources/ProvidersReliability.swift +302 -0
- package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +5 -0
- package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +190 -0
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +158 -126
- package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +462 -26
- package/dist/native/sks-menubar/Sources/SKSKeychainStore.swift +344 -0
- package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +27 -0
- package/dist/native/sks-menubar/Sources/SingletonInstanceGuard.swift +328 -0
- package/dist/native/sks-menubar/Sources/StatusItemController.swift +10 -2
- package/dist/native/sks-menubar/Sources/TelegramPrivateFileStore.swift +498 -0
- package/dist/native/sks-menubar/Sources/TelegramPrivateFileSupport.swift +236 -0
- package/dist/native/sks-menubar/Sources/TelegramProcessGateway.swift +454 -0
- package/dist/native/sks-menubar/Sources/TelegramRuntimeSupport.swift +56 -0
- package/dist/native/sks-menubar/Sources/TelegramStateLock.swift +448 -0
- package/dist/native/sks-menubar/Sources/TelegramSupport.swift +187 -0
- package/dist/native/sks-menubar/Sources/TelegramTransport.swift +499 -0
- package/dist/native/sks-menubar/Sources/main.swift +15 -1
- package/dist/scripts/all-feature-deep-completion-check.js +5 -1
- package/dist/scripts/check-publish-tag.js +56 -0
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +10 -3
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +12 -3
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +4 -2
- package/dist/scripts/codex-native-agent-role-content-check.js +3 -3
- package/dist/scripts/codex-native-gate-lib.js +14 -7
- package/dist/scripts/current-command-surface-check.js +7 -7
- package/dist/scripts/current-surface-update-e2e-check.js +4 -3
- package/dist/scripts/current-upgrade-matrix-check.js +5 -24
- package/dist/scripts/docs-truthfulness-check.js +17 -13
- package/dist/scripts/gate-lib.js +0 -2
- package/dist/scripts/gate-policy-audit-check.js +3 -2
- package/dist/scripts/harness-benchmark-check.js +1 -1
- package/dist/scripts/init-deep-backup-retention-check.js +1 -1
- package/dist/scripts/lib/codex-sdk-gate-lib.js +1 -2
- package/dist/scripts/loop-directive-check-lib.js +28 -38
- package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +14 -180
- package/dist/scripts/mad-sks-launch-sql-plane-boundary-check.js +2 -11
- package/dist/scripts/official-subagent-workflow-check.js +1 -1
- package/dist/scripts/packlist-performance-check.js +1 -2
- package/dist/scripts/prepublish-release-check-or-fast.js +32 -0
- package/dist/scripts/publish-preflight.js +12 -0
- package/dist/scripts/release-affected-selector-check.js +2 -2
- package/dist/scripts/release-gate-batch-runner-check.js +2 -2
- package/dist/scripts/release-metadata-check.js +8 -12
- package/dist/scripts/release-real-check.js +2 -54
- package/dist/scripts/runtime-domain-gate-lib.js +2 -96
- package/dist/scripts/runtime-proof-summary-check.js +2 -6
- package/dist/scripts/search-visibility-gate-lib.js +0 -1
- package/dist/scripts/sks-cli-gate-lib.js +1 -1
- package/dist/scripts/typed-routing-gate-lib.js +7 -59
- package/docs/demo.tape +1 -1
- package/infra-harness-gates.json +1 -1456
- package/package.json +10 -7
- package/release-gates.v2.json +0 -1
- package/schemas/agents/parallel-runtime-proof.schema.json +0 -2
- package/schemas/codex/agent-result.schema.json +0 -6
- package/schemas/naruto/naruto-concurrency-governor.schema.json +1 -3
- package/schemas/release/release-gate-node.schema.json +1 -1
- package/dist/commands/zellij-lane.js +0 -22
- package/dist/commands/zellij-monitor-pane.js +0 -26
- package/dist/commands/zellij-slot-column-anchor.js +0 -22
- package/dist/commands/zellij-slot-pane.js +0 -80
- package/dist/commands/zellij-viewport-pane.js +0 -57
- package/dist/commands/zellij.js +0 -422
- package/dist/core/agents/agent-runner-zellij.js +0 -164
- package/dist/core/agents/agent-slot-pane-binding-proof.js +0 -96
- package/dist/core/agents/parallel-write-fixture.js +0 -305
- package/dist/core/agents/worker-pane-communication-contract.js +0 -100
- package/dist/core/agents/zellij-lane-supervisor.js +0 -428
- package/dist/core/agents/zellij-right-lane-cockpit.js +0 -66
- package/dist/core/doctor/doctor-zellij-repair.js +0 -40
- package/dist/core/ops/upgrade-migration-fixtures.js +0 -119
- package/dist/core/proof/route-finalizer-fixtures.js +0 -21
- package/dist/core/zellij/homebrew-policy.js +0 -43
- package/dist/core/zellij/zellij-capability.js +0 -126
- package/dist/core/zellij/zellij-clipboard-config.js +0 -52
- package/dist/core/zellij/zellij-command.js +0 -149
- package/dist/core/zellij/zellij-fake-adapter.js +0 -186
- package/dist/core/zellij/zellij-lane-renderer.js +0 -706
- package/dist/core/zellij/zellij-lane-runtime.js +0 -189
- package/dist/core/zellij/zellij-launcher.js +0 -268
- package/dist/core/zellij/zellij-layout-builder.js +0 -191
- package/dist/core/zellij/zellij-monitor-renderer.js +0 -52
- package/dist/core/zellij/zellij-official-subagent-activity.js +0 -526
- package/dist/core/zellij/zellij-official-subagent-telemetry.js +0 -258
- package/dist/core/zellij/zellij-pane-proof.js +0 -226
- package/dist/core/zellij/zellij-right-column-manager.js +0 -308
- package/dist/core/zellij/zellij-screen-proof.js +0 -120
- package/dist/core/zellij/zellij-self-heal-types.js +0 -44
- package/dist/core/zellij/zellij-self-heal.js +0 -408
- package/dist/core/zellij/zellij-slot-column-anchor.js +0 -304
- package/dist/core/zellij/zellij-slot-pane-renderer.js +0 -521
- package/dist/core/zellij/zellij-slot-telemetry.js +0 -384
- package/dist/core/zellij/zellij-theme.js +0 -66
- package/dist/core/zellij/zellij-ui-mode.js +0 -34
- package/dist/core/zellij/zellij-update.js +0 -348
- package/dist/core/zellij/zellij-viewport-binder.js +0 -61
- package/dist/core/zellij/zellij-worker-pane-manager.js +0 -881
- package/dist/core/zellij/zellij-worker-pane-summary.js +0 -64
- package/dist/native/sks-menubar/Tests/AppRuntimeTestSupport.swift +0 -26
- package/dist/native/sks-menubar/Tests/OperationCoordinatorTests.swift +0 -174
- package/dist/native/sks-menubar/Tests/ProcessClientTests.swift +0 -20
- package/dist/native/sks-menubar/Tests/ProvidersViewControllerTests.swift +0 -142
- package/dist/scripts/zellij-pane-proof-check.js +0 -88
- package/dist/scripts/zellij-real-session-cleanup-check.js +0 -139
- package/dist/scripts/zellij-real-session-launch-check.js +0 -126
- package/dist/scripts/zellij-screen-proof-check.js +0 -43
- package/schemas/zellij/zellij-right-column-state.schema.json +0 -40
- package/schemas/zellij/zellij-slot-telemetry.schema.json +0 -89
- package/schemas/zellij/zellij-worker-pane.schema.json +0 -53
- package/scripts/build-clean-atomic.mjs +0 -323
|
@@ -7,6 +7,7 @@ import { closeAgentSessionGeneration, createAgentSessionGeneration, writeAgentSe
|
|
|
7
7
|
import { appendParallelRuntimeEvent } from './parallel-runtime-proof.js';
|
|
8
8
|
export const AGENT_SCHEDULER_SCHEMA = 'sks.agent-scheduler.v1';
|
|
9
9
|
export const AGENT_SCHEDULER_EVENT_SCHEMA = 'sks.agent-scheduler-event.v1';
|
|
10
|
+
export const DEFAULT_AGENT_SCHEDULER_MAX_WALL_MS = 30 * 60 * 1000;
|
|
10
11
|
export async function runAgentScheduler(input) {
|
|
11
12
|
const maxActiveSlots = Number.isFinite(Number(input.maxActiveSlots)) && Number(input.maxActiveSlots) >= 1 ? Math.floor(Number(input.maxActiveSlots)) : MAX_AGENT_COUNT;
|
|
12
13
|
const targetActiveSlots = normalizeTargetActiveSlots(input.targetActiveSlots ?? input.roster?.concurrency ?? input.roster?.agent_count ?? DEFAULT_AGENT_CONCURRENCY, maxActiveSlots);
|
|
@@ -21,100 +22,191 @@ export async function runAgentScheduler(input) {
|
|
|
21
22
|
const active = new Map();
|
|
22
23
|
const results = [];
|
|
23
24
|
const schedulerStartedAt = Date.now();
|
|
25
|
+
const maxWallMs = normalizeSchedulerMaxWallMs(input.maxWallMs);
|
|
26
|
+
const stopSignal = createSchedulerStopSignal(maxWallMs, input.signal);
|
|
24
27
|
let lastUtilizationUpdateMs = schedulerStartedAt;
|
|
25
28
|
let activeSlotTimeMs = 0;
|
|
26
29
|
let batchCounter = 0;
|
|
27
30
|
let batchLaunchSpanTotalMs = 0;
|
|
28
31
|
let batchDispatchInProgress = false;
|
|
32
|
+
let terminalStopReason = null;
|
|
29
33
|
let state = buildState(input.missionId, targetActiveSlots, queue, slots, active, {
|
|
30
34
|
status: 'initializing',
|
|
31
35
|
refillDelayMs: input.refillDelayMs || 0,
|
|
32
36
|
rateLimitBackoffMs: input.rateLimitBackoffMs || 0
|
|
33
37
|
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
await
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
38
|
+
try {
|
|
39
|
+
await writeAll(input.root, state, slots, queue, active, { event_type: 'scheduler_initialized' }, input.onSchedulerEvent);
|
|
40
|
+
const initialStopReason = stopSignal.currentReason();
|
|
41
|
+
if (initialStopReason)
|
|
42
|
+
await stopScheduler(initialStopReason);
|
|
43
|
+
else
|
|
44
|
+
await refillSlots(null);
|
|
45
|
+
while (active.size > 0 || unfinishedWorkItems(queue).length > 0) {
|
|
46
|
+
const immediateStopReason = stopSignal.currentReason();
|
|
47
|
+
if (immediateStopReason) {
|
|
48
|
+
await stopScheduler(immediateStopReason);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
if (!batchDispatchInProgress && active.size === 0) {
|
|
52
|
+
const ready = pendingWorkItems(queue);
|
|
53
|
+
if (ready.length > 0) {
|
|
54
|
+
await refillSlots(null);
|
|
55
|
+
if (active.size > 0)
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
await stopScheduler(ready.length > 0
|
|
59
|
+
? 'scheduler_ready_queue_without_launchable_slot'
|
|
60
|
+
: 'scheduler_unresolvable_dependencies');
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
const settled = await Promise.race([
|
|
64
|
+
...[...active.values()].map((entry) => entry.promise),
|
|
65
|
+
stopSignal.promise
|
|
66
|
+
]);
|
|
67
|
+
if (isSchedulerStopSignal(settled)) {
|
|
68
|
+
await stopScheduler(settled.scheduler_stop_reason);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
const entry = active.get(settled.session_id);
|
|
72
|
+
if (!entry)
|
|
73
|
+
continue;
|
|
74
|
+
const activeCountBeforeClose = active.size;
|
|
75
|
+
accumulateActiveSlotTime();
|
|
76
|
+
active.delete(settled.session_id);
|
|
77
|
+
const resultStatus = settled.result?.status === 'done' ? 'completed' : settled.result?.status === 'blocked' ? 'blocked' : 'failed';
|
|
78
|
+
completeWorkItem(queue, entry.work_item_id, settled.session_id, resultStatus, settled.error || null);
|
|
79
|
+
if (resultStatus !== 'completed')
|
|
80
|
+
addUniqueBlocker(state, `scheduler_work_item_${resultStatus}:${entry.work_item_id}`);
|
|
81
|
+
const slotIndex = slots.findIndex((slot) => slot.slot_id === entry.slot_id);
|
|
82
|
+
const closingSlot = slotIndex >= 0 ? slots[slotIndex] : null;
|
|
83
|
+
if (slotIndex >= 0 && closingSlot)
|
|
84
|
+
slots[slotIndex] = markWorkerSlotGenerationClosed(closingSlot, settled.session_id, resultStatus);
|
|
85
|
+
await closeAgentSessionGeneration(input.root, settled.session_id, {
|
|
86
|
+
status: resultStatus === 'completed' ? 'closed' : resultStatus,
|
|
87
|
+
resultArtifactPath: settled.result?.artifacts?.[0] || null,
|
|
88
|
+
terminalCloseReportPath: settled.terminal_close_report_path || path.join('sessions', entry.slot_id, `gen-${settled.generation_index}`, 'agent-terminal-close-report.json')
|
|
68
89
|
});
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
90
|
+
results.push(settled.result);
|
|
91
|
+
const followUps = resultStatus === 'completed' && Array.isArray(settled.result?.follow_up_work_items) ? settled.result.follow_up_work_items : [];
|
|
92
|
+
if (followUps.length) {
|
|
93
|
+
const enqueue = enqueueFollowUpWorkItems(queue, followUps, {
|
|
94
|
+
originSessionId: settled.session_id,
|
|
95
|
+
sourceIntelligenceRefs: input.sourceIntelligenceRefs || null,
|
|
96
|
+
goalModeRef: input.goalModeRef || null
|
|
97
|
+
});
|
|
98
|
+
if (enqueue.blocked.length)
|
|
99
|
+
state.blockers.push(...enqueue.blocked);
|
|
100
|
+
await appendAgentWorkQueueEvent(input.root, 'follow_up_work_items_enqueued', { accepted: enqueue.accepted.length, blocked: enqueue.blocked_count });
|
|
101
|
+
}
|
|
102
|
+
const pendingAfterClose = pendingWorkItems(queue).length;
|
|
103
|
+
if (pendingAfterClose > 0)
|
|
104
|
+
state.expected_backfill_count += 1;
|
|
105
|
+
updateUtilizationMetrics();
|
|
106
|
+
await writeAll(input.root, state, slots, queue, active, {
|
|
107
|
+
event_type: 'session_completed',
|
|
108
|
+
session_id: settled.session_id,
|
|
109
|
+
slot_id: entry.slot_id,
|
|
110
|
+
work_item_id: entry.work_item_id,
|
|
111
|
+
active_count_before_close: activeCountBeforeClose,
|
|
112
|
+
active_count_after_close: active.size,
|
|
113
|
+
pending_count_after_close: pendingAfterClose
|
|
114
|
+
}, input.onSchedulerEvent);
|
|
115
|
+
await refillSlots(pendingAfterClose > 0 ? {
|
|
116
|
+
closed_session_id: settled.session_id,
|
|
117
|
+
active_count_before: active.size,
|
|
118
|
+
closed_at_ms: Date.now()
|
|
119
|
+
} : null);
|
|
72
120
|
}
|
|
73
|
-
const pendingAfterClose = pendingWorkItems(queue).length;
|
|
74
|
-
if (pendingAfterClose > 0)
|
|
75
|
-
state.expected_backfill_count += 1;
|
|
76
121
|
updateUtilizationMetrics();
|
|
122
|
+
state.status = state.blockers.length ? 'blocked' : 'draining';
|
|
123
|
+
await writeAll(input.root, state, slots, queue, active, { event_type: 'scheduler_draining' }, input.onSchedulerEvent);
|
|
124
|
+
slots = closeWorkerSlotsAfterDrain(slots);
|
|
125
|
+
state = buildState(input.missionId, targetActiveSlots, queue, slots, active, {
|
|
126
|
+
previous: state,
|
|
127
|
+
status: state.blockers.length ? 'blocked' : 'drained',
|
|
128
|
+
refillDelayMs: input.refillDelayMs || 0,
|
|
129
|
+
rateLimitBackoffMs: input.rateLimitBackoffMs || 0
|
|
130
|
+
});
|
|
131
|
+
state.pending_queue_drained = unfinishedWorkItems(queue).length === 0;
|
|
132
|
+
state.all_slots_closed_after_drain = slots.every((slot) => slot.status === 'closed');
|
|
133
|
+
state.all_generations_closed = active.size === 0 && slots.every((slot) => slot.history.every((entry) => Boolean(entry.closed_at) && entry.status !== 'running'));
|
|
134
|
+
if (!state.pending_queue_drained)
|
|
135
|
+
addUniqueBlocker(state, 'scheduler_pending_queue_not_drained');
|
|
136
|
+
if (!state.all_generations_closed)
|
|
137
|
+
addUniqueBlocker(state, 'scheduler_generations_not_closed');
|
|
138
|
+
state.status = state.blockers.length ? 'blocked' : 'drained';
|
|
139
|
+
state.stop_reason = terminalStopReason || (state.blockers.length ? 'scheduler_completed_with_blockers' : null);
|
|
140
|
+
state.completion_claim_allowed = state.status === 'drained';
|
|
141
|
+
updateUtilizationMetrics();
|
|
142
|
+
await writeAll(input.root, state, slots, queue, active, { event_type: 'scheduler_drained' }, input.onSchedulerEvent);
|
|
143
|
+
return {
|
|
144
|
+
schema: 'sks.agent-scheduler-result.v1',
|
|
145
|
+
ok: state.completion_claim_allowed,
|
|
146
|
+
state,
|
|
147
|
+
queue,
|
|
148
|
+
slots,
|
|
149
|
+
results
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
stopSignal.dispose();
|
|
154
|
+
}
|
|
155
|
+
async function stopScheduler(reason) {
|
|
156
|
+
if (terminalStopReason)
|
|
157
|
+
return;
|
|
158
|
+
terminalStopReason = reason;
|
|
159
|
+
state.status = 'blocked';
|
|
160
|
+
state.stop_reason = reason;
|
|
161
|
+
state.completion_claim_allowed = false;
|
|
162
|
+
addUniqueBlocker(state, reason);
|
|
163
|
+
const cleanup = await invokeBoundedStop(input.onStop, reason);
|
|
164
|
+
if (!cleanup.ok)
|
|
165
|
+
addUniqueBlocker(state, cleanup.blocker);
|
|
166
|
+
const activeEntries = [...active.values()];
|
|
167
|
+
const activeWorkItemIds = new Set(activeEntries.map((entry) => entry.work_item_id));
|
|
168
|
+
for (const entry of activeEntries) {
|
|
169
|
+
completeWorkItem(queue, entry.work_item_id, entry.session_id, 'blocked', reason);
|
|
170
|
+
const slotIndex = slots.findIndex((slot) => slot.slot_id === entry.slot_id);
|
|
171
|
+
const currentSlot = slotIndex >= 0 ? slots[slotIndex] : null;
|
|
172
|
+
if (slotIndex >= 0 && currentSlot)
|
|
173
|
+
slots[slotIndex] = markWorkerSlotGenerationClosed(currentSlot, entry.session_id, 'blocked');
|
|
174
|
+
results.push(schedulerStoppedResult(input.missionId, entry, reason));
|
|
175
|
+
}
|
|
176
|
+
await Promise.all(activeEntries.map((entry) => closeAgentSessionGeneration(input.root, entry.session_id, {
|
|
177
|
+
status: 'blocked',
|
|
178
|
+
terminalCloseReportPath: null
|
|
179
|
+
}).catch(() => null)));
|
|
180
|
+
active.clear();
|
|
181
|
+
for (const item of queue.items) {
|
|
182
|
+
if (item.status !== 'pending' && item.status !== 'running')
|
|
183
|
+
continue;
|
|
184
|
+
if (!activeWorkItemIds.has(item.id)) {
|
|
185
|
+
results.push(schedulerStoppedResult(input.missionId, {
|
|
186
|
+
slot_id: 'scheduler',
|
|
187
|
+
work_item_id: item.id,
|
|
188
|
+
session_id: item.running_session_id || `unlaunched:${item.id}`
|
|
189
|
+
}, reason));
|
|
190
|
+
}
|
|
191
|
+
item.status = 'blocked';
|
|
192
|
+
item.running_session_id = null;
|
|
193
|
+
item.blocked_reason = reason;
|
|
194
|
+
}
|
|
195
|
+
queue.updated_at = nowIso();
|
|
77
196
|
await writeAll(input.root, state, slots, queue, active, {
|
|
78
|
-
event_type: '
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
work_item_id: entry.work_item_id,
|
|
82
|
-
active_count_before_close: activeCountBeforeClose,
|
|
83
|
-
active_count_after_close: active.size,
|
|
84
|
-
pending_count_after_close: pendingAfterClose
|
|
197
|
+
event_type: 'scheduler_terminal_unverified',
|
|
198
|
+
stop_reason: reason,
|
|
199
|
+
completion_claim_allowed: false
|
|
85
200
|
}, input.onSchedulerEvent);
|
|
86
|
-
await refillSlots(pendingAfterClose > 0 ? {
|
|
87
|
-
closed_session_id: settled.session_id,
|
|
88
|
-
active_count_before: active.size,
|
|
89
|
-
closed_at_ms: Date.now()
|
|
90
|
-
} : null);
|
|
91
201
|
}
|
|
92
|
-
updateUtilizationMetrics();
|
|
93
|
-
state.status = 'draining';
|
|
94
|
-
await writeAll(input.root, state, slots, queue, active, { event_type: 'scheduler_draining' }, input.onSchedulerEvent);
|
|
95
|
-
slots = closeWorkerSlotsAfterDrain(slots);
|
|
96
|
-
state = buildState(input.missionId, targetActiveSlots, queue, slots, active, {
|
|
97
|
-
previous: state,
|
|
98
|
-
status: state.blockers.length ? 'blocked' : 'drained',
|
|
99
|
-
refillDelayMs: input.refillDelayMs || 0,
|
|
100
|
-
rateLimitBackoffMs: input.rateLimitBackoffMs || 0
|
|
101
|
-
});
|
|
102
|
-
state.pending_queue_drained = pendingWorkItems(queue).length === 0;
|
|
103
|
-
state.all_slots_closed_after_drain = slots.every((slot) => slot.status === 'closed');
|
|
104
|
-
state.all_generations_closed = true;
|
|
105
|
-
if (!state.pending_queue_drained)
|
|
106
|
-
state.blockers.push('scheduler_pending_queue_not_drained');
|
|
107
|
-
updateUtilizationMetrics();
|
|
108
|
-
await writeAll(input.root, state, slots, queue, active, { event_type: 'scheduler_drained' }, input.onSchedulerEvent);
|
|
109
|
-
return {
|
|
110
|
-
schema: 'sks.agent-scheduler-result.v1',
|
|
111
|
-
ok: state.blockers.length === 0,
|
|
112
|
-
state,
|
|
113
|
-
queue,
|
|
114
|
-
slots,
|
|
115
|
-
results
|
|
116
|
-
};
|
|
117
202
|
async function refillSlots(backfill) {
|
|
203
|
+
if (terminalStopReason)
|
|
204
|
+
return;
|
|
205
|
+
const stopReason = stopSignal.currentReason();
|
|
206
|
+
if (stopReason) {
|
|
207
|
+
await stopScheduler(stopReason);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
118
210
|
state.status = 'running';
|
|
119
211
|
const launches = collectLaunchBatch();
|
|
120
212
|
if (!launches.length)
|
|
@@ -252,8 +344,16 @@ export async function runAgentScheduler(input) {
|
|
|
252
344
|
active_count_after: active.size
|
|
253
345
|
});
|
|
254
346
|
}
|
|
255
|
-
if (input.refillDelayMs && input.refillDelayMs > 0)
|
|
256
|
-
await
|
|
347
|
+
if (input.refillDelayMs && input.refillDelayMs > 0) {
|
|
348
|
+
const delayed = await Promise.race([
|
|
349
|
+
delay(input.refillDelayMs).then(() => null),
|
|
350
|
+
stopSignal.promise
|
|
351
|
+
]);
|
|
352
|
+
if (isSchedulerStopSignal(delayed)) {
|
|
353
|
+
await stopScheduler(delayed.scheduler_stop_reason);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
257
357
|
const launchSpanMs = Math.max(0, Date.now() - batchStart);
|
|
258
358
|
batchLaunchSpanTotalMs += launchSpanMs;
|
|
259
359
|
state.batch_dispatch_count += 1;
|
|
@@ -282,6 +382,10 @@ export async function runAgentScheduler(input) {
|
|
|
282
382
|
session_ids: launches.map((launch) => launch.generation.session_id)
|
|
283
383
|
}, input.onSchedulerEvent);
|
|
284
384
|
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
addUniqueBlocker(state, `scheduler_batch_dispatch_error:${errorMessage(error)}`);
|
|
387
|
+
await stopScheduler('scheduler_batch_dispatch_failed');
|
|
388
|
+
}
|
|
285
389
|
finally {
|
|
286
390
|
batchDispatchInProgress = false;
|
|
287
391
|
}
|
|
@@ -350,13 +454,19 @@ export function normalizeTargetActiveSlots(value, maxActiveSlots = MAX_AGENT_COU
|
|
|
350
454
|
}
|
|
351
455
|
function buildState(missionId, targetActiveSlots, queue, slots, active, opts) {
|
|
352
456
|
const previous = opts.previous;
|
|
353
|
-
const pendingCount =
|
|
457
|
+
const pendingCount = queue.items.filter((item) => item.status === 'pending').length;
|
|
354
458
|
const completed = queue.items.filter((item) => item.status === 'completed').map((item) => item.id);
|
|
355
459
|
const failed = queue.items.filter((item) => item.status === 'failed').map((item) => item.id);
|
|
356
460
|
const blocked = queue.items.filter((item) => item.status === 'blocked').map((item) => item.id);
|
|
461
|
+
const blockers = [...(previous?.blockers || [])];
|
|
462
|
+
const completionClaimAllowed = opts.status === 'drained'
|
|
463
|
+
&& blockers.length === 0
|
|
464
|
+
&& unfinishedWorkItems(queue).length === 0
|
|
465
|
+
&& active.size === 0;
|
|
466
|
+
const updatedAt = nowIso();
|
|
357
467
|
return {
|
|
358
468
|
schema: AGENT_SCHEDULER_SCHEMA,
|
|
359
|
-
updated_at:
|
|
469
|
+
updated_at: updatedAt,
|
|
360
470
|
mission_id: missionId,
|
|
361
471
|
status: opts.status,
|
|
362
472
|
target_active_slots: targetActiveSlots,
|
|
@@ -380,10 +490,13 @@ function buildState(missionId, targetActiveSlots, queue, slots, active, opts) {
|
|
|
380
490
|
completed,
|
|
381
491
|
failed,
|
|
382
492
|
blocked,
|
|
383
|
-
pending_queue_drained:
|
|
493
|
+
pending_queue_drained: unfinishedWorkItems(queue).length === 0,
|
|
384
494
|
all_slots_closed_after_drain: slots.length > 0 && slots.every((slot) => slot.status === 'closed'),
|
|
385
|
-
all_generations_closed:
|
|
386
|
-
|
|
495
|
+
all_generations_closed: active.size === 0 && slots.every((slot) => slot.history.every((entry) => Boolean(entry.closed_at) && entry.status !== 'running')),
|
|
496
|
+
stop_reason: previous?.stop_reason || null,
|
|
497
|
+
completion_claim_allowed: completionClaimAllowed,
|
|
498
|
+
runtime_evidence: schedulerRuntimeEvidence(completionClaimAllowed, opts.status, blockers, updatedAt),
|
|
499
|
+
blockers,
|
|
387
500
|
batch_dispatch_count: previous?.batch_dispatch_count || 0,
|
|
388
501
|
largest_batch_size: previous?.largest_batch_size || 0,
|
|
389
502
|
first_batch_launch_span_ms: previous?.first_batch_launch_span_ms || 0,
|
|
@@ -418,6 +531,10 @@ async function writeAll(root, currentState, slots, queue, active, event, onSched
|
|
|
418
531
|
currentState.blocked = nextState.blocked;
|
|
419
532
|
currentState.pending_queue_drained = nextState.pending_queue_drained;
|
|
420
533
|
currentState.all_slots_closed_after_drain = nextState.all_slots_closed_after_drain;
|
|
534
|
+
currentState.all_generations_closed = nextState.all_generations_closed;
|
|
535
|
+
currentState.stop_reason = nextState.stop_reason;
|
|
536
|
+
currentState.completion_claim_allowed = nextState.completion_claim_allowed;
|
|
537
|
+
currentState.runtime_evidence = nextState.runtime_evidence;
|
|
421
538
|
currentState.batch_dispatch_count = nextState.batch_dispatch_count;
|
|
422
539
|
currentState.largest_batch_size = nextState.largest_batch_size;
|
|
423
540
|
currentState.first_batch_launch_span_ms = nextState.first_batch_launch_span_ms;
|
|
@@ -430,7 +547,23 @@ async function writeAll(root, currentState, slots, queue, active, event, onSched
|
|
|
430
547
|
await writeJsonAtomic(path.join(root, 'agent-scheduler-state.json'), currentState);
|
|
431
548
|
const entry = { schema: AGENT_SCHEDULER_EVENT_SCHEMA, ts: nowIso(), ...event };
|
|
432
549
|
await appendJsonl(path.join(root, 'agent-scheduler-events.jsonl'), entry);
|
|
433
|
-
|
|
550
|
+
if (onSchedulerEvent) {
|
|
551
|
+
const callback = await invokeBoundedSchedulerCallback(onSchedulerEvent, { event: entry, state: currentState, slots, queue });
|
|
552
|
+
if (!callback.ok) {
|
|
553
|
+
addUniqueBlocker(currentState, callback.blocker);
|
|
554
|
+
currentState.status = 'blocked';
|
|
555
|
+
currentState.stop_reason = currentState.stop_reason || 'scheduler_event_callback_failed';
|
|
556
|
+
currentState.completion_claim_allowed = false;
|
|
557
|
+
currentState.runtime_evidence = schedulerRuntimeEvidence(false, 'blocked', currentState.blockers, nowIso());
|
|
558
|
+
await writeJsonAtomic(path.join(root, 'agent-scheduler-state.json'), currentState);
|
|
559
|
+
await appendJsonl(path.join(root, 'agent-scheduler-events.jsonl'), {
|
|
560
|
+
schema: AGENT_SCHEDULER_EVENT_SCHEMA,
|
|
561
|
+
ts: nowIso(),
|
|
562
|
+
event_type: 'scheduler_event_callback_failed',
|
|
563
|
+
blocker: callback.blocker
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
}
|
|
434
567
|
}
|
|
435
568
|
function buildAgentForGeneration(slot, generation, workItem) {
|
|
436
569
|
const persona = slot.persona_assignment || {};
|
|
@@ -461,6 +594,115 @@ function activeWritePaths(queue) {
|
|
|
461
594
|
.map((file) => String(file || '').replace(/\\/g, '/').replace(/^\.\/+/, '').replace(/\/+$/, ''))
|
|
462
595
|
.filter(Boolean);
|
|
463
596
|
}
|
|
597
|
+
function unfinishedWorkItems(queue) {
|
|
598
|
+
return queue.items.filter((item) => item.status === 'pending' || item.status === 'running');
|
|
599
|
+
}
|
|
600
|
+
function normalizeSchedulerMaxWallMs(value) {
|
|
601
|
+
const parsed = Number(value ?? DEFAULT_AGENT_SCHEDULER_MAX_WALL_MS);
|
|
602
|
+
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
603
|
+
return DEFAULT_AGENT_SCHEDULER_MAX_WALL_MS;
|
|
604
|
+
return Math.max(10, Math.min(Math.floor(parsed), 24 * 60 * 60 * 1000));
|
|
605
|
+
}
|
|
606
|
+
function createSchedulerStopSignal(maxWallMs, signal) {
|
|
607
|
+
let currentReason = signal?.aborted ? 'scheduler_external_abort' : null;
|
|
608
|
+
let resolveStop = () => undefined;
|
|
609
|
+
const promise = new Promise((resolve) => {
|
|
610
|
+
resolveStop = resolve;
|
|
611
|
+
if (currentReason)
|
|
612
|
+
resolve({ scheduler_stop_reason: currentReason });
|
|
613
|
+
});
|
|
614
|
+
const stop = (reason) => {
|
|
615
|
+
if (currentReason)
|
|
616
|
+
return;
|
|
617
|
+
currentReason = reason;
|
|
618
|
+
resolveStop({ scheduler_stop_reason: reason });
|
|
619
|
+
};
|
|
620
|
+
const timer = setTimeout(() => stop('scheduler_wall_time_budget_exhausted'), maxWallMs);
|
|
621
|
+
const abort = () => stop('scheduler_external_abort');
|
|
622
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
623
|
+
return {
|
|
624
|
+
promise,
|
|
625
|
+
currentReason: () => currentReason,
|
|
626
|
+
dispose: () => {
|
|
627
|
+
clearTimeout(timer);
|
|
628
|
+
signal?.removeEventListener('abort', abort);
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
function isSchedulerStopSignal(value) {
|
|
633
|
+
return Boolean(value && typeof value === 'object' && typeof value.scheduler_stop_reason === 'string');
|
|
634
|
+
}
|
|
635
|
+
function addUniqueBlocker(state, blocker) {
|
|
636
|
+
if (blocker && !state.blockers.includes(blocker))
|
|
637
|
+
state.blockers.push(blocker);
|
|
638
|
+
}
|
|
639
|
+
function schedulerRuntimeEvidence(completionClaimAllowed, status, blockers, observedAt) {
|
|
640
|
+
if (completionClaimAllowed) {
|
|
641
|
+
return {
|
|
642
|
+
schema: 'sks.runtime-evidence.v1',
|
|
643
|
+
runtime_status: 'proven',
|
|
644
|
+
evidence_source: 'runtime',
|
|
645
|
+
receipts: [{ command: 'runAgentScheduler', exit_code: 0, observed_at: observedAt }],
|
|
646
|
+
blockers: []
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
return {
|
|
650
|
+
schema: 'sks.runtime-evidence.v1',
|
|
651
|
+
runtime_status: status === 'blocked' ? 'blocked' : 'partial',
|
|
652
|
+
evidence_source: 'runtime',
|
|
653
|
+
receipts: [],
|
|
654
|
+
blockers: [...blockers]
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
async function invokeBoundedStop(callback, reason) {
|
|
658
|
+
if (!callback)
|
|
659
|
+
return { ok: true, blocker: '' };
|
|
660
|
+
return boundedCallback(() => callback(reason), 10_000, 'scheduler_stop_cleanup_timeout', 'scheduler_stop_cleanup_failed');
|
|
661
|
+
}
|
|
662
|
+
async function invokeBoundedSchedulerCallback(callback, ctx) {
|
|
663
|
+
return boundedCallback(() => callback(ctx), 30_000, 'scheduler_event_callback_timeout', 'scheduler_event_callback_failed');
|
|
664
|
+
}
|
|
665
|
+
async function boundedCallback(callback, timeoutMs, timeoutBlocker, errorPrefix) {
|
|
666
|
+
let timer = null;
|
|
667
|
+
try {
|
|
668
|
+
return await Promise.race([
|
|
669
|
+
Promise.resolve()
|
|
670
|
+
.then(callback)
|
|
671
|
+
.then(() => ({ ok: true, blocker: '' }))
|
|
672
|
+
.catch((error) => ({ ok: false, blocker: `${errorPrefix}:${errorMessage(error)}` })),
|
|
673
|
+
new Promise((resolve) => {
|
|
674
|
+
timer = setTimeout(() => resolve({ ok: false, blocker: timeoutBlocker }), timeoutMs);
|
|
675
|
+
})
|
|
676
|
+
]);
|
|
677
|
+
}
|
|
678
|
+
finally {
|
|
679
|
+
if (timer)
|
|
680
|
+
clearTimeout(timer);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
function schedulerStoppedResult(missionId, entry, reason) {
|
|
684
|
+
return {
|
|
685
|
+
schema: 'sks.agent-result.v1',
|
|
686
|
+
mission_id: missionId,
|
|
687
|
+
agent_id: entry.slot_id,
|
|
688
|
+
session_id: entry.session_id,
|
|
689
|
+
task_slice_id: entry.work_item_id,
|
|
690
|
+
status: 'blocked',
|
|
691
|
+
backend: 'scheduler',
|
|
692
|
+
summary: `Scheduler stopped before runtime completion: ${reason}`,
|
|
693
|
+
blockers: [reason],
|
|
694
|
+
unverified: ['worker_runtime_completion'],
|
|
695
|
+
changed_files: [],
|
|
696
|
+
artifacts: [],
|
|
697
|
+
verification: { status: 'unverified', checks: [] },
|
|
698
|
+
completion_claim_allowed: false
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
function errorMessage(error) {
|
|
702
|
+
return (error instanceof Error ? error.message : String(error || 'unknown_error'))
|
|
703
|
+
.replace(/\s+/g, ' ')
|
|
704
|
+
.slice(0, 240);
|
|
705
|
+
}
|
|
464
706
|
function delay(ms) {
|
|
465
707
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
466
708
|
}
|
|
@@ -12,7 +12,7 @@ export const OFFICIAL_SUBAGENT_EXECUTION_STAGE_ID = 'official_subagent_execution
|
|
|
12
12
|
export const MAX_AGENT_COUNT = 20;
|
|
13
13
|
export const DEFAULT_AGENT_CONCURRENCY = DEFAULT_NARUTO_MAX_THREADS;
|
|
14
14
|
export const HARD_AGENT_CONCURRENCY = HARD_NARUTO_MAX_THREADS;
|
|
15
|
-
export const AGENT_BACKENDS = ['fake', 'process', 'codex-sdk', '
|
|
15
|
+
export const AGENT_BACKENDS = ['fake', 'process', 'codex-sdk', 'ollama', 'local-llm'];
|
|
16
16
|
export function normalizeAgentBackend(input) {
|
|
17
17
|
const value = String(input || 'codex-sdk');
|
|
18
18
|
return AGENT_BACKENDS.includes(value) ? value : null;
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { nowIso, readJson, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
|
|
3
3
|
import { OFFICIAL_SUBAGENT_EXECUTION_ARTIFACTS, OFFICIAL_SUBAGENT_EXECUTION_AUTHORITY } from '../proof/fake-real-proof-policy.js';
|
|
4
|
-
import { readZellijLaneSupervisor } from './zellij-lane-supervisor.js';
|
|
5
4
|
export async function writeAgentTrustReport(root, input = {}) {
|
|
6
|
-
const laneSupervisor = await readZellijLaneSupervisor(root);
|
|
7
|
-
const zellijRuntimeManifest = await readJson(path.join(root, 'zellij-lane-runtime.json'), null);
|
|
8
|
-
const zellijPaneProof = await readJson(path.join(root, 'zellij-pane-proof.json'), null);
|
|
9
5
|
const cleanupProof = await readJson(path.join(root, 'agent-cleanup-proof.json'), null);
|
|
10
6
|
const intelligentWorkGraph = await readJson(path.join(root, 'agent-intelligent-work-graph.json'), null);
|
|
11
7
|
const fakeRealPolicy = await readJson(path.join(root, 'fake-real-proof-policy.json'), null);
|
|
@@ -30,14 +26,12 @@ export async function writeAgentTrustReport(root, input = {}) {
|
|
|
30
26
|
else if (/blocked|failed|missing/.test(status))
|
|
31
27
|
runtimeTruthGroups.Blocked.push(label);
|
|
32
28
|
};
|
|
33
|
-
pushTruth(zellijPaneProof?.ok === true ? 'passed' : zellijPaneProof ? 'blocked' : 'not_run', 'Zellij pane proof');
|
|
34
29
|
pushTruth(cleanupProof?.ok === true ? 'passed' : cleanupProof ? 'blocked' : 'not_run', 'cleanup executor');
|
|
35
30
|
pushTruth(intelligentWorkGraph?.ok === true ? 'passed' : intelligentWorkGraph ? 'partial' : 'not_run', 'intelligent work graph');
|
|
36
31
|
pushTruth(officialSubagentExecution?.proof_level || 'not_run', 'official Codex subagent execution');
|
|
37
32
|
const subsystemProofLevels = {
|
|
38
33
|
...(fakeRealPolicy?.subsystem_levels || {}),
|
|
39
34
|
...Object.fromEntries((runtimeTruthMatrix?.rows || runtimeTruthMatrix?.subsystems || []).map((row) => [row.subsystem, row.proof_level])),
|
|
40
|
-
zellij_pane: runtimeTruthMatrix?.rows?.find?.((row) => row.subsystem === 'zellij_pane')?.proof_level || fakeRealPolicy?.subsystem_levels?.zellij_pane || (zellijPaneProof?.ok === true ? 'proven' : zellijPaneProof ? 'blocked' : 'not_run'),
|
|
41
35
|
cleanup: runtimeTruthMatrix?.rows?.find?.((row) => row.subsystem === 'cleanup')?.proof_level || fakeRealPolicy?.subsystem_levels?.cleanup || (cleanupProof?.ok === true ? 'proven' : cleanupProof ? 'blocked' : 'not_run'),
|
|
42
36
|
intelligent_work_graph: runtimeTruthMatrix?.rows?.find?.((row) => row.subsystem === 'intelligent_work_graph')?.proof_level || fakeRealPolicy?.subsystem_levels?.intelligent_work_graph || intelligentWorkGraph?.proof_level || (intelligentWorkGraph ? 'partial' : 'not_run')
|
|
43
37
|
};
|
|
@@ -64,31 +58,10 @@ export async function writeAgentTrustReport(root, input = {}) {
|
|
|
64
58
|
expected_backfill_count: input.proof?.expected_backfill_count ?? input.scheduler?.expected_backfill_count ?? null,
|
|
65
59
|
pending_queue_drained: input.proof?.pending_queue_drained ?? input.scheduler?.pending_queue_drained ?? null,
|
|
66
60
|
generation_count: input.proof?.generation_count ?? null,
|
|
67
|
-
zellij_attach_command: input.missionId ? `zellij attach sks-${input.missionId}` : null,
|
|
68
|
-
zellij_lane_manifest: 'agent-zellij-lanes.json',
|
|
69
|
-
zellij_lane_persistence: {
|
|
70
|
-
supervisor: 'agent-zellij-lane-supervisor.json',
|
|
71
|
-
runtime_manifest: zellijRuntimeManifest ? 'zellij-lane-runtime.json' : null,
|
|
72
|
-
dispatch_mode: laneSupervisor?.dispatch_mode || zellijRuntimeManifest?.dispatch_mode || null,
|
|
73
|
-
fifo_policy: laneSupervisor?.fifo_policy || zellijRuntimeManifest?.fifo_policy || null,
|
|
74
|
-
resource_throttle_ms: laneSupervisor?.resource_throttle_ms || zellijRuntimeManifest?.resource_throttle_ms || null,
|
|
75
|
-
nice_level: laneSupervisor?.nice_level ?? zellijRuntimeManifest?.nice_level ?? null,
|
|
76
|
-
runtime_policy_ok: Array.isArray(laneSupervisor?.lanes) && laneSupervisor.lanes.every((lane) => lane?.dispatch_mode === 'jsonl_nonblocking' && lane?.command_inbox && lane?.state_dir),
|
|
77
|
-
pane_id_source_ok: Array.isArray(laneSupervisor?.lanes) && laneSupervisor.lanes.every((lane) => typeof lane?.pane_id_source === 'string' && lane.pane_id_source.length > 0),
|
|
78
|
-
no_flicker_verified: laneSupervisor?.no_flicker_verified === true,
|
|
79
|
-
pane_survival_checked: laneSupervisor?.pane_survival_checked === true,
|
|
80
|
-
unexpected_close_count: laneSupervisor?.unexpected_close_count || 0,
|
|
81
|
-
lane_count: laneSupervisor?.lane_count || 0,
|
|
82
|
-
pane_proof_ok: zellijPaneProof?.ok === true,
|
|
83
|
-
pane_proof_status: zellijPaneProof ? (zellijPaneProof.ok === true ? 'passed' : 'blocked') : 'not_run',
|
|
84
|
-
pane_proof: zellijPaneProof ? 'zellij-pane-proof.json' : null,
|
|
85
|
-
pane_count: zellijPaneProof?.pane_count ?? null
|
|
86
|
-
},
|
|
87
61
|
cleanup_executor: {
|
|
88
62
|
status: cleanupProof?.ok === true ? 'passed' : cleanupProof ? 'blocked' : 'not_run',
|
|
89
63
|
proof: cleanupProof ? 'agent-cleanup-proof.json' : null,
|
|
90
64
|
stale_processes_killed: cleanupProof?.stale_processes_killed || [],
|
|
91
|
-
stale_zellij_panes_closed: cleanupProof?.stale_zellij_panes_closed || [],
|
|
92
65
|
orphan_temp_dirs_removed: cleanupProof?.orphan_temp_dirs_removed || [],
|
|
93
66
|
stale_locks_removed: cleanupProof?.stale_locks_removed || [],
|
|
94
67
|
skipped_active_sessions: cleanupProof?.skipped_active_sessions || []
|
|
@@ -152,15 +125,6 @@ function renderAgentTrustReportMarkdown(report) {
|
|
|
152
125
|
`- backfill_count: ${orchestration.backfill_count ?? 'unknown'}`,
|
|
153
126
|
`- expected_backfill_count: ${orchestration.expected_backfill_count ?? 'unknown'}`,
|
|
154
127
|
`- pending_queue_drained: ${orchestration.pending_queue_drained === true}`,
|
|
155
|
-
`- zellij_lane_manifest: ${orchestration.zellij_lane_manifest || 'unknown'}`,
|
|
156
|
-
`- zellij_runtime_manifest: ${orchestration.zellij_lane_persistence?.runtime_manifest || 'not_run'}`,
|
|
157
|
-
`- zellij_dispatch_mode: ${orchestration.zellij_lane_persistence?.dispatch_mode || 'unknown'}`,
|
|
158
|
-
`- zellij_fifo_policy: ${orchestration.zellij_lane_persistence?.fifo_policy || 'unknown'}`,
|
|
159
|
-
`- zellij_runtime_policy_ok: ${orchestration.zellij_lane_persistence?.runtime_policy_ok === true}`,
|
|
160
|
-
`- zellij_no_flicker_verified: ${orchestration.zellij_lane_persistence?.no_flicker_verified === true}`,
|
|
161
|
-
`- zellij_pane_survival_checked: ${orchestration.zellij_lane_persistence?.pane_survival_checked === true}`,
|
|
162
|
-
`- zellij_pane_proof_ok: ${orchestration.zellij_lane_persistence?.pane_proof_ok === true}`,
|
|
163
|
-
`- zellij_pane_count: ${orchestration.zellij_lane_persistence?.pane_count ?? 'unknown'}`,
|
|
164
128
|
`- cleanup_executor: ${orchestration.cleanup_executor?.status || 'not_run'}`,
|
|
165
129
|
`- work_graph_quality_score: ${orchestration.intelligent_work_graph?.score ?? 'unknown'}`,
|
|
166
130
|
`- runtime_truth_fake: ${(report.runtime_truth_groups?.Fake || []).join(', ') || 'None'}`,
|
|
@@ -49,7 +49,6 @@ export function validateAgentWorkerResult(result) {
|
|
|
49
49
|
...(result?.backend_router_report === undefined ? {} : { backend_router_report: result.backend_router_report }),
|
|
50
50
|
...(result?.codex_child_report === undefined ? {} : { codex_child_report: result.codex_child_report }),
|
|
51
51
|
...(result?.process_child_report === undefined ? {} : { process_child_report: result.process_child_report }),
|
|
52
|
-
...(result?.zellij_child_report === undefined ? {} : { zellij_child_report: result.zellij_child_report }),
|
|
53
52
|
...(result?.codex_sdk_thread === undefined ? {} : { codex_sdk_thread: result.codex_sdk_thread }),
|
|
54
53
|
...(result?.model_authored_patch_envelopes === undefined ? {} : { model_authored_patch_envelopes: Boolean(result.model_authored_patch_envelopes) }),
|
|
55
54
|
...(result?.fixture_patch_envelopes === undefined ? {} : { fixture_patch_envelopes: Boolean(result.fixture_patch_envelopes) }),
|
|
@@ -122,10 +122,9 @@ export function applyFastModeToRoster(roster, policy) {
|
|
|
122
122
|
export async function writeFastModePropagationProof(root, input = { policy: resolveFastModePolicy() }) {
|
|
123
123
|
const workerProcessReports = await collectNamedJson(root, 'worker-process-report.json');
|
|
124
124
|
const agentProcessReports = await collectNamedJson(root, 'agent-process-report.json');
|
|
125
|
-
const zellijReports = await collectNamedJson(root, 'agent-zellij-report.json');
|
|
126
125
|
const madReports = await collectNamedJson(root, 'mad-sks-worker-report.json');
|
|
127
126
|
const defaultFastExpected = input.policy.fast_mode === true;
|
|
128
|
-
const childReports = [...workerProcessReports, ...agentProcessReports, ...
|
|
127
|
+
const childReports = [...workerProcessReports, ...agentProcessReports, ...madReports];
|
|
129
128
|
const missingFast = defaultFastExpected
|
|
130
129
|
? childReports.filter((row) => row.json?.fast_mode !== true && row.json?.fast_mode !== 'true')
|
|
131
130
|
: [];
|
|
@@ -150,7 +149,6 @@ export async function writeFastModePropagationProof(root, input = { policy: reso
|
|
|
150
149
|
worker_process_report_count: workerProcessReports.length,
|
|
151
150
|
codex_sdk_process_report_count: agentProcessReports.filter((row) => row.json?.backend === 'codex-sdk').length,
|
|
152
151
|
process_report_count: agentProcessReports.filter((row) => row.json?.backend === 'process').length,
|
|
153
|
-
zellij_report_count: zellijReports.length,
|
|
154
152
|
mad_report_count: madReports.length,
|
|
155
153
|
child_report_count: childReports.length,
|
|
156
154
|
artifacts: childReports.map((row) => row.relative_path),
|
|
@@ -15,7 +15,7 @@ export async function writeNativeCliWorkerRuntimeProof(root, input = {}) {
|
|
|
15
15
|
const spawnedWorkerProcessCount = Number(runtime?.spawned_worker_process_count || 0);
|
|
16
16
|
const maxObservedWorkerProcessCount = Number(runtime?.max_observed_worker_process_count || 0);
|
|
17
17
|
const processIds = Array.isArray(runtime?.process_ids) ? runtime.process_ids.filter((pid) => Number.isFinite(Number(pid))) : [];
|
|
18
|
-
const allowedScalingPrimitives = new Set(['native_cli_process'
|
|
18
|
+
const allowedScalingPrimitives = new Set(['native_cli_process']);
|
|
19
19
|
const blockers = [
|
|
20
20
|
...(!runtime ? ['native_cli_worker_runtime_missing'] : []),
|
|
21
21
|
...(runtime && !allowedScalingPrimitives.has(String(runtime.scaling_primitive || '')) ? ['scaling_primitive_not_native_cli_process'] : []),
|