create-walle 0.10.1 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/lib/owner-write-safety.js +135 -0
- package/lib/public-runtime.js +13 -5
- package/lib/release-schema.json +3 -2
- package/lib/runtime-closure-policy.json +6 -4
- package/package.json +1 -1
- package/template/bin/deps-doctor.js +1 -1
- package/template/bin/node-bin.sh +11 -0
- package/template/coding-task-manager/api-prompts.js +10 -22
- package/template/coding-task-manager/bin/claude-hook.js +7 -3
- package/template/coding-task-manager/bin/claude-table-parity.js +307 -0
- package/template/coding-task-manager/bin/conversation-storage-auto-migration-lib.js +16 -1
- package/template/coding-task-manager/bin/conversation-storage-generation-evidence.js +9 -2
- package/template/coding-task-manager/bin/conversation-storage-service-entry-lib.js +16 -1
- package/template/coding-task-manager/bin/conversation-storage-walle-owner.js +247 -0
- package/template/coding-task-manager/bin/ctm-machine-pair.js +160 -0
- package/template/coding-task-manager/bin/lead-wait-census.js +1348 -0
- package/template/coding-task-manager/bin/repair-foreign-clone.js +564 -0
- package/template/coding-task-manager/bin/repair-resume-echo-titles.js +248 -0
- package/template/coding-task-manager/bin/write-lock-bench.js +111 -0
- package/template/coding-task-manager/db.js +705 -286
- package/template/coding-task-manager/git-utils.js +44 -0
- package/template/coding-task-manager/lib/adopted-host-redial.js +4 -0
- package/template/coding-task-manager/lib/agent-presets.js +15 -0
- package/template/coding-task-manager/lib/agent-title-apply.js +88 -0
- package/template/coding-task-manager/lib/agent-title-backfill-read.js +92 -0
- package/template/coding-task-manager/lib/api/host-stats.js +98 -0
- package/template/coding-task-manager/lib/api/ingress.js +35 -12
- package/template/coding-task-manager/lib/api/machine-pairing.js +285 -0
- package/template/coding-task-manager/lib/api/machine-pool.js +307 -0
- package/template/coding-task-manager/lib/api/machines.js +461 -0
- package/template/coding-task-manager/lib/api/misc-ops.js +20 -5
- package/template/coding-task-manager/lib/api/providers.js +53 -6
- package/template/coding-task-manager/lib/api/resume-from-store.js +25 -0
- package/template/coding-task-manager/lib/api/sessions.js +160 -8
- package/template/coding-task-manager/lib/api/transcript-history.js +17 -4
- package/template/coding-task-manager/lib/api/worktrees.js +38 -37
- package/template/coding-task-manager/lib/approval-drift.js +16 -1
- package/template/coding-task-manager/lib/approval-logical-frame.js +5 -1
- package/template/coding-task-manager/lib/approval-scope.js +68 -4
- package/template/coding-task-manager/lib/auth-context.js +32 -2
- package/template/coding-task-manager/lib/auth-rate-limit.js +41 -1
- package/template/coding-task-manager/lib/auth-rules.js +186 -45
- package/template/coding-task-manager/lib/broadcast-serialize.js +2 -1
- package/template/coding-task-manager/lib/browser-session-broker.js +9 -1
- package/template/coding-task-manager/lib/browser-use-adapter.js +33 -2
- package/template/coding-task-manager/lib/claude-markdown-ansi.js +27 -85
- package/template/coding-task-manager/lib/claude-session-title.js +6 -30
- package/template/coding-task-manager/lib/claude-table-layout.js +322 -0
- package/template/coding-task-manager/lib/client-diag-handler.js +5 -0
- package/template/coding-task-manager/lib/codex-config-guard.js +33 -3
- package/template/coding-task-manager/lib/codex-harness-qualification.js +12 -0
- package/template/coding-task-manager/lib/codex-launch-health.js +29 -2
- package/template/coding-task-manager/lib/codex-link-preparation.js +9 -8
- package/template/coding-task-manager/lib/codex-paths.js +2 -1
- package/template/coding-task-manager/lib/coding-agent-models.js +21 -30
- package/template/coding-task-manager/lib/coding-session-model-adapters.js +27 -2
- package/template/coding-task-manager/lib/coding-session-model-projection.js +5 -0
- package/template/coding-task-manager/lib/coding-session-model-runtime.js +1 -2
- package/template/coding-task-manager/lib/coding-session-model-state.js +10 -0
- package/template/coding-task-manager/lib/coding-session-model-sync-state.js +0 -1
- package/template/coding-task-manager/lib/conversation-import/cursor-guard-owner.js +10 -0
- package/template/coding-task-manager/lib/create/resolve-launch-params.js +8 -1
- package/template/coding-task-manager/lib/ctm-boot-lifecycle.js +17 -1
- package/template/coding-task-manager/lib/db-domain-tables.js +7 -0
- package/template/coding-task-manager/lib/db-domains.js +21 -2
- package/template/coding-task-manager/lib/db-owner-op-registry.js +7 -0
- package/template/coding-task-manager/lib/db-schema-source-files.js +1 -0
- package/template/coding-task-manager/lib/feature-manifest.js +1 -1
- package/template/coding-task-manager/lib/fs-watcher.js +3 -2
- package/template/coding-task-manager/lib/harness-history-transition.js +3 -3
- package/template/coding-task-manager/lib/headless-inflight-ops.js +203 -0
- package/template/coding-task-manager/lib/headless-missing-reply.js +42 -0
- package/template/coding-task-manager/lib/headless-term-service.js +55 -17
- package/template/coding-task-manager/lib/host-control-dial.js +167 -0
- package/template/coding-task-manager/lib/host-handoff-orchestrator.js +16 -2
- package/template/coding-task-manager/lib/host-handoff.js +51 -13
- package/template/coding-task-manager/lib/host-health-ledger.js +164 -12
- package/template/coding-task-manager/lib/host-self-truth-watchdog.js +4 -0
- package/template/coding-task-manager/lib/host-stats.js +328 -0
- package/template/coding-task-manager/lib/host-threadpool-evacuation.js +160 -0
- package/template/coding-task-manager/lib/host-threadpool-monitor.js +14 -1
- package/template/coding-task-manager/lib/hosted-input-dispatch.js +203 -0
- package/template/coding-task-manager/lib/hosted-sync-worker.js +113 -5
- package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +4 -0
- package/template/coding-task-manager/lib/instance-manifest-runtime.js +3 -0
- package/template/coding-task-manager/lib/instance-manifest.js +13 -1
- package/template/coding-task-manager/lib/instance-sync-status.js +15 -0
- package/template/coding-task-manager/lib/launch-model-override.js +160 -1
- package/template/coding-task-manager/lib/launch-plan-worker.js +59 -2
- package/template/coding-task-manager/lib/lead-model-switch-runtime.js +57 -4
- package/template/coding-task-manager/lib/lead-model-switch.js +3 -2
- package/template/coding-task-manager/lib/lead-model-transition-store.js +61 -3
- package/template/coding-task-manager/lib/legacy-draft-cancellation-recovery.js +111 -0
- package/template/coding-task-manager/lib/login-tripwire.js +1 -0
- package/template/coding-task-manager/lib/machine-pairing.js +238 -0
- package/template/coding-task-manager/lib/machine-pool.js +409 -0
- package/template/coding-task-manager/lib/machine-registry.js +749 -0
- package/template/coding-task-manager/lib/machine-self.js +66 -0
- package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +52 -4
- package/template/coding-task-manager/lib/media-journal-control-reader.js +473 -0
- package/template/coding-task-manager/lib/media-journal.js +84 -27
- package/template/coding-task-manager/lib/media-store-options.js +43 -15
- package/template/coding-task-manager/lib/migrations/v56-host-samples-and-machine-pool.js +76 -0
- package/template/coding-task-manager/lib/mirror-feed-sanitize.js +12 -3
- package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
- package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
- package/template/coding-task-manager/lib/model-proxy/handoff.js +494 -0
- package/template/coding-task-manager/lib/model-proxy/lead-worker-picks.js +25 -0
- package/template/coding-task-manager/lib/model-proxy/native-lead-listener.js +61 -7
- package/template/coding-task-manager/lib/model-proxy/proxy-cli.js +200 -0
- package/template/coding-task-manager/lib/model-proxy/proxy-instance-record.js +257 -0
- package/template/coding-task-manager/lib/model-proxy/stream-accounting.js +205 -0
- package/template/coding-task-manager/lib/model-proxy/tokens.js +78 -0
- package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
- package/template/coding-task-manager/lib/native-history-control.js +2 -2
- package/template/coding-task-manager/lib/native-lead-settings-client.js +2 -1
- package/template/coding-task-manager/lib/native-lead-tls.js +18 -4
- package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +628 -64
- package/template/coding-task-manager/lib/owner-action-manifest-data.json +14 -0
- package/template/coding-task-manager/lib/painted-row-recorder.js +9 -1
- package/template/coding-task-manager/lib/prompt-submission-contract.js +21 -1
- package/template/coding-task-manager/lib/provider-login-broker.js +192 -9
- package/template/coding-task-manager/lib/provider-login-capture.js +153 -0
- package/template/coding-task-manager/lib/queue-draft-status-overlay.js +36 -0
- package/template/coding-task-manager/lib/raw-codex-history-window.js +5 -3
- package/template/coding-task-manager/lib/read-pool-client.js +5 -2
- package/template/coding-task-manager/lib/read-pool-op-registry.js +10 -1
- package/template/coding-task-manager/lib/recent-catalog-query.js +26 -0
- package/template/coding-task-manager/lib/recent-session-catalog-response.js +9 -0
- package/template/coding-task-manager/lib/remote-command-context.js +12 -0
- package/template/coding-task-manager/lib/remote-command-runtime.js +13 -1
- package/template/coding-task-manager/lib/remote-machine-catalog.js +1062 -0
- package/template/coding-task-manager/lib/remote-machine-create.js +693 -0
- package/template/coding-task-manager/lib/remote-machine-link.js +939 -0
- package/template/coding-task-manager/lib/remote-machine-proxy.js +520 -0
- package/template/coding-task-manager/lib/remote-session-forward.js +306 -0
- package/template/coding-task-manager/lib/remote-submission-status.js +6 -0
- package/template/coding-task-manager/lib/restart-outcome-truth.js +20 -3
- package/template/coding-task-manager/lib/restart-preflight.js +9 -2
- package/template/coding-task-manager/lib/restore-backoff-gate.js +10 -2
- package/template/coding-task-manager/lib/restore-prepare-retry.js +12 -5
- package/template/coding-task-manager/lib/restore-resume-batch.js +22 -1
- package/template/coding-task-manager/lib/resume-blocked-wire.js +62 -1
- package/template/coding-task-manager/lib/resume-cwd.js +13 -0
- package/template/coding-task-manager/lib/resume-from-store.js +12 -1
- package/template/coding-task-manager/lib/resume-origin-facts.js +38 -1
- package/template/coding-task-manager/lib/resume-preflight.js +21 -16
- package/template/coding-task-manager/lib/review-repo-admission.js +39 -6
- package/template/coding-task-manager/lib/review-repo-registry.js +17 -0
- package/template/coding-task-manager/lib/root-delivery-runtime.js +72 -15
- package/template/coding-task-manager/lib/root-delivery-selection.js +37 -1
- package/template/coding-task-manager/lib/root-prompt-admission.js +33 -2
- package/template/coding-task-manager/lib/root-prompt-flow.js +167 -33
- package/template/coding-task-manager/lib/scrollback-archive-store.js +7 -4
- package/template/coding-task-manager/lib/session-analysis-memory.js +2 -0
- package/template/coding-task-manager/lib/session-create/codex-native-provider-gate.js +218 -0
- package/template/coding-task-manager/lib/session-create/codex-resume-exit-classify.js +52 -0
- package/template/coding-task-manager/lib/session-create/delegate-worker.js +95 -6
- package/template/coding-task-manager/lib/session-create/identity.js +20 -1
- package/template/coding-task-manager/lib/session-create/prepared.js +69 -1
- package/template/coding-task-manager/lib/session-create/provider-launch-context.js +77 -0
- package/template/coding-task-manager/lib/session-create/provider-process.js +34 -37
- package/template/coding-task-manager/lib/session-create/response.js +30 -12
- package/template/coding-task-manager/lib/session-create/transcript.js +13 -4
- package/template/coding-task-manager/lib/session-create/worker-continuation.js +43 -1
- package/template/coding-task-manager/lib/session-create/worker-notices.js +94 -5
- package/template/coding-task-manager/lib/session-create/worker-observability.js +99 -7
- package/template/coding-task-manager/lib/session-create/worker-stop.js +11 -3
- package/template/coding-task-manager/lib/session-create/worker-wait-watcher.js +315 -0
- package/template/coding-task-manager/lib/session-geometry-authority-handler.js +10 -1
- package/template/coding-task-manager/lib/session-host-manager.js +152 -206
- package/template/coding-task-manager/lib/session-jobs.js +17 -9
- package/template/coding-task-manager/lib/session-lifecycle.js +18 -0
- package/template/coding-task-manager/lib/session-model-action-preconditions.js +9 -0
- package/template/coding-task-manager/lib/session-resource-sampler.js +19 -9
- package/template/coding-task-manager/lib/session-standup.js +67 -4
- package/template/coding-task-manager/lib/session-status-ledger.js +42 -3
- package/template/coding-task-manager/lib/session-status-runtime.js +45 -1
- package/template/coding-task-manager/lib/session-title-mirror.js +25 -57
- package/template/coding-task-manager/lib/session-transcript-trash.js +8 -1
- package/template/coding-task-manager/lib/startup-pointer-write.js +57 -0
- package/template/coding-task-manager/lib/state-sync/painted-frame-field.js +11 -0
- package/template/coding-task-manager/lib/storage/coding-session-model-store.js +21 -22
- package/template/coding-task-manager/lib/surviving-owner-bootstrap.js +7 -2
- package/template/coding-task-manager/lib/surviving-owner-recovery.js +2 -1
- package/template/coding-task-manager/lib/terminal-draft-http-status.js +25 -0
- package/template/coding-task-manager/lib/transcript-archiver.js +229 -229
- package/template/coding-task-manager/lib/transcript-frame-cache.js +12 -2
- package/template/coding-task-manager/lib/transcript-guard-job.js +55 -4
- package/template/coding-task-manager/lib/transcript-link.js +77 -0
- package/template/coding-task-manager/lib/transcript-manifest-store.js +8 -4
- package/template/coding-task-manager/lib/transcript-source.js +8 -3
- package/template/coding-task-manager/lib/transcript-store.js +40 -0
- package/template/coding-task-manager/lib/tunnel-lane-governor.js +6 -3
- package/template/coding-task-manager/lib/typing-interaction-trace.js +92 -0
- package/template/coding-task-manager/lib/typing-worker-stages.js +60 -0
- package/template/coding-task-manager/lib/visible-revision-watchdog.js +8 -12
- package/template/coding-task-manager/lib/wake-skip-reasons.js +46 -0
- package/template/coding-task-manager/lib/walle-supervisor.js +98 -14
- package/template/coding-task-manager/lib/worker-failure-classify.js +13 -1
- package/template/coding-task-manager/lib/ws/state-sync.js +19 -2
- package/template/coding-task-manager/lib/ws/terminal-attach.js +32 -1
- package/template/coding-task-manager/lib/ws-router.js +68 -1
- package/template/coding-task-manager/lib/ws-send-admission.js +22 -4
- package/template/coding-task-manager/oauth-proxy.js +99 -55
- package/template/coding-task-manager/package-lock.json +24 -0
- package/template/coding-task-manager/package.json +3 -0
- package/template/coding-task-manager/providers/codex-mcp-extract.js +121 -19
- package/template/coding-task-manager/providers/codex-mcp.js +14 -5
- package/template/coding-task-manager/public/css/app.css +279 -1
- package/template/coding-task-manager/public/css/reviews.css +4 -0
- package/template/coding-task-manager/public/index.html +294 -223
- package/template/coding-task-manager/public/js/app/machines-page.js +1252 -0
- package/template/coding-task-manager/public/js/app/models-tab.js +546 -36
- package/template/coding-task-manager/public/js/app/worktrees-panel.js +7 -5
- package/template/coding-task-manager/public/js/background-work.js +13 -7
- package/template/coding-task-manager/public/js/coding-session-model-presentation.js +44 -4
- package/template/coding-task-manager/public/js/core/session-commands.js +676 -0
- package/template/coding-task-manager/public/js/core/session-selectors.js +5 -1
- package/template/coding-task-manager/public/js/history-app-seam.js +26 -2
- package/template/coding-task-manager/public/js/history-painted-rows.js +17 -2
- package/template/coding-task-manager/public/js/history-reader-park.js +13 -1
- package/template/coding-task-manager/public/js/history-scroller.js +187 -9
- package/template/coding-task-manager/public/js/history-transcript-pages.js +5 -5
- package/template/coding-task-manager/public/js/machine-pool-shared.js +436 -0
- package/template/coding-task-manager/public/js/private-state-scope.js +31 -3
- package/template/coding-task-manager/public/js/prompt-submission-client.js +173 -8
- package/template/coding-task-manager/public/js/prompt-submission-tray.js +281 -0
- package/template/coding-task-manager/public/js/queue-panel-submission-reconcile.js +174 -1
- package/template/coding-task-manager/public/js/reviews.js +7 -3
- package/template/coding-task-manager/public/js/root-draft-lifetime.js +139 -2
- package/template/coding-task-manager/public/js/root-queue-builder-lifetime.js +16 -0
- package/template/coding-task-manager/public/js/row-join.js +4 -2
- package/template/coding-task-manager/public/js/session-model-picker.js +1 -1
- package/template/coding-task-manager/public/js/session-search-utils.js +46 -19
- package/template/coding-task-manager/public/js/state-sync-client.js +4 -0
- package/template/coding-task-manager/public/js/terminal/runtime-02.js +16 -7
- package/template/coding-task-manager/public/js/terminal/runtime-03.js +41 -0
- package/template/coding-task-manager/public/js/terminal/runtime-04.js +41 -4
- package/template/coding-task-manager/public/js/terminal/runtime-12.js +52 -2
- package/template/coding-task-manager/public/js/terminal/runtime-16.js +12 -12
- package/template/coding-task-manager/public/js/terminal/runtime-18.js +14 -0
- package/template/coding-task-manager/public/js/terminal/runtime-19.js +8 -4
- package/template/coding-task-manager/public/js/terminal/runtime-20.js +210 -73
- package/template/coding-task-manager/public/js/terminal/runtime-21.js +19 -6
- package/template/coding-task-manager/public/js/terminal/runtime-22.js +86 -0
- package/template/coding-task-manager/public/js/terminal-history-viewport.js +1 -1
- package/template/coding-task-manager/public/js/terminal-wheel.js +39 -2
- package/template/coding-task-manager/public/js/walle/chat-conversation.js +11 -3
- package/template/coding-task-manager/public/js/walle-session.js +30 -7
- package/template/coding-task-manager/public/m/app.css +226 -8
- package/template/coding-task-manager/public/m/app.js +502 -9
- package/template/coding-task-manager/public/m/index.html +38 -1
- package/template/coding-task-manager/public/m/machines.js +1313 -0
- package/template/coding-task-manager/public/m/pool-failover.js +391 -0
- package/template/coding-task-manager/public/m/private-queue-actions.js +26 -7
- package/template/coding-task-manager/public/m/sw.js +5 -0
- package/template/coding-task-manager/queue-engine.js +13 -0
- package/template/coding-task-manager/server/approvals.js +5 -6
- package/template/coding-task-manager/server/boot.js +136 -17
- package/template/coding-task-manager/server.js +902 -239
- package/template/coding-task-manager/session-integrity.js +7 -9
- package/template/coding-task-manager/workers/db-owner-worker.js +53 -7
- package/template/coding-task-manager/workers/read-pool-worker.js +17 -6
- package/template/coding-task-manager/workers/session-host-pool-process.js +18 -4
- package/template/coding-task-manager/workers/session-host-process.js +14 -3
- package/template/coding-task-manager/workers/transcript-archive-worker.js +1 -1
- package/template/coding-task-manager/workers/worktree-worker.js +34 -0
- package/template/package-lock.json +2 -2
- package/template/package.json +1 -1
- package/template/scripts/conversation-storage-v2-migration.js +78 -11
- package/template/shared/conversation-storage-v2-contract.js +42 -6
- package/template/shared/fixtures/worker-status-payloads.json +392 -0
- package/template/shared/git-remote-key.js +83 -0
- package/template/shared/host-identity.js +98 -2
- package/template/shared/owner-write-safety.js +135 -0
- package/template/shared/public-runtime.js +13 -5
- package/template/shared/release-schema.json +3 -2
- package/template/shared/report-citations.js +14 -0
- package/template/shared/sqlite-write-lock.js +361 -223
- package/template/shared/storage/contract.js +35 -3
- package/template/wall-e/agent.js +21 -0
- package/template/wall-e/api-walle.js +5 -0
- package/template/wall-e/bin/brain-purge-legacy-ctm.js +3 -2
- package/template/wall-e/bin/walle-mcp-stdio.js +12 -6
- package/template/wall-e/brain/helper-rules-schema.js +129 -0
- package/template/wall-e/brain/migrations.js +51 -22
- package/template/wall-e/brain/model-deployment-facts.js +31 -1
- package/template/wall-e/brain/owner-call-whitelist.js +16 -0
- package/template/wall-e/brain/schema-ensures.js +22 -0
- package/template/wall-e/brain.js +1 -1
- package/template/wall-e/coding/journal-dispatcher.js +51 -0
- package/template/wall-e/coding/session-journal.js +28 -40
- package/template/wall-e/coding-orchestrator.js +23 -26
- package/template/wall-e/http/auth.js +18 -1
- package/template/wall-e/http/blog-views-api.js +318 -0
- package/template/wall-e/http/helper-rules-api.js +321 -0
- package/template/wall-e/http/model-proxy-providers.js +3 -1
- package/template/wall-e/http/telemetry-api.js +12 -0
- package/template/wall-e/lib/blog-view-policy.js +88 -0
- package/template/wall-e/lib/blog-view-store.js +169 -0
- package/template/wall-e/lib/client-config-lock.js +2 -1
- package/template/wall-e/lib/coding-journal-writer-child-client.js +67 -18
- package/template/wall-e/lib/error-kinds.js +10 -1
- package/template/wall-e/lib/feature-manifest.js +1 -1
- package/template/wall-e/lib/helper-rules/cell-state.js +123 -0
- package/template/wall-e/lib/helper-rules/evaluate.js +357 -0
- package/template/wall-e/lib/helper-rules/explore-rubric.md +12 -0
- package/template/wall-e/lib/helper-rules/grade.js +277 -0
- package/template/wall-e/lib/helper-rules/label.js +247 -0
- package/template/wall-e/lib/helper-rules/lead-call-hook.js +522 -0
- package/template/wall-e/lib/helper-rules/store.js +667 -0
- package/template/wall-e/lib/mcp-integration.js +5 -6
- package/template/wall-e/lib/runtime-worker-pool.js +1 -0
- package/template/wall-e/lib/scheduler-worker-jobs.js +6 -0
- package/template/wall-e/lib/telemetry-db-schema.js +37 -0
- package/template/wall-e/lib/telemetry-process-client.js +76 -1
- package/template/wall-e/llm/default-fallback.js +4 -0
- package/template/wall-e/llm/model-catalog.js +13 -4
- package/template/wall-e/llm/model-roles.js +6 -0
- package/template/wall-e/llm/portkey-http.js +150 -0
- package/template/wall-e/llm/portkey-sync.js +15 -145
- package/template/wall-e/llm/worker-mcp-routing.js +61 -0
- package/template/wall-e/llm/worker-route.js +43 -1
- package/template/wall-e/loops/brain-custom-writes.js +45 -0
- package/template/wall-e/mcp-protocol-contract.js +41 -1
- package/template/wall-e/mcp-server.js +13 -2
- package/template/wall-e/mcp-worker-schemas.js +20 -2
- package/template/wall-e/memory/ctm-context-client.js +25 -5
- package/template/wall-e/shared/release-schema.json +3 -2
- package/template/wall-e/shared/sqlite-write-lock.js +361 -223
- package/template/wall-e/shared/storage/contract.js +35 -3
- package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
- package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +6 -0
- package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +7 -2
- package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +7 -2
- package/template/wall-e/tools/local-tools.js +6 -4
- package/template/wall-e/workers/brain-owner-worker.js +9 -0
- package/template/wall-e/workers/coding-journal-writer-child.js +8 -1
- package/template/wall-e/workers/telemetry-worker.js +8 -0
|
@@ -7,6 +7,12 @@ const admissionDefault = require('../worker-admission');
|
|
|
7
7
|
const { restoreSucceeded } = require('../resume-rung-enrich');
|
|
8
8
|
const transcriptRetention = require('../transcript-retention-check');
|
|
9
9
|
const transcriptSource = require('../transcript-source');
|
|
10
|
+
// WP-2 (D-4/D-7): the derived-transcript-path helper and its verifier (see the preflight at the
|
|
11
|
+
// transcript link below). serverConfig is the same live-read env seam production uses for the
|
|
12
|
+
// Claude config dir (server.js:6743 getClaudeConfigDir).
|
|
13
|
+
const serverConfig = require('../server-config');
|
|
14
|
+
const { deriveClaudeTranscriptPath } = require('../resume-cwd');
|
|
15
|
+
const { verifyClaudeTranscriptAt } = require('../transcript-link');
|
|
10
16
|
const { isColdDeferredSession, notifyWorkerGeneration } = require('./worker-observability');
|
|
11
17
|
const { budgetSentence } = require('./worker-brief');
|
|
12
18
|
const { attachProgressGuard } = require('./worker-progress-guard');
|
|
@@ -533,7 +539,43 @@ function createWorkerContinuation({ getDeps, admission = admissionDefault, helpe
|
|
|
533
539
|
catch {
|
|
534
540
|
return failReceipt('worker_transcript_unavailable', 'The provider transcript link could not be read.', { retryable: true });
|
|
535
541
|
}
|
|
536
|
-
|
|
542
|
+
// WP-2 (D-4, worker-transcript-link-derived-not-discovered-2026-10-25.html §5 D-4/D-7): an
|
|
543
|
+
// empty jsonl_path is "we never recorded the link", not "the transcript is gone". Claude Code
|
|
544
|
+
// writes a session's transcript at a path derivable from (cwd, session id) alone, so derive
|
|
545
|
+
// it, VERIFY it through the one transcript reader (lib/transcript-link.js -- the file's own
|
|
546
|
+
// first line must name this session), link it, and continue. A derived path that verifies
|
|
547
|
+
// false, or a row with no cwd to derive from, refuses exactly as before -- now naming what
|
|
548
|
+
// was checked. Codex rows never enter this branch (their resume identity is the rollout
|
|
549
|
+
// thread, and a missing link there is a different failure).
|
|
550
|
+
let transcriptPath = String(agentRow && agentRow.jsonl_path || '').trim();
|
|
551
|
+
if (!transcriptPath && agentRow && recipe.agent === 'claude') {
|
|
552
|
+
const cwd = String(recipe.cwd || agentRow.project_path || agentRow.cwd || '').trim();
|
|
553
|
+
const providerSessionId = String(agentRow.agent_session_id || id);
|
|
554
|
+
let derived = '';
|
|
555
|
+
try {
|
|
556
|
+
derived = deriveClaudeTranscriptPath({
|
|
557
|
+
cwd,
|
|
558
|
+
agentSessionId: providerSessionId,
|
|
559
|
+
// The house coercion for this dep (lib/session-create/worker-mcp-servers.js:45): production's
|
|
560
|
+
// deps carries no `homedir` at all, and the test corpus injects both a getter and a string.
|
|
561
|
+
homeDir: typeof deps.homedir === 'function' ? deps.homedir() : deps.homedir,
|
|
562
|
+
claudeConfigDir: deps.claudeConfigDir || serverConfig.CLAUDE_CONFIG_DIR || '',
|
|
563
|
+
});
|
|
564
|
+
} catch { /* expected: a row with no cwd (or no agent_session_id) has nothing to derive -- fall through to the unchanged refusal */ }
|
|
565
|
+
if (derived) {
|
|
566
|
+
const verified = await verifyClaudeTranscriptAt(derived, providerSessionId, {
|
|
567
|
+
...(typeof deps.resolveTranscriptSource === 'function' ? { resolveTranscriptSource: deps.resolveTranscriptSource } : {}),
|
|
568
|
+
...(typeof deps.readTranscriptHead === 'function' ? { readTranscriptHead: deps.readTranscriptHead } : {}),
|
|
569
|
+
});
|
|
570
|
+
if (!verified.ok) {
|
|
571
|
+
return failReceipt('worker_transcript_missing', 'The provider transcript is not linked to this worker.', {
|
|
572
|
+
extra: { derived_path: derived, derived_state: verified.state },
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
if (typeof db.updateAgentSessionTranscriptLink === 'function') db.updateAgentSessionTranscriptLink(providerSessionId, derived);
|
|
576
|
+
transcriptPath = derived;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
537
579
|
if (!transcriptPath) return failReceipt('worker_transcript_missing', 'The provider transcript is not linked to this worker.');
|
|
538
580
|
|
|
539
581
|
let providerId = '';
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// A lead hears that its delegated worker stopped through its next PostToolUse / UserPromptSubmit
|
|
4
|
-
// hook
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// hook, and -- RC-1, docs/session-stops-mid-job-2026-10-24.html D-1..D-3 -- through its Stop hook
|
|
5
|
+
// too, which is answered synchronously by CTM with the drained notices plus, when the lead still
|
|
6
|
+
// owns a live worker and nothing pending will wake it, a nudge naming walle_worker_wait /
|
|
7
|
+
// walle_stop_worker. The queue lives here; the durable truth is the terminal receipt's
|
|
8
|
+
// `delivered_at_ms` in worker_sessions.runtime_json, so a CTM restart rebuilds the undelivered
|
|
9
|
+
// notices once per parent. Never types into the lead's terminal (D-5).
|
|
7
10
|
|
|
8
11
|
const mainDbCensus = require('../main-db-census');
|
|
9
12
|
const { nextStepFor } = require('../worker-failure-classify');
|
|
@@ -13,6 +16,88 @@ const MAX_TEXT = 400;
|
|
|
13
16
|
|
|
14
17
|
const _queues = new Map(); // parent ctm id -> [{ receipt_id, worker_id, parent, text, at_ms }]
|
|
15
18
|
|
|
19
|
+
// WP-0 (D-2/D-7): the live-worker index, maintained from the receipts CTM already publishes.
|
|
20
|
+
// Memory only -- the hook path touches no DB, and a CTM restart retires every live worker, so the
|
|
21
|
+
// index starts empty and needs no rebuild.
|
|
22
|
+
const _live = new Map(); // parent ctm id -> Map(worker id -> { generation, at_ms })
|
|
23
|
+
|
|
24
|
+
// WP-1 (D-4): one nudge per tool epoch. `nudgedAtEpoch` starts at `null` so the first Stop
|
|
25
|
+
// (toolEpoch 0) nudges; a second Stop with no PostToolUse between sees toolEpoch === nudgedAtEpoch.
|
|
26
|
+
const _epochs = new Map(); // parent ctm id -> { toolEpoch, nudgedAtEpoch }
|
|
27
|
+
|
|
28
|
+
function _epochFor(parent) {
|
|
29
|
+
let epoch = _epochs.get(parent);
|
|
30
|
+
if (!epoch) { epoch = { toolEpoch: 0, nudgedAtEpoch: null }; _epochs.set(parent, epoch); }
|
|
31
|
+
return epoch;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// D-2: a `started` receipt says this worker is live for its parent until a terminal receipt for the
|
|
35
|
+
// same or a newer generation arrives. No parent or no worker id -> nothing to index.
|
|
36
|
+
function markWorkerLive(receipt) {
|
|
37
|
+
if (!receipt || receipt.kind !== 'started') return null;
|
|
38
|
+
const parent = String(receipt.parent_ctm_session_id || '');
|
|
39
|
+
const workerId = String(receipt.worker_id || '');
|
|
40
|
+
if (!parent || !workerId) return null;
|
|
41
|
+
const generation = Number(receipt.generation) || 1;
|
|
42
|
+
const atMs = Number(receipt.at_ms) || Date.now();
|
|
43
|
+
const map = _live.get(parent) || new Map();
|
|
44
|
+
map.set(workerId, { generation, at_ms: atMs });
|
|
45
|
+
_live.set(parent, map);
|
|
46
|
+
return { worker_id: workerId, generation, at_ms: atMs };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// The terminal receipt retires the worker, but an OLDER generation's terminal must never erase a
|
|
50
|
+
// newer generation's `started` (AC-0c): the remove happens only while stored generation <= receipt
|
|
51
|
+
// generation.
|
|
52
|
+
function markWorkerGone(receipt) {
|
|
53
|
+
const parent = String(receipt?.parent_ctm_session_id || '');
|
|
54
|
+
const workerId = String(receipt?.worker_id || '');
|
|
55
|
+
if (!parent || !workerId) return false;
|
|
56
|
+
const map = _live.get(parent);
|
|
57
|
+
if (!map) return false;
|
|
58
|
+
const entry = map.get(workerId);
|
|
59
|
+
if (entry && Number(entry.generation) > (Number(receipt.generation) || 1)) return false;
|
|
60
|
+
map.delete(workerId);
|
|
61
|
+
if (!map.size) _live.delete(parent);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function liveWorkers(parentCtmSessionId) {
|
|
66
|
+
const parent = String(parentCtmSessionId || '');
|
|
67
|
+
const map = _live.get(parent);
|
|
68
|
+
if (!map || !map.size) return [];
|
|
69
|
+
return [...map.entries()]
|
|
70
|
+
.map(([worker_id, entry]) => ({ worker_id, generation: entry.generation, at_ms: entry.at_ms }))
|
|
71
|
+
.sort((a, b) => a.at_ms - b.at_ms);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function noteLeadToolUse(parentCtmSessionId) {
|
|
75
|
+
const parent = String(parentCtmSessionId || '');
|
|
76
|
+
if (!parent) return null;
|
|
77
|
+
const epoch = _epochFor(parent);
|
|
78
|
+
epoch.toolEpoch += 1;
|
|
79
|
+
return epoch.toolEpoch;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// D-3/D-4: the Stop nudge. Returns null when no worker is live, when a pending background task or
|
|
83
|
+
// session cron will wake the lead anyway, when the field is absent (Claude did not send it --
|
|
84
|
+
// unknown state fails open, never a nudge), or when this tool epoch was already nudged.
|
|
85
|
+
function stopNudge(parentCtmSessionId, { backgroundTasks = null, sessionCrons = null } = {}) {
|
|
86
|
+
const parent = String(parentCtmSessionId || '');
|
|
87
|
+
if (!parent) return null;
|
|
88
|
+
const workers = liveWorkers(parent);
|
|
89
|
+
if (!workers.length) return null;
|
|
90
|
+
if (Array.isArray(backgroundTasks) && backgroundTasks.some((task) => task && task.status === 'running')) return null;
|
|
91
|
+
if (Array.isArray(sessionCrons) && sessionCrons.length) return null;
|
|
92
|
+
if (!Array.isArray(backgroundTasks)) return null;
|
|
93
|
+
const epoch = _epochFor(parent);
|
|
94
|
+
if (epoch.toolEpoch === epoch.nudgedAtEpoch) return null;
|
|
95
|
+
epoch.nudgedAtEpoch = epoch.toolEpoch;
|
|
96
|
+
const firstId = workers[0].worker_id;
|
|
97
|
+
const text = `Delegated worker ${firstId} is still working (${workers.length} live) and nothing pending will wake you when it finishes. Call walle_worker_wait to keep waiting, or walle_stop_worker if you no longer need it. If you are deliberately handing back to your user with the worker still running, say so and end your turn again.`;
|
|
98
|
+
return { text, workers: workers.map((worker) => worker.worker_id) };
|
|
99
|
+
}
|
|
100
|
+
|
|
16
101
|
// D-25: the notice ends with the failure's next_step. The evidence carries it when the
|
|
17
102
|
// publisher stamped it; a receipt stored before that (or filtered by the evidence
|
|
18
103
|
// whitelist) still names the code/class/reason, so the SAME table derives the identical
|
|
@@ -51,6 +136,7 @@ function noticeText(receipt) {
|
|
|
51
136
|
function enqueueNotice(receipt) {
|
|
52
137
|
const parent = String(receipt?.parent_ctm_session_id || '');
|
|
53
138
|
if (!parent || receipt.kind !== 'terminal' || !receipt.receipt_id) return null;
|
|
139
|
+
markWorkerGone(receipt);
|
|
54
140
|
const notice = { receipt_id: receipt.receipt_id, worker_id: String(receipt.worker_id || ''), parent, text: noticeText(receipt), at_ms: Number(receipt.at_ms) || Date.now() };
|
|
55
141
|
const queue = _queues.get(parent) || [];
|
|
56
142
|
if (!queue.some((n) => n.receipt_id === notice.receipt_id)) queue.push(notice);
|
|
@@ -132,6 +218,9 @@ function drainNotices(parentCtmSessionId, { now = Date.now(), dbModule = null, d
|
|
|
132
218
|
};
|
|
133
219
|
}
|
|
134
220
|
|
|
135
|
-
function _resetForTest() { _queues.clear(); }
|
|
221
|
+
function _resetForTest() { _queues.clear(); _live.clear(); _epochs.clear(); }
|
|
136
222
|
|
|
137
|
-
module.exports = {
|
|
223
|
+
module.exports = {
|
|
224
|
+
enqueueNotice, rebuildFromDb, drainNotices, noticeText,
|
|
225
|
+
markWorkerLive, liveWorkers, noteLeadToolUse, stopNudge, _resetForTest,
|
|
226
|
+
};
|
|
@@ -4,7 +4,8 @@ const path = require('path');
|
|
|
4
4
|
const { captureWorkerProgress } = require('./worker-progress');
|
|
5
5
|
const { classifyFailure } = require('../worker-failure-classify');
|
|
6
6
|
const { terminalBudgetFailure, budgetEvidence } = require('../model-proxy/request-budget');
|
|
7
|
-
const { enqueueNotice } = require('./worker-notices');
|
|
7
|
+
const { enqueueNotice, markWorkerLive } = require('./worker-notices');
|
|
8
|
+
const { startWaitWatcher } = require('./worker-wait-watcher');
|
|
8
9
|
|
|
9
10
|
const PROGRESS_CACHE_MS = 5000;
|
|
10
11
|
const EVENT_RECEIPT_LIMIT = 32;
|
|
@@ -13,6 +14,10 @@ const NO_WRITE_ADVISORY_TURN_THRESHOLD = 20;
|
|
|
13
14
|
const NO_WRITE_TERMINAL_TURN_THRESHOLD = 40;
|
|
14
15
|
const EVENT_PRECEDENCE = { started: 0, progress: 1, advisory: 2, terminal: 3 };
|
|
15
16
|
const WORKER_FINAL_RESULT_CAP_BYTES = 64 * 1024;
|
|
17
|
+
// Lead-cost routing round 2 D-3 (§6.2): the ONE report-text byte cap, shared by the status reader
|
|
18
|
+
// (delegate-worker.js counts citations from the bounded text) and the ?include_report=1 reader
|
|
19
|
+
// (lib/api/sessions.js). Same 64 KiB as the final-result cap.
|
|
20
|
+
const WORKER_REPORT_TEXT_CAP_BYTES = 64 * 1024;
|
|
16
21
|
const FILE_PROBE_TTL_MS = 2000;
|
|
17
22
|
const THROTTLED_WINDOW_MS = 60000;
|
|
18
23
|
|
|
@@ -89,10 +94,17 @@ function _removeWaiterRegistration(waiter, ctmSessionId) {
|
|
|
89
94
|
if (!set.size) _waiters.delete(ctmSessionId);
|
|
90
95
|
}
|
|
91
96
|
const _liveWaiters = new Set(); // every not-yet-resolved waiter, once each (waiterCount counts waiters, not registrations)
|
|
92
|
-
function _finishWaiter(waiter, why, workerId) {
|
|
97
|
+
function _finishWaiter(waiter, why, workerId, detail) {
|
|
93
98
|
if (waiter.done) return;
|
|
94
99
|
waiter.done = true;
|
|
95
100
|
clearTimeout(waiter.timer);
|
|
101
|
+
// WP-1 (D-3): a resolved waiter stops its watcher first, so a late model reply is dropped
|
|
102
|
+
// (stop() marks the watcher dead) and no interval timer outlives the wait.
|
|
103
|
+
if (waiter.watch) {
|
|
104
|
+
try { waiter.watch.stop(); }
|
|
105
|
+
catch { /* expected: a watcher stop failure never blocks the resolve */ }
|
|
106
|
+
waiter.watch = null;
|
|
107
|
+
}
|
|
96
108
|
for (const id of waiter.watchedIds) _removeWaiterRegistration(waiter, id);
|
|
97
109
|
_liveWaiters.delete(waiter);
|
|
98
110
|
if (waiter.onHumanSubmit) {
|
|
@@ -100,9 +112,16 @@ function _finishWaiter(waiter, why, workerId) {
|
|
|
100
112
|
humanInputEvents.removeListener('humanSubmit', waiter.onHumanSubmit);
|
|
101
113
|
waiter.onHumanSubmit = null;
|
|
102
114
|
}
|
|
103
|
-
|
|
115
|
+
const result = { why, workerId: workerId != null ? workerId : null };
|
|
116
|
+
// WP-1: the watcher's own result fields exist only on a waiter that ran one -- a caller with
|
|
117
|
+
// no watcher sees exactly today's `{ why, workerId }` shape.
|
|
118
|
+
if (waiter.decisions) {
|
|
119
|
+
result.detail = detail || null;
|
|
120
|
+
result.decisions = waiter.decisions;
|
|
121
|
+
}
|
|
122
|
+
waiter.resolve(result);
|
|
104
123
|
}
|
|
105
|
-
function waitForWorkers({ workerIds, leadId, waitMs, generationById } = {}) {
|
|
124
|
+
function waitForWorkers({ workerIds, leadId, waitMs, generationById, watchMode, callModel, getStatus, readTail, workerRoute } = {}) {
|
|
106
125
|
const ids = Array.isArray(workerIds) ? workerIds.map((id) => String(id || '')).filter(Boolean) : [];
|
|
107
126
|
if (!ids.length) {
|
|
108
127
|
// No watched workers: the wait is still meaningful for a lead (a user_input wake with no
|
|
@@ -111,7 +130,7 @@ function waitForWorkers({ workerIds, leadId, waitMs, generationById } = {}) {
|
|
|
111
130
|
const empty = { generationById: {} };
|
|
112
131
|
return waitForWorkersWithListener([], leadId, waitMs, empty);
|
|
113
132
|
}
|
|
114
|
-
return waitForWorkersWithListener(ids, leadId, waitMs, { generationById });
|
|
133
|
+
return waitForWorkersWithListener(ids, leadId, waitMs, { generationById, watchMode, callModel, getStatus, readTail, workerRoute });
|
|
115
134
|
}
|
|
116
135
|
function waitForWorkersWithListener(ids, leadId, waitMs, state) {
|
|
117
136
|
let release = () => {};
|
|
@@ -124,7 +143,7 @@ function waitForWorkersWithListener(ids, leadId, waitMs, state) {
|
|
|
124
143
|
done: false,
|
|
125
144
|
resolve,
|
|
126
145
|
};
|
|
127
|
-
const finish = (why, workerId) => _finishWaiter(waiter, why, workerId);
|
|
146
|
+
const finish = (why, workerId, detail) => _finishWaiter(waiter, why, workerId, detail);
|
|
128
147
|
waiter.finish = finish;
|
|
129
148
|
waiter.timer = setTimeout(() => finish('timeout'), Math.max(0, Number(waitMs) || 0));
|
|
130
149
|
if (typeof waiter.timer.unref === 'function') waiter.timer.unref();
|
|
@@ -142,12 +161,64 @@ function waitForWorkersWithListener(ids, leadId, waitMs, state) {
|
|
|
142
161
|
humanInputEvents.on('humanSubmit', waiter.onHumanSubmit);
|
|
143
162
|
}
|
|
144
163
|
release = () => finish('timeout');
|
|
164
|
+
// WP-1 (D-3/D-4): the watcher parks BESIDE the waiter -- one tick per watched worker, the
|
|
165
|
+
// worker's own pinned model, and a `watcher`/`watcher_unavailable` wake through the same
|
|
166
|
+
// finish gate as every code wake. It is started only when the caller wired one (a caller
|
|
167
|
+
// with no watchMode/callModel keeps today's behaviour untouched).
|
|
168
|
+
if (ids.length && state.watchMode !== 'off' && typeof state.callModel === 'function') {
|
|
169
|
+
waiter.decisions = [];
|
|
170
|
+
waiter.watch = startWaitWatcher({
|
|
171
|
+
workerIds: ids,
|
|
172
|
+
mode: state.watchMode || 'on',
|
|
173
|
+
wake: (why, detail) => finish(why, detail && detail.worker_id, detail),
|
|
174
|
+
onDecision: (d) => waiter.decisions.push(d),
|
|
175
|
+
callModel: state.callModel,
|
|
176
|
+
getStatus: state.getStatus,
|
|
177
|
+
readTail: state.readTail,
|
|
178
|
+
workerRoute: state.workerRoute,
|
|
179
|
+
}) || null;
|
|
180
|
+
}
|
|
145
181
|
// F1: a waiter registered before the caller knows a worker's current generation (undefined
|
|
146
182
|
// wakes on any generation notice) is narrowed per worker once the first status read lands.
|
|
147
183
|
setGeneration = (workerId, value) => { if (!waiter.done) waiter.generationByCtmId.set(String(workerId), value); };
|
|
148
184
|
});
|
|
149
185
|
return { promise, release, setGeneration };
|
|
150
186
|
}
|
|
187
|
+
|
|
188
|
+
// WP-1 (D-3): the watcher's PRODUCTION model call. It rides the lane every other CTM
|
|
189
|
+
// background completion uses (lib/background-llm.js -> Wall-E's background-completion
|
|
190
|
+
// endpoint), so the resolved provider, the fallback chain and the circuit breakers stay the
|
|
191
|
+
// routing authority's and CTM builds no provider client of its own. The pin is the caller's
|
|
192
|
+
// `model` (the worker row's own route_alias + ':' + model, never a second route).
|
|
193
|
+
// A failure -- transport, an unroutable pin (route_throttled / route_unavailable /
|
|
194
|
+
// model_not_found), or a non-2xx decision -- answers `{ ok: false, error }`, which is exactly
|
|
195
|
+
// what the watcher's D-4 consecutive-failure counter reads.
|
|
196
|
+
function createWaitWatcherCallModel() {
|
|
197
|
+
return async function callWaitWatcherModel({ feature, model, system, messages, maxTokens, timeoutMs, sessionId }) {
|
|
198
|
+
let llm;
|
|
199
|
+
try {
|
|
200
|
+
llm = require('../background-llm');
|
|
201
|
+
// D-4: the watcher never takes a second route. background-llm's last-ditch Ollama hop
|
|
202
|
+
// fires on a Wall-E transport error unless the fallback setting is off, so this call
|
|
203
|
+
// carries an env copy with it off -- a transport failure is then `{ ok: false }` and the
|
|
204
|
+
// consecutive-failure counter ends the watcher with `watcher_unavailable`.
|
|
205
|
+
const env = { ...process.env, CTM_BACKGROUND_LLM_FALLBACK_PROVIDER: 'off' };
|
|
206
|
+
// WP-4a (D-9): the tick's `sessionId` is the watched worker's ctm_session_id (WP-1's
|
|
207
|
+
// per-worker tick). background-llm.js forwards it into the POST body only when it is a
|
|
208
|
+
// non-empty string, and Wall-E's ledger then keys the row by it -- so the cell's watcher
|
|
209
|
+
// spend is exactly the ledger rows of that cell's own workers.
|
|
210
|
+
const reply = await llm.callBackgroundLlm(messages, {
|
|
211
|
+
task: feature, model, system, maxTokens, timeoutMs, env,
|
|
212
|
+
...(typeof sessionId === 'string' && sessionId ? { sessionId } : {}),
|
|
213
|
+
});
|
|
214
|
+
const text = typeof reply?.text === 'string' ? reply.text : llm.extractBackgroundLlmText(reply);
|
|
215
|
+
return { ok: true, text };
|
|
216
|
+
} catch (error) {
|
|
217
|
+
return { ok: false, error: String((error && (error.code || error.message)) || 'watch_call_failed').slice(0, 200) };
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
151
222
|
// D-7: a route waiter is the same record shape in the same `_waiters` registry, under the key
|
|
152
223
|
// `route:<alias>`. Timer = min(waitMs, remaining hold) when the snapshot has a horizon, else waitMs.
|
|
153
224
|
// The registration/wake checks read snapshot() (never admit()) so a wait is never counted as a refusal.
|
|
@@ -634,6 +705,10 @@ function createWorkerObservability({ getDeps, readWorkerRuntime, getBaseStatus }
|
|
|
634
705
|
try { enqueueNotice(receipt); } catch { /* expected: the lead's hook notice is best-effort; walle_worker_wait and the sentinel still report */ }
|
|
635
706
|
_wakeWaiters(ctmSessionId, 'terminal');
|
|
636
707
|
auditScopeAtTerminal(ctmSessionId).catch((error) => reportObservationFailure(deps, ctmSessionId, error));
|
|
708
|
+
} else if (kind === 'started') {
|
|
709
|
+
// WP-0 (D-2): the live-worker index is maintained beside the notice queue from the same
|
|
710
|
+
// receipts. Memory only, so a failure here can never affect the receipt's persistence.
|
|
711
|
+
try { markWorkerLive(receipt); } catch { /* expected: the live index is best-effort; the notice queue and walle_worker_wait still report */ }
|
|
637
712
|
}
|
|
638
713
|
return receipt;
|
|
639
714
|
}
|
|
@@ -911,8 +986,22 @@ function withIncompleteStreams(runtime, requestBudget) {
|
|
|
911
986
|
return { ...requestBudget, incomplete_streams: count, incomplete_stream_ms: ms };
|
|
912
987
|
}
|
|
913
988
|
|
|
989
|
+
// D-1 (session-stops-followups-2026-10-24.html): the terminal statuses a LIVE payload can carry.
|
|
990
|
+
// The DB-row readers in lib/api/sessions.js keep their own copy (_WORKER_TERMINAL_STATUSES):
|
|
991
|
+
// a row's terminal_status is written only at a real exit, so it can never be provisional.
|
|
992
|
+
const WORKER_TERMINAL_STATUSES = new Set(['report_ready', 'failed', 'exited']);
|
|
993
|
+
|
|
994
|
+
/** D-1: a status payload is final when it is terminal AND not a report written while the process
|
|
995
|
+
* is still alive (delegate-worker.js report_provisional). An absent field is final, so DB rows
|
|
996
|
+
* and fixtures keep today's meaning.
|
|
997
|
+
* @param {{status?: string, report_provisional?: boolean}|null|undefined} status
|
|
998
|
+
* @returns {boolean} */
|
|
999
|
+
function isFinalWorkerStatus(status) {
|
|
1000
|
+
return !!status && WORKER_TERMINAL_STATUSES.has(status.status) && status.report_provisional !== true;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
914
1003
|
function pollAfterMs({ status, requestBudget } = {}) {
|
|
915
|
-
if (
|
|
1004
|
+
if (isFinalWorkerStatus(status)
|
|
916
1005
|
|| (status?.exitCode !== null && status?.exitCode !== undefined)) return 0;
|
|
917
1006
|
const p50 = requestBudget?.requestDurationP50Ms;
|
|
918
1007
|
if (!Number.isInteger(p50) || p50 <= 0) return 30000;
|
|
@@ -921,6 +1010,8 @@ function pollAfterMs({ status, requestBudget } = {}) {
|
|
|
921
1010
|
|
|
922
1011
|
module.exports = {
|
|
923
1012
|
waitForWorkerChange, waitForWorkerChangeHandle, waitForWorkers, notifyWorkerGeneration, notifyWorkerAdvisory, waiterCount, waitForRouteClear, _resetRouteSubscriptionsForTest,
|
|
1013
|
+
createWaitWatcherCallModel,
|
|
1014
|
+
isFinalWorkerStatus,
|
|
924
1015
|
pollAfterMs,
|
|
925
1016
|
withIncompleteStreams,
|
|
926
1017
|
createWorkerObservability,
|
|
@@ -940,6 +1031,7 @@ module.exports = {
|
|
|
940
1031
|
computeExitFailure,
|
|
941
1032
|
boundedWorkerText,
|
|
942
1033
|
isColdDeferredSession,
|
|
1034
|
+
WORKER_REPORT_TEXT_CAP_BYTES,
|
|
943
1035
|
THROTTLED_WINDOW_MS,
|
|
944
1036
|
EVENT_RECEIPT_LIMIT,
|
|
945
1037
|
NO_WRITE_ADVISORY_TURN_THRESHOLD,
|
|
@@ -65,9 +65,17 @@ async function stopWorkerSession(ctmSessionId, { mode = 'after_turn', reason = '
|
|
|
65
65
|
return refuse('worker_not_owned', 403, id, { message: 'Only the lead that created this worker can stop it.', next_step: nextStepFor({ code: 'worker_not_owned' }) });
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
// WP-2 (worker-terminal-stamp-durable 2026-10-26 D-2/D-3): a dead process with an unstamped row is repaired first,
|
|
69
|
+
// so the verb below answers the truth (already_terminal), never 'stopping' on a process that no longer exists.
|
|
70
|
+
let repaired = null;
|
|
71
|
+
if (typeof helpers.repairExitedWorkerRow === 'function') {
|
|
72
|
+
try { repaired = helpers.repairExitedWorkerRow(id) || null; } catch { repaired = null; /* expected: a repair that throws leaves the row as read; the stop proceeds on the row's own truth */ }
|
|
73
|
+
if (repaired) { try { row = deps.dbModule.getWorkerSession(id) || row; } catch { /* expected: keep the row already read */ } }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 4. idempotent on a terminal worker -- or on a repaired one whose stamp is still riding the WP-1 retry (D-3: never 'stopping' for a dead process)
|
|
77
|
+
if (repaired || row.terminal_at || TERMINAL_STATUSES.includes(String(row.terminal_status || ''))) {
|
|
78
|
+
return refuse('already_terminal', 200, id, { terminal_status: row.terminal_status || '', generation: Number(row.generation || 1), status: 'terminal', repaired });
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
// 5. the stop record: journaled by the proxy for a proxied worker, on the row for a proxyless one
|