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
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const conversationChangeFeed = require('./conversation-change-feed');
|
|
4
|
+
const SessionSearchUtils = require('../public/js/session-search-utils');
|
|
5
|
+
const sessionContextLocator = require('./session-context-locator');
|
|
4
6
|
|
|
5
7
|
let ctmSessionContext = null;
|
|
6
8
|
let ctmSessionContextLoadError = null;
|
|
@@ -47,7 +49,13 @@ function makeSplitRoutingHandle(dbModule) {
|
|
|
47
49
|
});
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
function handleCtmSessionContextApi(req, res, url, {
|
|
52
|
+
function handleCtmSessionContextApi(req, res, url, {
|
|
53
|
+
db, dbModule, runHeavy, runMutation,
|
|
54
|
+
// WP-2 (docs/cross-machine-session-context-2026-10-31.html §6.1): test seams for the hub owner
|
|
55
|
+
// resolver. Production passes neither — server.js (inside the file-size-frozen `handleApi`) is
|
|
56
|
+
// untouched and every default is lazy in lib/session-context-locator.js.
|
|
57
|
+
locatorDeps = {}, env = process.env,
|
|
58
|
+
} = {}) {
|
|
51
59
|
const rangeMatch = /^\/api\/sessions\/([^/]+)\/messages\/range$/.exec(url.pathname);
|
|
52
60
|
// WP-0 (one-transcript-ingestor §6.1): the conversation change-feed routes live here
|
|
53
61
|
// beside the session-memory reads. The guard must admit them or dispatch never reaches
|
|
@@ -129,8 +137,10 @@ function handleCtmSessionContextApi(req, res, url, { db, dbModule, runHeavy, run
|
|
|
129
137
|
query: url.searchParams.get('q') || url.searchParams.get('query') || '',
|
|
130
138
|
limit: url.searchParams.get('limit') || undefined,
|
|
131
139
|
};
|
|
132
|
-
|
|
133
|
-
|
|
140
|
+
// WP-4 (§6.2/R-7): `scope=pool` (the default) fans the search out to every dialable member
|
|
141
|
+
// under one deadline and merges by RRF; `scope=local` keeps today's local-only answer.
|
|
142
|
+
const scope = url.searchParams.get('scope') || 'pool';
|
|
143
|
+
return serveSearchAnywhere({ args, scope, res, context, runHeavy, db, locatorDeps, env });
|
|
134
144
|
}
|
|
135
145
|
|
|
136
146
|
if ((url.pathname === '/api/ctm/session-memory/context' || rangeMatch) && req.method === 'GET') {
|
|
@@ -151,9 +161,25 @@ function handleCtmSessionContextApi(req, res, url, { db, dbModule, runHeavy, run
|
|
|
151
161
|
format: url.searchParams.get('format') || 'messages',
|
|
152
162
|
projection: url.searchParams.get('projection') || 'envelope',
|
|
153
163
|
};
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
164
|
+
// WP-2 (§6.2/R-3): the RANGE route stays LOCAL-ONLY and unchanged — it keeps today's
|
|
165
|
+
// args verbatim (no `ref`, no `scope`) and never leaves this machine.
|
|
166
|
+
if (rangeMatch) {
|
|
167
|
+
return serveHeavy('ctmSessionMemoryContext', args,
|
|
168
|
+
() => context.getCtmSessionContext({ ...args, db }),
|
|
169
|
+
{ typedRangeStatus: true });
|
|
170
|
+
}
|
|
171
|
+
// R-1 (§6.2): `ref` is any identity string parseSessionIdentityQuery understands — a
|
|
172
|
+
// `#session=<id>` link, `review=<id>`, or a bare uuid — merged into session_ids. The context
|
|
173
|
+
// route is answered by the hub owner resolver, which reads locally first and only leaves this
|
|
174
|
+
// machine on a local miss. `scope=pool` is the default; lib/session-context-locator.js is the
|
|
175
|
+
// single reader of the R-11 flag (an off flag skips both the owner forward and the probe).
|
|
176
|
+
const ref = String(url.searchParams.get('ref') || '').trim();
|
|
177
|
+
if (ref) {
|
|
178
|
+
const parsedRef = SessionSearchUtils.parseSessionIdentityQuery(ref);
|
|
179
|
+
if (parsedRef.sessionIds.length) args.session_ids = [...args.session_ids, ...parsedRef.sessionIds];
|
|
180
|
+
}
|
|
181
|
+
args.scope = url.searchParams.get('scope') || 'pool';
|
|
182
|
+
return serveContextAnywhere({ args, res, context, runHeavy, db, locatorDeps, env });
|
|
157
183
|
}
|
|
158
184
|
|
|
159
185
|
if (
|
|
@@ -300,6 +326,71 @@ function handleCtmSessionContextApi(req, res, url, { db, dbModule, runHeavy, run
|
|
|
300
326
|
}
|
|
301
327
|
}
|
|
302
328
|
|
|
329
|
+
/**
|
|
330
|
+
* WP-2 (§6.2, R-3/R-5): answer `GET /api/ctm/session-memory/context` through the hub owner
|
|
331
|
+
* resolver. The local read is today's off-thread path (`runHeavy` when wired, `computeSync`
|
|
332
|
+
* otherwise), so a local hit is today's answer plus `location`; only a local MISS leaves this
|
|
333
|
+
* machine (one forwarded GET to the directory's owner, else a deadline-bounded parallel probe).
|
|
334
|
+
*/
|
|
335
|
+
function serveContextAnywhere({ args, res, context, runHeavy, db, locatorDeps, env }) {
|
|
336
|
+
const readLocal = (localArgs) => {
|
|
337
|
+
// `scope` is the locator's key, never a worker argument: the worker re-runs today's op.
|
|
338
|
+
const workerArgs = { ...localArgs };
|
|
339
|
+
delete workerArgs.scope;
|
|
340
|
+
const computeSync = () => context.getCtmSessionContext({ ...workerArgs, db });
|
|
341
|
+
if (typeof runHeavy !== 'function') return Promise.resolve().then(computeSync);
|
|
342
|
+
return Promise.resolve().then(() => runHeavy('ctmSessionMemoryContext', workerArgs, computeSync));
|
|
343
|
+
};
|
|
344
|
+
Promise.resolve()
|
|
345
|
+
.then(() => sessionContextLocator.readSessionContextAnywhere(
|
|
346
|
+
{ args, excludeMachineId: '', env: env || process.env },
|
|
347
|
+
{ ...locatorDeps, readLocal },
|
|
348
|
+
))
|
|
349
|
+
.then((result) => {
|
|
350
|
+
const payload = asApiResult(result);
|
|
351
|
+
return respondJson(res, rangeHttpStatus(payload), payload);
|
|
352
|
+
})
|
|
353
|
+
.catch((err) => respondJson(res, 500, {
|
|
354
|
+
ok: false,
|
|
355
|
+
source: 'ctm-api',
|
|
356
|
+
authority: 'ctm',
|
|
357
|
+
reason: 'ctm_session_context_failed',
|
|
358
|
+
error: err.message,
|
|
359
|
+
}));
|
|
360
|
+
return true;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* WP-4 (§6.2, R-7): answer `GET /api/ctm/session-memory/search` through the pool fan-out. The local
|
|
365
|
+
* search IS today's off-thread path (`runHeavy` when wired, `computeSync` otherwise) so a local-only
|
|
366
|
+
* read answers with today's rows — only the MERGE adds `machine_id`/`machine_name`/`rank`, and only
|
|
367
|
+
* when the pool is on does anything leave this machine (one `scope=local` GET per dialable member).
|
|
368
|
+
* A deferred local read (`null`) still renders today's deferred envelope.
|
|
369
|
+
*/
|
|
370
|
+
function serveSearchAnywhere({ args, scope, res, context, runHeavy, db, locatorDeps, env }) {
|
|
371
|
+
const searchLocal = (localArgs) => {
|
|
372
|
+
const computeSync = () => context.searchCtmSessions({ ...localArgs, db });
|
|
373
|
+
if (typeof runHeavy !== 'function') return Promise.resolve().then(computeSync);
|
|
374
|
+
return Promise.resolve().then(() => runHeavy('ctmSessionMemorySearch', localArgs, computeSync));
|
|
375
|
+
};
|
|
376
|
+
Promise.resolve()
|
|
377
|
+
.then(() => sessionContextLocator.searchSessionsAnywhere(
|
|
378
|
+
{
|
|
379
|
+
query: args.query, limit: args.limit, scope, env: env || process.env,
|
|
380
|
+
},
|
|
381
|
+
{ ...locatorDeps, searchLocal },
|
|
382
|
+
))
|
|
383
|
+
.then((result) => respondJson(res, 200, asApiResult(result)))
|
|
384
|
+
.catch((err) => respondJson(res, 500, {
|
|
385
|
+
ok: false,
|
|
386
|
+
source: 'ctm-api',
|
|
387
|
+
authority: 'ctm',
|
|
388
|
+
reason: 'ctm_session_context_failed',
|
|
389
|
+
error: err.message,
|
|
390
|
+
}));
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
|
|
303
394
|
async function handleMessageIndexBackfill({ body, res, context, db, dbModule }) {
|
|
304
395
|
const limit = clampInt(body.limit, 100, 1, 1000);
|
|
305
396
|
const chunkSize = clampInt(body.chunk_size ?? body.chunkSize, 250, 25, 2000);
|
|
@@ -169,6 +169,7 @@ const TABLE_DOMAINS = Object.freeze({
|
|
|
169
169
|
// intentionally base/firehose-resident so the preflight and its guarded
|
|
170
170
|
// rows remain atomic across core/telemetry extraction.
|
|
171
171
|
conversation_retained_history_guard_v2: 'firehose', conversation_projection_deletes_v2: 'firehose', conversation_store_epoch_v2: 'firehose', conversation_usage_turn_changes_v1: 'firehose', // v36 change feed; v41 usage turn-change outbox schema
|
|
172
|
+
conversation_item_clock: 'firehose', conversation_vv: 'firehose', conversation_local_seq: 'firehose', // v61 shared-memory replica clock: same file as conversation_text_items_v2
|
|
172
173
|
|
|
173
174
|
// firehose — transcript row store + FTS + ingest cursors (lib/transcript-store.js)
|
|
174
175
|
transcript_files: 'firehose',
|
|
@@ -262,6 +262,7 @@ const CTM_WRITE_OPS = Object.freeze([
|
|
|
262
262
|
'commitConversationDelta', 'enrollConversationSource',
|
|
263
263
|
'markConversationUpdatePublished', 'markConversationUpdateUnresolvable',
|
|
264
264
|
'redriveConversationSourceDebt', 'recordResumeLineage', 'ackConversationChanges',
|
|
265
|
+
'conversationSyncVector', 'conversationSyncChanges', 'conversationSyncApply',
|
|
265
266
|
// Not in §9 table A (the gate is derived from the action REGISTRY, so it sees the
|
|
266
267
|
// 14 extra actions the design's 205-action count predates — see the contract.js
|
|
267
268
|
// comment beside their OP_META rows). Both write/repair conversation-store tables
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// WP-0c (docs/session-create-accept-then-complete-2026-11-01.html §6.5 D-13, AC-0e): the
|
|
4
|
+
// low-over-signalled probe that workers/db-owner-worker.js _pump() calls after dequeuing a `low`
|
|
5
|
+
// task. The work signal counts requests the main thread has issued, including ones that have not
|
|
6
|
+
// reached the queue's lanes yet, so a signalled total above the queue's own ready high/urgent
|
|
7
|
+
// depth means a `low` task was dispatched while higher-priority work was waiting.
|
|
8
|
+
// A factory with no worker globals, so the decision and its 10 s emit window are unit-testable
|
|
9
|
+
// without spawning the worker thread; read-only — it never reorders dispatch.
|
|
10
|
+
const DISPATCH_PROBE_WINDOW_MS = 10 * 1000;
|
|
11
|
+
function createLowOverSignalledProbe({ windowMs = DISPATCH_PROBE_WINDOW_MS, log = (line) => console.log(line) } = {}) {
|
|
12
|
+
let lastEmitAt = 0;
|
|
13
|
+
let suppressed = 0;
|
|
14
|
+
return function observeLowDispatch({ op, snapshot, queuedUrgent = 0, queuedHigh = 0, at = Date.now() }) {
|
|
15
|
+
if (!snapshot) return null;
|
|
16
|
+
const signalledHigh = Number(snapshot.interactivePending || 0);
|
|
17
|
+
const signalledUrgent = Number(snapshot.urgentPending || 0);
|
|
18
|
+
if (signalledHigh + signalledUrgent <= Number(queuedUrgent || 0) + Number(queuedHigh || 0)) return null;
|
|
19
|
+
if (lastEmitAt && at - lastEmitAt < windowMs) {
|
|
20
|
+
suppressed += 1;
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const line = `[db-owner-dispatch] low-over-signalled op=${op} signalledHigh=${signalledHigh} signalledUrgent=${signalledUrgent} `
|
|
24
|
+
+ `queuedHigh=${Number(queuedHigh || 0)} queuedUrgent=${Number(queuedUrgent || 0)} suppressed=${suppressed}`;
|
|
25
|
+
lastEmitAt = at;
|
|
26
|
+
suppressed = 0;
|
|
27
|
+
try { log(line); } catch { /* expected: a throwing injected log must not break dispatch */ }
|
|
28
|
+
return line;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = { DISPATCH_PROBE_WINDOW_MS, createLowOverSignalledProbe };
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// WP-0 M-5 (docs/hub-local-cpu-memory-burn-2026-10-31.html §3.5, §7 M-5). MEASUREMENT ONLY.
|
|
4
|
+
//
|
|
5
|
+
// After every hub boot the DB-owner worker absorbs a 1-2 min storm of expired requests
|
|
6
|
+
// (200k-1.8M, mostly runtime-event / session-diagnostic writes) while catchUpTranscriptFiles
|
|
7
|
+
// occupies the writer. Nothing on the client side says WHICH producers issue them, so these
|
|
8
|
+
// counters attribute every request() attempt — including the ones REFUSED before they ever
|
|
9
|
+
// reach the worker — to the minute it was issued: per worker op, and per runtime-event /
|
|
10
|
+
// session-diagnostic NAME for the event writers.
|
|
11
|
+
//
|
|
12
|
+
// Stated bounds (enforced below, no I/O and no allocation beyond the current bucket):
|
|
13
|
+
// * a fixed ring of the last REQUEST_COUNT_RING_MINUTES one-minute buckets;
|
|
14
|
+
// * at most REQUEST_COUNT_KEY_MAX distinct op keys and REQUEST_COUNT_KEY_MAX distinct event
|
|
15
|
+
// keys per bucket — every further key folds into `_other`;
|
|
16
|
+
// * O(1) work per request (one clock read, one ring index, one map write).
|
|
17
|
+
const REQUEST_COUNT_RING_MINUTES = 30;
|
|
18
|
+
const REQUEST_COUNT_KEY_MAX = 64;
|
|
19
|
+
const REQUEST_COUNT_KEY_CLIP = 80;
|
|
20
|
+
// `refused` = the client never handed the op to the worker (quarantine, circuit breaker, worker
|
|
21
|
+
// not running, worker died/recycled mid-flight). Non-timeout failures are `error`.
|
|
22
|
+
const REQUEST_COUNT_OUTCOMES = Object.freeze(['ok', 'timeout', 'refused', 'error']);
|
|
23
|
+
|
|
24
|
+
// Errors that mean "the client refused / could not reach the worker" rather than "the op ran
|
|
25
|
+
// and failed" — the refused share of the boot storm.
|
|
26
|
+
const REQUEST_REFUSED_CODES = new Set([
|
|
27
|
+
'CTM_DB_OWNER_OP_QUARANTINED',
|
|
28
|
+
'CTM_DB_OWNER_WORKER_DEGRADED',
|
|
29
|
+
'CTM_DB_OWNER_WORKER_DISABLED',
|
|
30
|
+
'CTM_DB_OWNER_WORKER_EXITED',
|
|
31
|
+
'CTM_DB_OWNER_WORKER_FATAL',
|
|
32
|
+
'CTM_DB_OWNER_WORKER_RECYCLED',
|
|
33
|
+
'CTM_DB_OWNER_ISOLATION_RECYCLED',
|
|
34
|
+
'CTM_DB_OWNER_CLOSED',
|
|
35
|
+
'CTM_DB_OWNER_CLOSING',
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
function _requestCountOutcome(error) {
|
|
39
|
+
return error && REQUEST_REFUSED_CODES.has(error.code) ? 'refused' : 'error';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Ops whose payload carries a runtime-event / session-diagnostic NAME. BOTH dispatch shapes
|
|
43
|
+
// reach this client: the direct worker op (payload = { events | entries } — see
|
|
44
|
+
// workers/db-owner-worker.js case 'appendRuntimeEventsBatch' and db.js flushSessionDiagnostics)
|
|
45
|
+
// and the generic `runDbMutation` wrapper (payload = { action, args } — server.js's
|
|
46
|
+
// configureOwnerMutations dispatch for db.js's appendRuntimeEvent/addSessionDiagnostic).
|
|
47
|
+
// addSessionDiagnostic has no separate batch op: db.js's flushSessionDiagnostics IS its batch
|
|
48
|
+
// form (its entries each carry the diagnostic name in `event`).
|
|
49
|
+
const RUNTIME_EVENT_WRITE_OPS = new Set([
|
|
50
|
+
'appendRuntimeEvent',
|
|
51
|
+
'appendRuntimeEventsBatch',
|
|
52
|
+
'addSessionDiagnostic',
|
|
53
|
+
'flushSessionDiagnostics',
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
function _eventNameText(value) {
|
|
57
|
+
if (typeof value !== 'string') return '';
|
|
58
|
+
const text = value.trim();
|
|
59
|
+
return text ? text.slice(0, REQUEST_COUNT_KEY_CLIP) : '';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// The NAME a runtime-event / diagnostic row is written under: `type` for ctm_runtime_events
|
|
63
|
+
// (db.js normalizeRuntimeEvent) and `event` for session_diagnostics (db.js addSessionDiagnostic's
|
|
64
|
+
// second argument, and a flush entry's `event`). Tolerates the object or the bare-string form.
|
|
65
|
+
function _runtimeEventName(candidate) {
|
|
66
|
+
if (typeof candidate === 'string') return _eventNameText(candidate);
|
|
67
|
+
if (!candidate || typeof candidate !== 'object') return '';
|
|
68
|
+
return _eventNameText(candidate.type) || _eventNameText(candidate.event)
|
|
69
|
+
|| _eventNameText(candidate.kind) || _eventNameText(candidate.name);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Names contributed by ONE request, or null when this op is not an event/diagnostic write.
|
|
73
|
+
// A batch contributes one entry per element. An unnamed write still counts, as 'unknown'.
|
|
74
|
+
function _runtimeEventNamesFor(op, payload) {
|
|
75
|
+
if (!payload || typeof payload !== 'object') return null;
|
|
76
|
+
const action = op === 'runDbMutation' ? String(payload.action || '') : String(op || '');
|
|
77
|
+
if (!RUNTIME_EVENT_WRITE_OPS.has(action)) return null;
|
|
78
|
+
const args = Array.isArray(payload.args) ? payload.args : null;
|
|
79
|
+
const batch = Array.isArray(payload.events) ? payload.events
|
|
80
|
+
: (Array.isArray(payload.entries) ? payload.entries : null);
|
|
81
|
+
if (batch) return batch.map((item) => _runtimeEventName(item) || 'unknown');
|
|
82
|
+
if (args && Array.isArray(args[0])) {
|
|
83
|
+
return args[0].map((item) => _runtimeEventName(item) || 'unknown');
|
|
84
|
+
}
|
|
85
|
+
// Diagnostics take their name from the second db.js argument (the first is the session id);
|
|
86
|
+
// runtime events are the event object itself.
|
|
87
|
+
const single = action === 'addSessionDiagnostic'
|
|
88
|
+
? (_runtimeEventName(payload.event) || _runtimeEventName(payload.kind) || _runtimeEventName(args?.[1]))
|
|
89
|
+
: (_runtimeEventName(payload.event) || _runtimeEventName(args?.[0]) || _runtimeEventName(payload));
|
|
90
|
+
return [single || 'unknown'];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function _minuteStartMs(nowMs) {
|
|
94
|
+
return Math.floor(nowMs / 60000) * 60000;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function _newOpCounts() {
|
|
98
|
+
return { requested: 0, ok: 0, timeout: 0, refused: 0, error: 0 };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Fixed-size per-minute request counter. Takes its clock as an option so tests can drive
|
|
102
|
+
// simulated minutes without sleeping (the client itself has no time injection).
|
|
103
|
+
class DbOwnerRequestsPerMinute {
|
|
104
|
+
constructor(options = {}) {
|
|
105
|
+
this.enabled = options.enabled !== false;
|
|
106
|
+
this.now = typeof options.now === 'function' ? options.now : Date.now;
|
|
107
|
+
this.ringMinutes = Math.max(1, Math.trunc(Number(options.ringMinutes)) || REQUEST_COUNT_RING_MINUTES);
|
|
108
|
+
this.keyMax = Math.max(1, Math.trunc(Number(options.keyMax)) || REQUEST_COUNT_KEY_MAX);
|
|
109
|
+
this._buckets = [];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// The current minute's bucket, created on demand — at most one push + one eviction per
|
|
113
|
+
// minute boundary, so the per-request cost stays O(1).
|
|
114
|
+
_bucket() {
|
|
115
|
+
const minuteStartMs = _minuteStartMs(this.now());
|
|
116
|
+
const last = this._buckets[this._buckets.length - 1];
|
|
117
|
+
if (last && last.minuteStartMs === minuteStartMs) return last;
|
|
118
|
+
const bucket = { minuteStartMs, byOp: {}, byEvent: {}, opKeys: 0, eventKeys: 0 };
|
|
119
|
+
this._buckets.push(bucket);
|
|
120
|
+
while (this._buckets.length > this.ringMinutes) this._buckets.shift();
|
|
121
|
+
return bucket;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
_opEntry(bucket, op) {
|
|
125
|
+
const key = String(op || 'unknown').slice(0, REQUEST_COUNT_KEY_CLIP);
|
|
126
|
+
const existing = bucket.byOp[key];
|
|
127
|
+
if (existing) return existing;
|
|
128
|
+
if (bucket.opKeys >= this.keyMax) {
|
|
129
|
+
if (!bucket.byOp._other) bucket.byOp._other = _newOpCounts();
|
|
130
|
+
return bucket.byOp._other;
|
|
131
|
+
}
|
|
132
|
+
const entry = _newOpCounts();
|
|
133
|
+
bucket.byOp[key] = entry;
|
|
134
|
+
bucket.opKeys += 1;
|
|
135
|
+
return entry;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
_bumpEvent(bucket, name) {
|
|
139
|
+
const key = String(name || 'unknown').slice(0, REQUEST_COUNT_KEY_CLIP);
|
|
140
|
+
if (bucket.byEvent[key] !== undefined) {
|
|
141
|
+
bucket.byEvent[key] += 1;
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (bucket.eventKeys >= this.keyMax) {
|
|
145
|
+
bucket.byEvent._other = (bucket.byEvent._other || 0) + 1;
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
bucket.byEvent[key] = 1;
|
|
149
|
+
bucket.eventKeys += 1;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
recordRequest(op, payload) {
|
|
153
|
+
if (!this.enabled) return;
|
|
154
|
+
const bucket = this._bucket();
|
|
155
|
+
this._opEntry(bucket, op).requested += 1;
|
|
156
|
+
const names = _runtimeEventNamesFor(op, payload);
|
|
157
|
+
if (!names) return;
|
|
158
|
+
for (const name of names) this._bumpEvent(bucket, name);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
recordOutcome(op, outcome) {
|
|
162
|
+
if (!this.enabled) return;
|
|
163
|
+
const key = REQUEST_COUNT_OUTCOMES.includes(outcome) ? outcome : 'error';
|
|
164
|
+
this._opEntry(this._bucket(), op)[key] += 1;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Oldest bucket first, the current minute last. Empty when the flag turns attribution off.
|
|
168
|
+
snapshot() {
|
|
169
|
+
if (!this.enabled) return [];
|
|
170
|
+
return this._buckets.map((bucket) => {
|
|
171
|
+
const byOp = {};
|
|
172
|
+
for (const [op, counts] of Object.entries(bucket.byOp)) byOp[op] = { ...counts };
|
|
173
|
+
return { minuteStartMs: bucket.minuteStartMs, byOp, byEvent: { ...bucket.byEvent } };
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
module.exports = { DbOwnerRequestsPerMinute, requestCountOutcome: _requestCountOutcome };
|
|
@@ -17,6 +17,8 @@ const { createFailureRollup } = require('./db-owner-failure-rollup');
|
|
|
17
17
|
const os = require('node:os');
|
|
18
18
|
const fs = require('node:fs');
|
|
19
19
|
const { hydrateCleanupError } = require('./worker-error-metadata');
|
|
20
|
+
const { boolFlag } = require('./env-flags');
|
|
21
|
+
const { DbOwnerRequestsPerMinute, requestCountOutcome: _requestCountOutcome } = require('./db-owner-request-counts');
|
|
20
22
|
|
|
21
23
|
const activeClientsByDbPath = new Map();
|
|
22
24
|
const cooperativeCapabilities = new WeakMap();
|
|
@@ -213,6 +215,8 @@ function _writerLabelForDbPath(dbPath) {
|
|
|
213
215
|
// oldest entry is evicted first.
|
|
214
216
|
const TIMED_OUT_MAX = 256;
|
|
215
217
|
|
|
218
|
+
// WP-0 M-5 request counts per minute: lib/db-owner-request-counts.js.
|
|
219
|
+
|
|
216
220
|
class CtmDbOwnerWorkerClient {
|
|
217
221
|
constructor(options = {}) {
|
|
218
222
|
if (!options.dbPath) throw new Error('CtmDbOwnerWorkerClient requires dbPath');
|
|
@@ -360,6 +364,12 @@ class CtmDbOwnerWorkerClient {
|
|
|
360
364
|
};
|
|
361
365
|
this._lastStatusAt = 0;
|
|
362
366
|
this._statusWaiters = [];
|
|
367
|
+
// WP-0 M-5 (§3.5): per-minute request attribution. On by default IN SOURCE —
|
|
368
|
+
// CTM_PERF_ATTRIBUTION=0 disables it (read through lib/env-flags.js so this file keeps
|
|
369
|
+
// zero raw process.env reads of its own).
|
|
370
|
+
this._requestsPerMinute = new DbOwnerRequestsPerMinute({
|
|
371
|
+
enabled: boolFlag('CTM_PERF_ATTRIBUTION', true),
|
|
372
|
+
});
|
|
363
373
|
}
|
|
364
374
|
|
|
365
375
|
start() {
|
|
@@ -706,24 +716,27 @@ class CtmDbOwnerWorkerClient {
|
|
|
706
716
|
const canLog = this.logger && typeof this.logger.warn === 'function';
|
|
707
717
|
if (!canLog) return;
|
|
708
718
|
const now = Date.now();
|
|
709
|
-
// `startedAt` is
|
|
710
|
-
//
|
|
719
|
+
// `startedAt` is the worker's 'started' stamp; without it the whole span is queue time, printed as
|
|
720
|
+
// `started=0 queueMs=<span> serviceMs=0` (WP-0c D-13: 2026-11-01's unstarted hub requests hid as serviceMs).
|
|
711
721
|
const started = record.startedAt || 0;
|
|
712
|
-
const serviceMs = started ? Math.max(0, now - started) :
|
|
713
|
-
const queueMs = started ? Math.max(0, started - record.enqueuedAt) : 0;
|
|
722
|
+
const serviceMs = started ? Math.max(0, now - started) : 0;
|
|
723
|
+
const queueMs = started ? Math.max(0, started - record.enqueuedAt) : Math.max(0, now - record.enqueuedAt);
|
|
714
724
|
const lateByMs = Math.max(0, now - record.timedOutAt);
|
|
715
|
-
const result = msg.error
|
|
716
|
-
|
|
717
|
-
|
|
725
|
+
const result = msg.error ? `error:${msg.error.code || 'unknown'}` : 'ok';
|
|
726
|
+
const span = started
|
|
727
|
+
? `serviceMs=${Math.round(serviceMs)} queueMs=${Math.round(queueMs)} lateByMs=${Math.round(lateByMs)} result=${result} started=1`
|
|
728
|
+
: `started=0 queueMs=${Math.round(queueMs)} serviceMs=0 lateByMs=${Math.round(lateByMs)} result=${result}`;
|
|
718
729
|
try {
|
|
719
730
|
this.logger.warn(
|
|
720
|
-
`[db-owner-late] writer=${this.writer} op=${record.op} action=${record.action} ` +
|
|
721
|
-
`serviceMs=${Math.round(serviceMs)} queueMs=${Math.round(queueMs)} lateByMs=${Math.round(lateByMs)} result=${result}`
|
|
731
|
+
`[db-owner-late] writer=${this.writer} op=${record.op} action=${record.action} ` + span
|
|
722
732
|
);
|
|
723
733
|
} catch { /* expected: a throwing injected logger must not break the response path */ }
|
|
724
734
|
}
|
|
725
735
|
|
|
726
736
|
_recordTimeout(op) {
|
|
737
|
+
// WP-0 M-5: the request settled as a timeout (the timer path rejects directly, so this is
|
|
738
|
+
// the one place that sees the timed-out op).
|
|
739
|
+
this._requestsPerMinute.recordOutcome(op, 'timeout');
|
|
727
740
|
this._consecutiveTimeouts += 1;
|
|
728
741
|
if (this._consecutiveTimeouts >= this._degradeAfter) {
|
|
729
742
|
const wasDegraded = this.isDegraded();
|
|
@@ -776,14 +789,29 @@ class CtmDbOwnerWorkerClient {
|
|
|
776
789
|
|
|
777
790
|
async request(op, payload = {}, options = {}) {
|
|
778
791
|
if (!op) throw new Error('DB owner worker request requires op');
|
|
779
|
-
|
|
780
|
-
|
|
792
|
+
// WP-0 M-5: count the ATTEMPT before any early throw below, so the requests this client
|
|
793
|
+
// refuses (quarantine / degraded / not running) are attributed to their producer too —
|
|
794
|
+
// they are a large share of the post-boot storm.
|
|
795
|
+
this._requestsPerMinute.recordRequest(op, payload);
|
|
796
|
+
if (options.signal?.aborted) {
|
|
797
|
+
this._requestsPerMinute.recordOutcome(op, 'error');
|
|
798
|
+
throw _abortError(options.signal);
|
|
799
|
+
}
|
|
800
|
+
if (this._recyclePromise) {
|
|
801
|
+
try {
|
|
802
|
+
await _awaitWithAbort(this._recyclePromise, options.signal);
|
|
803
|
+
} catch (error) {
|
|
804
|
+
this._requestsPerMinute.recordOutcome(op, _requestCountOutcome(error));
|
|
805
|
+
throw error; // RETHROW: attribution must not swallow a recycle/abort failure
|
|
806
|
+
}
|
|
807
|
+
}
|
|
781
808
|
const sourceKey = sourceKeyForDbOwnerPayload(payload);
|
|
782
809
|
const quarantine = this._opQuarantine.admit(op, sourceKey);
|
|
783
810
|
if (!quarantine.allowed) {
|
|
784
811
|
const err = new Error(`DB owner operation is cooling down after consecutive deadlines: ${op}`);
|
|
785
812
|
err.code = 'CTM_DB_OWNER_OP_QUARANTINED';
|
|
786
813
|
err.retryAfterMs = quarantine.retryAfterMs;
|
|
814
|
+
this._requestsPerMinute.recordOutcome(op, 'refused');
|
|
787
815
|
throw err;
|
|
788
816
|
}
|
|
789
817
|
// Circuit breaker: when the worker is degraded, fail best-effort ops fast
|
|
@@ -793,11 +821,23 @@ class CtmDbOwnerWorkerClient {
|
|
|
793
821
|
if (options.bestEffort && options.priority !== 'urgent' && this.isDegraded()) {
|
|
794
822
|
const err = new Error(`DB owner worker degraded; skipped best-effort op: ${op}`);
|
|
795
823
|
err.code = 'CTM_DB_OWNER_WORKER_DEGRADED';
|
|
824
|
+
this._requestsPerMinute.recordOutcome(op, 'refused');
|
|
796
825
|
throw err;
|
|
797
826
|
}
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
827
|
+
try {
|
|
828
|
+
await _awaitWithAbort(this.start(), options.signal);
|
|
829
|
+
} catch (error) {
|
|
830
|
+
this._requestsPerMinute.recordOutcome(op, _requestCountOutcome(error));
|
|
831
|
+
throw error; // RETHROW: attribution must not change a failed start into a success
|
|
832
|
+
}
|
|
833
|
+
if (options.signal?.aborted) {
|
|
834
|
+
this._requestsPerMinute.recordOutcome(op, 'error');
|
|
835
|
+
throw _abortError(options.signal);
|
|
836
|
+
}
|
|
837
|
+
if (!this._worker) {
|
|
838
|
+
this._requestsPerMinute.recordOutcome(op, 'refused');
|
|
839
|
+
throw new Error('DB owner worker is not running');
|
|
840
|
+
}
|
|
801
841
|
const requestId = this._nextRequestId++;
|
|
802
842
|
const timeoutMs = _durationMs(options.timeoutMs, this.requestTimeoutMs);
|
|
803
843
|
const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : 0;
|
|
@@ -872,6 +912,7 @@ class CtmDbOwnerWorkerClient {
|
|
|
872
912
|
this._invalidateRowCursorSources(sourceIds, { all: sourceIds.length === 0 });
|
|
873
913
|
}
|
|
874
914
|
this._status.pendingClientRequests = this._pending.size;
|
|
915
|
+
this._requestsPerMinute.recordOutcome(op, 'error');
|
|
875
916
|
reject(_abortError(options.signal));
|
|
876
917
|
};
|
|
877
918
|
this._pending.get(requestId).abortHandler = abortHandler;
|
|
@@ -975,6 +1016,10 @@ class CtmDbOwnerWorkerClient {
|
|
|
975
1016
|
workSignal: this._workSignal.snapshot(),
|
|
976
1017
|
ingestAdmission: this._ingestAdmissionSignal.snapshot(),
|
|
977
1018
|
opQuarantine: this._opQuarantine.snapshot(),
|
|
1019
|
+
// WP-0 M-5 (§3.5): the last 30 one-minute request buckets, oldest first. Reaches
|
|
1020
|
+
// perf-summary (lib/perf-summary.js:196 passes this whole status through as
|
|
1021
|
+
// workers.dbOwner) and the diagnostics routes with no change to either.
|
|
1022
|
+
requestsPerMinute: this._requestsPerMinute.snapshot(),
|
|
978
1023
|
lastStatusAt: this._lastStatusAt,
|
|
979
1024
|
dbPath: this.dbPath,
|
|
980
1025
|
resourceLimits: { ...this.resourceLimits },
|
|
@@ -1062,6 +1107,9 @@ class CtmDbOwnerWorkerClient {
|
|
|
1062
1107
|
if (pending.abortHandler) {
|
|
1063
1108
|
pending.signal?.removeEventListener?.('abort', pending.abortHandler);
|
|
1064
1109
|
}
|
|
1110
|
+
// WP-0 M-5: the request settled on the worker's reply (or on a postMessage failure) —
|
|
1111
|
+
// attribute it to the op the client recorded at request() time.
|
|
1112
|
+
this._requestsPerMinute.recordOutcome(pending.op, error ? _requestCountOutcome(error) : 'ok');
|
|
1065
1113
|
if (error) {
|
|
1066
1114
|
const err = error instanceof Error ? error : new Error(String(error.message || error || 'DB owner worker request failed'));
|
|
1067
1115
|
if (error.code) err.code = error.code;
|
|
@@ -1181,6 +1229,9 @@ class CtmDbOwnerWorkerClient {
|
|
|
1181
1229
|
if (req.abortHandler) {
|
|
1182
1230
|
req.signal?.removeEventListener?.('abort', req.abortHandler);
|
|
1183
1231
|
}
|
|
1232
|
+
// WP-0 M-5: a worker death / recycle / close rejects work the client had already
|
|
1233
|
+
// accepted — "refused: not running", the other half of the storm's refusals.
|
|
1234
|
+
this._requestsPerMinute.recordOutcome(req.op, 'refused');
|
|
1184
1235
|
req.reject(err);
|
|
1185
1236
|
}
|
|
1186
1237
|
}
|
|
@@ -1355,4 +1406,7 @@ module.exports = {
|
|
|
1355
1406
|
requestOnActiveDbOwner,
|
|
1356
1407
|
getActiveClientForDbPath,
|
|
1357
1408
|
startParentWedgeWatchdog,
|
|
1409
|
+
// WP-0 M-5: exported so the ring/key-bound/flag behaviour can be unit-tested with an
|
|
1410
|
+
// injected clock (the client itself spawns a worker and has no time injection).
|
|
1411
|
+
DbOwnerRequestsPerMinute,
|
|
1358
1412
|
};
|
|
@@ -40,6 +40,11 @@ const SCHEMA_SOURCE_FILES = Object.freeze([
|
|
|
40
40
|
'lib/migrations/v53-session-model-intent.js',
|
|
41
41
|
'lib/migrations/v54-session-lead-model.js',
|
|
42
42
|
'lib/migrations/v56-host-samples-and-machine-pool.js',
|
|
43
|
+
'lib/migrations/v57-delegate-pref-mirror-opencode.js',
|
|
44
|
+
'lib/migrations/v58-subagent-launch-native-subagents.js',
|
|
45
|
+
'lib/migrations/v59-coding-session-model-state-dsh.js',
|
|
46
|
+
'lib/migrations/v60-delegate-pref-mirror-dsh.js',
|
|
47
|
+
'lib/migrations/v61-conversation-item-clock.js', // shared-memory WP-5: conversation replica clock
|
|
43
48
|
'lib/migrations/v29-usage-accounting.js', 'lib/migrations/v30-usage-reporting.js', 'lib/migrations/v36-conversation-projection-deletes.js',
|
|
44
49
|
'../shared/usage-store.js', '../shared/usage-reporting-schema.js',
|
|
45
50
|
'lib/delete-ctm-session-saga.js',
|
|
@@ -165,8 +165,12 @@ function captureDeferredRestoreLaunchOwnership(sourceSession) {
|
|
|
165
165
|
if (Object.hasOwn(launchContext, 'providerThreadId') && launchContext.providerThreadId !== null
|
|
166
166
|
&& !sourceThreadIdentities(sourceSession, recipe).has(launchContext.providerThreadId)) return null;
|
|
167
167
|
}
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
// §5 D-7: a session whose launch environment the host could not capture parks as unavailable, not as a
|
|
169
|
+
// captured environment re-read off a roots-only override set. Every other state keeps today's capture.
|
|
170
|
+
const launchEnvironment = sourceSession._launchEnvOverridesCaptureState === 'unavailable'
|
|
171
|
+
? Object.freeze({ state: 'unavailable', values: null })
|
|
172
|
+
: capturePrivateSourceEnvironment(
|
|
173
|
+
Object.hasOwn(sourceSession, '_launchEnvOverrides') ? sourceSession._launchEnvOverrides : null);
|
|
170
174
|
const leadRoute = sourceSession.lead_route && typeof sourceSession.lead_route === 'object'
|
|
171
175
|
? copyCapturedData(sourceSession.lead_route, copyState) : null;
|
|
172
176
|
const leadRouteTokenOwnership = sourceSession._leadRouteTokenOwnership
|
|
@@ -989,6 +989,10 @@ const FEATURES = [
|
|
|
989
989
|
{ id: "ctm_ctm_opencode_import_slice_size", env: "CTM_OPENCODE_IMPORT_SLICE_SIZE", owner: "ctm-core-team", stage: "ops", tunable: true, default: 1, since: "2026-08-24", expires: null, note: "numeric tunable" },
|
|
990
990
|
// numeric-tunable suffix/read shape; 1 site(s); first: server.js:9929
|
|
991
991
|
{ id: "ctm_ctm_opencode_import_worker_timeout_ms", env: "CTM_OPENCODE_IMPORT_WORKER_TIMEOUT_MS", owner: "ctm-core-team", stage: "ops", tunable: true, default: 5, since: "2026-08-24", expires: null, note: "numeric tunable" },
|
|
992
|
+
// spawn-env carrier for the OpenCode 1.x switch relaunch (WP-5); 1 site(s); first: lib/opencode-v1-plugin/model-carrier.mjs:19
|
|
993
|
+
{ id: "ctm_ctm_opencode_switch_model", env: "CTM_OPENCODE_SWITCH_MODEL", owner: "ctm-core-team", stage: "ops", defaultOn: true, since: "2026-10-30", expires: null, note: "genuine config" },
|
|
994
|
+
// spawn-env carrier for the OpenCode 1.x switch relaunch (WP-5); 1 site(s); first: lib/opencode-v1-plugin/model-carrier.mjs:20
|
|
995
|
+
{ id: "ctm_ctm_opencode_switch_session", env: "CTM_OPENCODE_SWITCH_SESSION", owner: "ctm-core-team", stage: "ops", defaultOn: true, since: "2026-10-30", expires: null, note: "genuine config" },
|
|
992
996
|
// !== '0' comparison found; 1 site(s); first: lib/conversation-commit-kernel.js:179
|
|
993
997
|
{ id: "ctm_ctm_order_key_migration", env: "CTM_ORDER_KEY_MIGRATION", owner: "ctm-core-team", stage: "stable", defaultOn: true, since: "2026-08-24", expires: null },
|
|
994
998
|
// !== '0' comparison found; 1 site(s); first: server.js:13369
|