create-walle 0.10.0 → 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 +88 -41
- 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 +7 -5
- package/package.json +10 -4
- 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/capture-codex-rollout-records.js +417 -0
- package/template/coding-task-manager/bin/census-codex-lead-history.js +325 -0
- 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/seam-replay-codex.js +301 -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 +25 -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-history-terminal-renderer.js +33 -33
- 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-local-links.js +267 -0
- package/template/coding-task-manager/lib/codex-markdown-lists.js +160 -0
- package/template/coding-task-manager/lib/codex-native-history-prefix.js +4 -0
- package/template/coding-task-manager/lib/codex-paths.js +2 -1
- package/template/coding-task-manager/lib/codex-source-handoff.js +186 -0
- 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-owner-worker-client.js +22 -0
- package/template/coding-task-manager/lib/db-schema-source-files.js +1 -0
- package/template/coding-task-manager/lib/feature-manifest.js +1 -3
- package/template/coding-task-manager/lib/fs-watcher.js +3 -2
- package/template/coding-task-manager/lib/harness-history-transition.js +41 -14
- 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 +60 -23
- package/template/coding-task-manager/lib/history-transition-read-op.js +179 -23
- 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/kernel/diag-log.js +12 -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-observer.js +17 -2
- package/template/coding-task-manager/lib/lead-model-switch-runtime.js +57 -4
- package/template/coding-task-manager/lib/lead-model-switch.js +11 -2
- package/template/coding-task-manager/lib/lead-model-transition-runtime.js +42 -4
- 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 +18 -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 +56 -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-execution-recipe-metadata.js +16 -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/collaboration-codec.js +94 -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/responses-face.js +24 -2
- 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 +62 -14
- 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-admission-trace.js +69 -0
- 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/raw-history-block.js +3 -1
- package/template/coding-task-manager/lib/read-pool-client.js +36 -24
- package/template/coding-task-manager/lib/read-pool-op-registry.js +10 -1
- package/template/coding-task-manager/lib/read-pool-telemetry.js +14 -5
- 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 +18 -5
- 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 +43 -11
- package/template/coding-task-manager/lib/root-prompt-flow.js +175 -38
- package/template/coding-task-manager/lib/scrollback-archive-store.js +7 -4
- package/template/coding-task-manager/lib/server-memory-sampler-runtime.js +10 -0
- package/template/coding-task-manager/lib/server-memory-sampler.js +41 -2
- 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 +38 -39
- 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 +20 -50
- package/template/coding-task-manager/lib/session-model-action-preconditions.js +68 -3
- package/template/coding-task-manager/lib/session-resource-sampler.js +67 -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-status.js +2 -2
- 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 +136 -2
- package/template/coding-task-manager/lib/typing-worker-stages.js +208 -1
- package/template/coding-task-manager/lib/usage-ledger/claude-parse.js +53 -2
- package/template/coding-task-manager/lib/usage-ledger/ingest.js +13 -4
- package/template/coding-task-manager/lib/usage-ledger/read.js +14 -0
- package/template/coding-task-manager/lib/usage-ledger/schema.js +49 -1
- package/template/coding-task-manager/lib/usage-ledger/store.js +337 -6
- package/template/coding-task-manager/lib/usage-ledger/task-read.js +123 -5
- 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/input.js +1 -0
- 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/protocol/message-table.json +0 -10
- package/template/coding-task-manager/protocol/messages.js +0 -10
- package/template/coding-task-manager/protocol/ws-schema.json +0 -20
- package/template/coding-task-manager/protocol/ws-schema.md +0 -2
- 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 -2
- package/template/coding-task-manager/public/css/reviews.css +4 -0
- package/template/coding-task-manager/public/index.html +297 -240
- 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/client-health-core.js +81 -0
- package/template/coding-task-manager/public/js/client-health-main.js +61 -0
- 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 -4
- package/template/coding-task-manager/public/js/prompt-submission-tray.js +281 -0
- package/template/coding-task-manager/public/js/protocol.js +0 -10
- 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 +18 -3
- 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/session-usage-view.js +1 -0
- 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 -3
- 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 +964 -425
- 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/host-capabilities.js +2 -2
- 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/fly.toml +1 -1
- 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 +12 -5
- 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
- package/template/coding-task-manager/lib/giant-freeze-park.js +0 -31
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// native-same-thread-model-switch / §6.5: the PRIVATE launch capture a rollback recovery replays.
|
|
4
|
+
// It is recorded for EVERY native harness whose `recoverSource` can resume the same canonical
|
|
5
|
+
// thread -- Codex AND Claude -- because this capture is the only proof of THIS spawn's
|
|
6
|
+
// executable/argv/cwd/home/generation. It is taken from the prepared launch plan at the REAL
|
|
7
|
+
// spawn (never synthesized later from mutable session fields), and every field is a copy: the
|
|
8
|
+
// argv array is cloned, so a later `session.args` rewrite cannot edit the receipt.
|
|
9
|
+
// WP-0b: extracted verbatim from provider-process.js (same spawn point) so that file stays under
|
|
10
|
+
// the file-size ceiling; behavior is unchanged. The existing Codex receipt dependency is called
|
|
11
|
+
// once as before; this adds no reader, state, or credential copy.
|
|
12
|
+
|
|
13
|
+
const path = require('node:path');
|
|
14
|
+
const { strFlag } = require('../env-flags');
|
|
15
|
+
|
|
16
|
+
// Explicit launch inputs (never the whole process env): the prepared plan, the caller's argv/cwd,
|
|
17
|
+
// the ACTUAL spawn env, the recipe/generation the launch was prepared with, the Codex config
|
|
18
|
+
// receipt already read for this spawn, and the existing codex-paths dependency (no extra read).
|
|
19
|
+
// Returns `null` for a harness with no same-canonical-thread rollout to resume.
|
|
20
|
+
function buildModelTransitionLaunchContext({ agentType, preparedLaunchPlan, cmd, args, cwd, spawnEnv,
|
|
21
|
+
serverHome, executionRecipe, processGeneration, nativeConfigReceipt = null, codexPaths = null }) {
|
|
22
|
+
if (agentType !== 'codex' && agentType !== 'claude') return null;
|
|
23
|
+
const capturedHome = spawnEnv.HOME || serverHome || null;
|
|
24
|
+
const capturedTmpDir = typeof spawnEnv.TMPDIR === 'string' && path.isAbsolute(spawnEnv.TMPDIR)
|
|
25
|
+
? spawnEnv.TMPDIR : null;
|
|
26
|
+
if (agentType === 'claude') {
|
|
27
|
+
// A native Claude launch claims NO Codex receipt/config: `codexHome`, `nativeStorageRootReceipt`
|
|
28
|
+
// and `nativeConfigReceipt` (read from the Codex `config.toml`) are explicitly null, so a
|
|
29
|
+
// rollback can never mistake this capture for a Codex one. The configured storage root is the
|
|
30
|
+
// Claude `projects/` dir under the ACTUAL `CLAUDE_CONFIG_DIR` (else `HOME/.claude`) and stays
|
|
31
|
+
// null when neither is known. The canonical thread is this launch's OWN recipe thread --
|
|
32
|
+
// computed by `launchProviderThreadId` from the resume plan, an injected/explicit
|
|
33
|
+
// `--session-id` and the caller's argv -- never inferred from the CTM session id, and left
|
|
34
|
+
// null (a fail-closed refusal in `recoverSource`) when the identity is unknown.
|
|
35
|
+
// A blank child CLAUDE_CONFIG_DIR falls back to that child's HOME/.claude, never the parent's
|
|
36
|
+
// config root. Codex keeps its CTM_CODEX_SESSIONS_DIR fallback below, unchanged.
|
|
37
|
+
const claudeConfigDir = spawnEnv.CLAUDE_CONFIG_DIR
|
|
38
|
+
|| (capturedHome ? path.join(capturedHome, '.claude') : null);
|
|
39
|
+
return {
|
|
40
|
+
executablePath: preparedLaunchPlan?.cmd || cmd,
|
|
41
|
+
args: Array.isArray(preparedLaunchPlan?.args) ? [...preparedLaunchPlan.args] : [...args],
|
|
42
|
+
workingDirectory: preparedLaunchPlan?.cwd || cwd,
|
|
43
|
+
providerThreadId: executionRecipe?.providerThreadId || null,
|
|
44
|
+
processGeneration,
|
|
45
|
+
homeDir: capturedHome,
|
|
46
|
+
codexHome: null,
|
|
47
|
+
nativeStorageRootConfiguredPath: claudeConfigDir ? path.join(claudeConfigDir, 'projects') : null,
|
|
48
|
+
nativeStorageRootReceipt: null,
|
|
49
|
+
tmpDir: capturedTmpDir,
|
|
50
|
+
nativeConfigReceipt: null,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const sessionsDir = spawnEnv.CTM_CODEX_SESSIONS_DIR || strFlag('CTM_CODEX_SESSIONS_DIR', '');
|
|
54
|
+
return {
|
|
55
|
+
executablePath: preparedLaunchPlan?.cmd || cmd,
|
|
56
|
+
args: Array.isArray(preparedLaunchPlan?.args) ? [...preparedLaunchPlan.args] : [...args],
|
|
57
|
+
workingDirectory: preparedLaunchPlan?.cwd || cwd,
|
|
58
|
+
providerThreadId: preparedLaunchPlan?.resume?.providerResumeId || preparedLaunchPlan?.resume?.sessionId
|
|
59
|
+
|| preparedLaunchPlan?.resume?.agentSessionId || null,
|
|
60
|
+
processGeneration,
|
|
61
|
+
homeDir: capturedHome,
|
|
62
|
+
codexHome: spawnEnv.CODEX_HOME || (capturedHome ? path.join(capturedHome, '.codex') : null),
|
|
63
|
+
nativeStorageRootConfiguredPath: spawnEnv.CTM_CODEX_SESSIONS_DIR
|
|
64
|
+
|| sessionsDir
|
|
65
|
+
|| ((spawnEnv.CODEX_HOME || capturedHome)
|
|
66
|
+
? path.join(spawnEnv.CODEX_HOME || path.join(capturedHome, '.codex'), 'sessions') : null),
|
|
67
|
+
nativeStorageRootReceipt: codexPaths?.codexSessionsRootReceipt?.({
|
|
68
|
+
homeDir: capturedHome,
|
|
69
|
+
codexHomePath: spawnEnv.CODEX_HOME || (capturedHome ? path.join(capturedHome, '.codex') : null),
|
|
70
|
+
sessionsDir: sessionsDir || undefined,
|
|
71
|
+
}) || null,
|
|
72
|
+
tmpDir: capturedTmpDir,
|
|
73
|
+
nativeConfigReceipt: nativeConfigReceipt || { state: 'unknown' },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = { buildModelTransitionLaunchContext };
|
|
@@ -20,8 +20,11 @@ const { RECIPE_ENV_KEY, MAX_RECIPE_BYTES, modelExecutionRecipeMetadata } = requi
|
|
|
20
20
|
const { validateDeferredRestoreAttempt } = require('../deferred-restore-attempt');
|
|
21
21
|
const { getPrivateSourceRecoveryEnvironment, capturePrivateSourceEnvironment,
|
|
22
22
|
hasCapturedEmptySourceEnvironmentRestore } = require('../lead-model-restore-reconciliation');
|
|
23
|
-
const { modelStorageRootsFromEnv } = require('../host-handoff');
|
|
24
|
-
|
|
23
|
+
const { modelStorageRootsFromEnv, privateOverridesFromEnv } = require('../host-handoff');
|
|
24
|
+
// WP-0b: the rollback launch capture (moved out of this file, same spawn point) -- see
|
|
25
|
+
// lib/session-create/provider-launch-context.js for the field-by-field contract.
|
|
26
|
+
const { buildModelTransitionLaunchContext } = require('./provider-launch-context');
|
|
27
|
+
const codexNativeProviderGate = require('./codex-native-provider-gate');
|
|
25
28
|
const MAX_CODEX_CONFIG_BYTES = 1024 * 1024;
|
|
26
29
|
|
|
27
30
|
async function readCodexConfigReceipt(codexHome, onCleanupError = () => {}) {
|
|
@@ -76,7 +79,7 @@ function applyModelExecutionRecipeToSpawnEnv(env, recipe, expected = {}) {
|
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
function modelExecutionRecipeForSpawn({ sessionId, processGeneration, agent, launchPlan, leadRoute, transition,
|
|
79
|
-
sourceEnvironmentReference, providerThreadId: explicitProviderThreadId }) {
|
|
82
|
+
sourceEnvironmentReference, providerThreadId: explicitProviderThreadId, nativeConfigReceipt }) {
|
|
80
83
|
const routeId = leadRoute ? String(leadRoute.routeId || leadRoute.alias || '') : null;
|
|
81
84
|
const profile = leadRoute?.profile || leadRoute?.preparedPlan?.profile || null;
|
|
82
85
|
const ownership = leadRoute?.ownership || leadRoute?.preparedPlan?.ownership || null;
|
|
@@ -93,6 +96,8 @@ function modelExecutionRecipeForSpawn({ sessionId, processGeneration, agent, lau
|
|
|
93
96
|
factsRevision: routeId ? (profile.factsRevision || ownership?.factsRevision || null) : null,
|
|
94
97
|
transitionId: transition?.transitionId || leadRoute?.transitionId || ownership?.transitionId || null,
|
|
95
98
|
...(sourceEnvironmentReference ? { sourceEnvironmentReference } : {}),
|
|
99
|
+
...(nativeConfigReceipt && ['present', 'missing'].includes(nativeConfigReceipt.state)
|
|
100
|
+
? { nativeConfigReceipt: { state: nativeConfigReceipt.state, sha256: nativeConfigReceipt.sha256 ?? null } } : {}),
|
|
96
101
|
};
|
|
97
102
|
}
|
|
98
103
|
|
|
@@ -193,6 +198,7 @@ async function prepareProviderSession(state) {
|
|
|
193
198
|
_wsSend,
|
|
194
199
|
recordSessionDiagnostic,
|
|
195
200
|
harnessModelProfileLoader,
|
|
201
|
+
markSessionResumeBlocked, // WP-1: the deterministic refusal hook (server.js)
|
|
196
202
|
} = _getDeps();
|
|
197
203
|
const { args, cmd, createAgentType, cwd, env, id, msg, preparedLaunchPlan, restoreSeedSnapshot, ws, signal,
|
|
198
204
|
claudeResumeId, _injectedSessionId } = state;
|
|
@@ -322,6 +328,14 @@ async function prepareProviderSession(state) {
|
|
|
322
328
|
if (typeof recordSessionDiagnostic === 'function') recordSessionDiagnostic(id, 'lead-route-read-failed', { message: String(error && error.message || error).slice(0, 200) });
|
|
323
329
|
}
|
|
324
330
|
}
|
|
331
|
+
// WP-1 (codex-routed-fork-cold-restore-guard §5 D-2..D-4): a native `codex resume T` loads the provider
|
|
332
|
+
// STORED IN T; the gate refuses (D-4) or repairs the route from the journal (D-3) before any spawn.
|
|
333
|
+
if (!target && !readFailed && createAgentType === 'codex' && resolvedProviderThreadId) {
|
|
334
|
+
const gated = await codexNativeProviderGate.gateNativeCodexLaunch({ sessionId: id, threadId: resolvedProviderThreadId,
|
|
335
|
+
env, preparedLaunchPlan, dbModule, recordSessionDiagnostic, markSessionResumeBlocked, ws, wsSend: _wsSend });
|
|
336
|
+
if (gated.refused) { if (runtime) await runtime.close(); return { handled: true, providerState: null }; }
|
|
337
|
+
if (gated.target) target = gated.target;
|
|
338
|
+
}
|
|
325
339
|
if (target && !readFailed) {
|
|
326
340
|
let lr;
|
|
327
341
|
if (target.preparedPlan) {
|
|
@@ -861,13 +875,17 @@ function createProviderSession(state) {
|
|
|
861
875
|
const leadApplied = _applyLeadRouteToSpawn({ launchArgs, env, leadRoute });
|
|
862
876
|
launchArgs = leadApplied.launchArgs;
|
|
863
877
|
// The host receipt carries only whether the original per-session overrides were empty or
|
|
864
|
-
// require a surviving private owner. Storage roots
|
|
865
|
-
// launch context
|
|
878
|
+
// require a surviving private owner. Storage roots and TMPDIR projected into the launch context
|
|
879
|
+
// (`launchEnvironmentOverrides`) are launch context, not private overrides: for EVERY spawn, not
|
|
880
|
+
// only a host restore, they are dropped before the receipt is computed, so a projected HOME/TMPDIR
|
|
881
|
+
// never turns an otherwise empty override set into a private environment. The spawned child still
|
|
882
|
+
// receives them (`launchEnvOverrides` below).
|
|
866
883
|
const trustedCapturedEmptySourceEnvironment = msg._isRestore === true
|
|
867
884
|
&& hasCapturedEmptySourceEnvironmentRestore(msg);
|
|
868
885
|
const sourceOverrideCapture = capturePrivateSourceEnvironment(sourceRecoveryEnvironment
|
|
869
|
-
? sourceRecoveryEnvironment.environment
|
|
870
|
-
|
|
886
|
+
? privateOverridesFromEnv(sourceRecoveryEnvironment.environment)
|
|
887
|
+
: trustedCapturedEmptySourceEnvironment ? {}
|
|
888
|
+
: privateOverridesFromEnv(msg.env && typeof msg.env === 'object' ? msg.env : {}));
|
|
871
889
|
const sourceEnvironmentReference = trustedCapturedEmptySourceEnvironment ? 'captured-empty'
|
|
872
890
|
: sourceOverrideCapture.state === 'captured'
|
|
873
891
|
? (Object.keys(sourceOverrideCapture.values || {}).length === 0 ? 'captured-empty' : 'private-owner-required')
|
|
@@ -890,7 +908,7 @@ function createProviderSession(state) {
|
|
|
890
908
|
const modelProcessGeneration = capturedModelProcessGeneration;
|
|
891
909
|
const executionRecipe = modelExecutionRecipeForSpawn({ sessionId: id, processGeneration: modelProcessGeneration,
|
|
892
910
|
agent: createAgentType, launchPlan: preparedLaunchPlan, leadRoute, transition: msg._leadModelTransition || null,
|
|
893
|
-
sourceEnvironmentReference, providerThreadId: launchProviderThreadId({ agent: createAgentType,
|
|
911
|
+
sourceEnvironmentReference, nativeConfigReceipt, providerThreadId: launchProviderThreadId({ agent: createAgentType,
|
|
894
912
|
launchPlan: preparedLaunchPlan, claudeResumeId, injectedSessionId: _injectedSessionId, args: launchArgs }) });
|
|
895
913
|
let spawnEnv = { ...applyModelExecutionRecipeToSpawnEnv(leadApplied.spawnEnv, executionRecipe,
|
|
896
914
|
{ sessionId: id, processGeneration: modelProcessGeneration }), CTM_MODEL_PROCESS_GENERATION: String(modelProcessGeneration) };
|
|
@@ -1063,32 +1081,14 @@ function createProviderSession(state) {
|
|
|
1063
1081
|
_modelProcessGeneration: modelProcessGeneration,
|
|
1064
1082
|
_modelExecutionRecipe: modelExecutionRecipeMetadata(executionRecipe,
|
|
1065
1083
|
{ sessionId: id, processGeneration: modelProcessGeneration }).modelExecutionRecipe || null,
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|| preparedLaunchPlan?.resume?.agentSessionId || null,
|
|
1075
|
-
processGeneration: modelProcessGeneration,
|
|
1076
|
-
homeDir: capturedHome,
|
|
1077
|
-
codexHome: leadApplied.spawnEnv.CODEX_HOME || (capturedHome ? path.join(capturedHome, '.codex') : null),
|
|
1078
|
-
nativeStorageRootConfiguredPath: leadApplied.spawnEnv.CTM_CODEX_SESSIONS_DIR
|
|
1079
|
-
|| sessionsDir
|
|
1080
|
-
|| ((leadApplied.spawnEnv.CODEX_HOME || capturedHome)
|
|
1081
|
-
? path.join(leadApplied.spawnEnv.CODEX_HOME || path.join(capturedHome, '.codex'), 'sessions') : null),
|
|
1082
|
-
nativeStorageRootReceipt: codexPaths?.codexSessionsRootReceipt?.({
|
|
1083
|
-
homeDir: capturedHome,
|
|
1084
|
-
codexHomePath: leadApplied.spawnEnv.CODEX_HOME || (capturedHome ? path.join(capturedHome, '.codex') : null),
|
|
1085
|
-
sessionsDir: sessionsDir || undefined,
|
|
1086
|
-
}) || null,
|
|
1087
|
-
tmpDir: typeof leadApplied.spawnEnv.TMPDIR === 'string' && path.isAbsolute(leadApplied.spawnEnv.TMPDIR)
|
|
1088
|
-
? leadApplied.spawnEnv.TMPDIR : null,
|
|
1089
|
-
nativeConfigReceipt: nativeConfigReceipt || { state: 'unknown' },
|
|
1090
|
-
};
|
|
1091
|
-
})() } : {}),
|
|
1084
|
+
// native-same-thread-model-switch / §6.5, WP-0b: the PRIVATE launch capture a rollback recovery
|
|
1085
|
+
// replays, built at THIS REAL spawn point by the sibling module (see
|
|
1086
|
+
// lib/session-create/provider-launch-context.js for the field-by-field contract).
|
|
1087
|
+
...((createAgentType === 'codex' || createAgentType === 'claude') ? { _modelTransitionLaunchContext: buildModelTransitionLaunchContext({
|
|
1088
|
+
agentType: createAgentType, preparedLaunchPlan, cmd, args, cwd,
|
|
1089
|
+
spawnEnv: leadApplied.spawnEnv, serverHome: serverConfig.HOME,
|
|
1090
|
+
executionRecipe, processGeneration: modelProcessGeneration, nativeConfigReceipt, codexPaths,
|
|
1091
|
+
}) } : {}),
|
|
1092
1092
|
clients: sessionClients,
|
|
1093
1093
|
_primaryWs: null,
|
|
1094
1094
|
// scrollback removed — headless terminal is source of truth (Phase 3D)
|
|
@@ -1453,11 +1453,10 @@ function createProviderSession(state) {
|
|
|
1453
1453
|
provider: sessionAgentType,
|
|
1454
1454
|
providerResumeId: sessionAgentType === 'codex' ? (claudeResumeId || '') : '',
|
|
1455
1455
|
cwd,
|
|
1456
|
-
|
|
1457
|
-
userRenamed: !!session.userRenamed,
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
titleStatusReason: session.userRenamed ? 'new_session_title' : '',
|
|
1456
|
+
// D-2 (session-name design 2026-10-23): a resume of a titled row keeps its title + provenance (upsertSession keeps omitted keys).
|
|
1457
|
+
...(isResumeLaunch && existingTitle?.title ? {} : { title: session.title || session.label, userRenamed: !!session.userRenamed,
|
|
1458
|
+
titleSource: session.userRenamed ? 'user' : '', titleStatus: session.userRenamed ? 'user_named' : '',
|
|
1459
|
+
titleStatusReason: session.userRenamed ? 'new_session_title' : '' }),
|
|
1461
1460
|
projectEntry: sessionAgentType === 'claude' ? encodeClaudeProjectEntry(cwd) : encodeProjectEntry(cwd),
|
|
1462
1461
|
projectPath: cwd,
|
|
1463
1462
|
},
|
|
@@ -9,6 +9,12 @@ const { releaseAdmissionOnExit, retireWorkerOnExit, scheduleWorkerObservation }
|
|
|
9
9
|
// whole frame is built by the SAME bounded pure transport leaf (it copies the fixed typed whitelist out
|
|
10
10
|
// of the payload `_sessionPayload` already produced).
|
|
11
11
|
const { buildCreatedSessionPayload } = require('../coding-session-model-public');
|
|
12
|
+
// WP-2 (docs/codex-routed-fork-cold-restore-guard-2026-10-22.html §5 D-5): the module carries the
|
|
13
|
+
// rationale — a Codex config-load failure is a precondition failure, never a restart-budget consumer.
|
|
14
|
+
const { classifyCodexResumeExit } = require('./codex-resume-exit-classify');
|
|
15
|
+
const { codexProviderMissingMessage } = require('./codex-native-provider-gate'); // WP-1 owns the one block sentence
|
|
16
|
+
// WP-1 (D-1/D-2, S-11): the pure chooser for the block a deferred exit carries (a direct require, like the two leaves above: the injected `runtime` is built in server.js, which this WP does not own).
|
|
17
|
+
const { deferBlockForExit } = require('../resume-blocked-wire');
|
|
12
18
|
|
|
13
19
|
// D-9 (delegated-worker-lifecycle-identity-observability-2026-09-27.html §5 D-9, §9 S-15):
|
|
14
20
|
// best-effort proxy-token revoke for a worker session exiting on the CREATE path (never
|
|
@@ -887,7 +893,7 @@ function installResponseRuntime(runtime) {
|
|
|
887
893
|
// classification BEFORE this handler is installed; the handler then passes its FULL event through it.
|
|
888
894
|
const leadRouteCleanup = runtime.session.agentRole === 'worker' ? null : require('./lead-route-launch').createLeadRouteLifetimeCleanup({ sessionId: runtime.session.id, ownership: runtime.session._leadRouteTokenOwnership, hosted: _useSessionHostProcessForPty() === true });
|
|
889
895
|
const onPtyExit = async (exitEvent) => {
|
|
890
|
-
const { exitCode, signal } = exitEvent || {};
|
|
896
|
+
const { exitCode, signal, exitSource } = exitEvent || {};
|
|
891
897
|
runtime.sessionInputAuthority.observeProvider({ sessionId: runtime.id, status: 'exited' });
|
|
892
898
|
runtime.session._ptyExitLifecycle = {
|
|
893
899
|
stage: 'capturing-viewport',
|
|
@@ -1064,6 +1070,20 @@ function installResponseRuntime(runtime) {
|
|
|
1064
1070
|
// retry path as an exit 1 rather than being mistaken for a completed terminal lifecycle.
|
|
1065
1071
|
const maxAutoRestarts = 3;
|
|
1066
1072
|
const restartCount = runtime.session._autoRestartCount || 0;
|
|
1073
|
+
// WP-2 (§5 D-5, §9 S-9/S-10): classify THIS attempt's buffer — never scrollback — before the
|
|
1074
|
+
// auto-restart decision, and block a Codex config-load failure instead of spending the budget.
|
|
1075
|
+
const codexProviderMissingExit = (agentType === 'codex' && exitedBeforeResumeReady) ? classifyCodexResumeExit(runtime.session._resumeAttemptOutput || '') : null;
|
|
1076
|
+
if (codexProviderMissingExit) {
|
|
1077
|
+
runtime.recordSessionDiagnostic(runtime.id, 'codex-provider-missing-exit', { provider: codexProviderMissingExit.provider, exitCode });
|
|
1078
|
+
// Marked ONCE. This is what makes the auto-restart decision below false
|
|
1079
|
+
// (`resumeBlocked: isSessionResumeBlocked(runtime.id)`), so `handleCreatePrepared` is never
|
|
1080
|
+
// scheduled for this exit; the flow then falls through to the ordinary exit-persistence path,
|
|
1081
|
+
// which sees the session already blocked and keeps the placeholder + startup recipe as is.
|
|
1082
|
+
markSessionResumeBlocked(runtime.id, {
|
|
1083
|
+
code: 'codex_provider_missing', detail: codexProviderMissingExit.line, agentType: 'codex', deterministic: true,
|
|
1084
|
+
message: codexProviderMissingMessage(codexProviderMissingExit.provider),
|
|
1085
|
+
}, 'codex-provider-exit');
|
|
1086
|
+
}
|
|
1067
1087
|
// A worker continuation does launch `-p --resume` / `exec resume`, but its exit is terminal and
|
|
1068
1088
|
// never an interactive auto-restart (that would relaunch it as a TUI under the worker's identity,
|
|
1069
1089
|
// stuck at worker-status 'starting'). lib/session-class.js declares that: relaunchFromRestore=false.
|
|
@@ -1208,25 +1228,22 @@ function installResponseRuntime(runtime) {
|
|
|
1208
1228
|
const exitPersistence = sessionExitPersistenceDecision({
|
|
1209
1229
|
intentionalKill: !!runtime.session._intentionalKill,
|
|
1210
1230
|
exitCode,
|
|
1211
|
-
signal,
|
|
1231
|
+
signal, exitSource,
|
|
1212
1232
|
isResumable,
|
|
1213
1233
|
resumeContext: resumeExitContext(runtime.session), deferOnAbnormalExit: sessionPolicy(runtime.session).deferOnAbnormalExit,
|
|
1214
1234
|
});
|
|
1215
1235
|
runtime.session._ptyExitLifecycle.stage = `persistence-${String(exitPersistence.action || 'unknown')}`;
|
|
1216
1236
|
if (exitPersistence.action === 'defer') {
|
|
1217
1237
|
const latestResumeExit = resumeExitContext(runtime.session);
|
|
1218
|
-
|
|
1219
|
-
|
|
1238
|
+
const label = getAgentCapabilities(agentType).label || 'The agent';
|
|
1239
|
+
// WP-1 (D-1/D-2): the block comes from the exit EVIDENCE -- an unknown exit yields null (defer with no block: exited, and the next input resumes it).
|
|
1240
|
+
const block = deferBlockForExit({ exitPersistence, latestResumeExit, exitCode, signal, autoRestartCount: runtime.session._autoRestartCount || 0, label });
|
|
1241
|
+
if (block && !isSessionResumeBlocked(runtime.id)) {
|
|
1220
1242
|
markSessionResumeBlocked(runtime.id, {
|
|
1221
|
-
|
|
1222
|
-
? (latestResumeExit.code || 'resume_failed')
|
|
1223
|
-
: 'session_crash_loop',
|
|
1224
|
-
message: latestResumeExit.failedBeforeReady
|
|
1225
|
-
? `${label} did not become ready while resuming.`
|
|
1226
|
-
: `${label} exited unexpectedly and automatic recovery was exhausted.`,
|
|
1243
|
+
...block,
|
|
1227
1244
|
detail: resumeFailureDetail(agentType, runtime.session._resumeAttemptOutput || ''),
|
|
1228
1245
|
agentType,
|
|
1229
|
-
});
|
|
1246
|
+
}, 'response-defer');
|
|
1230
1247
|
}
|
|
1231
1248
|
// Keep the CTM identity and startup recipe as a deferred placeholder. Retiring the startup
|
|
1232
1249
|
// task here would make retry impossible. Failed resume mirrors also stay provisional so they
|
|
@@ -1243,7 +1260,8 @@ function installResponseRuntime(runtime) {
|
|
|
1243
1260
|
runtime.session._restoreStarting = false;
|
|
1244
1261
|
runtime.session._lifecycleState = 'deferred';
|
|
1245
1262
|
runtime._markServerSessionTurnClosed(runtime.session, Date.now(), 'session-exit'); // R-15: PROCESS_EXIT, never a dead wait
|
|
1246
|
-
|
|
1263
|
+
// WP-1 (D-1): read the flag, never assert it -- a defer with no block is "exited, resumes on input", not "resuming".
|
|
1264
|
+
runtime.session._resumeBlocked = isSessionResumeBlocked(runtime.id);
|
|
1247
1265
|
runtime.session._exitPersistenceReason = exitPersistence.reason;
|
|
1248
1266
|
runtime.session._restoreTask = {
|
|
1249
1267
|
session_id: runtime.id,
|
|
@@ -120,12 +120,21 @@ async function createWalleSession(state) {
|
|
|
120
120
|
if (createResult) deps.recordWalleTranscriptAppend(session, createResult);
|
|
121
121
|
for (const record of seeded.records) deps.recordWalleTranscriptAppend(session, record);
|
|
122
122
|
try {
|
|
123
|
+
// WP-0 (session-name-agent-title-precedence-2026-10-23.html §5 D-2): reusing an existing
|
|
124
|
+
// Wall-E transcript must not rewrite the row's title or its provenance — the client echoes
|
|
125
|
+
// the displayed name back (D-1), and upsertSession keeps the stored value for any omitted
|
|
126
|
+
// title key (or empty titleSource/titleStatus/titleStatusReason), so omit them on a resume
|
|
127
|
+
// of a row that already has a title.
|
|
128
|
+
const preserveTitleProvenance = !msg._isRestore
|
|
129
|
+
&& (launch.walleResumeRequest || launch.isResumeLaunch) && !!existingTitle?.title;
|
|
123
130
|
void deps.detachOwnerMutation('walle-session-created', () => deps.dbModule.upsertSession(id, {
|
|
124
131
|
agentSessionId: chatSessionId, provider: 'walle', cwd, projectPath: cwd,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
132
|
+
...(preserveTitleProvenance ? {} : {
|
|
133
|
+
title: session.title, userRenamed: !!session.userRenamed,
|
|
134
|
+
titleSource: session.userRenamed ? 'user' : '',
|
|
135
|
+
titleStatus: session.userRenamed ? 'user_named' : '',
|
|
136
|
+
titleStatusReason: session.userRenamed ? 'new_session_title' : '',
|
|
137
|
+
}),
|
|
129
138
|
jsonlPath, fileSize: 0, modifiedAt: '', model: modelId || '', hostname: deps.hostname,
|
|
130
139
|
}));
|
|
131
140
|
} catch (error) {
|
|
@@ -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
|
+
};
|