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
|
@@ -10,7 +10,8 @@ const {
|
|
|
10
10
|
createRootDeliveryRuntime, getRootDeliveryJobLifetime, isRootDeliveryJobLifetimeCurrent,
|
|
11
11
|
} = require('./root-delivery-runtime');
|
|
12
12
|
const { ROOT_PROMPT_ACTION } = require('./remote-command-purpose');
|
|
13
|
-
const { selectRootDeliveryAttempt } = require('./root-delivery-selection');
|
|
13
|
+
const { selectRootDeliveryAttempt, selectRootDeliveryRecovery } = require('./root-delivery-selection');
|
|
14
|
+
const promptAdmissionTrace = require('./prompt-admission-trace');
|
|
14
15
|
|
|
15
16
|
const TERMINAL_STATUSES = new Set([
|
|
16
17
|
'sent', 'accepted_by_terminal', 'durable_user_message_seen', 'response_started', 'queued_by_agent',
|
|
@@ -18,6 +19,49 @@ const TERMINAL_STATUSES = new Set([
|
|
|
18
19
|
const PREFLIGHT_RETRYABLE = new Set([
|
|
19
20
|
'session_input_in_flight', 'session_resume_not_ready', 'command_deferred_until_idle',
|
|
20
21
|
]);
|
|
22
|
+
const PREFLIGHT_USER_ACTION = new Set(['session_not_live', 'session_waiting_for_approval']);
|
|
23
|
+
// WP-0 (queue-delivery-recovery): one wording per recovery action, so the persisted
|
|
24
|
+
// row, the broadcast frame and the direct reply cannot describe the same verdict
|
|
25
|
+
// differently. Both describe the preserved prompt and the action the user owns;
|
|
26
|
+
// neither claims the prompt was not sent while its effect is unknown.
|
|
27
|
+
const RESEND_MESSAGE = 'Your prompt is saved and was not sent. Choose Resend to try again.';
|
|
28
|
+
const REVIEW_MESSAGE = 'CTM could not safely confirm this desktop delivery. Review the submission before resending.';
|
|
29
|
+
const SAFE_DIAGNOSTIC_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,159}$/u;
|
|
30
|
+
|
|
31
|
+
function safeDiagnosticId(value) {
|
|
32
|
+
return typeof value === 'string' && SAFE_DIAGNOSTIC_ID_RE.test(value) ? value : '';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// WP-0: what a cached (restart-surviving) parent row plus its scoped delivery
|
|
36
|
+
// receipts prove about the prompt, and the exact action the user owns. Delegates
|
|
37
|
+
// the proof rules to root-delivery-selection so read evidence and classification
|
|
38
|
+
// cannot drift; anything uncertified stays `unknown`/`review`.
|
|
39
|
+
function classifyReplayRecovery(snapshot) {
|
|
40
|
+
const verdict = selectRootDeliveryRecovery(snapshot);
|
|
41
|
+
if (verdict.deliveryState === 'sent') {
|
|
42
|
+
const recorded = String(snapshot?.parent?.status || '');
|
|
43
|
+
return Object.freeze({
|
|
44
|
+
recoveryAction: verdict.recoveryAction, deliveryState: verdict.deliveryState,
|
|
45
|
+
reason: '', // Canonical Root confirmation stores 'sent' for provider_transcript_match.
|
|
46
|
+
terminalStatus: recorded === 'sent' ? 'durable_user_message_seen' : recorded,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (verdict.recoveryAction === 'resend') {
|
|
50
|
+
// The certified no-effect proof names the exact earlier blocker; keep that
|
|
51
|
+
// specific reason instead of flattening it to the generic refusal code.
|
|
52
|
+
const blocker = snapshot?.latest?.result?.result?.delivery_evidence?.blocker;
|
|
53
|
+
const specific = typeof blocker === 'string'
|
|
54
|
+
&& (PREFLIGHT_RETRYABLE.has(blocker) || PREFLIGHT_USER_ACTION.has(blocker)) ? blocker : '';
|
|
55
|
+
return Object.freeze({
|
|
56
|
+
recoveryAction: verdict.recoveryAction, deliveryState: verdict.deliveryState,
|
|
57
|
+
reason: specific, terminalStatus: '',
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return Object.freeze({
|
|
61
|
+
recoveryAction: verdict.recoveryAction, deliveryState: verdict.deliveryState,
|
|
62
|
+
reason: '', terminalStatus: '',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
21
65
|
const SAFE_DIAGNOSTIC_ERROR_KINDS = new Set(['ReferenceError', 'TypeError', 'RangeError', 'SqliteError', 'Error']);
|
|
22
66
|
const SAFE_DIAGNOSTIC_SOURCE_FILES = new Set([
|
|
23
67
|
'root-prompt-admission.js', 'remote-relay-store.js', 'server.js', 'main-db-census.js',
|
|
@@ -49,6 +93,7 @@ function safeResult(response, publicId, sessionId, fallbackSource = 'unknown') {
|
|
|
49
93
|
reason: mapped.reason,
|
|
50
94
|
source: mapped.source,
|
|
51
95
|
retryable: mapped.retryable,
|
|
96
|
+
recoveryAction: mapped.recoveryAction,
|
|
52
97
|
...(mapped.message ? { message: mapped.message } : {}),
|
|
53
98
|
...(detail.duplicate === true || response?.duplicate === true ? { duplicate: true } : {}),
|
|
54
99
|
...(detail.retrying === true || response?.retrying === true ? { retrying: true } : {}),
|
|
@@ -68,6 +113,7 @@ function safeResult(response, publicId, sessionId, fallbackSource = 'unknown') {
|
|
|
68
113
|
reason: mapped.reason,
|
|
69
114
|
source: mapped.source,
|
|
70
115
|
retryable: mapped.retryable,
|
|
116
|
+
recoveryAction: mapped.recoveryAction,
|
|
71
117
|
...(mapped.message ? { message: mapped.message } : {}),
|
|
72
118
|
...(Number.isInteger(httpStatus) && httpStatus >= 400 && httpStatus <= 599 ? { httpStatus } : {}),
|
|
73
119
|
};
|
|
@@ -94,6 +140,11 @@ function createRootPromptFlow(deps = {}) {
|
|
|
94
140
|
const observerLifetimes = new WeakMap();
|
|
95
141
|
const sessionDrains = new WeakMap();
|
|
96
142
|
const httpRequestScopes = new WeakMap();
|
|
143
|
+
// WP-0: the normalized session/client-message correlation for the operation
|
|
144
|
+
// currently running on a captured scope, so every diagnostic that scope emits
|
|
145
|
+
// (admission, driver, delivery stage, replay recovery) can be joined to the one
|
|
146
|
+
// user-visible submission. Both values are bounded ids, never receipt ids.
|
|
147
|
+
const scopeCorrelation = new WeakMap();
|
|
97
148
|
|
|
98
149
|
function registryFor(db) {
|
|
99
150
|
let registry = registries.get(db);
|
|
@@ -120,6 +171,9 @@ function createRootPromptFlow(deps = {}) {
|
|
|
120
171
|
function reportFailure(scope, phase, code, details = {}) {
|
|
121
172
|
if (!scope?.isCurrent()) return;
|
|
122
173
|
const event = { category: 'root-prompt-flow', phase, code };
|
|
174
|
+
const correlation = scopeCorrelation.get(scope);
|
|
175
|
+
if (correlation?.sessionId) event.sessionId = correlation.sessionId;
|
|
176
|
+
if (correlation?.clientMessageId) event.clientMessageId = correlation.clientMessageId;
|
|
123
177
|
for (const key of ['returnedRecordConfirmed', 'canonicalRecordConfirmed', 'recordFieldsMatch']) {
|
|
124
178
|
if (typeof details[key] === 'boolean') event[key] = details[key];
|
|
125
179
|
}
|
|
@@ -182,6 +236,11 @@ function createRootPromptFlow(deps = {}) {
|
|
|
182
236
|
},
|
|
183
237
|
isDeliveryCurrent: (_handle, metadata) => scope.isCurrent() === true && now() < metadata.expiresAt,
|
|
184
238
|
now,
|
|
239
|
+
// WP-0 criterion 6: the driver reports the exact rejected handoff stage
|
|
240
|
+
// (delivery_snapshot / delivery_text / delivery_selection / delivery_dispatch /
|
|
241
|
+
// admission_metadata) with a static code. reportFailure bounds the event and
|
|
242
|
+
// swallows a throwing sink, so diagnostics can never change an outcome.
|
|
243
|
+
reportDiagnostic: (event) => reportFailure(scope, event?.phase, event?.code, {}),
|
|
185
244
|
});
|
|
186
245
|
}
|
|
187
246
|
|
|
@@ -230,14 +289,18 @@ function createRootPromptFlow(deps = {}) {
|
|
|
230
289
|
{
|
|
231
290
|
retire(registry, job);
|
|
232
291
|
if (job.scope.isCurrent()) {
|
|
292
|
+
// WP-0 criterion 7: the certificate is gone without a completion proof,
|
|
293
|
+
// so the effect of this prompt is UNKNOWN. Say so, and keep the
|
|
294
|
+
// conservative review action rather than claiming nothing was sent.
|
|
295
|
+
const expired = code === 'root_delivery_expired';
|
|
233
296
|
try {
|
|
234
297
|
await storeStatus(job.sessionId, job.receiptId, 'needs_attention', {
|
|
235
|
-
reason: code
|
|
236
|
-
? code : 'root_job_unresolved',
|
|
298
|
+
reason: expired ? code : 'root_job_unresolved',
|
|
237
299
|
retryable: false,
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
300
|
+
recoveryAction: 'review',
|
|
301
|
+
message: expired
|
|
302
|
+
? 'The desktop delivery permission expired before CTM could confirm this delivery. Review the submission before resending.'
|
|
303
|
+
: REVIEW_MESSAGE,
|
|
241
304
|
source: job.source,
|
|
242
305
|
});
|
|
243
306
|
} catch { reportFailure(job.scope, 'publish_unresolved', 'status_write_failed'); }
|
|
@@ -321,6 +384,11 @@ function createRootPromptFlow(deps = {}) {
|
|
|
321
384
|
const scope = operationScope || commandRuntime.captureRootPromptCoordinator();
|
|
322
385
|
if (!scope || !requestCurrent(scope, current)) return denial('remote_command_auth_unavailable');
|
|
323
386
|
const publicId = agentSessionKernel.normalizeClientMessageId(options.clientMessageId);
|
|
387
|
+
// WP-0: correlate every diagnostic this operation emits with its normalized
|
|
388
|
+
// session/client-message identity (bounded ids only -- never a receipt id).
|
|
389
|
+
scopeCorrelation.set(scope, {
|
|
390
|
+
sessionId: safeDiagnosticId(sessionId), clientMessageId: safeDiagnosticId(publicId),
|
|
391
|
+
});
|
|
324
392
|
const authState = { auth: null, namespace: null };
|
|
325
393
|
const freshContext = transportKind === 'ws'
|
|
326
394
|
? (socket, namespace) => commandRuntime.freshRootPromptContext(socket, namespace)
|
|
@@ -351,7 +419,7 @@ function createRootPromptFlow(deps = {}) {
|
|
|
351
419
|
const admission = makeAdmission({ scope, current, freshContext, authState, sessionId, text, options });
|
|
352
420
|
let admitted;
|
|
353
421
|
try {
|
|
354
|
-
admitted = await admission.submit(client, sessionId, text, options);
|
|
422
|
+
admitted = await promptAdmissionTrace.time('admission', () => admission.submit(client, sessionId, text, options));
|
|
355
423
|
} catch {
|
|
356
424
|
admitted = { response: denial('remote_command_unresolved'), admission: null };
|
|
357
425
|
}
|
|
@@ -383,6 +451,15 @@ function createRootPromptFlow(deps = {}) {
|
|
|
383
451
|
driver, writeActive: true, autoPending: true, inFlight: false, lastResult: null,
|
|
384
452
|
};
|
|
385
453
|
registry.set(receiptId, job);
|
|
454
|
+
} else {
|
|
455
|
+
// WP-0 criterion 4: a committed admission whose delivery facade cannot be
|
|
456
|
+
// registered is a typed handoff failure, never a silent acceptance. The
|
|
457
|
+
// committed historical record is left exactly as it is.
|
|
458
|
+
reportFailure(scope, 'driver_registration', 'root_driver_registration_unavailable');
|
|
459
|
+
admitted = { ...admitted, response: { ...denial('root_driver_registration_unavailable', 503),
|
|
460
|
+
recoveryAction: 'resend',
|
|
461
|
+
message: 'CTM saved your prompt but could not start delivery. Resend to try again.',
|
|
462
|
+
} };
|
|
386
463
|
}
|
|
387
464
|
}
|
|
388
465
|
if (job) {
|
|
@@ -392,37 +469,86 @@ function createRootPromptFlow(deps = {}) {
|
|
|
392
469
|
void firstDrive.catch(() => reportFailure(scope, 'drive', 'unexpected_failure'));
|
|
393
470
|
}
|
|
394
471
|
} else if (admitted?.response?.ok === true) {
|
|
395
|
-
// A cached parent is not a process-local write marker. Never adopt it after
|
|
472
|
+
// A cached parent is not a process-local write marker. Never adopt it after
|
|
473
|
+
// restart, and never answer with its cached acceptance: a reply is truthful
|
|
474
|
+
// only when this process holds the job, or when a scoped read proves what
|
|
475
|
+
// actually happened to the prompt.
|
|
396
476
|
let context = null;
|
|
477
|
+
let contextFailed = false;
|
|
397
478
|
try { context = await freshContext(client, null); }
|
|
398
|
-
catch {
|
|
399
|
-
if (context?.ok
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
479
|
+
catch { contextFailed = true; }
|
|
480
|
+
if (!contextFailed && (!context?.ok || !requestCurrent(scope, current))) contextFailed = true;
|
|
481
|
+
if (contextFailed) {
|
|
482
|
+
// WP-0 criterion 4: no current authority and no proof -- refuse, never
|
|
483
|
+
// fall through to the cached `received`/`accepted` response.
|
|
484
|
+
reportFailure(scope, 'replay_recovery', 'root_replay_context_unavailable');
|
|
485
|
+
return denial(context?.code || 'remote_command_auth_unavailable', context?.status || 503);
|
|
486
|
+
}
|
|
487
|
+
const receiptId = remoteCommandStore.remoteCommandReceiptId(context.namespace.namespaceHash, publicId);
|
|
488
|
+
const resident = registry.get(receiptId);
|
|
489
|
+
let requestedIntentHash = '';
|
|
490
|
+
try {
|
|
491
|
+
const intentHandle = rootPromptIntent.captureRootPromptIntent({
|
|
492
|
+
sessionId, text, source: options.source, attachments: options.attachments,
|
|
493
|
+
}, { maxPromptBytes });
|
|
494
|
+
requestedIntentHash = intentHandle.body.intent_hash;
|
|
495
|
+
} catch { requestedIntentHash = ''; reportFailure(scope, 'replay_recovery', 'root_replay_intent_unavailable'); }
|
|
496
|
+
const residentProof = resident && getCommittedRootAdmission(resident.admissionHandle);
|
|
497
|
+
if (resident?.writeActive && now() < resident.expiresAt && resident.scope.isCurrent()
|
|
498
|
+
&& residentProof?.selector?.sessionId === sessionId
|
|
499
|
+
&& residentProof.selector.namespaceHash === context.namespace.namespaceHash
|
|
500
|
+
&& residentProof.selector.intentHash === requestedIntentHash) {
|
|
501
|
+
// A same-id manual retry with a live local job keeps the existing child
|
|
502
|
+
// selection semantics; no read evidence is consulted for it.
|
|
503
|
+
job = resident;
|
|
504
|
+
const retry = driveJob(registry, resident, false);
|
|
505
|
+
void retry.catch(() => reportFailure(scope, 'drive', 'unexpected_failure'));
|
|
506
|
+
} else {
|
|
507
|
+
// WP-0 criterion 3: the delivery permission is gone (restart, lost
|
|
508
|
+
// registry). Ask the scoped store what the prompt's own receipts prove --
|
|
509
|
+
// authenticated namespace + session + command id + a freshly captured
|
|
510
|
+
// intent hash -- and recheck the request scope after every await.
|
|
511
|
+
let snapshot = null;
|
|
512
|
+
let readFailed = false;
|
|
403
513
|
try {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
514
|
+
snapshot = await runReadPoolOp('getLatestRootJobDeliveryReceipt', {
|
|
515
|
+
dbPath: scope.dbPath,
|
|
516
|
+
selector: {
|
|
517
|
+
namespaceHash: context.namespace.namespaceHash, commandId: publicId,
|
|
518
|
+
instanceId: scope.instanceId, sessionId, intentHash: requestedIntentHash,
|
|
519
|
+
},
|
|
520
|
+
}, { telemetryReason: 'root-prompt-replay-recovery' });
|
|
521
|
+
} catch { readFailed = true; }
|
|
522
|
+
if (!requestCurrent(scope, current)) return denial('remote_command_auth_unavailable');
|
|
523
|
+
if (readFailed) reportFailure(scope, 'replay_recovery', 'root_delivery_replay_unavailable');
|
|
524
|
+
const proof = classifyReplayRecovery(readFailed ? null : snapshot);
|
|
525
|
+
if (proof.deliveryState === 'sent') {
|
|
526
|
+
// Read evidence proves the prompt was already delivered: report the
|
|
527
|
+
// recorded sent signal as a duplicate. No new delivery, no new
|
|
528
|
+
// authority, and the preserved row is not downgraded.
|
|
529
|
+
admitted = { ...admitted, response: {
|
|
530
|
+
ok: true, status: proof.terminalStatus, duplicate: true,
|
|
531
|
+
source: options.source || 'web',
|
|
532
|
+
} };
|
|
417
533
|
} else {
|
|
534
|
+
const action = proof.recoveryAction === 'resend' ? 'resend' : 'review';
|
|
535
|
+
const status = action === 'resend' ? 'needs_attention' : 'blocked';
|
|
536
|
+
const details = {
|
|
537
|
+
reason: proof.reason || 'root_job_unresolved', retryable: false,
|
|
538
|
+
recoveryAction: action,
|
|
539
|
+
message: action === 'resend' ? RESEND_MESSAGE : REVIEW_MESSAGE,
|
|
540
|
+
source: options.source || 'web',
|
|
541
|
+
};
|
|
542
|
+
reportFailure(scope, 'replay_recovery', 'root_job_unresolved');
|
|
418
543
|
try {
|
|
419
|
-
await storeStatus(sessionId, receiptId,
|
|
420
|
-
reason: 'root_job_unresolved', retryable: false,
|
|
421
|
-
message: 'The original desktop delivery permission is unavailable. Resend this prompt to try again.',
|
|
422
|
-
source: options.source || 'web',
|
|
423
|
-
});
|
|
544
|
+
await storeStatus(sessionId, receiptId, status, details);
|
|
424
545
|
} catch { reportFailure(scope, 'proof_loss_status', 'status_write_failed'); }
|
|
425
|
-
|
|
546
|
+
if (!requestCurrent(scope, current)) return denial('remote_command_auth_unavailable');
|
|
547
|
+
admitted = { ...admitted, response: {
|
|
548
|
+
ok: false, status, code: 'root_job_unresolved', httpStatus: 409,
|
|
549
|
+
reason: details.reason, message: details.message, retryable: false,
|
|
550
|
+
recoveryAction: action, source: details.source,
|
|
551
|
+
} };
|
|
426
552
|
}
|
|
427
553
|
}
|
|
428
554
|
}
|
|
@@ -445,6 +571,7 @@ function createRootPromptFlow(deps = {}) {
|
|
|
445
571
|
type: 'submit-prompt-status', id: sessionId, clientMessageId: publicId,
|
|
446
572
|
status: safe.status, signal: safe.signal, reason: safe.reason, source: safe.source,
|
|
447
573
|
code: safe.code || '', retryable: safe.retryable === true,
|
|
574
|
+
recoveryAction: safe.recoveryAction || 'none',
|
|
448
575
|
...(safe.message ? { message: safe.message } : {}),
|
|
449
576
|
};
|
|
450
577
|
try { sendWsJson(client, frame); } catch { reportFailure(scope, 'status_reply', 'socket_write_failed'); }
|
|
@@ -456,8 +583,9 @@ function createRootPromptFlow(deps = {}) {
|
|
|
456
583
|
function submitWs(ws, sessionId, text, options = {}) {
|
|
457
584
|
const authReference = ws?.auth;
|
|
458
585
|
const current = () => ws?.readyState === 1 && ws?.auth === authReference;
|
|
459
|
-
return
|
|
460
|
-
|
|
586
|
+
return promptAdmissionTrace.run({ sessionId, source: options.source, transport: 'ws', receivedAt: options.wsReceivedAt },
|
|
587
|
+
() => submit({ client: ws, sessionId, text, options, transportKind: 'ws',
|
|
588
|
+
current, req: null, url: null }));
|
|
461
589
|
}
|
|
462
590
|
|
|
463
591
|
function submitHttp(req, url, sessionId, options = {}) {
|
|
@@ -470,8 +598,9 @@ function createRootPromptFlow(deps = {}) {
|
|
|
470
598
|
|| url?.pathname !== state.url.pathname || url?.search !== state.url.search) {
|
|
471
599
|
return Promise.resolve(denial('invalid_request', 400));
|
|
472
600
|
}
|
|
473
|
-
return
|
|
474
|
-
|
|
601
|
+
return promptAdmissionTrace.run({ sessionId, source: options.source, transport: 'http' },
|
|
602
|
+
() => submit({ client: req, sessionId, text: options.text, options,
|
|
603
|
+
transportKind: 'http', req, url: state.url, current: state.current, operationScope: state.scope }));
|
|
475
604
|
}
|
|
476
605
|
|
|
477
606
|
function captureHttpScope(req, url, response) {
|
|
@@ -503,6 +632,7 @@ function createRootPromptFlow(deps = {}) {
|
|
|
503
632
|
const scope = capturedScope || commandRuntime.captureRootPromptCoordinator();
|
|
504
633
|
if (!scope || (databaseHandle && scope.databaseHandle !== databaseHandle)
|
|
505
634
|
|| (instanceId && scope.instanceId !== instanceId) || !scope.isCurrent()) return 0;
|
|
635
|
+
scopeCorrelation.set(scope, { sessionId: safeDiagnosticId(sessionId) });
|
|
506
636
|
let rows;
|
|
507
637
|
try { rows = remoteRelayStore.listRemoteSubmissions(scope.databaseHandle, { sessionId, limit: 200 }); }
|
|
508
638
|
catch { return 0; }
|
|
@@ -524,7 +654,12 @@ function createRootPromptFlow(deps = {}) {
|
|
|
524
654
|
if (!scope.isCurrent()) break;
|
|
525
655
|
const details = {
|
|
526
656
|
reason: 'root_job_unresolved', retryable: false,
|
|
527
|
-
|
|
657
|
+
// WP-0 criterion 7: a missing process-local marker is not proof that the
|
|
658
|
+
// prompt was never sent (a restart can lose the marker after delivery).
|
|
659
|
+
// Only a scoped no-effect certificate would justify "resend"; none is
|
|
660
|
+
// reachable from a bare durable row, so the action is review.
|
|
661
|
+
recoveryAction: 'review',
|
|
662
|
+
message: REVIEW_MESSAGE,
|
|
528
663
|
source: row.result?.source || 'web',
|
|
529
664
|
};
|
|
530
665
|
try {
|
|
@@ -548,6 +683,7 @@ function createRootPromptFlow(deps = {}) {
|
|
|
548
683
|
if (!id) return { driven: 0, escalated: 0 };
|
|
549
684
|
const scope = commandRuntime.captureRootPromptCoordinator();
|
|
550
685
|
if (!scope || !scope.isCurrent()) return { driven: 0, escalated: 0 };
|
|
686
|
+
scopeCorrelation.set(scope, { sessionId: safeDiagnosticId(id) });
|
|
551
687
|
const registry = registryFor(scope.databaseHandle);
|
|
552
688
|
const inFlight = sessionDrains.get(scope.databaseHandle) || new Set();
|
|
553
689
|
if (!sessionDrains.has(scope.databaseHandle)) sessionDrains.set(scope.databaseHandle, inFlight);
|
|
@@ -566,7 +702,8 @@ function createRootPromptFlow(deps = {}) {
|
|
|
566
702
|
try {
|
|
567
703
|
await storeStatus(job.sessionId, job.receiptId, 'needs_attention', {
|
|
568
704
|
reason: 'root_delivery_expired', retryable: false,
|
|
569
|
-
|
|
705
|
+
recoveryAction: 'review',
|
|
706
|
+
message: 'The desktop delivery permission expired before CTM could confirm this delivery. Review the submission before resending.',
|
|
570
707
|
});
|
|
571
708
|
} catch { reportFailure(job.scope, 'expiry_status', 'status_write_failed'); }
|
|
572
709
|
continue;
|
|
@@ -103,6 +103,8 @@ function createScrollbackArchive(options = {}) {
|
|
|
103
103
|
const flushMs = options.flushMs !== undefined && Number.isFinite(Number(options.flushMs))
|
|
104
104
|
? Number(options.flushMs)
|
|
105
105
|
: ARCHIVE_FLUSH_MS;
|
|
106
|
+
// Test seam, like `now`: a test drives ticks itself instead of waiting on the wall clock.
|
|
107
|
+
const scheduleInterval = typeof options.setInterval === 'function' ? options.setInterval : setInterval;
|
|
106
108
|
const pendingMaxRows = Math.max(1, Number(options.pendingMaxRows) || ARCHIVE_PENDING_MAX_ROWS);
|
|
107
109
|
const pendingMaxBytes = Math.max(1, Number(options.pendingMaxBytes) || ARCHIVE_PENDING_MAX_BYTES);
|
|
108
110
|
const blockBytes = Math.max(1, Number(options.blockBytes) || DEFAULT_BLOCK_BYTES);
|
|
@@ -525,12 +527,12 @@ function createScrollbackArchive(options = {}) {
|
|
|
525
527
|
|
|
526
528
|
function _scheduleTimer() {
|
|
527
529
|
if (timer || flushMs <= 0) return;
|
|
528
|
-
|
|
530
|
+
const tick = () => {
|
|
529
531
|
// A slow async tick skips re-entry; the next tick resumes round-robin order.
|
|
530
|
-
if (tickInFlight) return;
|
|
532
|
+
if (tickInFlight) return null;
|
|
531
533
|
tickInFlight = true;
|
|
532
534
|
const ids = Array.from(sessions.keys());
|
|
533
|
-
(async () => {
|
|
535
|
+
return (async () => {
|
|
534
536
|
// 1) Write buffered appends for every session -- cheap, one appendFile
|
|
535
537
|
// per session's active bucket, no gzip involved.
|
|
536
538
|
for (const id of ids) {
|
|
@@ -561,7 +563,8 @@ function createScrollbackArchive(options = {}) {
|
|
|
561
563
|
})()
|
|
562
564
|
.catch(() => { /* expected: the background timer tick itself must never throw -- every step inside already catches its own failures; this is the final backstop */ })
|
|
563
565
|
.finally(() => { tickInFlight = false; });
|
|
564
|
-
}
|
|
566
|
+
};
|
|
567
|
+
timer = scheduleInterval(tick, flushMs);
|
|
565
568
|
if (typeof timer.unref === 'function') timer.unref();
|
|
566
569
|
}
|
|
567
570
|
|
|
@@ -46,6 +46,13 @@ function startServerMemorySamplerRuntime(options = {}) {
|
|
|
46
46
|
// WP-0b (§5 D-2): () => [{ owner, memory }] over the read-pool / db-owner worker clients.
|
|
47
47
|
// Forwarded verbatim; absent -> the sampler's own () => [] default keeps workers[] empty.
|
|
48
48
|
workersSource,
|
|
49
|
+
// WP-A P-2 (freeze-probes): () => the work in flight at sample time (read-pool ops, db-owner
|
|
50
|
+
// pending ops, recent main-loop spans). Forwarded verbatim; absent -> the sampler's () => null
|
|
51
|
+
// default keeps the row's `inFlight` null.
|
|
52
|
+
inFlightSource,
|
|
53
|
+
// WP-A P-3 (freeze-probes): { sampleFootprintRegions(pid) } for the main pid -- the categorized
|
|
54
|
+
// `/usr/bin/footprint` read. Forwarded verbatim; absent -> main.regions stays null.
|
|
55
|
+
regionSampler,
|
|
49
56
|
samplerOptions,
|
|
50
57
|
} = options;
|
|
51
58
|
// WP-4 (design doc §5 D-5, §8 WP-4): reuse the SAME 'mirrors-report' IPC round trip
|
|
@@ -62,6 +69,9 @@ function startServerMemorySamplerRuntime(options = {}) {
|
|
|
62
69
|
mirrorsSampler,
|
|
63
70
|
// Explicit workersSource wins; otherwise a workersSource carried in samplerOptions (test seam).
|
|
64
71
|
workersSource: typeof workersSource === 'function' ? workersSource : samplerOptions?.workersSource,
|
|
72
|
+
// WP-A P-2/P-3: forwarded the same way, so server.js's one call site wires all three probes.
|
|
73
|
+
inFlightSource: typeof inFlightSource === 'function' ? inFlightSource : samplerOptions?.inFlightSource,
|
|
74
|
+
regionSampler: regionSampler || samplerOptions?.regionSampler || null,
|
|
65
75
|
listProcesses: () => serverProcessList({ sessionHostManager, desktopIndex, errorSink }),
|
|
66
76
|
buildLedgerInput: () => ({
|
|
67
77
|
processMemory: process.memoryUsage(),
|
|
@@ -135,6 +135,15 @@ function createServerMemorySampler(options = {}) {
|
|
|
135
135
|
// liveDecoders } }] in raw bytes -- read from the read-pool/db-owner worker clients. Omitted ->
|
|
136
136
|
// workers[] is empty and workersTotal sums are 0 (never fabricated from nothing).
|
|
137
137
|
workersSource = () => [],
|
|
138
|
+
// WP-A P-2 (freeze-probes): () => any JSON-safe value describing the work in flight when the row
|
|
139
|
+
// was taken (read-pool ops, db-owner pending ops, recent main-loop spans). Stored verbatim on the
|
|
140
|
+
// row as `inFlight`; a throw or an absent source yields null ("unknown"), never a lost row.
|
|
141
|
+
inFlightSource = () => null,
|
|
142
|
+
// WP-A P-3 (freeze-probes): optional { sampleFootprintRegions(pid): Promise<{ totalMB, top }|null> }
|
|
143
|
+
// -- the CATEGORIZED `/usr/bin/footprint` read (lib/session-resource-sampler.js), a fresh spawn per
|
|
144
|
+
// call rather than the TTL-cached sampleFootprints() summary, so the region that just grew is
|
|
145
|
+
// named. Omitted -> main.regions stays null, never fabricated.
|
|
146
|
+
regionSampler = null,
|
|
138
147
|
now = () => Date.now(),
|
|
139
148
|
// Injectable so a test isn't forced to monkey-patch the process-global console (which
|
|
140
149
|
// would race other concurrently-running tests in the same file).
|
|
@@ -199,6 +208,17 @@ function createServerMemorySampler(options = {}) {
|
|
|
199
208
|
};
|
|
200
209
|
}
|
|
201
210
|
|
|
211
|
+
// WP-A P-2: the in-flight snapshot for this row. A broken/absent source reports null rather than
|
|
212
|
+
// failing the tick (same disposition as readWorkerMemory above).
|
|
213
|
+
function readInFlight() {
|
|
214
|
+
try {
|
|
215
|
+
return (typeof inFlightSource === 'function' ? inFlightSource() : null) ?? null;
|
|
216
|
+
} catch {
|
|
217
|
+
/* expected: the read-pool/db-owner clients can be mid-restart; "unknown in flight" beats a lost row */
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
202
222
|
async function sampleProcessesRss(pids) {
|
|
203
223
|
if (!pids.length) return new Map();
|
|
204
224
|
const psCommand = platform === 'darwin' ? '/bin/ps' : 'ps';
|
|
@@ -261,6 +281,18 @@ function createServerMemorySampler(options = {}) {
|
|
|
261
281
|
const mu = process.memoryUsage();
|
|
262
282
|
const mainProc = procs.find((p) => p.role === 'main') || null;
|
|
263
283
|
const poolProc = procs.find((p) => p.role === 'session-host-pool') || null;
|
|
284
|
+
// WP-A P-3: the MAIN process' categorized footprint regions -- the only read that can NAME the
|
|
285
|
+
// category behind a step (the 4<->9 GB swing is entirely "Malloc Large"). `null` (never
|
|
286
|
+
// fabricated) when unwired, when the main pid is unknown, or when the read failed.
|
|
287
|
+
let regions = null;
|
|
288
|
+
if (regionSampler && typeof regionSampler.sampleFootprintRegions === 'function' && mainProc && mainProc.pid) {
|
|
289
|
+
try {
|
|
290
|
+
regions = (await regionSampler.sampleFootprintRegions(mainProc.pid)) ?? null;
|
|
291
|
+
} catch {
|
|
292
|
+
/* expected: /usr/bin/footprint can be missing, denied or killed; the row must still record */
|
|
293
|
+
regions = null;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
264
296
|
const main = {
|
|
265
297
|
heapUsedMB: roundMB(mu.heapUsed),
|
|
266
298
|
externalMB: roundMB(mu.external),
|
|
@@ -273,6 +305,8 @@ function createServerMemorySampler(options = {}) {
|
|
|
273
305
|
footprintMB: mainProc ? mainProc.physFootprintMB : null,
|
|
274
306
|
// WP-0b (§5 D-2): main-thread's OWN live zstd contexts (workers report theirs separately).
|
|
275
307
|
liveDecoders: liveDecoderCount(),
|
|
308
|
+
// WP-A P-3: categorized footprint regions of this same pid (null when unwired/unsampled).
|
|
309
|
+
regions,
|
|
276
310
|
};
|
|
277
311
|
// WP-0b (§5 D-2, §9 S-9): per-worker heap/external/arrayBuffers + live decoder count, summed
|
|
278
312
|
// into workersTotal so the row explains what the main isolate's process.memoryUsage() cannot.
|
|
@@ -338,7 +372,10 @@ function createServerMemorySampler(options = {}) {
|
|
|
338
372
|
}
|
|
339
373
|
const ledger = compactLedgerSubset(fullLedger);
|
|
340
374
|
|
|
341
|
-
|
|
375
|
+
// WP-A P-2: the work in flight at sample time, so a step in rss/footprint can be read against
|
|
376
|
+
// what was running when it happened (`null` = unknown/not wired).
|
|
377
|
+
const inFlight = readInFlight();
|
|
378
|
+
const sample = { schemaVersion: SCHEMA_VERSION, reason, procs, main, poolHost, ledger, workers, workersTotal, inFlight };
|
|
342
379
|
if (typeof record === 'function') {
|
|
343
380
|
try { record('server-memory', sample); } catch { /* expected: a broken diagnostic sink must not break the sampler loop itself */ }
|
|
344
381
|
}
|
|
@@ -363,13 +400,15 @@ function createServerMemorySampler(options = {}) {
|
|
|
363
400
|
// WP-0b (§5 D-2, §9 S-9): run an extra sample whenever main RSS stepped >= minStepMB since the
|
|
364
401
|
// last recorded row. Never throws; returns the sample or null when skipped (no prior sample,
|
|
365
402
|
// caller rss unavailable, below threshold, an unrepresentable prior rss, or a sample in flight).
|
|
403
|
+
// WP-A P-3: the default threshold is 768 MB, not 2048 -- the live 2026-10-21 measurement showed the
|
|
404
|
+
// server's real steps are ~970 MB of "Malloc Large", which the old 2048 default silently skipped.
|
|
366
405
|
async function sampleIfStep(options = {}) {
|
|
367
406
|
try {
|
|
368
407
|
const opts = options && typeof options === 'object' ? options : {};
|
|
369
408
|
const target = Number(opts.rssMB);
|
|
370
409
|
if (!Number.isFinite(target)) return null;
|
|
371
410
|
if (!_lastMain || !Number.isFinite(Number(_lastMain.rssMB))) return null;
|
|
372
|
-
const threshold = Number.isFinite(Number(opts.minStepMB)) ? Number(opts.minStepMB) :
|
|
411
|
+
const threshold = Number.isFinite(Number(opts.minStepMB)) ? Number(opts.minStepMB) : 768;
|
|
373
412
|
if (Math.abs(target - Number(_lastMain.rssMB)) < threshold) return null;
|
|
374
413
|
return await sampleOnce({ reason: 'rss-step', rssMB: target });
|
|
375
414
|
} catch {
|
|
@@ -322,6 +322,8 @@ function loadCodingJournalOutcomes(sessionIds, options = {}) {
|
|
|
322
322
|
archived_at, consolidated_at, extraction_status
|
|
323
323
|
FROM memories INDEXED BY idx_memories_session_summary
|
|
324
324
|
WHERE archived_at IS NULL
|
|
325
|
+
AND source IN ('walle-coding', 'walle-diary')
|
|
326
|
+
AND memory_type IN ('coding_journal', 'coding_journal_segment', 'agent_diary')
|
|
325
327
|
AND source = 'walle-coding'
|
|
326
328
|
AND memory_type = 'coding_journal'
|
|
327
329
|
AND subject IN (${placeholders})
|