create-walle 0.10.2 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/lib/release-schema.json +2 -2
- package/lib/runtime-closure-policy.json +8 -7
- package/package.json +1 -1
- package/template/coding-task-manager/api-prompts.js +45 -7
- package/template/coding-task-manager/bin/claude-hook.js +55 -1
- package/template/coding-task-manager/bin/ctm-relay-client.js +35 -12
- package/template/coding-task-manager/bin/land.js +2069 -0
- package/template/coding-task-manager/bin/memory-census.js +4 -2
- package/template/coding-task-manager/bin/memory-sync-verify.js +151 -0
- package/template/coding-task-manager/bin/probe-refusal-scope.js +530 -0
- package/template/coding-task-manager/db.js +156 -32
- package/template/coding-task-manager/lib/acp/acp-client.js +383 -0
- package/template/coding-task-manager/lib/acp/dsh-context-truth.js +176 -0
- package/template/coding-task-manager/lib/acp/dsh-launch-model.js +302 -0
- package/template/coding-task-manager/lib/acp/dsh-mcp-servers.js +194 -0
- package/template/coding-task-manager/lib/acp/dsh-prompt-lane.js +616 -0
- package/template/coding-task-manager/lib/acp/dsh-route-patch.js +308 -0
- package/template/coding-task-manager/lib/acp/dsh-session-runtime.js +522 -0
- package/template/coding-task-manager/lib/acp/dsh-transcript.js +395 -0
- package/template/coding-task-manager/lib/acp/dsh-usage-log.js +162 -0
- package/template/coding-task-manager/lib/acp/ndjson-stdio-transport.js +225 -0
- package/template/coding-task-manager/lib/adopted-host-redial.js +47 -11
- package/template/coding-task-manager/lib/adopted-launch-environment.js +123 -0
- package/template/coding-task-manager/lib/agent-auto-update-runtime.js +0 -3
- package/template/coding-task-manager/lib/agent-auto-update.js +26 -10
- package/template/coding-task-manager/lib/agent-bundle/build.js +657 -0
- package/template/coding-task-manager/lib/agent-bundle/codex-install.js +558 -0
- package/template/coding-task-manager/lib/agent-bundle/drift.js +120 -0
- package/template/coding-task-manager/lib/agent-bundle/gc.js +522 -0
- package/template/coding-task-manager/lib/agent-bundle/inventory.js +346 -0
- package/template/coding-task-manager/lib/agent-bundle/push.js +717 -0
- package/template/coding-task-manager/lib/agent-bundle/skill-transfer.js +724 -0
- package/template/coding-task-manager/lib/agent-bundle/spawn.js +119 -0
- package/template/coding-task-manager/lib/agent-bundle/store.js +568 -0
- package/template/coding-task-manager/lib/agent-capabilities.js +142 -12
- package/template/coding-task-manager/lib/agent-cli-cache.js +30 -5
- package/template/coding-task-manager/lib/agent-definitions.js +19 -0
- package/template/coding-task-manager/lib/agent-hooks-codex-toml.js +28 -16
- package/template/coding-task-manager/lib/agent-hooks-codex-workspace.js +9 -1
- package/template/coding-task-manager/lib/agent-hooks-installer.js +23 -8
- package/template/coding-task-manager/lib/agent-hooks-prune.js +37 -11
- package/template/coding-task-manager/lib/agent-hooks-shim.js +105 -0
- package/template/coding-task-manager/lib/agent-presets.js +84 -1
- package/template/coding-task-manager/lib/agent-upgrade-jobs.js +12 -1
- package/template/coding-task-manager/lib/agent-version-service.js +74 -11
- package/template/coding-task-manager/lib/all-sessions-query.js +6 -2
- package/template/coding-task-manager/lib/api/agent-bundles.js +436 -0
- package/template/coding-task-manager/lib/api/backup-retention.js +83 -0
- package/template/coding-task-manager/lib/api/conversation-sync-routes.js +124 -0
- package/template/coding-task-manager/lib/api/diagnostics.js +549 -69
- package/template/coding-task-manager/lib/api/fleet.js +118 -0
- package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
- package/template/coding-task-manager/lib/api/ingress.js +9 -1
- package/template/coding-task-manager/lib/api/landing.js +403 -0
- package/template/coding-task-manager/lib/api/machines.js +691 -2
- package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
- package/template/coding-task-manager/lib/api/misc-ops.js +8 -3
- package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
- package/template/coding-task-manager/lib/api/session-attach.js +623 -0
- package/template/coding-task-manager/lib/api/session-messages.js +1384 -0
- package/template/coding-task-manager/lib/api/sessions.js +77 -51
- package/template/coding-task-manager/lib/api/setup-network.js +544 -16
- package/template/coding-task-manager/lib/api/setup-wizard-handlers.js +884 -0
- package/template/coding-task-manager/lib/api/setup.js +829 -10
- package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
- package/template/coding-task-manager/lib/attachment-reconciler-wiring.js +5 -2
- package/template/coding-task-manager/lib/auth-rate-limit.js +23 -0
- package/template/coding-task-manager/lib/auth-rules.js +292 -21
- package/template/coding-task-manager/lib/background-stop.js +369 -0
- package/template/coding-task-manager/lib/best-of-attempts.js +4 -1
- package/template/coding-task-manager/lib/best-of-launch-plan.js +52 -0
- package/template/coding-task-manager/lib/box-keep-awake.js +89 -0
- package/template/coding-task-manager/lib/broadcast-reason-stats.js +152 -0
- package/template/coding-task-manager/lib/broadcast-serialize.js +5 -0
- package/template/coding-task-manager/lib/build-info.js +4 -2
- package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
- package/template/coding-task-manager/lib/claude-transcript-terminal-renderer.js +17 -13
- package/template/coding-task-manager/lib/client-diag-handler.js +64 -2
- package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
- package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
- package/template/coding-task-manager/lib/codex-harness-qualification.js +43 -20
- package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
- package/template/coding-task-manager/lib/coding-agent-models.js +27 -12
- package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
- package/template/coding-task-manager/lib/coding-session-model-adapters.js +43 -2
- package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
- package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
- package/template/coding-task-manager/lib/coding-session-model-runtime.js +23 -4
- package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
- package/template/coding-task-manager/lib/coding-session-model-state.js +7 -0
- package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
- package/template/coding-task-manager/lib/conversation-item-clock.js +261 -0
- package/template/coding-task-manager/lib/conversation-source-registry.js +5 -0
- package/template/coding-task-manager/lib/conversation-store-v2.js +44 -0
- package/template/coding-task-manager/lib/conversation-sync.js +355 -0
- package/template/coding-task-manager/lib/create/resolve-launch-params.js +96 -12
- package/template/coding-task-manager/lib/create/worker-role-profile.js +4 -4
- package/template/coding-task-manager/lib/create-intent-lease.js +51 -0
- package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
- package/template/coding-task-manager/lib/db-domain-tables.js +1 -0
- package/template/coding-task-manager/lib/db-domains.js +1 -0
- package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
- package/template/coding-task-manager/lib/db-owner-request-counts.js +178 -0
- package/template/coding-task-manager/lib/db-owner-worker-client.js +68 -14
- package/template/coding-task-manager/lib/db-schema-source-files.js +5 -0
- package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
- package/template/coding-task-manager/lib/feature-manifest.js +4 -0
- package/template/coding-task-manager/lib/fleet-conversation-route.js +97 -0
- package/template/coding-task-manager/lib/fleet-fanout.js +78 -0
- package/template/coding-task-manager/lib/fleet-hub.js +762 -0
- package/template/coding-task-manager/lib/fleet-origin-follower.js +252 -0
- package/template/coding-task-manager/lib/fleet-resolver-effects.js +147 -0
- package/template/coding-task-manager/lib/fleet-resolver-tick.js +148 -0
- package/template/coding-task-manager/lib/fleet-resolver.js +454 -0
- package/template/coding-task-manager/lib/fleet-session-list-routes.js +114 -0
- package/template/coding-task-manager/lib/fleet-session-lists.js +672 -0
- package/template/coding-task-manager/lib/fleet-update.js +798 -0
- package/template/coding-task-manager/lib/fs-watcher-root-watch.js +141 -0
- package/template/coding-task-manager/lib/fs-watcher.js +58 -42
- package/template/coding-task-manager/lib/harness-history-transition.js +50 -9
- package/template/coding-task-manager/lib/headless-term-service.js +84 -8
- package/template/coding-task-manager/lib/hermetic-agent-launch-guard.js +10 -0
- package/template/coding-task-manager/lib/history-transition-read-op.js +175 -8
- package/template/coding-task-manager/lib/host-cpu-categories.js +310 -0
- package/template/coding-task-manager/lib/host-fseventsd-sampler.js +399 -0
- package/template/coding-task-manager/lib/host-handoff.js +16 -19
- package/template/coding-task-manager/lib/host-stats.js +150 -3
- package/template/coding-task-manager/lib/hosted-sync-worker.js +43 -320
- package/template/coding-task-manager/lib/hub-bridge-access.js +798 -0
- package/template/coding-task-manager/lib/hub-bridge-box.js +409 -0
- package/template/coding-task-manager/lib/hub-bridge-mcp.js +380 -0
- package/template/coding-task-manager/lib/hub-bridge-mesh.js +313 -0
- package/template/coding-task-manager/lib/hub-bridge-ops.js +721 -0
- package/template/coding-task-manager/lib/hub-bridge.js +398 -0
- package/template/coding-task-manager/lib/idle-notify.js +491 -0
- package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +8 -0
- package/template/coding-task-manager/lib/instance-manifest.js +5 -1
- package/template/coding-task-manager/lib/instance-sync-status.js +18 -8
- package/template/coding-task-manager/lib/landing/agent-rule.txt +1 -0
- package/template/coding-task-manager/lib/landing/batch-runner.js +366 -0
- package/template/coding-task-manager/lib/landing/config.js +536 -0
- package/template/coding-task-manager/lib/landing/ctm-view.js +256 -0
- package/template/coding-task-manager/lib/landing/gate.js +360 -0
- package/template/coding-task-manager/lib/landing/git.js +344 -0
- package/template/coding-task-manager/lib/landing/lease.js +247 -0
- package/template/coding-task-manager/lib/landing/merge-delta.js +380 -0
- package/template/coding-task-manager/lib/landing/proof.js +223 -0
- package/template/coding-task-manager/lib/landing/queue.js +998 -0
- package/template/coding-task-manager/lib/landing/radar.js +489 -0
- package/template/coding-task-manager/lib/landing/resolve-cli.js +424 -0
- package/template/coding-task-manager/lib/landing/state.js +263 -0
- package/template/coding-task-manager/lib/landing/stop.js +49 -0
- package/template/coding-task-manager/lib/landing/sync-cli.js +475 -0
- package/template/coding-task-manager/lib/landing/sync.js +456 -0
- package/template/coding-task-manager/lib/landing/train.js +885 -0
- package/template/coding-task-manager/lib/landing/window.js +57 -0
- package/template/coding-task-manager/lib/launch-environment.js +121 -0
- package/template/coding-task-manager/lib/launch-model-override.js +36 -10
- package/template/coding-task-manager/lib/launch-plan-pool.js +2 -1
- package/template/coding-task-manager/lib/launch-plan-warm-cache.js +6 -0
- package/template/coding-task-manager/lib/lead-model-observer.js +57 -1
- package/template/coding-task-manager/lib/lead-model-options.js +160 -3
- package/template/coding-task-manager/lib/lead-model-restore-reconciliation.js +106 -24
- package/template/coding-task-manager/lib/lead-model-switch-runtime.js +352 -68
- package/template/coding-task-manager/lib/lead-model-switch.js +114 -10
- package/template/coding-task-manager/lib/lead-model-transition-runtime.js +14 -2
- package/template/coding-task-manager/lib/lead-model-transition-store.js +24 -6
- package/template/coding-task-manager/lib/lead-route-preflight.js +179 -0
- package/template/coding-task-manager/lib/lead-switch-history-mode.js +110 -0
- package/template/coding-task-manager/lib/lead-wire-agent.js +7 -0
- package/template/coding-task-manager/lib/lifecycle-wake-experiment.js +9 -2
- package/template/coding-task-manager/lib/live-defer-announce.js +45 -0
- package/template/coding-task-manager/lib/machine-registry.js +750 -5
- package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
- package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +433 -53
- package/template/coding-task-manager/lib/mainloop-observability.js +14 -9
- package/template/coding-task-manager/lib/media-draft-owner.js +16 -3
- package/template/coding-task-manager/lib/memory-join.js +337 -0
- package/template/coding-task-manager/lib/memory-sync-verify.js +393 -0
- package/template/coding-task-manager/lib/memory-sync.js +565 -0
- package/template/coding-task-manager/lib/migrations/v57-delegate-pref-mirror-opencode.js +68 -0
- package/template/coding-task-manager/lib/migrations/v58-subagent-launch-native-subagents.js +42 -0
- package/template/coding-task-manager/lib/migrations/v59-coding-session-model-state-dsh.js +73 -0
- package/template/coding-task-manager/lib/migrations/v60-delegate-pref-mirror-dsh.js +78 -0
- package/template/coding-task-manager/lib/migrations/v61-conversation-item-clock.js +71 -0
- package/template/coding-task-manager/lib/model-availability.js +727 -0
- package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +4 -6
- package/template/coding-task-manager/lib/model-host-receipt.js +6 -3
- package/template/coding-task-manager/lib/model-id-rule.js +19 -0
- package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
- package/template/coding-task-manager/lib/model-proxy/auto-mode-review.js +110 -23
- package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
- package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
- package/template/coding-task-manager/lib/model-proxy/historical-tool-declarations.js +37 -0
- package/template/coding-task-manager/lib/model-proxy/lead-request-validation.js +1 -0
- package/template/coding-task-manager/lib/model-proxy/lead-token-admin.js +130 -0
- package/template/coding-task-manager/lib/model-proxy/refusal-scope.js +151 -0
- package/template/coding-task-manager/lib/model-proxy/request-budget-store.js +11 -2
- package/template/coding-task-manager/lib/model-proxy/tokens.js +69 -5
- package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
- package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
- package/template/coding-task-manager/lib/native-history-control.js +6 -4
- package/template/coding-task-manager/lib/native-lead-settings-client.js +44 -4
- package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +173 -36
- package/template/coding-task-manager/lib/online-backup-worker-client.js +2 -0
- package/template/coding-task-manager/lib/opencode-cli.js +480 -0
- package/template/coding-task-manager/lib/opencode-launch-model.js +471 -0
- package/template/coding-task-manager/lib/opencode-v1-plugin/model-carrier.mjs +35 -0
- package/template/coding-task-manager/lib/opencode-v2-plugin/server.js +118 -0
- package/template/coding-task-manager/lib/owner-action-manifest-data.json +1 -1
- package/template/coding-task-manager/lib/park-composer-draft.js +54 -0
- package/template/coding-task-manager/lib/park-fresh-relaunch.js +41 -10
- package/template/coding-task-manager/lib/perf-phase-trace.js +72 -0
- package/template/coding-task-manager/lib/perf-summary.js +7 -0
- package/template/coding-task-manager/lib/perf-tracker.js +63 -2
- package/template/coding-task-manager/lib/project-config.js +7 -0
- package/template/coding-task-manager/lib/prompt-purge-v2.js +52 -1
- package/template/coding-task-manager/lib/provider-login-broker.js +72 -15
- package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
- package/template/coding-task-manager/lib/read-pool-client.js +89 -2
- package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
- package/template/coding-task-manager/lib/recent-catalog-query.js +15 -0
- package/template/coding-task-manager/lib/recent-session-catalog-response.js +67 -10
- package/template/coding-task-manager/lib/recovery-evidence.js +26 -11
- package/template/coding-task-manager/lib/relay-client.js +57 -3
- package/template/coding-task-manager/lib/relink-audit.js +34 -5
- package/template/coding-task-manager/lib/remote-machine-catalog.js +321 -26
- package/template/coding-task-manager/lib/remote-machine-create.js +576 -36
- package/template/coding-task-manager/lib/remote-machine-link.js +546 -59
- package/template/coding-task-manager/lib/remote-machine-proxy.js +143 -9
- package/template/coding-task-manager/lib/remote-session-forward.js +65 -7
- package/template/coding-task-manager/lib/remote-terminal-target.js +9 -2
- package/template/coding-task-manager/lib/restart-guard.js +18 -6
- package/template/coding-task-manager/lib/restore-seed-modes.js +87 -0
- package/template/coding-task-manager/lib/restored-scrollback-hydration-runtime.js +22 -2
- package/template/coding-task-manager/lib/resume-admission.js +17 -3
- package/template/coding-task-manager/lib/review-repo-registry.js +58 -19
- package/template/coding-task-manager/lib/root-delivery-runtime.js +2 -2
- package/template/coding-task-manager/lib/root-prompt-flow.js +1 -1
- package/template/coding-task-manager/lib/runtime-contract.js +3 -1
- package/template/coding-task-manager/lib/schema-indexes.js +1 -0
- package/template/coding-task-manager/lib/session-context-locator.js +742 -0
- package/template/coding-task-manager/lib/session-create/attachment.js +2 -2
- package/template/coding-task-manager/lib/session-create/create-phases.js +118 -0
- package/template/coding-task-manager/lib/session-create/delegate-worker.js +86 -16
- package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
- package/template/coding-task-manager/lib/session-create/lead-route-launch.js +186 -13
- package/template/coding-task-manager/lib/session-create/native-lead-lifetime.js +55 -3
- package/template/coding-task-manager/lib/session-create/opencode-lead-provider.js +50 -0
- package/template/coding-task-manager/lib/session-create/prepared.js +162 -38
- package/template/coding-task-manager/lib/session-create/provider-process.js +160 -28
- package/template/coding-task-manager/lib/session-create/response.js +7 -7
- package/template/coding-task-manager/lib/session-create/structured-session.js +27 -0
- package/template/coding-task-manager/lib/session-create/subagent-pick-table.js +3 -1
- package/template/coding-task-manager/lib/session-create/subagent-pick.js +458 -9
- package/template/coding-task-manager/lib/session-create/transcript.js +1 -1
- package/template/coding-task-manager/lib/session-create/worker-budget-setup.js +21 -2
- package/template/coding-task-manager/lib/session-create/worker-continuation.js +7 -1
- package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
- package/template/coding-task-manager/lib/session-create/worker-observability.js +2 -2
- package/template/coding-task-manager/lib/session-empty.js +13 -10
- package/template/coding-task-manager/lib/session-host-manager.js +60 -0
- package/template/coding-task-manager/lib/session-jobs.js +3 -1
- package/template/coding-task-manager/lib/session-lifecycle.js +10 -4
- package/template/coding-task-manager/lib/session-model-action-preconditions.js +6 -2
- package/template/coding-task-manager/lib/session-model-intent-contract.js +11 -8
- package/template/coding-task-manager/lib/session-park.js +738 -0
- package/template/coding-task-manager/lib/session-path-grant.js +13 -4
- package/template/coding-task-manager/lib/session-status-ledger.js +106 -4
- package/template/coding-task-manager/lib/session-transport.js +17 -0
- package/template/coding-task-manager/lib/session-workspace-projection.js +54 -5
- package/template/coding-task-manager/lib/session-workspace-tracking-runtime.js +213 -1
- package/template/coding-task-manager/lib/skill-autocomplete-query.js +120 -3
- package/template/coding-task-manager/lib/skill-autocomplete.js +15 -1
- package/template/coding-task-manager/lib/sqlite-file-set.js +39 -0
- package/template/coding-task-manager/lib/standup-search-adapter.js +16 -2
- package/template/coding-task-manager/lib/state-sync/client-ledger.js +12 -0
- package/template/coding-task-manager/lib/state-sync/frame-emitter.js +319 -100
- package/template/coding-task-manager/lib/storage/coding-session-model-store.js +4 -1
- package/template/coding-task-manager/lib/storage/delegate-pref-mirror-store.js +32 -9
- package/template/coding-task-manager/lib/structured-session-boot-sweep.js +235 -0
- package/template/coding-task-manager/lib/submission-ack.js +90 -2
- package/template/coding-task-manager/lib/systemd-scope.js +115 -0
- package/template/coding-task-manager/lib/telemetry-receiver.js +39 -0
- package/template/coding-task-manager/lib/terminal-attach-geometry.js +985 -0
- package/template/coding-task-manager/lib/terminal-bootstrap.js +30 -0
- package/template/coding-task-manager/lib/terminal-draft-operation.js +357 -0
- package/template/coding-task-manager/lib/terminal-input-admission.js +17 -1
- package/template/coding-task-manager/lib/terminal-input-prepared.js +563 -0
- package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
- package/template/coding-task-manager/lib/transcript-frame-cache.js +8 -3
- package/template/coding-task-manager/lib/transcript-source.js +36 -4
- package/template/coding-task-manager/lib/transcript-store.js +9 -0
- package/template/coding-task-manager/lib/typing-interaction-trace.js +106 -3
- package/template/coding-task-manager/lib/usage-ledger/backfill.js +40 -5
- package/template/coding-task-manager/lib/usage-ledger/client.js +4 -1
- package/template/coding-task-manager/lib/usage-ledger/dsh-parse.js +152 -0
- package/template/coding-task-manager/lib/usage-ledger/dsh-read.js +73 -0
- package/template/coding-task-manager/lib/usage-ledger/ingest.js +34 -6
- package/template/coding-task-manager/lib/usage-ledger/live.js +35 -8
- package/template/coding-task-manager/lib/usage-ledger/read.js +29 -20
- package/template/coding-task-manager/lib/usage-ledger/schema.js +61 -1
- package/template/coding-task-manager/lib/usage-ledger/task-coordinator.js +4 -2
- package/template/coding-task-manager/lib/wake-skip-reasons.js +1 -0
- package/template/coding-task-manager/lib/walle/turn.js +1 -1
- package/template/coding-task-manager/lib/walle-history-serve.js +838 -0
- package/template/coding-task-manager/lib/walle-kill-authority.js +2 -2
- package/template/coding-task-manager/lib/walle-log-rotation.js +164 -1
- package/template/coding-task-manager/lib/walle-mcp-auto-config.js +56 -2
- package/template/coding-task-manager/lib/walle-row-history.js +495 -0
- package/template/coding-task-manager/lib/walle-supervisor.js +33 -14
- package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
- package/template/coding-task-manager/lib/worker-terminal-output.js +5 -2
- package/template/coding-task-manager/lib/ws/hub-bridge.js +35 -0
- package/template/coding-task-manager/lib/ws/lifecycle.js +6 -11
- package/template/coding-task-manager/lib/ws/misc.js +1 -1
- package/template/coding-task-manager/lib/ws/state-sync.js +106 -4
- package/template/coding-task-manager/lib/ws/terminal-attach.js +91 -0
- package/template/coding-task-manager/oauth-proxy.js +112 -115
- package/template/coding-task-manager/package-lock.json +10 -94
- package/template/coding-task-manager/package.json +4 -3
- package/template/coding-task-manager/protocol/message-table.json +10 -0
- package/template/coding-task-manager/protocol/messages.js +10 -0
- package/template/coding-task-manager/protocol/ws-schema.json +20 -0
- package/template/coding-task-manager/protocol/ws-schema.md +2 -0
- package/template/coding-task-manager/public/css/app.css +170 -0
- package/template/coding-task-manager/public/css/walle-session.css +4 -0
- package/template/coding-task-manager/public/index.html +473 -243
- package/template/coding-task-manager/public/js/agent-command.js +86 -0
- package/template/coding-task-manager/public/js/app/backups-panel.js +111 -5
- package/template/coding-task-manager/public/js/app/coding-agent-upgrade.js +103 -4
- package/template/coding-task-manager/public/js/app/machines-page.js +1328 -8
- package/template/coding-task-manager/public/js/app/models-tab.js +113 -38
- package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
- package/template/coding-task-manager/public/js/app/worktrees-panel.js +184 -2
- package/template/coding-task-manager/public/js/background-work.js +196 -27
- package/template/coding-task-manager/public/js/coding-session-model-presentation.js +138 -10
- package/template/coding-task-manager/public/js/core/active-session-groups.js +179 -0
- package/template/coding-task-manager/public/js/core/pending-create.js +238 -0
- package/template/coding-task-manager/public/js/core/recent-machine-source.js +228 -0
- package/template/coding-task-manager/public/js/core/session-commands.js +180 -14
- package/template/coding-task-manager/public/js/dashboard-client-function-order.json +8 -0
- package/template/coding-task-manager/public/js/document-review-links.js +9 -1
- package/template/coding-task-manager/public/js/file-resolution-client.js +52 -1
- package/template/coding-task-manager/public/js/history-app-seam.js +22 -2
- package/template/coding-task-manager/public/js/machine-pool-shared.js +558 -3
- package/template/coding-task-manager/public/js/message-renderer.js +4 -3
- package/template/coding-task-manager/public/js/model-picker.js +3 -1
- package/template/coding-task-manager/public/js/native-subagent-review.js +15 -2
- package/template/coding-task-manager/public/js/new-session-agent-grid.js +346 -0
- package/template/coding-task-manager/public/js/pasted-content.js +236 -0
- package/template/coding-task-manager/public/js/pe-private-content-lifetime.js +39 -7
- package/template/coding-task-manager/public/js/private-model-lifetime.js +6 -2
- package/template/coding-task-manager/public/js/prompts.js +11 -10
- package/template/coding-task-manager/public/js/protocol.js +10 -0
- package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -1
- package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
- package/template/coding-task-manager/public/js/session-search-utils.js +18 -2
- package/template/coding-task-manager/public/js/session-usage-view.js +2 -1
- package/template/coding-task-manager/public/js/session-workspace-tracking.js +51 -1
- package/template/coding-task-manager/public/js/state-sync-client.js +10 -1
- package/template/coding-task-manager/public/js/stream-view.js +6 -5
- package/template/coding-task-manager/public/js/terminal/conv-only-session.js +287 -0
- package/template/coding-task-manager/public/js/terminal/runtime-09.js +2 -0
- package/template/coding-task-manager/public/js/terminal/runtime-10.js +5 -5
- package/template/coding-task-manager/public/js/terminal/runtime-12.js +8 -1
- package/template/coding-task-manager/public/js/terminal/runtime-16.js +4 -0
- package/template/coding-task-manager/public/js/terminal/runtime-20.js +1 -1
- package/template/coding-task-manager/public/js/terminal-attachment-draft.js +67 -13
- package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
- package/template/coding-task-manager/public/js/terminal-wheel.js +23 -3
- package/template/coding-task-manager/public/js/walle/chat-conversation.js +4 -4
- package/template/coding-task-manager/public/js/walle.js +6 -0
- package/template/coding-task-manager/public/js/ws/live-dispatch.js +10 -0
- package/template/coding-task-manager/public/m/app.css +140 -0
- package/template/coding-task-manager/public/m/app.js +507 -68
- package/template/coding-task-manager/public/m/index.html +17 -0
- package/template/coding-task-manager/public/m/machines.js +838 -4
- package/template/coding-task-manager/public/m/private-api.js +31 -1
- package/template/coding-task-manager/public/usage.html +1 -0
- package/template/coding-task-manager/scripts/dev-route-fixture/synthetic-route-upstream.js +104 -0
- package/template/coding-task-manager/scripts/dev-route-fixture.js +339 -0
- package/template/coding-task-manager/scripts/opencode-lead-route-probe.js +195 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe/fake-anthropic.js +168 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe/probe-plugin/server.js +95 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe.js +673 -0
- package/template/coding-task-manager/server.js +1950 -11679
- package/template/coding-task-manager/session-integrity.js +64 -4
- package/template/coding-task-manager/workers/db-owner-worker.js +19 -2
- package/template/coding-task-manager/workers/online-backup-worker.js +1 -0
- package/template/coding-task-manager/workers/read-pool-model-collector.js +51 -3
- package/template/coding-task-manager/workers/read-pool-worker.js +76 -6
- package/template/coding-task-manager/workers/session-host-pool-process.js +6 -6
- package/template/coding-task-manager/workers/session-host-process.js +5 -5
- package/template/coding-task-manager/workers/watch-worker.js +105 -0
- package/template/coding-task-manager/workers/worktree-worker.js +168 -33
- package/template/ctm-relay/lib/protocol.js +14 -1
- package/template/package-lock.json +2 -2
- package/template/package.json +1 -1
- package/template/shared/backup-retention.js +82 -0
- package/template/shared/conversation-admission.js +2 -0
- package/template/shared/conversation-provenance.js +3 -7
- package/template/shared/conversation-storage-v2-contract.js +5 -0
- package/template/shared/linked-worktree.js +51 -0
- package/template/shared/macos-fda-target.js +57 -0
- package/template/shared/orphan-parents.js +55 -0
- package/template/shared/release-schema.json +2 -2
- package/template/shared/storage/contract.js +3 -0
- package/template/wall-e/adapters/imessage.js +12 -0
- package/template/wall-e/agent.js +71 -4
- package/template/wall-e/api-walle.js +21 -1
- package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
- package/template/wall-e/bin/walle-mcp-stdio.js +5 -5
- package/template/wall-e/brain/brain-join.js +859 -0
- package/template/wall-e/brain/brain-sync-membership.js +20 -0
- package/template/wall-e/brain/brain-sync-store.js +131 -77
- package/template/wall-e/brain/brain-sync-v2-schema.js +203 -0
- package/template/wall-e/brain/brain-sync-v2.js +578 -0
- package/template/wall-e/brain/delegate-model-prefs-store.js +13 -4
- package/template/wall-e/brain/deterministic-id.js +51 -0
- package/template/wall-e/brain/memories.js +2 -2
- package/template/wall-e/brain/migrations.js +40 -6
- package/template/wall-e/brain/model-identity-migration.js +1 -1
- package/template/wall-e/brain/owner-call-whitelist.js +23 -7
- package/template/wall-e/brain/schema.js +45 -85
- package/template/wall-e/brain.js +171 -35
- package/template/wall-e/chat.js +3 -3
- package/template/wall-e/coding/agent-shell-env.js +7 -2
- package/template/wall-e/coding/prompt-bundle.js +66 -21
- package/template/wall-e/config/main-loop-exemptions.json +2 -2
- package/template/wall-e/http/admin-api.js +37 -0
- package/template/wall-e/http/gws-api.js +4 -0
- package/template/wall-e/http/helper-rules-api.js +7 -1
- package/template/wall-e/http/model-admin.js +8 -1
- package/template/wall-e/http/model-delegate-pref-admin.js +3 -3
- package/template/wall-e/http/model-proxy-providers.js +174 -1
- package/template/wall-e/http/model-route-health.js +157 -0
- package/template/wall-e/http/sync-api.js +278 -464
- package/template/wall-e/jobs/job-runner.js +28 -1
- package/template/wall-e/lib/brain-owner-op-priority.js +9 -1
- package/template/wall-e/lib/ctm-data-dir.js +26 -0
- package/template/wall-e/lib/derivation-home.js +147 -0
- package/template/wall-e/lib/helper-rules/evaluate.js +50 -9
- package/template/wall-e/lib/helper-rules/grade.js +51 -8
- package/template/wall-e/lib/helper-rules/lead-call-hook.js +38 -5
- package/template/wall-e/lib/helper-rules/store.js +4 -2
- package/template/wall-e/lib/landing-mcp-tools.js +170 -0
- package/template/wall-e/lib/mcp-client-config.js +133 -14
- package/template/wall-e/lib/mcp-gateway-migrate.js +28 -64
- package/template/wall-e/lib/mcp-integration.js +58 -13
- package/template/wall-e/lib/parent-death.js +7 -1
- package/template/wall-e/lib/scheduler-worker-jobs.js +6 -4
- package/template/wall-e/llm/delegate-lead-prefs.js +16 -1
- package/template/wall-e/llm/delegate-vendor-default.js +12 -5
- package/template/wall-e/llm/model-roles.js +1 -1
- package/template/wall-e/llm/native-delegate-selection.js +56 -8
- package/template/wall-e/llm/worker-delegate-args.js +72 -7
- package/template/wall-e/llm/worker-mcp-routing.js +66 -17
- package/template/wall-e/loops/brain-custom-writes.js +19 -0
- package/template/wall-e/loops/ingest.js +17 -1
- package/template/wall-e/loops/think.js +19 -4
- package/template/wall-e/mcp-contract.js +222 -6
- package/template/wall-e/mcp-protocol-contract.js +40 -5
- package/template/wall-e/mcp-server.js +128 -29
- package/template/wall-e/mcp-worker-schemas.js +5 -5
- package/template/wall-e/memory/ctm-context-client.js +85 -0
- package/template/wall-e/memory/ctm-session-context.js +9 -3
- package/template/wall-e/memory/hub-bridge-client.js +388 -0
- package/template/wall-e/memory/replica-origin.js +56 -0
- package/template/wall-e/memory/session-pool.js +135 -0
- package/template/wall-e/runtime/live-capabilities.js +8 -3
- package/template/wall-e/server.js +4 -2
- package/template/wall-e/shared/release-schema.json +2 -2
- package/template/wall-e/shared/sqlite-file-set.js +39 -0
- package/template/wall-e/shared/storage/contract.js +3 -0
- package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
- package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +7 -1
- package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +4 -4
- package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +6 -6
- package/template/wall-e/skills/_templates/fleet-sync/VERSION +1 -0
- package/template/wall-e/skills/_templates/fleet-sync/released-sha256.json +16 -0
- package/template/wall-e/skills/_templates/fleet-sync/templates/claude/SKILL.md +64 -0
- package/template/wall-e/skills/_templates/fleet-sync/templates/codex/SKILL.md +64 -0
- package/template/wall-e/tools/chrome-automation.js +6 -0
- package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
- package/template/wall-e/workers/brain-owner-worker.js +18 -4
- package/template/wall-e/workers/mcp-gateway-process.js +5 -5
package/template/wall-e/brain.js
CHANGED
|
@@ -15,8 +15,12 @@ const path = require('path');
|
|
|
15
15
|
const fs = require('fs');
|
|
16
16
|
const os = require('os');
|
|
17
17
|
const { createMigrationRunner, pragmaVersionStore, MigrationFailedError } = require('./shared/db-migration-runner');
|
|
18
|
+
const { removeSqliteFileSet } = require('./shared/sqlite-file-set');
|
|
19
|
+
// Shared backup-retention policy (R-1..R-6): one pure module both CTM and Wall-E call.
|
|
20
|
+
const backupRetention = require('../shared/backup-retention');
|
|
18
21
|
const crypto = require('crypto');
|
|
19
22
|
const { randomUUID: uuidv4 } = require('node:crypto');
|
|
23
|
+
const { deterministicEntityId } = require('./brain/deterministic-id'); // WP-0 §5 D-4: cross-machine entity identity
|
|
20
24
|
const { isMainThread, threadId } = require('node:worker_threads');
|
|
21
25
|
const { EventEmitter } = require('events');
|
|
22
26
|
const { createWriteAuditLog } = require('./db/write-audit');
|
|
@@ -107,6 +111,7 @@ function _isProtectedDevContext() {
|
|
|
107
111
|
if (process.env.NODE_ENV === 'test') return 'NODE_ENV=test';
|
|
108
112
|
if (/^test/.test(process.env.npm_lifecycle_event || '')) return 'npm_lifecycle_event';
|
|
109
113
|
if ([...process.execArgv, ...process.argv.slice(1)].some((a) => a === '--test')) return 'node --test';
|
|
114
|
+
if (require('../shared/linked-worktree').isLinkedWorktreeCheckout(__dirname)) return 'linked git worktree (unmerged branch code)'; // 2026-10-31 v59 incident
|
|
110
115
|
return null;
|
|
111
116
|
}
|
|
112
117
|
|
|
@@ -365,6 +370,22 @@ function _resetCloneSensitiveCursors(d) {
|
|
|
365
370
|
return reset;
|
|
366
371
|
}
|
|
367
372
|
|
|
373
|
+
// WP-0 (§5 D-4, §6.1): publish this host's own instance id to the v2 clock tables, so the
|
|
374
|
+
// capture triggers can stamp an addressable (origin_instance_id, origin_seq) without a kv
|
|
375
|
+
// lookup on every write (they read brain_local_identity, and fall back to '' — the v1
|
|
376
|
+
// "this host" convention — until this row exists). Host-local by construction: the row is
|
|
377
|
+
// never replicated and never part of a snapshot join (D-7). Runs after the identity step, so
|
|
378
|
+
// the id it reads is the one this boot resolved.
|
|
379
|
+
function _ensureBrainLocalClockIdentity(d) {
|
|
380
|
+
if (!_tableExists(d, 'brain_local_identity')) return;
|
|
381
|
+
const instanceId = require('./brain/brain-sync-store').localBrainInstanceId(d);
|
|
382
|
+
if (!instanceId) return;
|
|
383
|
+
d.prepare(`
|
|
384
|
+
INSERT INTO brain_local_identity (id, instance_id) VALUES (1, ?)
|
|
385
|
+
ON CONFLICT(id) DO UPDATE SET instance_id = excluded.instance_id
|
|
386
|
+
`).run(instanceId);
|
|
387
|
+
}
|
|
388
|
+
|
|
368
389
|
function _ensureBrainHostIdentity(d, dbPath) {
|
|
369
390
|
const identityContext = _brainHostIdentityContext(dbPath);
|
|
370
391
|
const dataDir = identityContext.dataDir;
|
|
@@ -546,6 +567,23 @@ function getBackupDirInfo() {
|
|
|
546
567
|
};
|
|
547
568
|
}
|
|
548
569
|
|
|
570
|
+
function getBackupRetentionInfo() {
|
|
571
|
+
let stored = null;
|
|
572
|
+
try { if (db) stored = getKv(backupRetention.BACKUP_RETENTION_SETTING_KEY); } catch { /* expected: kv_store not yet migrated on a fresh/old brain — the default retention applies */ }
|
|
573
|
+
return {
|
|
574
|
+
retention_days: backupRetention.normalizeRetentionDays(stored),
|
|
575
|
+
default_retention_days: backupRetention.DEFAULT_BACKUP_RETENTION_DAYS,
|
|
576
|
+
min: backupRetention.MIN_BACKUP_RETENTION_DAYS,
|
|
577
|
+
max: backupRetention.MAX_BACKUP_RETENTION_DAYS,
|
|
578
|
+
source: (stored !== null && stored !== undefined && stored !== '') ? 'settings' : 'default',
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
function setBackupRetentionDays(days) {
|
|
583
|
+
setKv(backupRetention.BACKUP_RETENTION_SETTING_KEY, String(backupRetention.normalizeRetentionDays(days)));
|
|
584
|
+
return getBackupRetentionInfo();
|
|
585
|
+
}
|
|
586
|
+
|
|
549
587
|
function _applyPersistedBackupDirSetting() {
|
|
550
588
|
try {
|
|
551
589
|
if (!db) return;
|
|
@@ -1990,6 +2028,8 @@ function initDb(dbPath) {
|
|
|
1990
2028
|
_bootSchemaVersion = Number(newDb.pragma('user_version', { simple: true }));
|
|
1991
2029
|
}
|
|
1992
2030
|
boot.measure('initDb.hostIdentity', () => _retryBusySync(() => _ensureBrainHostIdentity(newDb, dbPath), bootLockWaitMs));
|
|
2031
|
+
// WP-0 §6.1: the v2 clock's copy of the identity this boot just resolved (host-local row).
|
|
2032
|
+
boot.measure('initDb.brainLocalIdentity', () => _retryBusySync(() => _ensureBrainLocalClockIdentity(newDb), bootLockWaitMs));
|
|
1993
2033
|
// R-6: a responder mode configured BEFORE the db was open (agent.js reads the config
|
|
1994
2034
|
// ahead of initDb) lands AFTER the identity step — so explicit config overrides a
|
|
1995
2035
|
// clone verdict made in this same boot, and the owner sees the row on its next read.
|
|
@@ -3016,37 +3056,115 @@ function _quickCheckBackupFile(filePath) {
|
|
|
3016
3056
|
return _quickCheckFile(filePath);
|
|
3017
3057
|
}
|
|
3018
3058
|
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3059
|
+
// A backup runs for minutes, but shutdown forces the DB closed after 1 s and terminates the
|
|
3060
|
+
// process after 1.5 s (agent.js:2069-2070 via workers/brain-owner-worker.js:637-638), so a
|
|
3061
|
+
// backup killed mid-flight runs NO cleanup at all. The dot-name is invisible to listBackups()
|
|
3062
|
+
// and cleanOldBackups() (both filter on the non-dot `wall-e-brain-` prefix), so those strands
|
|
3063
|
+
// accumulated unseen — 6.6 GB observed on 2026-10-25. The owner pid in the name is the whole
|
|
3064
|
+
// ownership record: a dead pid's set is garbage no reader can use, and this process's own
|
|
3065
|
+
// leftovers are stale unless they are the caller's live tmpPath. Non-dot names are never touched.
|
|
3066
|
+
const STALE_BACKUP_TEMP_RE = /^\.wall-e-brain-.+\.db\.(\d+)\.tmp(-journal|-wal|-shm)?$/;
|
|
3022
3067
|
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3068
|
+
// Temps this process is writing RIGHT NOW. createBackup registers its tmpPath here for the whole
|
|
3069
|
+
// write (added before the sweep, removed in a finally), so an overlapping createBackup in the same
|
|
3070
|
+
// process — ensureDailyBackup plus a prompt-purge or a manual backup — cannot sweep the other
|
|
3071
|
+
// call's live file: unlinking it would let better-sqlite3 keep copying into a dead inode and the
|
|
3072
|
+
// in-flight backup would then fail at its rename.
|
|
3073
|
+
const _inFlightBackupTemps = new Set();
|
|
3028
3074
|
|
|
3029
|
-
|
|
3030
|
-
fs.rmSync(tmpPath, { force: true });
|
|
3075
|
+
function _isProcessAliveByPid(pid) {
|
|
3031
3076
|
try {
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
//
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3077
|
+
process.kill(pid, 0);
|
|
3078
|
+
return true;
|
|
3079
|
+
} catch (err) {
|
|
3080
|
+
// EPERM means the pid exists but is owned by another user — alive, not reclaimable.
|
|
3081
|
+
return err && err.code === 'EPERM';
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
|
|
3085
|
+
/** Reclaim dot-temps stranded in `backupDir` by an earlier backup run.
|
|
3086
|
+
* `keepPath` (this call's own tmpPath) is exempted; everything else whose name carries a dead
|
|
3087
|
+
* pid, or this process's pid, is unlinked. Returns the number of files removed. */
|
|
3088
|
+
function sweepStaleBackupTemps(backupDir, { keepPath = null, isProcessAlive } = {}) {
|
|
3089
|
+
if (!backupDir || !fs.existsSync(backupDir)) return 0;
|
|
3090
|
+
const alive = typeof isProcessAlive === 'function' ? isProcessAlive : _isProcessAliveByPid;
|
|
3091
|
+
const keepBase = keepPath ? path.basename(keepPath) : null;
|
|
3092
|
+
let removed = 0;
|
|
3093
|
+
for (const name of fs.readdirSync(backupDir)) {
|
|
3094
|
+
const match = STALE_BACKUP_TEMP_RE.exec(name);
|
|
3095
|
+
if (!match) continue;
|
|
3096
|
+
const pid = Number(match[1]);
|
|
3097
|
+
const base = name.slice(0, name.length - (match[2] || '').length);
|
|
3098
|
+
if (pid === process.pid) {
|
|
3099
|
+
// This process's own temps: never unlink `keepPath`, and never unlink a temp another
|
|
3100
|
+
// createBackup call in this process is still writing (see _inFlightBackupTemps).
|
|
3101
|
+
if (keepBase !== null && base === keepBase) continue;
|
|
3102
|
+
if (_inFlightBackupTemps.has(path.resolve(backupDir, base))) continue;
|
|
3103
|
+
} else if (alive(pid)) {
|
|
3104
|
+
continue; // a live peer may still be writing it
|
|
3105
|
+
}
|
|
3106
|
+
try {
|
|
3107
|
+
fs.unlinkSync(path.join(backupDir, name));
|
|
3108
|
+
removed += 1;
|
|
3109
|
+
} catch (err) {
|
|
3110
|
+
if (err && err.code === 'ENOENT') continue; // HANDLE: a peer swept the same temp first
|
|
3111
|
+
throw err; // RETHROW: a real unlink failure must not be swallowed
|
|
3112
|
+
}
|
|
3113
|
+
}
|
|
3114
|
+
return removed;
|
|
3115
|
+
}
|
|
3116
|
+
|
|
3117
|
+
// WP-4 (§5 D-6, §6.7 P-1): the consistent-snapshot primitive shared by the daily/manual backup
|
|
3118
|
+
// and the join snapshot route. Copies the LIVE brain to `destPath` through better-sqlite3's online
|
|
3119
|
+
// backup API — page batches that yield to the event loop (default 100 pages/batch), so a multi-GB
|
|
3120
|
+
// brain never freezes the loop, unlike the old synchronous `VACUUM INTO` (30-120s blocked). Like
|
|
3121
|
+
// VACUUM INTO it reads a consistent snapshot via a read transaction and does not force a WAL
|
|
3122
|
+
// checkpoint that would perturb peer processes; SQLite transparently re-copies any pages a peer
|
|
3123
|
+
// writes mid-backup. The image is written to a dot-temp beside the destination and validated with
|
|
3124
|
+
// quick_check before it is renamed into place, so a killed run strands a dot-temp (reclaimed by
|
|
3125
|
+
// sweepStaleBackupTemps), never a half-written snapshot. Returns { path }.
|
|
3126
|
+
async function createConsistentSnapshot(destPath) {
|
|
3127
|
+
getDb(); // throws if not initialized
|
|
3128
|
+
const dest = path.resolve(destPath);
|
|
3129
|
+
const dir = path.dirname(dest);
|
|
3130
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
3131
|
+
const tmpPath = path.join(dir, `.${path.basename(dest)}.${process.pid}.tmp`);
|
|
3132
|
+
|
|
3133
|
+
// Claim this tmpPath before anything touches the dir: the sweep below (and any overlapping
|
|
3134
|
+
// snapshot's own sweep) must skip a temp this process is still writing.
|
|
3135
|
+
_inFlightBackupTemps.add(path.resolve(tmpPath));
|
|
3136
|
+
try {
|
|
3137
|
+
// Reclaim anything an earlier run stranded here BEFORE writing: a temp left by a killed run
|
|
3138
|
+
// is the leak this exists for (D-6), and this run's own tmpPath is removed either way.
|
|
3139
|
+
sweepStaleBackupTemps(dir, { keepPath: null });
|
|
3140
|
+
removeSqliteFileSet(tmpPath);
|
|
3039
3141
|
await getDb().backup(tmpPath);
|
|
3040
3142
|
const check = _quickCheckBackupFile(tmpPath);
|
|
3041
3143
|
if (!check.ok) {
|
|
3042
3144
|
throw new Error(`backup quick_check failed: ${check.error}`);
|
|
3043
3145
|
}
|
|
3044
|
-
fs.renameSync(tmpPath,
|
|
3146
|
+
fs.renameSync(tmpPath, dest);
|
|
3045
3147
|
} catch (err) {
|
|
3046
|
-
try {
|
|
3148
|
+
try { removeSqliteFileSet(tmpPath); } catch { /* expected: tmp snapshot never materialised when getDb().backup() failed before writing; the snapshot error is rethrown */ }
|
|
3047
3149
|
throw err;
|
|
3150
|
+
} finally {
|
|
3151
|
+
_inFlightBackupTemps.delete(path.resolve(tmpPath));
|
|
3048
3152
|
}
|
|
3049
3153
|
|
|
3154
|
+
return { path: dest };
|
|
3155
|
+
}
|
|
3156
|
+
|
|
3157
|
+
async function createBackup(label) {
|
|
3158
|
+
getDb(); // throws if not initialized
|
|
3159
|
+
const backupDir = _backupDirForCurrentDb();
|
|
3160
|
+
|
|
3161
|
+
const timestamp = new Date().toISOString().replace(/:/g, '-');
|
|
3162
|
+
const safeLabel = String(label || 'manual').replace(/[^a-z0-9_.-]+/gi, '-').replace(/^-+|-+$/g, '') || 'manual';
|
|
3163
|
+
const backupName = `wall-e-brain-${timestamp}-${safeLabel}.db`;
|
|
3164
|
+
const backupPath = path.join(backupDir, backupName);
|
|
3165
|
+
|
|
3166
|
+
await createConsistentSnapshot(backupPath);
|
|
3167
|
+
|
|
3050
3168
|
cleanOldBackups(backupDir);
|
|
3051
3169
|
|
|
3052
3170
|
return { backupName, backupPath, timestamp };
|
|
@@ -3065,8 +3183,8 @@ function listBackups() {
|
|
|
3065
3183
|
}
|
|
3066
3184
|
|
|
3067
3185
|
function deleteBackup(backupName) {
|
|
3068
|
-
|
|
3069
|
-
|
|
3186
|
+
// The whole file set goes: a kept `-wal`/`-shm` beside a deleted base is an unreadable orphan.
|
|
3187
|
+
removeSqliteFileSet(path.join(_backupDirForCurrentDb(), path.basename(backupName)));
|
|
3070
3188
|
}
|
|
3071
3189
|
|
|
3072
3190
|
function _assertPromptPurgeBackupInventoryIsLocal() {
|
|
@@ -3142,17 +3260,18 @@ function restoreAndVerifyPromptPurgeBackupAbsent(baseline = {}, closure = {}) {
|
|
|
3142
3260
|
|
|
3143
3261
|
function cleanOldBackups(backupDir = BACKUP_DIR) {
|
|
3144
3262
|
if (!fs.existsSync(backupDir)) return;
|
|
3145
|
-
const
|
|
3146
|
-
const
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3263
|
+
const rows = [];
|
|
3264
|
+
for (const name of fs.readdirSync(backupDir)) {
|
|
3265
|
+
// Non-dot `wall-e-brain-*.db` only, the same filter listBackups() uses (dot names are -tmp).
|
|
3266
|
+
if (!name.startsWith('wall-e-brain-') || !name.endsWith('.db')) continue;
|
|
3267
|
+
try {
|
|
3268
|
+
rows.push({ name, createdAt: fs.statSync(path.join(backupDir, name)).mtime });
|
|
3269
|
+
} catch { /* expected: the base vanished between readdir and stat — a concurrent backup/delete; a missing row is simply not a prune candidate */ }
|
|
3270
|
+
}
|
|
3271
|
+
const days = getBackupRetentionInfo().retention_days;
|
|
3272
|
+
// R-1..R-3: keep EVERY backup from the N most recent UTC days that have one; remove the rest as a set.
|
|
3273
|
+
for (const row of backupRetention.selectExpiredBackups(rows, days)) {
|
|
3274
|
+
removeSqliteFileSet(path.join(backupDir, row.name));
|
|
3156
3275
|
}
|
|
3157
3276
|
}
|
|
3158
3277
|
|
|
@@ -3232,11 +3351,21 @@ function updatePerson(id, updates) {
|
|
|
3232
3351
|
function insertEntity({ canonical_name, entity_type, aliases, properties }) {
|
|
3233
3352
|
if (!canonical_name) throw new Error('Entity requires canonical_name');
|
|
3234
3353
|
if (!entity_type) throw new Error('Entity requires entity_type');
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3354
|
+
// WP-0 (§5 D-4): the id is derived from (lower(canonical_name), entity_type) — the same
|
|
3355
|
+
// entity extracted on two machines is the same row, and two spellings that differ only in
|
|
3356
|
+
// case are the same entity by construction. INSERT OR IGNORE makes the second insert a
|
|
3357
|
+
// no-op instead of a primary-key violation; the caller still gets the id of the live row.
|
|
3358
|
+
const id = deterministicEntityId(canonical_name, entity_type);
|
|
3359
|
+
const result = getDb().prepare(`
|
|
3360
|
+
INSERT OR IGNORE INTO entities (id, canonical_name, entity_type, aliases, properties)
|
|
3238
3361
|
VALUES (?, ?, ?, ?, ?)
|
|
3239
3362
|
`).run(id, canonical_name, entity_type, aliases || null, properties || null);
|
|
3363
|
+
if (result.changes === 0) {
|
|
3364
|
+
// The row is already there (this id, or a pre-WP-0 row that normalized to it). Returning
|
|
3365
|
+
// silently keeps the write log honest: nothing was inserted.
|
|
3366
|
+
const existing = getEntity(id) || findEntity(canonical_name);
|
|
3367
|
+
return { id: existing ? existing.id : id };
|
|
3368
|
+
}
|
|
3240
3369
|
logWrite('insert', 'entities', { id, subject: canonical_name, category: entity_type });
|
|
3241
3370
|
return { id };
|
|
3242
3371
|
}
|
|
@@ -5187,6 +5316,8 @@ module.exports = {
|
|
|
5187
5316
|
get BACKUP_DIR() { return _backupDirForCurrentDb(); },
|
|
5188
5317
|
getBackupDirInfo,
|
|
5189
5318
|
setBackupDir,
|
|
5319
|
+
getBackupRetentionInfo,
|
|
5320
|
+
setBackupRetentionDays,
|
|
5190
5321
|
// Owner
|
|
5191
5322
|
setOwner,
|
|
5192
5323
|
getOwner,
|
|
@@ -5369,6 +5500,8 @@ module.exports = {
|
|
|
5369
5500
|
// Backup
|
|
5370
5501
|
checkpointWalOrThrow,
|
|
5371
5502
|
createBackup,
|
|
5503
|
+
createConsistentSnapshot,
|
|
5504
|
+
sweepStaleBackupTemps,
|
|
5372
5505
|
listBackups,
|
|
5373
5506
|
deleteBackup,
|
|
5374
5507
|
listPromptPurgeBackupVersions,
|
|
@@ -5575,6 +5708,9 @@ module.exports = {
|
|
|
5575
5708
|
// underscore-prefixed, individual top-level exports.
|
|
5576
5709
|
__testing: {
|
|
5577
5710
|
_isProtectedDevContext, // WP-18: widened live-brain guard trigger, unit-tested directly
|
|
5711
|
+
// WP-2 (backup-retention-days): the prune is internal to createBackup; the retention tests
|
|
5712
|
+
// drive it directly against a real temp backup dir (the production call site is brain.js itself).
|
|
5713
|
+
cleanOldBackups,
|
|
5578
5714
|
__wp7RunMigration54ForTest: MIGRATIONS[54], // D-9 rule-host hygiene, WP-7
|
|
5579
5715
|
__wp2RunMigration23ForTest: MIGRATIONS[23], // rerunSafe:false both-ways proof, WP-2 db-migration-consolidation
|
|
5580
5716
|
__wp3RunMigration58ForTest: MIGRATIONS[58], // rerunSafe:false both-ways proof, WP-3 db-migration-consolidation
|
package/template/wall-e/chat.js
CHANGED
|
@@ -2302,9 +2302,9 @@ async function chatUnaccounted(message, opts = {}) {
|
|
|
2302
2302
|
}
|
|
2303
2303
|
} catch (error) { errorSink.report('chat', 'user-signal-evaluation', error); }
|
|
2304
2304
|
|
|
2305
|
-
// Configure permission checker with CTM connection if available
|
|
2306
|
-
|
|
2307
|
-
configurePermissions({ ctmUrl:
|
|
2305
|
+
// Configure permission checker with CTM connection if available (R-7: shared resolver;
|
|
2306
|
+
// WALLE_CTM_API=0 disables the bridge and an explicit base URL still wins).
|
|
2307
|
+
configurePermissions({ ctmUrl: ctmContextClient.resolveApiBaseUrl(process.env) || null, ctmToken: process.env.CTM_TOKEN });
|
|
2308
2308
|
|
|
2309
2309
|
let totalInputTokens = 0;
|
|
2310
2310
|
let totalOutputTokens = 0;
|
|
@@ -47,10 +47,15 @@ function prepareClaudeAgentShellEnv(overrides = {}, { baseEnv = process.env, tmp
|
|
|
47
47
|
const inheritedPrefix = env.CLAUDE_CODE_SHELL_PREFIX || '';
|
|
48
48
|
// Plugins add their bin directories after Claude starts. Its documented shell
|
|
49
49
|
// prefix runs at the final Bash execution boundary, after that plugin setup.
|
|
50
|
+
// The re-exec'd text overrides `eval()` and calls `builtin` (bash/zsh, not POSIX
|
|
51
|
+
// sh), so it runs in the user's SHELL only when that is bash or zsh, else bash:
|
|
52
|
+
// /bin/sh is dash on Debian/Ubuntu ("Syntax error: Bad function name", nightly
|
|
53
|
+
// 2026-10-27), and a service-launched process commonly has SHELL=/bin/sh.
|
|
50
54
|
fs.writeFileSync(wrapperFile, [
|
|
51
55
|
'#!/bin/sh',
|
|
56
|
+
'case "${SHELL:-}" in */bash|*/zsh) WALLE_AGENT_EVAL_SHELL="$SHELL" ;; *) WALLE_AGENT_EVAL_SHELL=/bin/bash ;; esac',
|
|
52
57
|
'if [ "${1:-}" = "--walle-run-original" ]; then',
|
|
53
|
-
` exec "$
|
|
58
|
+
` exec "$WALLE_AGENT_EVAL_SHELL" -c ${shellQuote([
|
|
54
59
|
`export PATH=${shellQuote(walleBin)}:"$PATH"`,
|
|
55
60
|
`eval() { export PATH=${shellQuote(walleBin)}:"$PATH"; builtin eval "$@"; }`,
|
|
56
61
|
'builtin eval "$WALLE_CLAUDE_ORIGINAL_COMMAND"',
|
|
@@ -59,7 +64,7 @@ function prepareClaudeAgentShellEnv(overrides = {}, { baseEnv = process.env, tmp
|
|
|
59
64
|
'[ "$#" -eq 1 ] || exit 64',
|
|
60
65
|
'export WALLE_CLAUDE_ORIGINAL_COMMAND="$1"',
|
|
61
66
|
'if [ -n "${WALLE_INHERITED_CLAUDE_SHELL_PREFIX:-}" ]; then',
|
|
62
|
-
` exec "$
|
|
67
|
+
` exec "$WALLE_AGENT_EVAL_SHELL" -c ${shellQuote('builtin eval "$WALLE_INHERITED_CLAUDE_SHELL_PREFIX \\"$1\\""')} walle-shell-prefix ${shellQuote(`${wrapperFile} --walle-run-original`)}`,
|
|
63
68
|
'fi',
|
|
64
69
|
`exec ${shellQuote(wrapperFile)} --walle-run-original`,
|
|
65
70
|
'',
|
|
@@ -89,53 +89,69 @@ function fitProjectInstructions(instructions, budgetBytes = PROJECT_INSTRUCTION_
|
|
|
89
89
|
for (const input of instructions || []) {
|
|
90
90
|
if (remaining <= 0) break;
|
|
91
91
|
if (!input?.content) continue;
|
|
92
|
+
const ordinal = fitted.length + 1;
|
|
92
93
|
if (input.renderedContent) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
// Already-fitted input (instruction-service hands its fitted frames back
|
|
95
|
+
// through here). Budget it on what rendering transmits, like any other
|
|
96
|
+
// frame; when it no longer fits the remaining cumulative budget, fall
|
|
97
|
+
// through and re-fit it rather than dropping the instruction.
|
|
98
|
+
const reused = measureTransmittedFrame(input.renderedContent, ordinal);
|
|
99
|
+
if (reused.bytes <= remaining && reused.intact) {
|
|
100
|
+
fitted.push({ ...input, includedBytes: reused.bytes });
|
|
101
|
+
remaining -= reused.bytes;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
98
104
|
}
|
|
99
|
-
const ordinal = fitted.length + 1;
|
|
100
105
|
const neutralized = neutralizeInstructionFrameContent(input.content, ordinal);
|
|
101
|
-
const
|
|
106
|
+
const contentBytes = Buffer.byteLength(neutralized, 'utf8');
|
|
107
|
+
// A re-fitted already-rendered input knows its own pre-truncation length:
|
|
108
|
+
// report that rather than the length of content an earlier fit cropped.
|
|
109
|
+
const declaredOriginalBytes = Math.floor(Number(input.originalContentBytes));
|
|
110
|
+
const originalContentBytes = Number.isFinite(declaredOriginalBytes) && declaredOriginalBytes > contentBytes
|
|
111
|
+
? declaredOriginalBytes
|
|
112
|
+
: contentBytes;
|
|
102
113
|
const sourceTruncated = Boolean(input.sourceTruncated || input.truncated);
|
|
103
114
|
const full = buildProjectInstructionFrame(input, ordinal, neutralized, {
|
|
104
|
-
contentBytes
|
|
115
|
+
contentBytes,
|
|
105
116
|
originalContentBytes,
|
|
106
117
|
truncated: sourceTruncated,
|
|
107
118
|
});
|
|
108
|
-
const
|
|
109
|
-
if (
|
|
119
|
+
const fullTransmitted = measureTransmittedFrame(full, ordinal);
|
|
120
|
+
if (fullTransmitted.bytes <= remaining && fullTransmitted.intact) {
|
|
110
121
|
fitted.push({
|
|
111
122
|
...input,
|
|
112
123
|
content: neutralized,
|
|
113
|
-
contentBytes
|
|
124
|
+
contentBytes,
|
|
114
125
|
originalContentBytes,
|
|
115
|
-
includedBytes:
|
|
116
|
-
originalBytes:
|
|
126
|
+
includedBytes: fullTransmitted.bytes,
|
|
127
|
+
originalBytes: fullTransmitted.bytes,
|
|
117
128
|
truncated: sourceTruncated,
|
|
118
129
|
renderedContent: full,
|
|
119
130
|
});
|
|
120
|
-
remaining -=
|
|
131
|
+
remaining -= fullTransmitted.bytes;
|
|
121
132
|
continue;
|
|
122
133
|
}
|
|
123
134
|
|
|
124
135
|
let low = 0;
|
|
125
|
-
let high = Math.min(
|
|
136
|
+
let high = Math.min(contentBytes, remaining);
|
|
126
137
|
let best = null;
|
|
127
138
|
while (low <= high) {
|
|
128
139
|
const target = Math.floor((low + high) / 2);
|
|
129
140
|
const content = truncateUtf8(neutralized, target);
|
|
130
|
-
const
|
|
141
|
+
const candidateBytes = Buffer.byteLength(content, 'utf8');
|
|
131
142
|
const renderedContent = buildProjectInstructionFrame(input, ordinal, content, {
|
|
132
|
-
contentBytes,
|
|
143
|
+
contentBytes: candidateBytes,
|
|
133
144
|
originalContentBytes,
|
|
134
145
|
truncated: true,
|
|
135
146
|
});
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
147
|
+
// The transmitted cost is not monotone in `target` — a cut inside a
|
|
148
|
+
// redaction marker is re-expanded by the renderer — so this is a bounded
|
|
149
|
+
// search for *a* fitting prefix, never a proof that it is the largest.
|
|
150
|
+
// Correctness only needs the accepted candidate to fit, which is checked
|
|
151
|
+
// on the measured bytes below.
|
|
152
|
+
const measured = measureTransmittedFrame(renderedContent, ordinal);
|
|
153
|
+
if (measured.bytes <= remaining && measured.intact) {
|
|
154
|
+
best = { content, contentBytes: candidateBytes, renderedContent, emittedBytes: measured.bytes };
|
|
139
155
|
low = target + 1;
|
|
140
156
|
} else {
|
|
141
157
|
high = target - 1;
|
|
@@ -148,7 +164,7 @@ function fitProjectInstructions(instructions, budgetBytes = PROJECT_INSTRUCTION_
|
|
|
148
164
|
contentBytes: best.contentBytes,
|
|
149
165
|
originalContentBytes,
|
|
150
166
|
includedBytes: best.emittedBytes,
|
|
151
|
-
originalBytes:
|
|
167
|
+
originalBytes: fullTransmitted.bytes,
|
|
152
168
|
truncated: true,
|
|
153
169
|
renderedContent: best.renderedContent,
|
|
154
170
|
});
|
|
@@ -157,6 +173,35 @@ function fitProjectInstructions(instructions, budgetBytes = PROJECT_INSTRUCTION_
|
|
|
157
173
|
return fitted;
|
|
158
174
|
}
|
|
159
175
|
|
|
176
|
+
/**
|
|
177
|
+
* What a project-instruction frame costs *in transmission*.
|
|
178
|
+
*
|
|
179
|
+
* `renderPromptEnvelope` re-applies each section's `redactionPolicy` on the way
|
|
180
|
+
* out (prompt-runtime.js renders `redactPromptContent(section.content, policy)`
|
|
181
|
+
* and section-creation here sets `redactionPolicy: 'secrets'`), so the bytes a
|
|
182
|
+
* frame actually spends are those of `redactPromptContent(frame)`, not those of
|
|
183
|
+
* the frame this module stored. That second pass is not a no-op on a truncated
|
|
184
|
+
* frame:
|
|
185
|
+
*
|
|
186
|
+
* - a cut inside a redaction marker leaves a fragment (`token=[REDAC`) that is
|
|
187
|
+
* not recognised as already redacted and is re-expanded (+4 bytes), and
|
|
188
|
+
* - a cut immediately after an assignment operator (`token=`) matches a value
|
|
189
|
+
* across the following newline and swallows the frame's own `--- END …`
|
|
190
|
+
* delimiter (secret-redaction.js's `\s*` crosses lines).
|
|
191
|
+
*
|
|
192
|
+
* Both are how a frame fitted to its pre-render byte count could be transmitted
|
|
193
|
+
* over budget or lose its framing, so the budget is enforced on this text and a
|
|
194
|
+
* candidate whose transmitted form has lost either delimiter is refused.
|
|
195
|
+
*/
|
|
196
|
+
function measureTransmittedFrame(frame, ordinal) {
|
|
197
|
+
const transmitted = redactPromptContent(frame, 'secrets');
|
|
198
|
+
return {
|
|
199
|
+
bytes: Buffer.byteLength(transmitted, 'utf8'),
|
|
200
|
+
intact: transmitted.startsWith(`--- BEGIN PROJECT INSTRUCTION ${ordinal} ---`)
|
|
201
|
+
&& transmitted.endsWith(`--- END PROJECT INSTRUCTION ${ordinal} ---`),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
160
205
|
function buildProjectInstructionFrame(item, ordinal, content, {
|
|
161
206
|
contentBytes,
|
|
162
207
|
originalContentBytes,
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
"function": "telemetry child-process route implementation",
|
|
8
8
|
"capability": "isolated_telemetry_sync_io",
|
|
9
9
|
"owner": "wall-e-runtime",
|
|
10
|
-
"reason": "These exact calls initialize and inspect the optional telemetry database after the daemon transfers telemetry and feedback requests to walle-telemetry-process. Re-reviewed 2026-10-
|
|
10
|
+
"reason": "These exact calls initialize and inspect the optional telemetry database after the daemon transfers telemetry and feedback requests to walle-telemetry-process. Re-reviewed 2026-10-27: handleWalleApi still proxies daemon telemetry/feedback routes before local dispatch; TelemetryProcessClient forks telemetry-worker with the isolated role. The unchanged child implementation has exactly 3 synchronous filesystem sites (getTelemetryDb exists/mkdir and telemetryFileStats stat) and 1 SQLite import; direct DB and unbounded brain read allowances stay zero. The next review expires in 14 days; no allowance count was increased.",
|
|
11
11
|
"max_duration_ms": 25,
|
|
12
12
|
"telemetry": "telemetry_process.request",
|
|
13
|
-
"expires": "2026-
|
|
13
|
+
"expires": "2026-11-10T00:00:00.000Z",
|
|
14
14
|
"allow": {
|
|
15
15
|
"sync_io": 3,
|
|
16
16
|
"direct_db": 0,
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
// in http/.
|
|
18
18
|
const path = require('path');
|
|
19
19
|
const { jsonResponse, readBody } = require('./api-utils');
|
|
20
|
+
// Shared backup-retention policy (R-1..R-6) — the same pure module brain.js prunes with.
|
|
21
|
+
const backupRetention = require('../../shared/backup-retention');
|
|
20
22
|
|
|
21
23
|
function handleAdminApi(req, res, url, deps) {
|
|
22
24
|
const {
|
|
@@ -183,6 +185,41 @@ function handleAdminApi(req, res, url, deps) {
|
|
|
183
185
|
return true;
|
|
184
186
|
}
|
|
185
187
|
|
|
188
|
+
// GET /api/wall-e/storage/backup-retention — the retention window plus the backups it expires.
|
|
189
|
+
// Read-only: never deletes a file (the scheduler's cleanOldBackups owns deletion).
|
|
190
|
+
if (p === '/api/wall-e/storage/backup-retention' && m === 'GET') {
|
|
191
|
+
if (!brain) return jsonResponse(res, { error: 'Brain not available' }, 503), true;
|
|
192
|
+
(async () => {
|
|
193
|
+
try {
|
|
194
|
+
if (ensureBrainInit) ensureBrainInit();
|
|
195
|
+
const info = brain.getBackupRetentionInfo();
|
|
196
|
+
const dirInfo = typeof brain.getBackupDirInfo === 'function' ? brain.getBackupDirInfo() : {};
|
|
197
|
+
const rows = await listBackupFiles(dirInfo.backup_dir || brain.BACKUP_DIR);
|
|
198
|
+
jsonResponse(res, { data: { ...info, expiring: backupRetention.selectExpiredBackups(rows, info.retention_days).map((r) => r.name) } });
|
|
199
|
+
} catch (e) { jsonResponse(res, { error: e.message }, 500); }
|
|
200
|
+
})();
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// PUT /api/wall-e/storage/backup-retention — persist a validated retention window (R-6).
|
|
205
|
+
if (p === '/api/wall-e/storage/backup-retention' && m === 'PUT') {
|
|
206
|
+
if (!brain || !ensureBrainInit()) return jsonResponse(res, { error: 'Brain not available' }, 503), true;
|
|
207
|
+
readBody(req, 32 * 1024)
|
|
208
|
+
.then(async (body) => {
|
|
209
|
+
const parsed = backupRetention.parseRetentionDaysInput(body.retention_days);
|
|
210
|
+
if (!parsed.ok) {
|
|
211
|
+
return jsonResponse(res, { error: 'retention_days_invalid', min: 1, max: 365 }, 400);
|
|
212
|
+
}
|
|
213
|
+
await writeBrain('setBackupRetentionDays', [parsed.days]);
|
|
214
|
+
const info = brain.getBackupRetentionInfo();
|
|
215
|
+
const dirInfo = typeof brain.getBackupDirInfo === 'function' ? brain.getBackupDirInfo() : {};
|
|
216
|
+
const rows = await listBackupFiles(dirInfo.backup_dir || brain.BACKUP_DIR);
|
|
217
|
+
jsonResponse(res, { data: { ...info, expiring: backupRetention.selectExpiredBackups(rows, info.retention_days).map((r) => r.name) } });
|
|
218
|
+
})
|
|
219
|
+
.catch((e) => jsonResponse(res, { error: e.message }, 400));
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
|
|
186
223
|
// POST /api/wall-e/backups — create brain backup
|
|
187
224
|
if (p === '/api/wall-e/backups' && m === 'POST') {
|
|
188
225
|
if (!brain || !ensureBrainInit()) return jsonResponse(res, { error: 'Brain not available' }, 503), true;
|
|
@@ -427,6 +427,9 @@ async function buildIMessageStatus(brain, imessageCapabilitiesOverride) {
|
|
|
427
427
|
return {
|
|
428
428
|
dbPresent: imessage.dbPresent,
|
|
429
429
|
fullDiskAccess: imessage.fullDiskAccess,
|
|
430
|
+
// signin-flow-restart-settle-and-fda-target-identity-2026-10-26 D-8: the exec the FDA grant
|
|
431
|
+
// must name, so the CTM banner can show the exact file (null on an older live-capabilities).
|
|
432
|
+
fdaTarget: imessage.fdaTarget || null,
|
|
430
433
|
lastIngestAt: imessage.lastIngestAt,
|
|
431
434
|
maxRowid: imessage.maxRowid,
|
|
432
435
|
count,
|
|
@@ -438,4 +441,5 @@ async function buildIMessageStatus(brain, imessageCapabilitiesOverride) {
|
|
|
438
441
|
|
|
439
442
|
module.exports = {
|
|
440
443
|
handleGwsApi,
|
|
444
|
+
buildIMessageStatus,
|
|
441
445
|
};
|
|
@@ -121,9 +121,10 @@ function _cellView(d, row) {
|
|
|
121
121
|
const cellKey = String(row.cell_key);
|
|
122
122
|
const window = readTrailingOutcomes(d, cellKey);
|
|
123
123
|
const metrics = _parseMetrics(row.metrics_json);
|
|
124
|
+
const kind = row.kind || kindFromCellKey(cellKey);
|
|
124
125
|
return {
|
|
125
126
|
cell_key: cellKey,
|
|
126
|
-
kind
|
|
127
|
+
kind,
|
|
127
128
|
state: _cellState(row),
|
|
128
129
|
user_veto: Number(row.user_veto) === 1 ? 1 : 0,
|
|
129
130
|
n_window: window.length,
|
|
@@ -131,6 +132,11 @@ function _cellView(d, row) {
|
|
|
131
132
|
metrics,
|
|
132
133
|
collecting: typeof metrics.collecting === 'boolean' ? metrics.collecting : window.length < COLLECTING_MIN,
|
|
133
134
|
last_event: _lastEvent(d, cellKey),
|
|
135
|
+
// D-8 (round 3): only a wait-watch cell can fail open into a full-rate watcher, so the
|
|
136
|
+
// per-reason fallback counts ride that view alone -- the explore switch starts no watcher.
|
|
137
|
+
...(kind === 'wait-watch'
|
|
138
|
+
? { watch_fallbacks: require('../lib/helper-rules/lead-call-hook').watchFallbackCounts() }
|
|
139
|
+
: {}),
|
|
134
140
|
};
|
|
135
141
|
}
|
|
136
142
|
|
|
@@ -39,6 +39,7 @@ const { workerRegistryResponse } = require('./model-registry-worker-projection')
|
|
|
39
39
|
const { pagedResult, catalogRouteInputs, codingCatalogRequestError, codingCatalogResponse, codingCatalogTokenSnap, registryListResponse, pricingListResponse, factsListResponse, scorecardPayload } = require('./model-registry-list');
|
|
40
40
|
const { buildWorkerRoute } = require('../llm/worker-route');
|
|
41
41
|
const { handleModelIdentityRoute } = require('./model-identity-routes');
|
|
42
|
+
const { handleModelRouteHealthRoute, annotateCatalogRouteCircuits } = require('./model-route-health');
|
|
42
43
|
const { handleWorkerCapabilityAdminRoute } = require('./model-worker-capability-admin');
|
|
43
44
|
const { handleExecProfileAdminRoute } = require('./model-exec-profile-admin');
|
|
44
45
|
const { handleDelegatePrefAdminRoute } = require('./model-delegate-pref-admin');
|
|
@@ -1196,6 +1197,10 @@ async function handleModelAdminApi(req, res, url) {
|
|
|
1196
1197
|
const identityRoute = await handleModelIdentityRoute({ req, res, p, m, brainApi, url });
|
|
1197
1198
|
if (identityRoute) return identityRoute;
|
|
1198
1199
|
|
|
1200
|
+
// WP-2 (D-3/D-4): CTM's routed-Lead probe verdict — see model-route-health.js.
|
|
1201
|
+
const routeHealth = await handleModelRouteHealthRoute({ req, res, p, m, brainApi });
|
|
1202
|
+
if (routeHealth) return routeHealth;
|
|
1203
|
+
|
|
1199
1204
|
const workerCapabilityRoute = await handleWorkerCapabilityAdminRoute({ req, res, p, m, brainApi, url });
|
|
1200
1205
|
if (workerCapabilityRoute) return workerCapabilityRoute;
|
|
1201
1206
|
|
|
@@ -1758,7 +1763,9 @@ async function handleModelAdminApi(req, res, url) {
|
|
|
1758
1763
|
} else {
|
|
1759
1764
|
({ snapshotId, payload } = await _codingCatalogBuildInFlight(brainApi, key, providerId, includeLive));
|
|
1760
1765
|
}
|
|
1761
|
-
|
|
1766
|
+
// WP-2 (D-6): annotate the pinned payload (a copy) BEFORE paging, so the
|
|
1767
|
+
// page-byte budget measures the circuit fields; pages key on catalog_id.
|
|
1768
|
+
const r = codingCatalogResponse(annotateCatalogRouteCircuits(payload), url, { snapshotId }); // paged read: http/model-registry-list.js
|
|
1762
1769
|
return jsonResponse(res, r.status, r.body);
|
|
1763
1770
|
} catch (e) {
|
|
1764
1771
|
if (e.code === 'WALL_E_HTTP_RESPONSE_TOO_LARGE') throw e; // the proxy maps it to 413
|