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
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// WP-6a (docs/shared-memory-every-machine-2026-10-31.html §6.5, gate E-3): the convergence verifier.
|
|
4
|
+
//
|
|
5
|
+
// verifyMemorySync(deps) -> { ok, hub: { instanceId, vector, counts }, members: [...], allEqual }
|
|
6
|
+
//
|
|
7
|
+
// Proves "exactly the same memory" the only way that survives a bucket collision: the bucketed
|
|
8
|
+
// content digest (§6.5) on the hub and on every enabled registry member, compared bucket by bucket.
|
|
9
|
+
// A bucket is equal when its row COUNTS match and — only for a non-empty bucket — its XOR fold
|
|
10
|
+
// matches; two empty buckets are equal whatever their xor string says, because the fold is over no
|
|
11
|
+
// rows at all.
|
|
12
|
+
//
|
|
13
|
+
// Three rules the caller depends on:
|
|
14
|
+
// * Read-only. This module never writes anywhere: no CTM row, no brain row, no file. It dials the
|
|
15
|
+
// local Wall-E (loopback + the CTM's own token), and each member's CTM front route.
|
|
16
|
+
// * A member that cannot be reached is REPORTED (`reachable:false`, `allEqual:false`) and the
|
|
17
|
+
// remaining members are still compared — one dead box must not hide the others' verdict.
|
|
18
|
+
// * The per-member `vectorLag` (hub max_seq − member max_seq, per origin) is the diagnosis the
|
|
19
|
+
// digest alone cannot give: a large positive lag means "still syncing", a NON-ZERO lag with an
|
|
20
|
+
// equal digest on every table means "diverged" (a row the hub holds and the member never will).
|
|
21
|
+
//
|
|
22
|
+
// Tier: this is the `bin/memory-sync-verify.js` core. The CLI owns arg parsing and the registry
|
|
23
|
+
// read; this module owns the comparison and the dials.
|
|
24
|
+
//
|
|
25
|
+
// NB (stabilization-lint): the two `setTimeout(` sites below (one in _localGet, one in _memberGet)
|
|
26
|
+
// are per-request abort deadlines, not recovery waits. Each is unref'd so a hung dial can never
|
|
27
|
+
// hold the process open. The lead registers the surfaces in release/ownership-registry.json — do
|
|
28
|
+
// not silence them here.
|
|
29
|
+
|
|
30
|
+
const machineRegistry = require('./machine-registry');
|
|
31
|
+
const { buildPeerControlHeaders } = require('./remote-machine-create');
|
|
32
|
+
|
|
33
|
+
// The hub's LOCAL Wall-E v2 routes (loopback + CTM token, exactly as lib/memory-sync.js reads them).
|
|
34
|
+
const LOCAL_PATHS = Object.freeze({
|
|
35
|
+
vector: '/api/walle/sync/v2/vector',
|
|
36
|
+
digest: '/api/walle/sync/v2/digest',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// The member's CTM front routes (§6.6), each of which forwards to the member's own Wall-E.
|
|
40
|
+
const MEMBER_PATHS = Object.freeze({
|
|
41
|
+
vector: '/api/sync/brain/v2/vector',
|
|
42
|
+
digest: '/api/sync/brain/v2/digest',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// D-11: the four tables "the same memory" means. `people` has no runtime writer today but is
|
|
46
|
+
// replicated and must still read equal (0/0) on every node rather than be silently skipped.
|
|
47
|
+
const DEFAULT_TABLES = Object.freeze(['memories', 'knowledge', 'entities', 'people']);
|
|
48
|
+
|
|
49
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
50
|
+
const BUCKET_COUNT = 256;
|
|
51
|
+
|
|
52
|
+
function _string(value, max = 160) {
|
|
53
|
+
if (typeof value === 'string') return value.trim().slice(0, max);
|
|
54
|
+
return value == null ? '' : String(value).trim().slice(0, max);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function _normalizeTables(tables) {
|
|
58
|
+
const list = Array.isArray(tables) ? tables : DEFAULT_TABLES;
|
|
59
|
+
const seen = new Set();
|
|
60
|
+
for (const raw of list) {
|
|
61
|
+
const name = _string(raw, 40);
|
|
62
|
+
if (name) seen.add(name);
|
|
63
|
+
}
|
|
64
|
+
return [...seen];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Dial order = `urls` first, then the pinned `url` (machine-registry D-3/_dialUrls). A row whose
|
|
68
|
+
// list is empty still gets one chance at its pinned URL.
|
|
69
|
+
function _memberUrls(member = {}) {
|
|
70
|
+
const list = (Array.isArray(member.urls) ? member.urls : []).map((u) => _string(u, 1000)).filter(Boolean);
|
|
71
|
+
if (list.length) return list;
|
|
72
|
+
const pinned = _string(member.url, 1000);
|
|
73
|
+
return pinned ? [pinned] : [];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function _joinUrl(base, pathname) {
|
|
77
|
+
return `${String(base).replace(/\/+$/, '')}${pathname}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The header builder for member dials. `deps.peerHeadersFor` wins (the hub-side production seam,
|
|
82
|
+
* the same one lib/memory-sync.js takes); with none, fall back to remote-machine-create's
|
|
83
|
+
* buildPeerControlHeaders so a bare caller still authenticates the way the probe does.
|
|
84
|
+
*/
|
|
85
|
+
function _peerHeadersBuilder(deps, env) {
|
|
86
|
+
if (typeof deps.peerHeadersFor === 'function') {
|
|
87
|
+
const build = deps.peerHeadersFor;
|
|
88
|
+
return (instanceId) => {
|
|
89
|
+
try {
|
|
90
|
+
const built = build(instanceId);
|
|
91
|
+
return built && typeof built === 'object' ? built : {};
|
|
92
|
+
} catch {
|
|
93
|
+
return {}; // expected: a credential-builder fault degrades to an anonymous dial, reported as unreachable
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
const fallbackEnv = env && typeof env === 'object' ? env : process.env;
|
|
98
|
+
return (instanceId) => buildPeerControlHeaders(fallbackEnv, { instanceId }) || {};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** One local Wall-E GET. Resolves { ok, json } — a transport fault is a verdict, never a throw. */
|
|
102
|
+
async function _localGet(walle, pathname, timeoutMs) {
|
|
103
|
+
if (!walle || typeof walle.requestJson !== 'function') return { ok: false, error: 'walle_client_missing' };
|
|
104
|
+
const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;
|
|
105
|
+
const timer = controller ? setTimeout(() => controller.abort(), timeoutMs) : null;
|
|
106
|
+
if (timer && typeof timer.unref === 'function') timer.unref();
|
|
107
|
+
try {
|
|
108
|
+
const res = await walle.requestJson(pathname, {
|
|
109
|
+
method: 'GET',
|
|
110
|
+
signal: controller ? controller.signal : undefined,
|
|
111
|
+
});
|
|
112
|
+
const status = Number(res && res.status) || 0;
|
|
113
|
+
if (status < 200 || status >= 300 || !res || !res.json) return { ok: false, error: `walle_http_${status}` };
|
|
114
|
+
return { ok: true, json: res.json };
|
|
115
|
+
} catch (err) {
|
|
116
|
+
return { ok: false, error: `walle_request_failed: ${err && err.message ? err.message : String(err)}` };
|
|
117
|
+
} finally {
|
|
118
|
+
if (timer) clearTimeout(timer);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** One member GET against one URL. Same deadline shape; status 0 means "nothing answered". */
|
|
123
|
+
async function _memberGet(fetchImpl, url, pathname, headers, timeoutMs) {
|
|
124
|
+
const fetchFn = fetchImpl || global.fetch;
|
|
125
|
+
if (typeof fetchFn !== 'function') return { ok: false, status: 0, error: 'fetch_unavailable' };
|
|
126
|
+
const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;
|
|
127
|
+
const timer = controller ? setTimeout(() => controller.abort(), timeoutMs) : null;
|
|
128
|
+
if (timer && typeof timer.unref === 'function') timer.unref();
|
|
129
|
+
try {
|
|
130
|
+
const res = await fetchFn(_joinUrl(url, pathname), {
|
|
131
|
+
method: 'GET',
|
|
132
|
+
headers: { ...headers, Accept: 'application/json' },
|
|
133
|
+
signal: controller ? controller.signal : undefined,
|
|
134
|
+
});
|
|
135
|
+
let json = null;
|
|
136
|
+
try { json = await res.json(); } catch { json = null; /* expected: a non-JSON body is degraded to null and reported by status */ }
|
|
137
|
+
const status = Number(res && res.status) || 0;
|
|
138
|
+
if (status < 200 || status >= 300 || !json) return { ok: false, status, error: `member_http_${status}` };
|
|
139
|
+
return { ok: true, status, json };
|
|
140
|
+
} catch (err) {
|
|
141
|
+
return { ok: false, status: 0, error: err && err.message ? err.message : String(err) };
|
|
142
|
+
} finally {
|
|
143
|
+
if (timer) clearTimeout(timer);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function _dialUrls(fetchImpl, urls, pathname, headers, timeoutMs) {
|
|
148
|
+
let last = { ok: false, status: 0, error: 'member_has_no_url' };
|
|
149
|
+
for (const url of urls) {
|
|
150
|
+
const res = await _memberGet(fetchImpl, url, pathname, headers, timeoutMs);
|
|
151
|
+
if (res.status > 0 || res.ok) return { ...res, url };
|
|
152
|
+
last = { ...res, url };
|
|
153
|
+
}
|
|
154
|
+
return last;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** `buckets` as a 256-slot array; a malformed/short array reads as zero-count buckets. */
|
|
158
|
+
function _bucketArray(digest) {
|
|
159
|
+
const out = new Array(BUCKET_COUNT);
|
|
160
|
+
const list = digest && Array.isArray(digest.buckets) ? digest.buckets : [];
|
|
161
|
+
for (const entry of list) {
|
|
162
|
+
const b = Number(entry && entry.b) | 0;
|
|
163
|
+
if (b < 0 || b >= BUCKET_COUNT) continue;
|
|
164
|
+
out[b] = { count: Math.max(0, Number(entry && entry.count) || 0), xor: _string(entry && entry.xor, 64) };
|
|
165
|
+
}
|
|
166
|
+
for (let b = 0; b < BUCKET_COUNT; b += 1) if (!out[b]) out[b] = { count: 0, xor: '' };
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// §6.5: equal when the counts match and — for a non-empty bucket — the xor folds match too. Two
|
|
171
|
+
// empty buckets are equal regardless of their xor string (the fold is over no rows).
|
|
172
|
+
function _bucketEqual(hub, member) {
|
|
173
|
+
if (hub.count !== member.count) return false;
|
|
174
|
+
if (hub.count === 0) return true;
|
|
175
|
+
return hub.xor === member.xor;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Compare one table's digests. Returns { equal, hubCount, memberCount, mismatchedBuckets }. */
|
|
179
|
+
function compareDigests(hubDigest, memberDigest) {
|
|
180
|
+
const hub = _bucketArray(hubDigest);
|
|
181
|
+
const member = _bucketArray(memberDigest);
|
|
182
|
+
const mismatchedBuckets = [];
|
|
183
|
+
for (let b = 0; b < BUCKET_COUNT; b += 1) {
|
|
184
|
+
if (!_bucketEqual(hub[b], member[b])) mismatchedBuckets.push(b);
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
equal: mismatchedBuckets.length === 0,
|
|
188
|
+
hubCount: Number(hubDigest && hubDigest.count) || 0,
|
|
189
|
+
memberCount: Number(memberDigest && memberDigest.count) || 0,
|
|
190
|
+
mismatchedBuckets,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* For every origin either side knows: hub max_seq − member max_seq. Positive = the hub holds
|
|
196
|
+
* updates the member has not applied; negative = the member is ahead (its rows have not reached
|
|
197
|
+
* the hub yet); 0 = this origin is level.
|
|
198
|
+
*/
|
|
199
|
+
function vectorLag(hubVector, memberVector) {
|
|
200
|
+
const hub = hubVector && typeof hubVector === 'object' ? hubVector : {};
|
|
201
|
+
const member = memberVector && typeof memberVector === 'object' ? memberVector : {};
|
|
202
|
+
const origins = new Set([...Object.keys(hub), ...Object.keys(member)]);
|
|
203
|
+
const lag = {};
|
|
204
|
+
for (const origin of [...origins].sort()) {
|
|
205
|
+
lag[origin] = (Number(hub[origin]) || 0) - (Number(member[origin]) || 0);
|
|
206
|
+
}
|
|
207
|
+
return lag;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function _emptyTables(tables) {
|
|
211
|
+
const out = {};
|
|
212
|
+
for (const t of tables) out[t] = { equal: false, hubCount: null, memberCount: null, mismatchedBuckets: [] };
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** The enabled registry rows to check. `deps.machines` (a pre-fetched view) wins over `deps.db`. */
|
|
217
|
+
function _memberRows(deps) {
|
|
218
|
+
const source = Array.isArray(deps.machines)
|
|
219
|
+
? deps.machines
|
|
220
|
+
: machineRegistry.listMachines({ db: deps.db }).machines;
|
|
221
|
+
return (source || []).filter((m) => m && m.enabled && _string(m.instanceId));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Compare the hub's digest against every enabled registry member.
|
|
226
|
+
*
|
|
227
|
+
* @param {object} deps { db, fetchImpl, walle, env, peerHeadersFor, tables, timeoutMs, machines }
|
|
228
|
+
* @returns {Promise<object>} { ok, error?, hub:{instanceId,vector,counts}, members:[...], allEqual }
|
|
229
|
+
*/
|
|
230
|
+
async function verifyMemorySync(deps = {}) {
|
|
231
|
+
const walle = deps.walle || require('./walle-client');
|
|
232
|
+
const fetchImpl = deps.fetchImpl || global.fetch;
|
|
233
|
+
const env = deps.env || process.env;
|
|
234
|
+
const tables = _normalizeTables(deps.tables);
|
|
235
|
+
const requested = Number(deps.timeoutMs);
|
|
236
|
+
const timeoutMs = Number.isFinite(requested) && requested > 0 ? requested : DEFAULT_TIMEOUT_MS;
|
|
237
|
+
const peerHeadersFor = _peerHeadersBuilder(deps, env);
|
|
238
|
+
|
|
239
|
+
// 1. The hub. Its vector carries the identity every member's vector is compared against; without
|
|
240
|
+
// it there is no reference, so this is the one fatal leg.
|
|
241
|
+
const hubVectorRes = await _localGet(walle, LOCAL_PATHS.vector, timeoutMs);
|
|
242
|
+
if (!hubVectorRes.ok) {
|
|
243
|
+
return { ok: false, error: hubVectorRes.error, hub: null, members: [], allEqual: false };
|
|
244
|
+
}
|
|
245
|
+
const hubInstanceId = _string(hubVectorRes.json.instanceId);
|
|
246
|
+
const hubVector = hubVectorRes.json.vector && typeof hubVectorRes.json.vector === 'object'
|
|
247
|
+
? { ...hubVectorRes.json.vector }
|
|
248
|
+
: {};
|
|
249
|
+
|
|
250
|
+
// 2. The hub digest per table. A table the hub cannot digest is a failed check, not a skipped one.
|
|
251
|
+
const hubDigests = {};
|
|
252
|
+
const hubCounts = {};
|
|
253
|
+
for (const table of tables) {
|
|
254
|
+
const res = await _localGet(walle, `${LOCAL_PATHS.digest}?table=${encodeURIComponent(table)}`, timeoutMs);
|
|
255
|
+
if (!res.ok) {
|
|
256
|
+
return {
|
|
257
|
+
ok: false,
|
|
258
|
+
error: `hub_digest_${table}: ${res.error}`,
|
|
259
|
+
hub: { instanceId: hubInstanceId, vector: hubVector, counts: null },
|
|
260
|
+
members: [],
|
|
261
|
+
allEqual: false,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
hubDigests[table] = res.json;
|
|
265
|
+
hubCounts[table] = Number(res.json && res.json.count) || 0;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// 3. Every enabled member, sequentially: one comparison per table. A member that does not answer
|
|
269
|
+
// the vector is unreachable — reported, never fatal to the others.
|
|
270
|
+
const members = [];
|
|
271
|
+
for (const row of _memberRows(deps)) {
|
|
272
|
+
const instanceId = _string(row.instanceId);
|
|
273
|
+
const urls = _memberUrls(row);
|
|
274
|
+
const headers = peerHeadersFor(instanceId);
|
|
275
|
+
const vectorRes = await _dialUrls(fetchImpl, urls, MEMBER_PATHS.vector, headers, timeoutMs);
|
|
276
|
+
if (!vectorRes.ok) {
|
|
277
|
+
members.push({
|
|
278
|
+
instanceId,
|
|
279
|
+
reachable: false,
|
|
280
|
+
vector: null,
|
|
281
|
+
counts: null,
|
|
282
|
+
tables: _emptyTables(tables),
|
|
283
|
+
vectorLag: null,
|
|
284
|
+
error: vectorRes.error || 'member_unreachable',
|
|
285
|
+
});
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
const memberVector = vectorRes.json.vector && typeof vectorRes.json.vector === 'object'
|
|
289
|
+
? { ...vectorRes.json.vector }
|
|
290
|
+
: {};
|
|
291
|
+
const memberTables = {};
|
|
292
|
+
const memberCounts = {};
|
|
293
|
+
for (const table of tables) {
|
|
294
|
+
const res = await _dialUrls(fetchImpl, urls, `${MEMBER_PATHS.digest}?table=${encodeURIComponent(table)}`, headers, timeoutMs);
|
|
295
|
+
if (!res.ok) {
|
|
296
|
+
memberTables[table] = { equal: false, hubCount: hubCounts[table], memberCount: null, mismatchedBuckets: [], error: res.error || 'member_digest_failed' };
|
|
297
|
+
memberCounts[table] = null;
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
const compared = compareDigests(hubDigests[table], res.json);
|
|
301
|
+
memberTables[table] = compared;
|
|
302
|
+
memberCounts[table] = compared.memberCount;
|
|
303
|
+
}
|
|
304
|
+
members.push({
|
|
305
|
+
instanceId,
|
|
306
|
+
reachable: true,
|
|
307
|
+
vector: memberVector,
|
|
308
|
+
counts: memberCounts,
|
|
309
|
+
tables: memberTables,
|
|
310
|
+
vectorLag: vectorLag(hubVector, memberVector),
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const allEqual = members.length > 0
|
|
315
|
+
&& members.every((m) => m.reachable && tables.every((t) => m.tables[t] && m.tables[t].equal));
|
|
316
|
+
|
|
317
|
+
return {
|
|
318
|
+
ok: true,
|
|
319
|
+
hub: { instanceId: hubInstanceId, vector: hubVector, counts: hubCounts },
|
|
320
|
+
members,
|
|
321
|
+
allEqual,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// ------------------------------------------------------------------------------------------------
|
|
326
|
+
// The CLI's pure half (bin/memory-sync-verify.js): one line per member, and the exit code.
|
|
327
|
+
|
|
328
|
+
/** One member's per-table cell: `memories =100/100` (equal) or `memories !100/99` (differs). */
|
|
329
|
+
function _tableCell(member, tables) {
|
|
330
|
+
return tables.map((t) => {
|
|
331
|
+
const row = member.tables && member.tables[t] ? member.tables[t] : null;
|
|
332
|
+
const hubCount = row && row.hubCount != null ? row.hubCount : '?';
|
|
333
|
+
const memberCount = row && row.memberCount != null ? row.memberCount : '?';
|
|
334
|
+
const mark = row && row.equal ? '=' : '!';
|
|
335
|
+
const extra = row && !row.equal && Array.isArray(row.mismatchedBuckets) && row.mismatchedBuckets.length
|
|
336
|
+
? ` b[${row.mismatchedBuckets.join(',')}]`
|
|
337
|
+
: '';
|
|
338
|
+
return `${t} ${mark}${hubCount}/${memberCount}${extra}`;
|
|
339
|
+
}).join(' ');
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function _lagCell(member) {
|
|
343
|
+
if (!member.vectorLag || typeof member.vectorLag !== 'object') return '-';
|
|
344
|
+
const entries = Object.entries(member.vectorLag);
|
|
345
|
+
if (!entries.length) return '-';
|
|
346
|
+
return entries.map(([origin, lag]) => `${origin}=${lag}`).join(',');
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* The human table: one row per member, then the verdict. Pure — no clock, no I/O.
|
|
351
|
+
*
|
|
352
|
+
* @param {object} result the verifyMemorySync result
|
|
353
|
+
* @param {object} [opts] { tables } — the table list to render in each row
|
|
354
|
+
*/
|
|
355
|
+
function formatReport(result, opts = {}) {
|
|
356
|
+
const r = result && typeof result === 'object' ? result : {};
|
|
357
|
+
const hub = r.hub || {};
|
|
358
|
+
const members = Array.isArray(r.members) ? r.members : [];
|
|
359
|
+
const derived = members[0] && members[0].tables ? Object.keys(members[0].tables) : [];
|
|
360
|
+
const requested = Array.isArray(opts.tables) && opts.tables.length ? opts.tables : derived;
|
|
361
|
+
const tables = _normalizeTables(requested.length ? requested : DEFAULT_TABLES);
|
|
362
|
+
const lines = [];
|
|
363
|
+
lines.push(`memory sync verify — hub ${hub.instanceId || '(unknown)'}`);
|
|
364
|
+
lines.push(`tables: ${tables.join(', ')}`);
|
|
365
|
+
lines.push('');
|
|
366
|
+
for (const member of members) {
|
|
367
|
+
const state = member.reachable ? 'reachable ' : 'unreachable';
|
|
368
|
+
const detail = member.reachable ? _tableCell(member, tables) : (member.error || 'unreachable');
|
|
369
|
+
lines.push(`${member.instanceId || '(unknown)'} ${state} ${detail} lag: ${_lagCell(member)}`);
|
|
370
|
+
}
|
|
371
|
+
if (!members.length) lines.push('(no enabled members registered)');
|
|
372
|
+
lines.push('');
|
|
373
|
+
lines.push(`allEqual: ${r.allEqual === true}`);
|
|
374
|
+
if (r.error) lines.push(`error: ${r.error}`);
|
|
375
|
+
return `${lines.join('\n')}\n`;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/** Exit code: 0 only when every enabled member is reachable and every table matches. */
|
|
379
|
+
function exitCodeFor(result) {
|
|
380
|
+
return result && result.ok === true && result.allEqual === true ? 0 : 1;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
module.exports = {
|
|
384
|
+
verifyMemorySync,
|
|
385
|
+
compareDigests,
|
|
386
|
+
vectorLag,
|
|
387
|
+
formatReport,
|
|
388
|
+
exitCodeFor,
|
|
389
|
+
DEFAULT_TABLES,
|
|
390
|
+
DEFAULT_TIMEOUT_MS,
|
|
391
|
+
LOCAL_PATHS,
|
|
392
|
+
MEMBER_PATHS,
|
|
393
|
+
};
|