OpenClaw 2026.7.1-2 pin, watchdog lifecycle hardening, 99.6% test coverage - #109
OpenClaw 2026.7.1-2 pin, watchdog lifecycle hardening, 99.6% test coverage#109garrytan wants to merge 18 commits into
Conversation
Latest npm stable; Fable 5 support lands in the 2026.6.6 train once its publish is fixed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
npm only runs prepack for registry publishes, not when installing from a git URL — so consumers pinning github:garrytan/alphaclaw got no lib/public/dist/ or generated Tailwind CSS (both gitignored), leaving the setup UI blank. prepare runs for git deps and rebuilds the same artifacts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add prepare script so git-dependency installs build the UI
ensureUsageTrackerPluginEntry only ever *added* the canonical __dirname-resolved usage-tracker path; it never removed paths left by a previous install at a different location. After a deployment switches from the @chrysb/alphaclaw npm package (installed at /app/node_modules/@chrysb/alphaclaw/...) to a git dependency (installed at /app/node_modules/alphaclaw/...), the old path lingers in openclaw.json, no longer exists on disk, and OpenClaw rejects the whole config as invalid — breaking the gateway and every openclaw subcommand (status/health/logs/doctor). Prune any `.../plugin/usage-tracker` load path that isn't the canonical one in the boot reconcile (ensureUsageTrackerPluginConfig), so existing configs migrate on the next boot. Kept out of the shared reconcile path so config sanitization semantics are unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AlphaClaw assumed it was always the published @chrysb/alphaclaw npm package: it resolved its own install dir and version by that exact dependency key, and its in-place "Update" ran npm install @chrysb/alphaclaw@latest from the registry. None of that holds when a consumer pins it as a git dependency (e.g. "alphaclaw": "git+https://github.com/<owner>/alphaclaw.git#main"). - Add lib/server/self-dependency.js: resolveSelfDependency() finds the consumer app root and how AlphaClaw is pinned, matching either the `alphaclaw` alias (git installs) or the `@chrysb/alphaclaw` npm scope, and classifies the spec as git vs npm (looksLikeGitDependency). - Rename the package to `alphaclaw`. - Route findInstallDir (openclaw-version + alphaclaw-version) and the template/version lookups through the shared resolver (dual-key). - Self-update is now spec-aware: npm-pinned installs keep the in-place npm update (using the resolved package name, no hardcoded scope); git-pinned installs return redeploy/reinstall instructions instead and skip the npm registry version check entirely. The pending-update path in bin/alphaclaw.js does the same. - Point the Render template + GitHub releases URLs at the garrytan fork. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Support git-based deployment of AlphaClaw
The boot-time prune added in the previous change lived in ensureUsageTrackerPluginConfig, which only runs via runOnboardedBootSequence — i.e. only when isOnboarded() is true. A deployment that carries a stale @chrysb/alphaclaw usage-tracker path but is not (yet) onboarded never got the path pruned, so OpenClaw kept rejecting the config and every openclaw command failed. bin/alphaclaw.js already has an unconditional "Config exists, reconciling channels" block that runs on every boot whenever openclaw.json exists, and it was *adding* the canonical usage-tracker path without removing stale ones (leaving both). Prune stale `.../plugin/usage-tracker` entries there too, so the migration is load-bearing regardless of onboarding state. The onboarded reconcile prune remains as a backstop. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Prune stale usage-tracker plugin paths on every boot
Latest npm stable. Brings Claude Fable 5 (registry-verified) and Haiku 4.5
model support, plus the 6.6 security-hardening batch (fail-closed exec
approvals, sandbox bind-path validation, MCP stdio/SSE hardening) and 6.8
admin-gating on HTTP model-override/session-kill endpoints.
Gateway is spawned with fixed args ("gateway run"), so the 6.8 CLI
usage-error exit-code change (0 -> non-zero) does not affect the watchdog's
exit-code handling.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Latest npm stable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Current npm latest: the 2026.7.1 stabilization train (gateway crash-loop recovery, fail-closed container upgrades, Sonnet 5 / Mythos 5 catalog) plus the out-of-band 2026.7.1-2 hotfix for npm plugin updates (#108336). Tarball diff against 2026.7.1 verified clean (same deps, no new install scripts) since the hotfix skipped the upstream release pipeline. OpenClaw 2026.7.1 moved normalizeThinkLevel into a thinking.shared-*.js chunk that the sentinel scan never covered; add a fallback scan so the thinking API resolves on both old and new dist layouts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
OpenClaw 2026.7.1 introduced two lifecycle behaviors the watchdog was blind to: 1. Fatal config errors now exit with EX_CONFIG (78), meaning "do not restart until the config is fixed". The watchdog previously treated 78 as a generic crash and restart-looped against that contract. It now enters a config_error lifecycle, attempts at most one auto-repair per incident (doctor --fix can genuinely fix config), never counts 78 toward the crash-loop window, and pauses with a notification otherwise. Failing health probes no longer demote the config_error state. 2. The gateway's own crash-loop breaker can boot into control-plane-safe mode: /health stays green while channel autostart is suppressed, which previously read as fully healthy. The watchdog now probes /readyz after each healthy check, surfaces safeMode/suppressedChannels in status, notifies once per suppression set, and exposes POST /api/watchdog/resume-channels which issues the gateway's channels.start override per suppressed channel. Covered by unit tests and an e2e suite driving the real watchdog through the real routes against a stateful fake gateway. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ty, GPT-5.6. Conflict resolutions: - openclaw-thinking.js: take upstream's native thinking-level normalization (replaces our dist-chunk duck-typing fallback entirely). - watchdog.js: adopt upstream's EX_CONFIG semantics (configuration_error lifecycle, latch until launch or forced repair, no auto-repair) over our one-shot-repair variant; keep our safe-mode /readyz detection and resume-channels API on top. Tests reconciled to upstream semantics. - usage-tracker-config.js: keep both our stale-path pruning and their Telegram streaming migration. - openclaw-version.js: keep both self-dependency resolution (git deploys) and their Node runtime gate. - package.json: keep fork name 'alphaclaw' and openclaw@2026.7.1-2 pin (upstream pins plain 2026.7.1, which has the doctor --fix plugins.allow-stripping bug); adopt their 0.9.31 version. Note: upstream's Node gate requires >=22.22.3 / >=24.15 / >=25.9 (SQLite WAL corruption fix); suite verified on Node 24.18.0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Systematic coverage push across the whole codebase, test files only (no source changes): server core (chat-ws WebSocket bridge via a real ws fake-gateway, gateway process supervision), all route surfaces (telegram, nodes, webhooks, codex OAuth, browse with real temp git repos, models, agents, doctor, system, onboarding), db layers (usage/webhooks/auth/doctor/ watchdog sqlite), gmail/google integration, cron service, cost/version services, CLI helpers, and frontend lib/components (including preact component logic tested via a hooks harness without a DOM). Remaining uncovered lines (53 of 14,370) are documented dead code or v8-to-istanbul instrumentation artifacts, verified per file by adversarial inspection. Two small CLI scripts (lib/cli/git-sync.js, lib/scripts/migrate-openclaw-codex.js) are not loaded by any test and sit outside the measured set. Also set vitest testTimeout to 30s: openclaw's plugin-sdk pays a >5s first-import cost per worker, which flaked timing-sensitive files under parallel load. Full suite verified green four consecutive runs on Node 24.18.0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… fix. Conflict resolutions: keep fork name and openclaw@2026.7.1-2 pin, adopt 0.9.33; cron-service.test.js keeps both our coverage helpers and upstream's SQLite cron-store harness. Adapted one coverage test to upstream's removal of the cron delivery-mismatch warning (delivery.mode=none with a message-tool prompt no longer warns). Full suite green: 2,079 tests / 146 files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
chrysb
left a comment
There was a problem hiding this comment.
Thanks for the OpenClaw 2026.7.1-2 and watchdog work. We can’t merge this PR as a whole because it also renames the published package, redirects release/template URLs to a fork, introduces git-deployment/update behavior, and adds a very large test-only expansion.
Please split out a narrowly scoped follow-up for the dependency hotfix and watchdog safe-mode/resume behavior (including its Watchdog UI). Keep the published package identity and official project/template URLs unchanged.
…files. Adds retry:1 to the two proxy-over-real-socket test files that showed rare transient connect races under parallel machine load (each passes 100% in isolation; deterministic failures still fail both attempts). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks for the review — makes sense. Opened #110 with exactly the scoped subset you asked for: the 2026.7.1-2 dependency hotfix and the watchdog safe-mode/resume behavior including its Watchdog UI (safe-mode banner + resume action + badge state). Package identity and project/template URLs untouched. Closing this one. |
Supersedes #92 (closed unmerged — much of its openclaw-migration content has since landed upstream independently; this PR carries the remaining unique work, rebased onto current
mainvia merges with no conflicts outstanding).What's in here
1. openclaw pin:
2026.7.1-2(not plain2026.7.1)The plain 2026.7.1 npm publish has the
doctor --fixbug that silently strips official external-catalog plugin ids (likecodex) fromplugins.allow(openclaw#107226, fixed in the 2026.7.1-2 hotfix republish, PR openclaw#108336). Since AlphaClaw's watchdog runsdoctor --fix --yesduring auto-repair, pinning plain 7.1 makes auto-repair actively harmful for Codex deployments. I tarball-diffed2026.7.1vs2026.7.1-2before adopting it (the hotfix was published outside openclaw's release pipeline): same dependencies, same bin/main, no new install scripts — clean.2. Watchdog hardening for the OpenClaw 2026.7.1 gateway lifecycle
Complements the EX_CONFIG handling already on main with the other half of openclaw's new crash-loop breaker contract:
/healthcheck, probe/readyz— when openclaw's own breaker suppresses channel autostart (gateway healthy, channels silently down), the watchdog now surfacessafeMode+suppressedChannelsin status, notifies once per suppression set, and clears with a recovery notice.POST /api/watchdog/resume-channels: issues openclaw's documentedchannels.startmanual override per suppressed channel, then re-checks health. 409 when nothing is suppressed.3. Git-based deployment support (carried from #92)
lib/server/self-dependency.js+ prepare-script wiring so AlphaClaw can be deployed from a git checkout rather than only the npm package, and unconditional usage-tracker stale-path pruning.4. Test coverage: 71% → 99.63% lines (2,079 tests / 146 files)
Test-files-only (zero source changes): full coverage of the chat-ws WebSocket bridge (driven by a real
wsserver playing the gateway side of protocol v4), gateway process supervision, every route surface, the sqlite db layers, gmail/google integration, cron, cost/version services, CLI helpers, and the frontend lib/components (preact component logic exercised via a hooks harness, no DOM). The 53 remaining uncovered lines are individually documented dead code or v8-to-istanbul artifacts. Also sets vitesttestTimeout: 30000— openclaw's plugin-sdk pays a >5s first-import cost per worker, which flaked timing-sensitive suites under parallel load.Test plan
/readyzpayload shape andchannels.startRPC verified against the actual openclaw 2026.7.1-2 dist, not just release notes.🤖 Generated with Claude Code