create-walle 0.10.2 → 0.10.3
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 +3 -1
- package/lib/release-schema.json +2 -2
- package/lib/runtime-closure-policy.json +8 -7
- package/package.json +1 -1
- package/template/coding-task-manager/api-prompts.js +45 -7
- package/template/coding-task-manager/bin/claude-hook.js +55 -1
- package/template/coding-task-manager/bin/ctm-relay-client.js +35 -12
- package/template/coding-task-manager/bin/land.js +2069 -0
- package/template/coding-task-manager/bin/memory-census.js +4 -2
- package/template/coding-task-manager/bin/memory-sync-verify.js +151 -0
- package/template/coding-task-manager/bin/probe-refusal-scope.js +530 -0
- package/template/coding-task-manager/db.js +156 -32
- package/template/coding-task-manager/lib/acp/acp-client.js +383 -0
- package/template/coding-task-manager/lib/acp/dsh-context-truth.js +176 -0
- package/template/coding-task-manager/lib/acp/dsh-launch-model.js +302 -0
- package/template/coding-task-manager/lib/acp/dsh-mcp-servers.js +194 -0
- package/template/coding-task-manager/lib/acp/dsh-prompt-lane.js +616 -0
- package/template/coding-task-manager/lib/acp/dsh-route-patch.js +308 -0
- package/template/coding-task-manager/lib/acp/dsh-session-runtime.js +522 -0
- package/template/coding-task-manager/lib/acp/dsh-transcript.js +395 -0
- package/template/coding-task-manager/lib/acp/dsh-usage-log.js +162 -0
- package/template/coding-task-manager/lib/acp/ndjson-stdio-transport.js +225 -0
- package/template/coding-task-manager/lib/adopted-host-redial.js +47 -11
- package/template/coding-task-manager/lib/adopted-launch-environment.js +123 -0
- package/template/coding-task-manager/lib/agent-auto-update-runtime.js +0 -3
- package/template/coding-task-manager/lib/agent-auto-update.js +26 -10
- package/template/coding-task-manager/lib/agent-bundle/build.js +657 -0
- package/template/coding-task-manager/lib/agent-bundle/codex-install.js +558 -0
- package/template/coding-task-manager/lib/agent-bundle/drift.js +120 -0
- package/template/coding-task-manager/lib/agent-bundle/gc.js +522 -0
- package/template/coding-task-manager/lib/agent-bundle/inventory.js +346 -0
- package/template/coding-task-manager/lib/agent-bundle/push.js +717 -0
- package/template/coding-task-manager/lib/agent-bundle/skill-transfer.js +724 -0
- package/template/coding-task-manager/lib/agent-bundle/spawn.js +119 -0
- package/template/coding-task-manager/lib/agent-bundle/store.js +568 -0
- package/template/coding-task-manager/lib/agent-capabilities.js +142 -12
- package/template/coding-task-manager/lib/agent-cli-cache.js +30 -5
- package/template/coding-task-manager/lib/agent-definitions.js +19 -0
- package/template/coding-task-manager/lib/agent-hooks-codex-toml.js +28 -16
- package/template/coding-task-manager/lib/agent-hooks-codex-workspace.js +9 -1
- package/template/coding-task-manager/lib/agent-hooks-installer.js +23 -8
- package/template/coding-task-manager/lib/agent-hooks-prune.js +37 -11
- package/template/coding-task-manager/lib/agent-hooks-shim.js +105 -0
- package/template/coding-task-manager/lib/agent-presets.js +84 -1
- package/template/coding-task-manager/lib/agent-upgrade-jobs.js +12 -1
- package/template/coding-task-manager/lib/agent-version-service.js +74 -11
- package/template/coding-task-manager/lib/all-sessions-query.js +6 -2
- package/template/coding-task-manager/lib/api/agent-bundles.js +436 -0
- package/template/coding-task-manager/lib/api/backup-retention.js +83 -0
- package/template/coding-task-manager/lib/api/conversation-sync-routes.js +124 -0
- package/template/coding-task-manager/lib/api/diagnostics.js +549 -69
- package/template/coding-task-manager/lib/api/fleet.js +118 -0
- package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
- package/template/coding-task-manager/lib/api/ingress.js +9 -1
- package/template/coding-task-manager/lib/api/landing.js +403 -0
- package/template/coding-task-manager/lib/api/machines.js +691 -2
- package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
- package/template/coding-task-manager/lib/api/misc-ops.js +8 -3
- package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
- package/template/coding-task-manager/lib/api/session-attach.js +623 -0
- package/template/coding-task-manager/lib/api/session-messages.js +1384 -0
- package/template/coding-task-manager/lib/api/sessions.js +77 -51
- package/template/coding-task-manager/lib/api/setup-network.js +544 -16
- package/template/coding-task-manager/lib/api/setup-wizard-handlers.js +884 -0
- package/template/coding-task-manager/lib/api/setup.js +829 -10
- package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
- package/template/coding-task-manager/lib/attachment-reconciler-wiring.js +5 -2
- package/template/coding-task-manager/lib/auth-rate-limit.js +23 -0
- package/template/coding-task-manager/lib/auth-rules.js +292 -21
- package/template/coding-task-manager/lib/background-stop.js +369 -0
- package/template/coding-task-manager/lib/best-of-attempts.js +4 -1
- package/template/coding-task-manager/lib/best-of-launch-plan.js +52 -0
- package/template/coding-task-manager/lib/box-keep-awake.js +89 -0
- package/template/coding-task-manager/lib/broadcast-reason-stats.js +152 -0
- package/template/coding-task-manager/lib/broadcast-serialize.js +5 -0
- package/template/coding-task-manager/lib/build-info.js +4 -2
- package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
- package/template/coding-task-manager/lib/claude-transcript-terminal-renderer.js +17 -13
- package/template/coding-task-manager/lib/client-diag-handler.js +64 -2
- package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
- package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
- package/template/coding-task-manager/lib/codex-harness-qualification.js +43 -20
- package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
- package/template/coding-task-manager/lib/coding-agent-models.js +27 -12
- package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
- package/template/coding-task-manager/lib/coding-session-model-adapters.js +43 -2
- package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
- package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
- package/template/coding-task-manager/lib/coding-session-model-runtime.js +23 -4
- package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
- package/template/coding-task-manager/lib/coding-session-model-state.js +7 -0
- package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
- package/template/coding-task-manager/lib/conversation-item-clock.js +261 -0
- package/template/coding-task-manager/lib/conversation-source-registry.js +5 -0
- package/template/coding-task-manager/lib/conversation-store-v2.js +44 -0
- package/template/coding-task-manager/lib/conversation-sync.js +355 -0
- package/template/coding-task-manager/lib/create/resolve-launch-params.js +96 -12
- package/template/coding-task-manager/lib/create/worker-role-profile.js +4 -4
- package/template/coding-task-manager/lib/create-intent-lease.js +51 -0
- package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
- package/template/coding-task-manager/lib/db-domain-tables.js +1 -0
- package/template/coding-task-manager/lib/db-domains.js +1 -0
- package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
- package/template/coding-task-manager/lib/db-owner-request-counts.js +178 -0
- package/template/coding-task-manager/lib/db-owner-worker-client.js +68 -14
- package/template/coding-task-manager/lib/db-schema-source-files.js +5 -0
- package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
- package/template/coding-task-manager/lib/feature-manifest.js +4 -0
- package/template/coding-task-manager/lib/fleet-conversation-route.js +97 -0
- package/template/coding-task-manager/lib/fleet-fanout.js +78 -0
- package/template/coding-task-manager/lib/fleet-hub.js +762 -0
- package/template/coding-task-manager/lib/fleet-origin-follower.js +252 -0
- package/template/coding-task-manager/lib/fleet-resolver-effects.js +147 -0
- package/template/coding-task-manager/lib/fleet-resolver-tick.js +148 -0
- package/template/coding-task-manager/lib/fleet-resolver.js +454 -0
- package/template/coding-task-manager/lib/fleet-session-list-routes.js +114 -0
- package/template/coding-task-manager/lib/fleet-session-lists.js +672 -0
- package/template/coding-task-manager/lib/fleet-update.js +798 -0
- package/template/coding-task-manager/lib/fs-watcher-root-watch.js +141 -0
- package/template/coding-task-manager/lib/fs-watcher.js +58 -42
- package/template/coding-task-manager/lib/harness-history-transition.js +50 -9
- package/template/coding-task-manager/lib/headless-term-service.js +84 -8
- package/template/coding-task-manager/lib/hermetic-agent-launch-guard.js +10 -0
- package/template/coding-task-manager/lib/history-transition-read-op.js +175 -8
- package/template/coding-task-manager/lib/host-cpu-categories.js +310 -0
- package/template/coding-task-manager/lib/host-fseventsd-sampler.js +399 -0
- package/template/coding-task-manager/lib/host-handoff.js +16 -19
- package/template/coding-task-manager/lib/host-stats.js +150 -3
- package/template/coding-task-manager/lib/hosted-sync-worker.js +43 -320
- package/template/coding-task-manager/lib/hub-bridge-access.js +798 -0
- package/template/coding-task-manager/lib/hub-bridge-box.js +409 -0
- package/template/coding-task-manager/lib/hub-bridge-mcp.js +380 -0
- package/template/coding-task-manager/lib/hub-bridge-mesh.js +313 -0
- package/template/coding-task-manager/lib/hub-bridge-ops.js +721 -0
- package/template/coding-task-manager/lib/hub-bridge.js +398 -0
- package/template/coding-task-manager/lib/idle-notify.js +491 -0
- package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +8 -0
- package/template/coding-task-manager/lib/instance-manifest.js +5 -1
- package/template/coding-task-manager/lib/instance-sync-status.js +18 -8
- package/template/coding-task-manager/lib/landing/agent-rule.txt +1 -0
- package/template/coding-task-manager/lib/landing/batch-runner.js +366 -0
- package/template/coding-task-manager/lib/landing/config.js +536 -0
- package/template/coding-task-manager/lib/landing/ctm-view.js +256 -0
- package/template/coding-task-manager/lib/landing/gate.js +360 -0
- package/template/coding-task-manager/lib/landing/git.js +344 -0
- package/template/coding-task-manager/lib/landing/lease.js +247 -0
- package/template/coding-task-manager/lib/landing/merge-delta.js +380 -0
- package/template/coding-task-manager/lib/landing/proof.js +223 -0
- package/template/coding-task-manager/lib/landing/queue.js +998 -0
- package/template/coding-task-manager/lib/landing/radar.js +489 -0
- package/template/coding-task-manager/lib/landing/resolve-cli.js +424 -0
- package/template/coding-task-manager/lib/landing/state.js +263 -0
- package/template/coding-task-manager/lib/landing/stop.js +49 -0
- package/template/coding-task-manager/lib/landing/sync-cli.js +475 -0
- package/template/coding-task-manager/lib/landing/sync.js +456 -0
- package/template/coding-task-manager/lib/landing/train.js +885 -0
- package/template/coding-task-manager/lib/landing/window.js +57 -0
- package/template/coding-task-manager/lib/launch-environment.js +121 -0
- package/template/coding-task-manager/lib/launch-model-override.js +36 -10
- package/template/coding-task-manager/lib/launch-plan-pool.js +2 -1
- package/template/coding-task-manager/lib/launch-plan-warm-cache.js +6 -0
- package/template/coding-task-manager/lib/lead-model-observer.js +57 -1
- package/template/coding-task-manager/lib/lead-model-options.js +160 -3
- package/template/coding-task-manager/lib/lead-model-restore-reconciliation.js +106 -24
- package/template/coding-task-manager/lib/lead-model-switch-runtime.js +352 -68
- package/template/coding-task-manager/lib/lead-model-switch.js +114 -10
- package/template/coding-task-manager/lib/lead-model-transition-runtime.js +14 -2
- package/template/coding-task-manager/lib/lead-model-transition-store.js +24 -6
- package/template/coding-task-manager/lib/lead-route-preflight.js +179 -0
- package/template/coding-task-manager/lib/lead-switch-history-mode.js +110 -0
- package/template/coding-task-manager/lib/lead-wire-agent.js +7 -0
- package/template/coding-task-manager/lib/lifecycle-wake-experiment.js +9 -2
- package/template/coding-task-manager/lib/live-defer-announce.js +45 -0
- package/template/coding-task-manager/lib/machine-registry.js +750 -5
- package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
- package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +433 -53
- package/template/coding-task-manager/lib/mainloop-observability.js +14 -9
- package/template/coding-task-manager/lib/media-draft-owner.js +16 -3
- package/template/coding-task-manager/lib/memory-join.js +337 -0
- package/template/coding-task-manager/lib/memory-sync-verify.js +393 -0
- package/template/coding-task-manager/lib/memory-sync.js +565 -0
- package/template/coding-task-manager/lib/migrations/v57-delegate-pref-mirror-opencode.js +68 -0
- package/template/coding-task-manager/lib/migrations/v58-subagent-launch-native-subagents.js +42 -0
- package/template/coding-task-manager/lib/migrations/v59-coding-session-model-state-dsh.js +73 -0
- package/template/coding-task-manager/lib/migrations/v60-delegate-pref-mirror-dsh.js +78 -0
- package/template/coding-task-manager/lib/migrations/v61-conversation-item-clock.js +71 -0
- package/template/coding-task-manager/lib/model-availability.js +727 -0
- package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +4 -6
- package/template/coding-task-manager/lib/model-host-receipt.js +6 -3
- package/template/coding-task-manager/lib/model-id-rule.js +19 -0
- package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
- package/template/coding-task-manager/lib/model-proxy/auto-mode-review.js +110 -23
- package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
- package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
- package/template/coding-task-manager/lib/model-proxy/historical-tool-declarations.js +37 -0
- package/template/coding-task-manager/lib/model-proxy/lead-request-validation.js +1 -0
- package/template/coding-task-manager/lib/model-proxy/lead-token-admin.js +130 -0
- package/template/coding-task-manager/lib/model-proxy/refusal-scope.js +151 -0
- package/template/coding-task-manager/lib/model-proxy/request-budget-store.js +11 -2
- package/template/coding-task-manager/lib/model-proxy/tokens.js +69 -5
- package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
- package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
- package/template/coding-task-manager/lib/native-history-control.js +6 -4
- package/template/coding-task-manager/lib/native-lead-settings-client.js +44 -4
- package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +173 -36
- package/template/coding-task-manager/lib/online-backup-worker-client.js +2 -0
- package/template/coding-task-manager/lib/opencode-cli.js +480 -0
- package/template/coding-task-manager/lib/opencode-launch-model.js +471 -0
- package/template/coding-task-manager/lib/opencode-v1-plugin/model-carrier.mjs +35 -0
- package/template/coding-task-manager/lib/opencode-v2-plugin/server.js +118 -0
- package/template/coding-task-manager/lib/owner-action-manifest-data.json +1 -1
- package/template/coding-task-manager/lib/park-composer-draft.js +54 -0
- package/template/coding-task-manager/lib/park-fresh-relaunch.js +41 -10
- package/template/coding-task-manager/lib/perf-phase-trace.js +72 -0
- package/template/coding-task-manager/lib/perf-summary.js +7 -0
- package/template/coding-task-manager/lib/perf-tracker.js +63 -2
- package/template/coding-task-manager/lib/project-config.js +7 -0
- package/template/coding-task-manager/lib/prompt-purge-v2.js +52 -1
- package/template/coding-task-manager/lib/provider-login-broker.js +72 -15
- package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
- package/template/coding-task-manager/lib/read-pool-client.js +89 -2
- package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
- package/template/coding-task-manager/lib/recent-catalog-query.js +15 -0
- package/template/coding-task-manager/lib/recent-session-catalog-response.js +67 -10
- package/template/coding-task-manager/lib/recovery-evidence.js +26 -11
- package/template/coding-task-manager/lib/relay-client.js +57 -3
- package/template/coding-task-manager/lib/relink-audit.js +34 -5
- package/template/coding-task-manager/lib/remote-machine-catalog.js +321 -26
- package/template/coding-task-manager/lib/remote-machine-create.js +576 -36
- package/template/coding-task-manager/lib/remote-machine-link.js +546 -59
- package/template/coding-task-manager/lib/remote-machine-proxy.js +143 -9
- package/template/coding-task-manager/lib/remote-session-forward.js +65 -7
- package/template/coding-task-manager/lib/remote-terminal-target.js +9 -2
- package/template/coding-task-manager/lib/restart-guard.js +18 -6
- package/template/coding-task-manager/lib/restore-seed-modes.js +87 -0
- package/template/coding-task-manager/lib/restored-scrollback-hydration-runtime.js +22 -2
- package/template/coding-task-manager/lib/resume-admission.js +17 -3
- package/template/coding-task-manager/lib/review-repo-registry.js +58 -19
- package/template/coding-task-manager/lib/root-delivery-runtime.js +2 -2
- package/template/coding-task-manager/lib/root-prompt-flow.js +1 -1
- package/template/coding-task-manager/lib/runtime-contract.js +3 -1
- package/template/coding-task-manager/lib/schema-indexes.js +1 -0
- package/template/coding-task-manager/lib/session-context-locator.js +742 -0
- package/template/coding-task-manager/lib/session-create/attachment.js +2 -2
- package/template/coding-task-manager/lib/session-create/create-phases.js +118 -0
- package/template/coding-task-manager/lib/session-create/delegate-worker.js +86 -16
- package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
- package/template/coding-task-manager/lib/session-create/lead-route-launch.js +186 -13
- package/template/coding-task-manager/lib/session-create/native-lead-lifetime.js +55 -3
- package/template/coding-task-manager/lib/session-create/opencode-lead-provider.js +50 -0
- package/template/coding-task-manager/lib/session-create/prepared.js +162 -38
- package/template/coding-task-manager/lib/session-create/provider-process.js +160 -28
- package/template/coding-task-manager/lib/session-create/response.js +7 -7
- package/template/coding-task-manager/lib/session-create/structured-session.js +27 -0
- package/template/coding-task-manager/lib/session-create/subagent-pick-table.js +3 -1
- package/template/coding-task-manager/lib/session-create/subagent-pick.js +458 -9
- package/template/coding-task-manager/lib/session-create/transcript.js +1 -1
- package/template/coding-task-manager/lib/session-create/worker-budget-setup.js +21 -2
- package/template/coding-task-manager/lib/session-create/worker-continuation.js +7 -1
- package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
- package/template/coding-task-manager/lib/session-create/worker-observability.js +2 -2
- package/template/coding-task-manager/lib/session-empty.js +13 -10
- package/template/coding-task-manager/lib/session-host-manager.js +60 -0
- package/template/coding-task-manager/lib/session-jobs.js +3 -1
- package/template/coding-task-manager/lib/session-lifecycle.js +10 -4
- package/template/coding-task-manager/lib/session-model-action-preconditions.js +6 -2
- package/template/coding-task-manager/lib/session-model-intent-contract.js +11 -8
- package/template/coding-task-manager/lib/session-park.js +738 -0
- package/template/coding-task-manager/lib/session-path-grant.js +13 -4
- package/template/coding-task-manager/lib/session-status-ledger.js +106 -4
- package/template/coding-task-manager/lib/session-transport.js +17 -0
- package/template/coding-task-manager/lib/session-workspace-projection.js +54 -5
- package/template/coding-task-manager/lib/session-workspace-tracking-runtime.js +213 -1
- package/template/coding-task-manager/lib/skill-autocomplete-query.js +120 -3
- package/template/coding-task-manager/lib/skill-autocomplete.js +15 -1
- package/template/coding-task-manager/lib/sqlite-file-set.js +39 -0
- package/template/coding-task-manager/lib/standup-search-adapter.js +16 -2
- package/template/coding-task-manager/lib/state-sync/client-ledger.js +12 -0
- package/template/coding-task-manager/lib/state-sync/frame-emitter.js +319 -100
- package/template/coding-task-manager/lib/storage/coding-session-model-store.js +4 -1
- package/template/coding-task-manager/lib/storage/delegate-pref-mirror-store.js +32 -9
- package/template/coding-task-manager/lib/structured-session-boot-sweep.js +235 -0
- package/template/coding-task-manager/lib/submission-ack.js +90 -2
- package/template/coding-task-manager/lib/systemd-scope.js +115 -0
- package/template/coding-task-manager/lib/telemetry-receiver.js +39 -0
- package/template/coding-task-manager/lib/terminal-attach-geometry.js +985 -0
- package/template/coding-task-manager/lib/terminal-bootstrap.js +30 -0
- package/template/coding-task-manager/lib/terminal-draft-operation.js +357 -0
- package/template/coding-task-manager/lib/terminal-input-admission.js +17 -1
- package/template/coding-task-manager/lib/terminal-input-prepared.js +563 -0
- package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
- package/template/coding-task-manager/lib/transcript-frame-cache.js +8 -3
- package/template/coding-task-manager/lib/transcript-source.js +36 -4
- package/template/coding-task-manager/lib/transcript-store.js +9 -0
- package/template/coding-task-manager/lib/typing-interaction-trace.js +106 -3
- package/template/coding-task-manager/lib/usage-ledger/backfill.js +40 -5
- package/template/coding-task-manager/lib/usage-ledger/client.js +4 -1
- package/template/coding-task-manager/lib/usage-ledger/dsh-parse.js +152 -0
- package/template/coding-task-manager/lib/usage-ledger/dsh-read.js +73 -0
- package/template/coding-task-manager/lib/usage-ledger/ingest.js +34 -6
- package/template/coding-task-manager/lib/usage-ledger/live.js +35 -8
- package/template/coding-task-manager/lib/usage-ledger/read.js +29 -20
- package/template/coding-task-manager/lib/usage-ledger/schema.js +61 -1
- package/template/coding-task-manager/lib/usage-ledger/task-coordinator.js +4 -2
- package/template/coding-task-manager/lib/wake-skip-reasons.js +1 -0
- package/template/coding-task-manager/lib/walle/turn.js +1 -1
- package/template/coding-task-manager/lib/walle-history-serve.js +838 -0
- package/template/coding-task-manager/lib/walle-kill-authority.js +2 -2
- package/template/coding-task-manager/lib/walle-log-rotation.js +164 -1
- package/template/coding-task-manager/lib/walle-mcp-auto-config.js +56 -2
- package/template/coding-task-manager/lib/walle-row-history.js +495 -0
- package/template/coding-task-manager/lib/walle-supervisor.js +33 -14
- package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
- package/template/coding-task-manager/lib/worker-terminal-output.js +5 -2
- package/template/coding-task-manager/lib/ws/hub-bridge.js +35 -0
- package/template/coding-task-manager/lib/ws/lifecycle.js +6 -11
- package/template/coding-task-manager/lib/ws/misc.js +1 -1
- package/template/coding-task-manager/lib/ws/state-sync.js +106 -4
- package/template/coding-task-manager/lib/ws/terminal-attach.js +91 -0
- package/template/coding-task-manager/oauth-proxy.js +112 -115
- package/template/coding-task-manager/package-lock.json +10 -94
- package/template/coding-task-manager/package.json +4 -3
- package/template/coding-task-manager/protocol/message-table.json +10 -0
- package/template/coding-task-manager/protocol/messages.js +10 -0
- package/template/coding-task-manager/protocol/ws-schema.json +20 -0
- package/template/coding-task-manager/protocol/ws-schema.md +2 -0
- package/template/coding-task-manager/public/css/app.css +170 -0
- package/template/coding-task-manager/public/css/walle-session.css +4 -0
- package/template/coding-task-manager/public/index.html +473 -243
- package/template/coding-task-manager/public/js/agent-command.js +86 -0
- package/template/coding-task-manager/public/js/app/backups-panel.js +111 -5
- package/template/coding-task-manager/public/js/app/coding-agent-upgrade.js +103 -4
- package/template/coding-task-manager/public/js/app/machines-page.js +1328 -8
- package/template/coding-task-manager/public/js/app/models-tab.js +113 -38
- package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
- package/template/coding-task-manager/public/js/app/worktrees-panel.js +184 -2
- package/template/coding-task-manager/public/js/background-work.js +196 -27
- package/template/coding-task-manager/public/js/coding-session-model-presentation.js +138 -10
- package/template/coding-task-manager/public/js/core/active-session-groups.js +179 -0
- package/template/coding-task-manager/public/js/core/pending-create.js +238 -0
- package/template/coding-task-manager/public/js/core/recent-machine-source.js +228 -0
- package/template/coding-task-manager/public/js/core/session-commands.js +180 -14
- package/template/coding-task-manager/public/js/dashboard-client-function-order.json +8 -0
- package/template/coding-task-manager/public/js/document-review-links.js +9 -1
- package/template/coding-task-manager/public/js/file-resolution-client.js +52 -1
- package/template/coding-task-manager/public/js/history-app-seam.js +22 -2
- package/template/coding-task-manager/public/js/machine-pool-shared.js +558 -3
- package/template/coding-task-manager/public/js/message-renderer.js +4 -3
- package/template/coding-task-manager/public/js/model-picker.js +3 -1
- package/template/coding-task-manager/public/js/native-subagent-review.js +15 -2
- package/template/coding-task-manager/public/js/new-session-agent-grid.js +346 -0
- package/template/coding-task-manager/public/js/pasted-content.js +236 -0
- package/template/coding-task-manager/public/js/pe-private-content-lifetime.js +39 -7
- package/template/coding-task-manager/public/js/private-model-lifetime.js +6 -2
- package/template/coding-task-manager/public/js/prompts.js +11 -10
- package/template/coding-task-manager/public/js/protocol.js +10 -0
- package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -1
- package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
- package/template/coding-task-manager/public/js/session-search-utils.js +18 -2
- package/template/coding-task-manager/public/js/session-usage-view.js +2 -1
- package/template/coding-task-manager/public/js/session-workspace-tracking.js +51 -1
- package/template/coding-task-manager/public/js/state-sync-client.js +10 -1
- package/template/coding-task-manager/public/js/stream-view.js +6 -5
- package/template/coding-task-manager/public/js/terminal/conv-only-session.js +287 -0
- package/template/coding-task-manager/public/js/terminal/runtime-09.js +2 -0
- package/template/coding-task-manager/public/js/terminal/runtime-10.js +5 -5
- package/template/coding-task-manager/public/js/terminal/runtime-12.js +8 -1
- package/template/coding-task-manager/public/js/terminal/runtime-16.js +4 -0
- package/template/coding-task-manager/public/js/terminal/runtime-20.js +1 -1
- package/template/coding-task-manager/public/js/terminal-attachment-draft.js +67 -13
- package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
- package/template/coding-task-manager/public/js/terminal-wheel.js +23 -3
- package/template/coding-task-manager/public/js/walle/chat-conversation.js +4 -4
- package/template/coding-task-manager/public/js/walle.js +6 -0
- package/template/coding-task-manager/public/js/ws/live-dispatch.js +10 -0
- package/template/coding-task-manager/public/m/app.css +140 -0
- package/template/coding-task-manager/public/m/app.js +507 -68
- package/template/coding-task-manager/public/m/index.html +17 -0
- package/template/coding-task-manager/public/m/machines.js +838 -4
- package/template/coding-task-manager/public/m/private-api.js +31 -1
- package/template/coding-task-manager/public/usage.html +1 -0
- package/template/coding-task-manager/scripts/dev-route-fixture/synthetic-route-upstream.js +104 -0
- package/template/coding-task-manager/scripts/dev-route-fixture.js +339 -0
- package/template/coding-task-manager/scripts/opencode-lead-route-probe.js +195 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe/fake-anthropic.js +168 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe/probe-plugin/server.js +95 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe.js +673 -0
- package/template/coding-task-manager/server.js +1950 -11679
- package/template/coding-task-manager/session-integrity.js +64 -4
- package/template/coding-task-manager/workers/db-owner-worker.js +19 -2
- package/template/coding-task-manager/workers/online-backup-worker.js +1 -0
- package/template/coding-task-manager/workers/read-pool-model-collector.js +51 -3
- package/template/coding-task-manager/workers/read-pool-worker.js +76 -6
- package/template/coding-task-manager/workers/session-host-pool-process.js +6 -6
- package/template/coding-task-manager/workers/session-host-process.js +5 -5
- package/template/coding-task-manager/workers/watch-worker.js +105 -0
- package/template/coding-task-manager/workers/worktree-worker.js +168 -33
- package/template/ctm-relay/lib/protocol.js +14 -1
- package/template/package-lock.json +2 -2
- package/template/package.json +1 -1
- package/template/shared/backup-retention.js +82 -0
- package/template/shared/conversation-admission.js +2 -0
- package/template/shared/conversation-provenance.js +3 -7
- package/template/shared/conversation-storage-v2-contract.js +5 -0
- package/template/shared/linked-worktree.js +51 -0
- package/template/shared/macos-fda-target.js +57 -0
- package/template/shared/orphan-parents.js +55 -0
- package/template/shared/release-schema.json +2 -2
- package/template/shared/storage/contract.js +3 -0
- package/template/wall-e/adapters/imessage.js +12 -0
- package/template/wall-e/agent.js +71 -4
- package/template/wall-e/api-walle.js +21 -1
- package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
- package/template/wall-e/bin/walle-mcp-stdio.js +5 -5
- package/template/wall-e/brain/brain-join.js +859 -0
- package/template/wall-e/brain/brain-sync-membership.js +20 -0
- package/template/wall-e/brain/brain-sync-store.js +131 -77
- package/template/wall-e/brain/brain-sync-v2-schema.js +203 -0
- package/template/wall-e/brain/brain-sync-v2.js +578 -0
- package/template/wall-e/brain/delegate-model-prefs-store.js +13 -4
- package/template/wall-e/brain/deterministic-id.js +51 -0
- package/template/wall-e/brain/memories.js +2 -2
- package/template/wall-e/brain/migrations.js +40 -6
- package/template/wall-e/brain/model-identity-migration.js +1 -1
- package/template/wall-e/brain/owner-call-whitelist.js +23 -7
- package/template/wall-e/brain/schema.js +45 -85
- package/template/wall-e/brain.js +171 -35
- package/template/wall-e/chat.js +3 -3
- package/template/wall-e/coding/agent-shell-env.js +7 -2
- package/template/wall-e/coding/prompt-bundle.js +66 -21
- package/template/wall-e/config/main-loop-exemptions.json +2 -2
- package/template/wall-e/http/admin-api.js +37 -0
- package/template/wall-e/http/gws-api.js +4 -0
- package/template/wall-e/http/helper-rules-api.js +7 -1
- package/template/wall-e/http/model-admin.js +8 -1
- package/template/wall-e/http/model-delegate-pref-admin.js +3 -3
- package/template/wall-e/http/model-proxy-providers.js +174 -1
- package/template/wall-e/http/model-route-health.js +157 -0
- package/template/wall-e/http/sync-api.js +278 -464
- package/template/wall-e/jobs/job-runner.js +28 -1
- package/template/wall-e/lib/brain-owner-op-priority.js +9 -1
- package/template/wall-e/lib/ctm-data-dir.js +26 -0
- package/template/wall-e/lib/derivation-home.js +147 -0
- package/template/wall-e/lib/helper-rules/evaluate.js +50 -9
- package/template/wall-e/lib/helper-rules/grade.js +51 -8
- package/template/wall-e/lib/helper-rules/lead-call-hook.js +38 -5
- package/template/wall-e/lib/helper-rules/store.js +4 -2
- package/template/wall-e/lib/landing-mcp-tools.js +170 -0
- package/template/wall-e/lib/mcp-client-config.js +133 -14
- package/template/wall-e/lib/mcp-gateway-migrate.js +28 -64
- package/template/wall-e/lib/mcp-integration.js +58 -13
- package/template/wall-e/lib/parent-death.js +7 -1
- package/template/wall-e/lib/scheduler-worker-jobs.js +6 -4
- package/template/wall-e/llm/delegate-lead-prefs.js +16 -1
- package/template/wall-e/llm/delegate-vendor-default.js +12 -5
- package/template/wall-e/llm/model-roles.js +1 -1
- package/template/wall-e/llm/native-delegate-selection.js +56 -8
- package/template/wall-e/llm/worker-delegate-args.js +72 -7
- package/template/wall-e/llm/worker-mcp-routing.js +66 -17
- package/template/wall-e/loops/brain-custom-writes.js +19 -0
- package/template/wall-e/loops/ingest.js +17 -1
- package/template/wall-e/loops/think.js +19 -4
- package/template/wall-e/mcp-contract.js +222 -6
- package/template/wall-e/mcp-protocol-contract.js +40 -5
- package/template/wall-e/mcp-server.js +128 -29
- package/template/wall-e/mcp-worker-schemas.js +5 -5
- package/template/wall-e/memory/ctm-context-client.js +85 -0
- package/template/wall-e/memory/ctm-session-context.js +9 -3
- package/template/wall-e/memory/hub-bridge-client.js +388 -0
- package/template/wall-e/memory/replica-origin.js +56 -0
- package/template/wall-e/memory/session-pool.js +135 -0
- package/template/wall-e/runtime/live-capabilities.js +8 -3
- package/template/wall-e/server.js +4 -2
- package/template/wall-e/shared/release-schema.json +2 -2
- package/template/wall-e/shared/sqlite-file-set.js +39 -0
- package/template/wall-e/shared/storage/contract.js +3 -0
- package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
- package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +7 -1
- package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +4 -4
- package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +6 -6
- package/template/wall-e/skills/_templates/fleet-sync/VERSION +1 -0
- package/template/wall-e/skills/_templates/fleet-sync/released-sha256.json +16 -0
- package/template/wall-e/skills/_templates/fleet-sync/templates/claude/SKILL.md +64 -0
- package/template/wall-e/skills/_templates/fleet-sync/templates/codex/SKILL.md +64 -0
- package/template/wall-e/tools/chrome-automation.js +6 -0
- package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
- package/template/wall-e/workers/brain-owner-worker.js +18 -4
- package/template/wall-e/workers/mcp-gateway-process.js +5 -5
|
@@ -27,6 +27,8 @@ const {
|
|
|
27
27
|
ClientConfigError,
|
|
28
28
|
OPERATIONS,
|
|
29
29
|
applySourceEdits,
|
|
30
|
+
asClient,
|
|
31
|
+
attributionOptions,
|
|
30
32
|
buildOwnershipManifest,
|
|
31
33
|
emptyJsonDocumentText,
|
|
32
34
|
creationBoundaryEvidence,
|
|
@@ -59,6 +61,38 @@ const MCP_TARGETS = Object.freeze([
|
|
|
59
61
|
{ id: 'claude-desktop', tool: 'Claude Desktop', configPath: 'Library/Application Support/Claude/claude_desktop_config.json', detectPath: 'Library/Application Support/Claude', kind: 'json' },
|
|
60
62
|
]);
|
|
61
63
|
|
|
64
|
+
// D-3: every ensure TARGET is worth NAMING when it refuses, so each MCP_TARGETS
|
|
65
|
+
// id maps onto exactly one token of the leaf's fixed client vocabulary
|
|
66
|
+
// (mcp-client-config.js CLIENT_CONFIG_CLIENTS); `asClient` carries that token
|
|
67
|
+
// onto whatever owned refusal the target's capture/parse/plan raises. The
|
|
68
|
+
// mapping is TOTAL over MCP_TARGETS on purpose — a new target id with no token
|
|
69
|
+
// here fails the coverage test in
|
|
70
|
+
// tests/client-config-error-attribution.test.js instead of inventing one, and
|
|
71
|
+
// `_targetClient` refuses at runtime rather than returning an unmapped value.
|
|
72
|
+
const MCP_TARGET_CLIENTS = Object.freeze({
|
|
73
|
+
'claude-code-user': 'claude-code',
|
|
74
|
+
'claude-code-project': 'claude-code',
|
|
75
|
+
codex: 'codex',
|
|
76
|
+
cursor: 'cursor',
|
|
77
|
+
windsurf: 'windsurf',
|
|
78
|
+
'claude-desktop': 'claude-desktop',
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
function _targetClient(target) {
|
|
82
|
+
const token = target ? MCP_TARGET_CLIENTS[target.id] : undefined;
|
|
83
|
+
// No token is a programming error, never a silently anonymous refusal.
|
|
84
|
+
if (!token) throw new TypeError('mcp-integration: unmapped MCP target id');
|
|
85
|
+
return token;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// D-3: the ensure boot lines (wall-e/server.js, CTM walle-mcp-auto-config.js)
|
|
89
|
+
// print the message plus the bounded attribution an owned refusal carries.
|
|
90
|
+
function ensureFailureMessage(err) {
|
|
91
|
+
const { client, refusal } = err && typeof err === 'object' ? attributionOptions(err) : {};
|
|
92
|
+
const parts = [client && `client=${client}`, refusal && `refusal=${refusal}`].filter(Boolean);
|
|
93
|
+
return `${err && err.message}${parts.length ? ` (${parts.join(', ')})` : ''}`;
|
|
94
|
+
}
|
|
95
|
+
|
|
62
96
|
const AGENT_INSTRUCTION_TARGETS = Object.freeze([
|
|
63
97
|
{
|
|
64
98
|
id: 'claude-code-instructions',
|
|
@@ -1588,10 +1622,10 @@ async function ensureMcpIntegrations(wallePort, opts = {}) {
|
|
|
1588
1622
|
let primary = null;
|
|
1589
1623
|
let failurePresent = false;
|
|
1590
1624
|
|
|
1591
|
-
const jobFor = (physicalPath, logicalPath, source) => {
|
|
1625
|
+
const jobFor = (physicalPath, logicalPath, source, client) => {
|
|
1592
1626
|
let job = jobsByPhysical.get(physicalPath);
|
|
1593
1627
|
if (!job) {
|
|
1594
|
-
job = { physicalPath, logicalPath, source, members: [], plugin: null, pluginPlan: null, emitted: null, action: null };
|
|
1628
|
+
job = { physicalPath, logicalPath, source, client, members: [], plugin: null, pluginPlan: null, emitted: null, action: null };
|
|
1595
1629
|
jobsByPhysical.set(physicalPath, job);
|
|
1596
1630
|
jobs.push(job);
|
|
1597
1631
|
sources.push(source);
|
|
@@ -1606,10 +1640,13 @@ async function ensureMcpIntegrations(wallePort, opts = {}) {
|
|
|
1606
1640
|
order.push({ kind: 'row', row: { kind: 'mcp_config', tool: target.tool, action: 'not_installed' } });
|
|
1607
1641
|
continue;
|
|
1608
1642
|
}
|
|
1643
|
+
// D-3: this target's client token, so its capture/parse/plan refusal
|
|
1644
|
+
// names the client instead of the anonymous boot line.
|
|
1645
|
+
const client = _targetClient(target);
|
|
1609
1646
|
if (target.kind === 'codex-toml') {
|
|
1610
|
-
const plan = _planCodexTarget({
|
|
1647
|
+
const plan = asClient(client, () => _planCodexTarget({
|
|
1611
1648
|
target, logicalPath: paths.configPath, wallePort, opts: scopedOpts, context, allowMissing: true, sources,
|
|
1612
|
-
});
|
|
1649
|
+
}));
|
|
1613
1650
|
if (plan.source) { jobs.push(Object.assign({ kind: 'toml', logicalPath: paths.configPath }, plan)); sources.push(plan.source); }
|
|
1614
1651
|
order.push({ kind: 'single', plan });
|
|
1615
1652
|
continue;
|
|
@@ -1618,12 +1655,12 @@ async function ensureMcpIntegrations(wallePort, opts = {}) {
|
|
|
1618
1655
|
// logical aliases of one file share ONE captured original: no second
|
|
1619
1656
|
// unregistered capture, and never two plans derived from two originals.
|
|
1620
1657
|
// `assertNotReserved` is also the reserved pre-FD admission.
|
|
1621
|
-
const groupingKey = assertNotReserved(paths.configPath, context);
|
|
1622
|
-
const member = { target, logicalPath: paths.configPath, tombstoned: _isTombstoned(target, scopedOpts) };
|
|
1658
|
+
const groupingKey = asClient(client, () => assertNotReserved(paths.configPath, context));
|
|
1659
|
+
const member = { target, client, logicalPath: paths.configPath, tombstoned: _isTombstoned(target, scopedOpts) };
|
|
1623
1660
|
let job = jobsByPhysical.get(groupingKey);
|
|
1624
1661
|
if (!job) {
|
|
1625
|
-
const source = captureClientConfigFile(paths.configPath, { mutexContext: context, allowMissing: true });
|
|
1626
|
-
job = jobFor(source.targetPath, paths.configPath, source);
|
|
1662
|
+
const source = asClient(client, () => captureClientConfigFile(paths.configPath, { mutexContext: context, allowMissing: true }));
|
|
1663
|
+
job = jobFor(source.targetPath, paths.configPath, source, client);
|
|
1627
1664
|
}
|
|
1628
1665
|
job.members.push(member);
|
|
1629
1666
|
order.push({ kind: 'json', job, target, logicalPath: paths.configPath });
|
|
@@ -1635,12 +1672,15 @@ async function ensureMcpIntegrations(wallePort, opts = {}) {
|
|
|
1635
1672
|
const routing = _planSessionPluginRouting(scopedOpts);
|
|
1636
1673
|
if (routing && routing.qualifiedNames.length) {
|
|
1637
1674
|
const claudeJsonPath = path.join(homeDir, '.claude.json');
|
|
1675
|
+
// …and it IS the Claude Code user config, so its refusals name that
|
|
1676
|
+
// client too.
|
|
1677
|
+
const pluginClient = MCP_TARGET_CLIENTS['claude-code-user'];
|
|
1638
1678
|
let physical = claudeJsonPath;
|
|
1639
1679
|
try { physical = fs.realpathSync(claudeJsonPath); } catch { physical = claudeJsonPath; }
|
|
1640
1680
|
let job = jobsByPhysical.get(physical);
|
|
1641
1681
|
if (!job) {
|
|
1642
|
-
const source = captureClientConfigFile(claudeJsonPath, { mutexContext: context, allowMissing: true });
|
|
1643
|
-
job = jobFor(source.targetPath, claudeJsonPath, source);
|
|
1682
|
+
const source = asClient(pluginClient, () => captureClientConfigFile(claudeJsonPath, { mutexContext: context, allowMissing: true }));
|
|
1683
|
+
job = jobFor(source.targetPath, claudeJsonPath, source, pluginClient);
|
|
1644
1684
|
}
|
|
1645
1685
|
job.plugin = routing;
|
|
1646
1686
|
order.push({ kind: 'plugin', job, tool: 'Claude Code Plugin Routing', configPath: claudeJsonPath });
|
|
@@ -1654,7 +1694,10 @@ async function ensureMcpIntegrations(wallePort, opts = {}) {
|
|
|
1654
1694
|
// _planCodexTarget and has no session-plugin stage to compose.
|
|
1655
1695
|
if (!job.source || job.kind === 'toml') continue;
|
|
1656
1696
|
let current = job.source.text === null ? emptyJsonDocumentText() : job.source.text;
|
|
1657
|
-
|
|
1697
|
+
// D-3: the job's JSON parse and each member's plan are attributed to the
|
|
1698
|
+
// client whose file this is (aliases of one physical document share the
|
|
1699
|
+
// token, and its members must agree).
|
|
1700
|
+
let doc = asClient(job.client, () => parseClientConfig(current, { format: 'json' }));
|
|
1658
1701
|
// GEN8-F: same-physical aliases must AGREE. Each member's own opt-out is
|
|
1659
1702
|
// evaluated separately (a tombstone for one client is never reported for
|
|
1660
1703
|
// another), and a disagreement — one alias tombstoned while another wants
|
|
@@ -1687,13 +1730,13 @@ async function ensureMcpIntegrations(wallePort, opts = {}) {
|
|
|
1687
1730
|
);
|
|
1688
1731
|
const perMember = job.members.map((member) => ({
|
|
1689
1732
|
member,
|
|
1690
|
-
plan: _planOwnJsonEntryEdits(doc, current, {
|
|
1733
|
+
plan: asClient(member.client, () => _planOwnJsonEntryEdits(doc, current, {
|
|
1691
1734
|
expected,
|
|
1692
1735
|
authority,
|
|
1693
1736
|
ownHttpUrl,
|
|
1694
1737
|
tombstoned: member.tombstoned === true,
|
|
1695
1738
|
allowCommandTransition,
|
|
1696
|
-
}),
|
|
1739
|
+
})),
|
|
1697
1740
|
}));
|
|
1698
1741
|
// GEN9: aliases of one physical document must agree on the FULL desired
|
|
1699
1742
|
// output (action AND the exact edits), not merely on the action name.
|
|
@@ -2000,6 +2043,8 @@ module.exports = {
|
|
|
2000
2043
|
AGENT_INSTRUCTIONS_BEGIN,
|
|
2001
2044
|
AGENT_INSTRUCTIONS_END,
|
|
2002
2045
|
MCP_TARGETS,
|
|
2046
|
+
MCP_TARGET_CLIENTS,
|
|
2047
|
+
ensureFailureMessage,
|
|
2003
2048
|
WALLE_SERVER_NAME,
|
|
2004
2049
|
detectAgentMemoryInstructions,
|
|
2005
2050
|
detectMcpIntegrations,
|
|
@@ -156,10 +156,16 @@ function installParentDeathWatch(options = {}) {
|
|
|
156
156
|
try { logger?.error?.(`[parent-death:${label}] failed to register disconnect listener`, err); } catch { /* expected: logger itself is best-effort here; nothing downstream depends on this line succeeding */ }
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
// Reparenting is "ppid changed since install", not "ppid is 1": a macOS orphan goes to
|
|
160
|
+
// launchd (pid 1), but a Linux orphan goes to the nearest subreaper (`systemd --user`), so
|
|
161
|
+
// `=== 1` alone never fired there (design nightly-linux-host-portability-2026-10-27, WP-4b).
|
|
162
|
+
// A process launched with ppid 1 (under launchd) keeps it, so it is never "changed".
|
|
163
|
+
let initialPpid = null;
|
|
164
|
+
try { initialPpid = getPpid(); } catch { /* expected: unknown at install -- only === 1 can fire */ }
|
|
159
165
|
interval = setIntervalImpl(() => {
|
|
160
166
|
let ppid;
|
|
161
167
|
try { ppid = getPpid(); } catch { return; }
|
|
162
|
-
if (ppid === 1) shutdown('ppid-reparented');
|
|
168
|
+
if (ppid === 1 || (initialPpid !== null && ppid !== initialPpid)) shutdown('ppid-reparented');
|
|
163
169
|
}, pollMs);
|
|
164
170
|
interval.unref?.();
|
|
165
171
|
|
|
@@ -151,8 +151,10 @@ async function runSchedulerJob(jobName, payload = {}) {
|
|
|
151
151
|
));
|
|
152
152
|
break;
|
|
153
153
|
case 'memory-consolidation':
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
// shared-memory D-5: derived from replicated rows — the derivation home only. This worker path
|
|
155
|
+
// is what production runs (agent.js's run wrapper is bypassed when the job is worker-routed).
|
|
156
|
+
result = await _measurePhase(phases, 'memoryConsolidation.run', () => require('./derivation-home').runIfHome(
|
|
157
|
+
'memory-consolidation', () => require('../memory/consolidation').runMemoryConsolidation({ brain }),
|
|
156
158
|
));
|
|
157
159
|
break;
|
|
158
160
|
case 'think':
|
|
@@ -183,12 +185,12 @@ async function runSchedulerJob(jobName, payload = {}) {
|
|
|
183
185
|
const generateFn = reflectFallbackOnly
|
|
184
186
|
? null
|
|
185
187
|
: createDailySummaryGenerateFn({ model: modelOverride?.model || undefined });
|
|
186
|
-
result = await _measurePhase(phases, 'reflect.runOnce', () => require('../loops/reflect').runOnce({
|
|
188
|
+
result = await _measurePhase(phases, 'reflect.runOnce', () => require('./derivation-home').runIfHome('reflect', () => require('../loops/reflect').runOnce({
|
|
187
189
|
generateFn,
|
|
188
190
|
allowProviderFallback: true,
|
|
189
191
|
fallbackReason: reflectFallbackOnly ? 'provider_backpressure' : '',
|
|
190
192
|
forceSummary: payload.forceSummary === true,
|
|
191
|
-
}));
|
|
193
|
+
}))); // shared-memory D-5: derivation home only (see memory-consolidation above)
|
|
192
194
|
break;
|
|
193
195
|
}
|
|
194
196
|
case 'backfill':
|
|
@@ -35,10 +35,19 @@ function parentLookupUnavailable() {
|
|
|
35
35
|
})), { code: LOOKUP_UNAVAILABLE_CODE });
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
// §9 S-16 (opencode-lead-and-delegate-model-selection-2026-10-28.html §8 WP-5): the ladder is keyed
|
|
39
|
+
// by the LEAD's OWN agent -- the agent of the session row the parent lookup resolved -- never by the
|
|
40
|
+
// worker harness the caller happens to ask for. The store is the ONE owner of the agent list, so a
|
|
41
|
+
// lead agent joins this derivation by joining store.AGENTS (dsh did, WP-10/P-6).
|
|
42
|
+
const STORE_AGENTS = new Set(store.AGENTS);
|
|
43
|
+
|
|
38
44
|
// `needSession: false` (the call named its own route/model) skips the CTM lookup: only the agent
|
|
39
45
|
// default is still read, for the route tie-break.
|
|
40
46
|
async function readLeadDelegatePrefs({ db, agent, parentAgentSessionId, lookupParent, timeoutMs, needSession = true } = {}) {
|
|
41
|
-
|
|
47
|
+
// The historical derivation from the caller's worker harness: a Codex worker means a Codex lead
|
|
48
|
+
// asked, anything else a Claude one. It STAYS the fallback -- it is the only signal available when
|
|
49
|
+
// the parent lookup did not answer (no lookup, an unreachable CTM, or an unresolved lead).
|
|
50
|
+
let leadAgent = agent === 'codex' ? 'codex' : 'claude';
|
|
42
51
|
const raw = String(parentAgentSessionId || '').trim();
|
|
43
52
|
let ctmSessionId = '';
|
|
44
53
|
let parentResolution = 'unresolved';
|
|
@@ -68,6 +77,12 @@ async function readLeadDelegatePrefs({ db, agent, parentAgentSessionId, lookupPa
|
|
|
68
77
|
// (an older CTM, or a lead that is not live) stays unknown rather than being inferred, and a
|
|
69
78
|
// lookup that resolved NO session has no running lead to describe -- unknown either way.
|
|
70
79
|
nativeSubagentLaunch = ctmSessionId ? nativeLaunchConstraints(found && found.native_subagent_launch) : UNKNOWN_NATIVE_LAUNCH;
|
|
80
|
+
// S-16: the resolved LIVE lead's own harness is the ladder's agent whenever it is one the store
|
|
81
|
+
// keys on -- an OpenCode lead reads default:opencode and a DeepSeek Harness lead default:dsh,
|
|
82
|
+
// exactly as they wrote them. A value this module cannot classify (an older CTM, or a lead
|
|
83
|
+
// whose agent is not projected) leaves the derivation above in place rather than inventing an
|
|
84
|
+
// agent -- which is why CTM must PROJECT `dsh` in native_subagent_launch.agent (D-24).
|
|
85
|
+
if (nativeSubagentLaunch && STORE_AGENTS.has(nativeSubagentLaunch.agent)) leadAgent = nativeSubagentLaunch.agent;
|
|
71
86
|
}
|
|
72
87
|
}
|
|
73
88
|
// The session row is read exactly ONCE, and the raw-id fallback above shares this one read: the
|
|
@@ -5,16 +5,23 @@
|
|
|
5
5
|
// a route or model outranks all three and is handled by resolveDelegateArgs itself.
|
|
6
6
|
//
|
|
7
7
|
// VENDOR_DEFAULT is the bottom rung: what a plain delegate uses when nothing is stored.
|
|
8
|
-
//
|
|
9
|
-
// ask Wall-E (walle_delegate_implementation answers lane:'native') instead of
|
|
10
|
-
// their own copy.
|
|
8
|
+
// The claude/codex model literals live HERE and nowhere else in server code; the skill
|
|
9
|
+
// templates ask Wall-E (walle_delegate_implementation answers lane:'native') instead of
|
|
10
|
+
// carrying their own copy. OpenCode carries no literal at all -- its rung is `inherit`.
|
|
11
11
|
const VENDOR_DEFAULT = Object.freeze({
|
|
12
12
|
claude: Object.freeze({ lane: 'native', model: 'sonnet' }),
|
|
13
13
|
codex: Object.freeze({ lane: 'native', model: 'gpt-5.6-terra' }),
|
|
14
|
+
// OpenCode's own built-in subagents (`general`, `explore`) run on the model of the primary agent
|
|
15
|
+
// that invoked them unless their own config names one (https://opencode.ai/docs/agents/), so the
|
|
16
|
+
// bottom rung is INHERIT -- CTM names no model literal here. opencode-lead-and-delegate-model-
|
|
17
|
+
// selection-2026-10-28.html §6.5: the projection turns an inherit rung into no `model` key at all.
|
|
18
|
+
opencode: Object.freeze({ lane: 'inherit', model: '' }),
|
|
14
19
|
});
|
|
15
20
|
|
|
21
|
+
// An unknown/absent agent keeps the historical claude fallback: every existing caller (a bare
|
|
22
|
+
// delegate, a Codex lead with no stored row) must fold exactly as it did before opencode existed.
|
|
16
23
|
function vendorDefaultFor(agent) {
|
|
17
|
-
return VENDOR_DEFAULT[agent
|
|
24
|
+
return VENDOR_DEFAULT[agent] || VENDOR_DEFAULT.claude;
|
|
18
25
|
}
|
|
19
26
|
|
|
20
27
|
function rungValue(pref) {
|
|
@@ -26,7 +33,7 @@ function rungValue(pref) {
|
|
|
26
33
|
|
|
27
34
|
/**
|
|
28
35
|
* @param {{session?:object|null, default?:object|null}} prefs stored rows (null/absent = unset)
|
|
29
|
-
* @param {'claude'|'codex'} agent
|
|
36
|
+
* @param {'claude'|'codex'|'opencode'} agent
|
|
30
37
|
* @returns {{effective:{lane,model,route_id,identity_id,display,effort,source}, ladder:Array<{rung,value}>}}
|
|
31
38
|
*/
|
|
32
39
|
function foldDelegateLadder(prefs, agent) {
|
|
@@ -289,6 +289,6 @@ async function recordRoleUsage({ task, response, model, providerId = null, provi
|
|
|
289
289
|
});
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
module.exports = { ROLES, TASK_ROLE, roleForTask, resolveRoleModel, completeForRole, recordRoleUsage };
|
|
292
|
+
module.exports = { ROLES, TASK_ROLE, MAX_COMPLETION_TOKENS, roleForTask, resolveRoleModel, completeForRole, recordRoleUsage };
|
|
293
293
|
// Test seam (non-enumerable, so the public surface stays the seven names above).
|
|
294
294
|
Object.defineProperty(module.exports, '_detectFallbackFrom', { value: _detectFallbackFrom, enumerable: false });
|
|
@@ -37,6 +37,10 @@
|
|
|
37
37
|
// `kind:'routed'` model is the launch-time CONFIGURED TARGET snapshot: that launch's native role
|
|
38
38
|
// forces the reserved worker alias and the live target may have moved since, so it describes what
|
|
39
39
|
// was configured at launch, never the model a subagent actually consumed.
|
|
40
|
+
//
|
|
41
|
+
// ONE LEAD HARNESS HAS NO NATIVE LANE AT ALL: a DeepSeek Harness lead (D-24). CTM cannot pin the
|
|
42
|
+
// model of dsh's own sub-agent tool, so its native answer is refused by the lead's own harness
|
|
43
|
+
// before any pin is compared -- see DSH_LEAD_AGENT below.
|
|
40
44
|
|
|
41
45
|
// Reason codes (the `error` field of a typed refusal; the MCP layer renders them as text).
|
|
42
46
|
const NATIVE_SELECTION_REQUIRES_RELAUNCH = 'native_selection_requires_relaunch';
|
|
@@ -48,7 +52,24 @@ const RELAUNCH_NEXT_STEP = 'Relaunch the lead to apply its native pick, or expli
|
|
|
48
52
|
// pick / vendor rung) and `unservable` (a pick CTM refused to install) are deliberately absent:
|
|
49
53
|
// they pin nothing, so a requested model is not overridden by them.
|
|
50
54
|
const PINNING_KINDS = new Set(['native', 'routed', 'inherit']);
|
|
51
|
-
|
|
55
|
+
// WP-5 (§9 S-20, opencode-lead-and-delegate-model-selection-2026-10-28.html §8): an OpenCode lead is
|
|
56
|
+
// a live lead too, and its native helper runs on OpenCode, so its harness and its pin are reported
|
|
57
|
+
// through exactly this sanitizer. The tool does NOT accept `opencode` as a worker harness (that
|
|
58
|
+
// anti-goal is unchanged) -- see the harness comparison below for what that means. dsh joins the
|
|
59
|
+
// same way (WP-10/P-6): its harness is reported here so D-24's refusal below can key on it.
|
|
60
|
+
const KNOWN_AGENTS = new Set(['codex', 'claude', 'opencode', 'dsh']);
|
|
61
|
+
// The harnesses a caller can actually REQUEST through walle_delegate_implementation
|
|
62
|
+
// (normalizeWorkerExecutionOptions). A lead harness outside this set (OpenCode) can never be equal
|
|
63
|
+
// to a request, so comparing against it would report every native answer as a cross-harness
|
|
64
|
+
// mismatch and hide the model/effort pin conflict this module exists to surface (AC-5c).
|
|
65
|
+
const REQUESTABLE_HARNESSES = new Set(['codex', 'claude']);
|
|
66
|
+
// D-24 (deepseek-harness-acp-agent-2026-10-28.html §5b, WP-10): a DeepSeek Harness lead delegates
|
|
67
|
+
// through ROUTED WORKERS ONLY. CTM cannot pin the model of dsh's own sub-agent tool, so no native
|
|
68
|
+
// answer describes anything a dsh lead could spawn: every native answer for it is the typed mismatch
|
|
69
|
+
// refusal below -- never a Claude model, never a silent substitution, and never a fallback to
|
|
70
|
+
// another lane. Unlike the OpenCode case there is no "same harness" native answer to preserve.
|
|
71
|
+
const DSH_LEAD_AGENT = 'dsh';
|
|
72
|
+
const DSH_ROUTED_ONLY_NEXT_STEP = 'A DeepSeek Harness lead delegates through routed workers only: name route/model (or route alone) to run an explicitly routed claude/codex worker.';
|
|
52
73
|
// 'inherit' is the Claude native lane's own literal for "same model as the lead" (CTM's
|
|
53
74
|
// resolveFromEffectivePref); a request for it matches an already-inheriting launch, so it is
|
|
54
75
|
// never treated as a specific model a routed alias/FORCE would override.
|
|
@@ -67,9 +88,10 @@ function _token(value, max = MAX_TOKEN_LENGTH) {
|
|
|
67
88
|
/**
|
|
68
89
|
* The sanitized descriptor of a lead's applied native launch constraints. PURE.
|
|
69
90
|
* @param {unknown} launch whatever arrived as native_subagent_launch (or nothing at all)
|
|
70
|
-
* @returns {{state:'known',agent:'codex'|'claude',kind:string,model:string,effort:string|null}
|
|
71
|
-
* | {state:'unknown',agent?:'codex'|'claude'}} exactly these keys, nothing else:
|
|
72
|
-
* keeps the lead's own harness (`agent`) when it is known, and only `state` when it
|
|
91
|
+
* @returns {{state:'known',agent:'codex'|'claude'|'opencode'|'dsh',kind:string,model:string,effort:string|null}
|
|
92
|
+
* | {state:'unknown',agent?:'codex'|'claude'|'opencode'|'dsh'}} exactly these keys, nothing else:
|
|
93
|
+
* an unknown pin keeps the lead's own harness (`agent`) when it is known, and only `state` when it
|
|
94
|
+
* is not
|
|
73
95
|
*/
|
|
74
96
|
function nativeLaunchConstraints(launch) {
|
|
75
97
|
if (!launch || typeof launch !== 'object' || Array.isArray(launch)) return { state: 'unknown' };
|
|
@@ -120,11 +142,36 @@ function checkNativeDelegateSelection({ launch, resolved, agent, effort } = {})
|
|
|
120
142
|
const constraints = nativeLaunchConstraints(launch);
|
|
121
143
|
const requestedAgent = agent === 'codex' || agent === 'claude' ? agent : '';
|
|
122
144
|
|
|
145
|
+
// D-24 FIRST, for EVERY native answer whose lead harness is dsh -- a known pin, an unknown one, or
|
|
146
|
+
// bare launch metadata alike (this module is only ever consulted for a native answer). There is no
|
|
147
|
+
// native configuration a DeepSeek Harness lead could run, so no pin comparison could ever make the
|
|
148
|
+
// answer acceptable: the refusal is the lead's own harness, not a conflict with what was asked
|
|
149
|
+
// for. Nothing is substituted -- the remedy is an explicitly routed worker.
|
|
150
|
+
if (constraints.agent === DSH_LEAD_AGENT) {
|
|
151
|
+
return {
|
|
152
|
+
ok: false,
|
|
153
|
+
constraints,
|
|
154
|
+
refusal: {
|
|
155
|
+
error: NATIVE_DELEGATE_HARNESS_MISMATCH,
|
|
156
|
+
// Only reported when the call actually named a worker harness: the refusal does not depend
|
|
157
|
+
// on one (a bare call is refused the same way), and an empty string would name nothing.
|
|
158
|
+
...(requestedAgent ? { requested_agent: requestedAgent } : {}),
|
|
159
|
+
configured_agent: DSH_LEAD_AGENT,
|
|
160
|
+
reason: 'lead_routed_only',
|
|
161
|
+
next_step: DSH_ROUTED_ONLY_NEXT_STEP,
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
123
166
|
// HARNESS FIRST, whenever the ACTUAL lead harness is known -- including an unknown pin, where
|
|
124
167
|
// the harness is still a known fact. A native helper runs on the lead's own harness, so a
|
|
125
168
|
// cross-harness request is the one refusal a relaunch cannot fix: the remedy is an explicitly
|
|
126
169
|
// routed worker. Nothing about the pin is claimed by this refusal.
|
|
127
|
-
|
|
170
|
+
//
|
|
171
|
+
// Only compared when the lead's harness is one the caller could have requested at all
|
|
172
|
+
// (REQUESTABLE_HARNESSES): an OpenCode lead's harness can never equal a request, and refusing
|
|
173
|
+
// there would mask the pin conflict with an unfixable-by-relaunch harness error (AC-5c).
|
|
174
|
+
if (requestedAgent && REQUESTABLE_HARNESSES.has(constraints.agent) && requestedAgent !== constraints.agent) {
|
|
128
175
|
return {
|
|
129
176
|
ok: false,
|
|
130
177
|
constraints,
|
|
@@ -178,9 +225,10 @@ function checkNativeDelegateSelection({ launch, resolved, agent, effort } = {})
|
|
|
178
225
|
// Codex native children get a role-file effort; a known NON-EMPTY effort the caller does not
|
|
179
226
|
// ask for cannot be changed without a relaunch. An EMPTY configured effort is a known "no role
|
|
180
227
|
// override", and an EMPTY requested effort means the call named none -- the CLI's own
|
|
181
|
-
// inheritance/default decides it, so neither is a claim about the other.
|
|
182
|
-
// native role effort
|
|
183
|
-
//
|
|
228
|
+
// inheritance/default decides it, so neither is a claim about the other. Only Codex installs a
|
|
229
|
+
// native role effort (Claude does not, and an OpenCode or DeepSeek Harness lead was answered
|
|
230
|
+
// above), so no other harness is refused on effort; a NULL configured effort is unknown and never
|
|
231
|
+
// claimed equal to the requested one.
|
|
184
232
|
if (constraints.agent === 'codex' && (constraints.kind === 'native' || constraints.kind === 'routed')
|
|
185
233
|
&& constraints.effort && constraints.effort !== requestedEffort) {
|
|
186
234
|
return {
|
|
@@ -31,6 +31,15 @@ function isExactModelOnRoute(model, routes, route) {
|
|
|
31
31
|
return Boolean(row && Array.isArray(row.models) && row.models.includes(model));
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
// WP-2 fix round 1 (§5 D-6): the one origin-refusal sentence tail, shared by the stored-pick
|
|
35
|
+
// and default-rung branches so both read identically -- the route IS configured; this machine
|
|
36
|
+
// just cannot dial its origin -- and both name the origin and when it was probed.
|
|
37
|
+
function originRefusalClause(ex) {
|
|
38
|
+
const origin = ex.origin || 'unknown';
|
|
39
|
+
const checked = ex.checked_at ? `, checked ${ex.checked_at}` : '';
|
|
40
|
+
return `cannot be reached from this machine (origin ${origin}${checked}) -- name a route this machine can reach, or pick one in the model picker`;
|
|
41
|
+
}
|
|
42
|
+
|
|
34
43
|
// WP-1 §6.2, §9 S-2: renders a resolver failure ({ok:false, code, candidates?|tried?})
|
|
35
44
|
// as a structured, readable tool error -- route ids and model ids only, never a
|
|
36
45
|
// provider name or credential. The caller throws this so handleMcpMessage's generic
|
|
@@ -55,9 +64,16 @@ function delegateArgsError(code, payload) {
|
|
|
55
64
|
// worker route feed at all (gone/not configured or carrying no enabled
|
|
56
65
|
// models) -- say that, not "cannot serve agent X" (which reads as a
|
|
57
66
|
// serve-time refusal of a route that exists).
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
// WP-2 fix round 1 (§5 D-6): an ORIGIN refusal is a third, different truth --
|
|
68
|
+
// the route IS configured and served, this machine just cannot dial its
|
|
69
|
+
// origin -- so it gets its own sentence rather than the "not in the feed" one.
|
|
70
|
+
const ex = Array.isArray(safe.excluded) ? safe.excluded[0] : null;
|
|
71
|
+
const originClause = ex && ex.reason === 'origin_unreachable' ? originRefusalClause(ex) : null;
|
|
72
|
+
detail = originClause
|
|
73
|
+
? `The default route ${route} ${originClause}`
|
|
74
|
+
: safe.cause === 'route_unavailable'
|
|
75
|
+
? `The default route ${route} is unavailable right now (not in the worker route feed: no enabled models or not configured) -- name one of eligible[] as route/model`
|
|
76
|
+
: `The default route ${route} cannot serve agent ${safe.agent || ''} -- name one of eligible[] as route/model`;
|
|
61
77
|
} else if (code === 'delegate_pref_unresolvable') {
|
|
62
78
|
const pref = safe.pref || {};
|
|
63
79
|
// WP-0 (§5 D-1/D-2): the stored pick hit the health gate -- the sentence
|
|
@@ -68,6 +84,11 @@ function delegateArgsError(code, payload) {
|
|
|
68
84
|
const ex = Array.isArray(safe.excluded) ? safe.excluded[0] : null;
|
|
69
85
|
if (safe.cause === 'route_unavailable' && pref.route_id && ex && (ex.reason === 'circuit_open' || ex.reason === 'throttled')) {
|
|
70
86
|
detail = `The stored ${safe.source || ''} delegate route "${pref.route_id}" ${ex.reason === 'throttled' ? 'is throttled' : 'has an open circuit'} (${retryPhrase(ex.retry_after_ms)}) -- wait, pick another route in the model picker, or name a model in the call`;
|
|
87
|
+
} else if (safe.cause === 'route_unavailable' && pref.route_id && ex && ex.reason === 'origin_unreachable') {
|
|
88
|
+
// WP-2 fix round 1 (§5 D-6): the route IS configured -- this machine cannot dial
|
|
89
|
+
// its origin. The "no longer configured" sentence below would be a lie here, and
|
|
90
|
+
// the lead needs to know WHICH origin and when it was probed.
|
|
91
|
+
detail = `The stored ${safe.source || ''} delegate route "${pref.route_id}" ${originRefusalClause(ex)}`;
|
|
71
92
|
} else if (safe.cause === 'route_unavailable' && pref.route_id) {
|
|
72
93
|
// D-7 (§6.4): a gone pref route_id names the route, not a model phrase -- the sentence
|
|
73
94
|
// points at the picker where that id was written, never at a re-resolved model.
|
|
@@ -159,6 +180,16 @@ function routeHealthRefusal(route, model, identityCtx) {
|
|
|
159
180
|
return null;
|
|
160
181
|
}
|
|
161
182
|
|
|
183
|
+
// WP-2 (§5 D-6): the second input to the health gate -- the box's OWN origin verdict for the stored
|
|
184
|
+
// pick's route. Only an explicit `unreachable`/`no_server` refuses; `unknown`, a missing row, or no
|
|
185
|
+
// availability at all is "no gate" (the delegation may still fail later as upstream_unready, which
|
|
186
|
+
// is the pre-WP-2 behaviour). Explicit `model`/`route` arguments never pass through here (D-7).
|
|
187
|
+
function originReachabilityRefusal(route, availability) {
|
|
188
|
+
const row = availability && Array.isArray(availability.routes) ? availability.routes.find((r) => r && r.id === route) : null;
|
|
189
|
+
if (!row || (row.reach !== 'unreachable' && row.reach !== 'no_server')) return null;
|
|
190
|
+
return { registry_id: route, reason: 'origin_unreachable', origin: row.origin || null, reach: row.reach, checked_at: availability.checkedAt || null };
|
|
191
|
+
}
|
|
192
|
+
|
|
162
193
|
// L-3: one offer per ROUTE (never one per model), at most MAX_ELIGIBLE_ROUTES, ordered so a lead
|
|
163
194
|
// can pick from the top: keyed before keyless, direct providers before gateway integration rows,
|
|
164
195
|
// then route id. A route has no per-route default model (only the per-agent default delegate
|
|
@@ -173,7 +204,10 @@ function eligibleRouteOffers(listing, agent, identityCtx = null) {
|
|
|
173
204
|
if (seen.has(row.route) || row.models.length === 0) return false;
|
|
174
205
|
seen.add(row.route);
|
|
175
206
|
return true;
|
|
176
|
-
}).filter((row) => routeHealthRefusal(row.route, row.model || (row.models && row.models[0]) || '', identityCtx) === null)
|
|
207
|
+
}).filter((row) => routeHealthRefusal(row.route, row.model || (row.models && row.models[0]) || '', identityCtx) === null)
|
|
208
|
+
// WP-2 (§5 D-6): an offer the box's own origin probe calls unreachable is not an
|
|
209
|
+
// offer -- naming it back would round-trip to the same refusal.
|
|
210
|
+
.filter((row) => originReachabilityRefusal(row.route, identityCtx && identityCtx.availability) === null);
|
|
177
211
|
const keyed = (row) => row.has_credential !== false;
|
|
178
212
|
const rank = (row) => (keyed(row) ? 0 : 2) + (row.gateway === true ? 1 : 0);
|
|
179
213
|
rows.sort((a, b) => rank(a) - rank(b) || (a.route < b.route ? -1 : a.route > b.route ? 1 : 0));
|
|
@@ -311,6 +345,26 @@ function resolveFromEffectivePref(effective, agent, listing, registryModels, ide
|
|
|
311
345
|
}
|
|
312
346
|
return unresolvablePref(effective, 'route_unavailable', { excluded, offers });
|
|
313
347
|
}
|
|
348
|
+
// WP-2 (§5 D-6/D-7): the stored pick's route exists and serves the agent, but this
|
|
349
|
+
// machine's own origin probe says it cannot be reached -- refuse NOW with the same
|
|
350
|
+
// route_unavailable shape (and offers[] filtered by the same verdict), instead of
|
|
351
|
+
// letting CTM die later as a raw 503 upstream_unready, after launch work. The
|
|
352
|
+
// explicit path (resolveRoutedPair with caller-given route/model) never reaches here.
|
|
353
|
+
const originRefusal = originReachabilityRefusal(routeId, identityCtx && identityCtx.availability);
|
|
354
|
+
if (originRefusal) {
|
|
355
|
+
if (source === 'default') {
|
|
356
|
+
return {
|
|
357
|
+
ok: false, code: 'default_route_not_servable', source, agent, cause: 'route_unavailable',
|
|
358
|
+
default: { route: routeId, model: effective.model, agents: [] },
|
|
359
|
+
// WP-2 fix round 1: carry the WHY (this machine cannot reach the origin) and the
|
|
360
|
+
// origin itself -- without it the sentence could only say "unavailable right now",
|
|
361
|
+
// and the lead could not tell an unreachable origin from a route gone from the feed.
|
|
362
|
+
excluded: [originRefusal],
|
|
363
|
+
eligible: eligibleRouteOffers(listing, agent, identityCtx),
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
return unresolvablePref(effective, 'route_unavailable', { excluded: [originRefusal], offers: eligibleRouteOffers(listing, agent, identityCtx) });
|
|
367
|
+
}
|
|
314
368
|
const resolved = resolveRoutedPair(agent, routeId, effective.model, listing, registryModels, identityCtx);
|
|
315
369
|
if (!resolved.ok) {
|
|
316
370
|
const { ok: _ok, code, ...detail } = resolved;
|
|
@@ -324,25 +378,36 @@ function resolveFromEffectivePref(effective, agent, listing, registryModels, ide
|
|
|
324
378
|
* Precedence (lead-and-delegate-model-picker-ux-2026-10-08.html D-9): a route/model named in the
|
|
325
379
|
* call > the lead's session pick > the default for its agent > the vendor default. Every success
|
|
326
380
|
* names its rung as `source` ('explicit' | 'session' | 'default' | 'vendor') and its `lane`.
|
|
381
|
+
*
|
|
382
|
+
* §9 S-16 (opencode-lead-and-delegate-model-selection-2026-10-28.html §8 WP-5): `prefs.agent` is the
|
|
383
|
+
* LEAD's own agent (what readLeadDelegatePrefs resolved the parent session row to). It keys the
|
|
384
|
+
* LADDER; `args.agent` stays the worker HARNESS every resolved pair is checked against, so an
|
|
385
|
+
* OpenCode lead's stored default:opencode/session pick still launches a claude-code or codex-cli
|
|
386
|
+
* worker. An absent/unrecognized prefs.agent keeps today's derivation from args.agent exactly.
|
|
327
387
|
* @param {{route?:string, model?:string, agent?:'claude'|'codex'}} args caller-given delegate args
|
|
328
388
|
* @param {{default:{route,model}, routes:Array}} listing buildWorkerRoutesResult() shape
|
|
329
389
|
* @param {Array} [registryModels] GET /api/models/registry rows, forwarded to resolveWorkerModel
|
|
330
390
|
* @param {object} [identityCtx] resolveWorkerModel's identity-tier ctx
|
|
331
|
-
* @param {{session?:object|null, default?:object|null}} [prefs]
|
|
391
|
+
* @param {{session?:object|null, default?:object|null, agent?:'claude'|'codex'|'opencode'}} [prefs]
|
|
392
|
+
* stored delegate_model_prefs rows (+ the lead agent that keys them)
|
|
332
393
|
* @returns {{ok:true, lane:'routed', route, model, source} | {ok:true, lane:'native', model, source}
|
|
333
394
|
* | {ok:false, code:'model_unknown'|'model_ambiguous'|'route_unavailable'|'default_route_not_servable'|'delegate_pref_unresolvable', ...}}
|
|
334
395
|
*/
|
|
335
396
|
function resolveDelegateArgs(args, listing, registryModels, identityCtx, prefs) {
|
|
336
397
|
const agent = args && args.agent === 'codex' ? 'codex' : 'claude';
|
|
398
|
+
// S-16: the ladder is the LEAD's; the harness is the WORKER's. An OpenCode lead folds
|
|
399
|
+
// default:opencode (or its own session rung) while the resolved worker harness stays claude/codex.
|
|
400
|
+
const ladderAgent = prefs && (prefs.agent === 'codex' || prefs.agent === 'claude' || prefs.agent === 'opencode')
|
|
401
|
+
? prefs.agent : agent;
|
|
337
402
|
const route = args && args.route;
|
|
338
403
|
const model = args && args.model;
|
|
339
404
|
|
|
340
405
|
if (!route && !model) {
|
|
341
|
-
const { effective } = foldDelegateLadder(prefs,
|
|
406
|
+
const { effective } = foldDelegateLadder(prefs, ladderAgent);
|
|
342
407
|
return resolveFromEffectivePref(effective, agent, listing, registryModels, identityCtx);
|
|
343
408
|
}
|
|
344
409
|
const resolved = resolveRoutedPair(agent, route, model, listing, registryModels, identityCtx);
|
|
345
410
|
return resolved.ok ? { ...resolved, lane: 'routed', source: 'explicit' } : resolved;
|
|
346
411
|
}
|
|
347
412
|
|
|
348
|
-
module.exports = { resolveDelegateArgs, isExactModelOnRoute, delegateArgsError, routeThrottledError, briefRefusalError };
|
|
413
|
+
module.exports = { resolveDelegateArgs, isExactModelOnRoute, delegateArgsError, routeThrottledError, briefRefusalError, originReachabilityRefusal };
|