Skip to content

fix(service-bot): re-publish after offline recreates the destroyed online bot#438

Draft
totalfrank wants to merge 1 commit into
devfrom
claude/github-issue-435-vqkuwt
Draft

fix(service-bot): re-publish after offline recreates the destroyed online bot#438
totalfrank wants to merge 1 commit into
devfrom
claude/github-issue-435-vqkuwt

Conversation

@totalfrank

Copy link
Copy Markdown
Collaborator

Summary

Fixes #435.

Offlining a SUCCESS service-bot publish tears down its online bot via a BaaS STOP, which for a TeClaw device physically destroys the underlying bot and leaves baas_bot.status = STOPPED (not RELEASED). The subsequent re-publish's online stage then took the UPGRADE (UPDATE) path against the already-destroyed bot and failed permanently with [DEVICE_NOT_FOUND] bot not found.

The root of the hole: the lifecycle that destroys the bot (offline → STOP → STOPPED) and the guard that detects a destroyed bot (_should_upgrade_online, which only treated RELEASED as "gone") disagreed on the terminal status, so a STOPPED previous bot slipped through as a valid UPGRADE target.

Changes

Primary fix — _should_upgrade_online (upgrade_resolution_mixin.py)
Treat every gone/not-live BaaS bot status — RELEASED, STOPPED, STOPPING, FAILED — as first-release, not just RELEASED. The re-publish now issues a fresh CREATE instead of an UPDATE against the destroyed bot.

Defense-in-depth — DEVICE_NOT_FOUND classification
Even if an UPDATE is somehow issued against a destroyed device, the "target bot gone → recreate" self-heal now fires:

  • operation_runner.py: the deploy atom classifies both BOT_NOT_FOUND and DEVICE_NOT_FOUND (new shared BOT_GONE_ERROR_CODES) as TargetBotGoneError, so the caller falls back to a first release.
  • bot_build_service.upgrade: surfaces DEVICE_NOT_FOUND as a structured {success: False, error_code: ...} result (like BOT_NOT_FOUND) instead of raising, so it reaches the classifier rather than failing the publish outright.

The two error-code constants are kept in sync by hand (documented in comments); the lower-level bot_build_service deliberately does not import from the publish-flow orchestration package to keep module load order acyclic.

Tests

  • test_should_upgrade_online_forces_first_release_when_prev_bot_gone — parametrized over RELEASED/STOPPED/STOPPING/FAILED.
  • test_execute_release_phase_first_release_when_offlined_online_bot_stopped — the full offline→re-publish cycle at the service layer: previous publish RELEASED + online bot STOPPED resolves to first release, not upgrade.
  • test_atom_device_not_found_abandons_with_reason_and_raises — the deploy atom classifies DEVICE_NOT_FOUND.
  • test_upgrade_teclaw_gone_bot_returns_structured_failure — parametrized over both gone-bot codes on the teclaw upgrade path.

All 671 tests under tests/community/core/service_bot/ pass, plus the e2e publish-boundary suite.

🤖 Generated with Claude Code


Generated by Claude Code

…line bot

Offlining a SUCCESS service-bot publish tears down its online bot via a
BaaS STOP, which for a TeClaw device physically destroys the underlying
bot and leaves baas_bot.status = STOPPED (not RELEASED). The re-publish's
online stage then took the UPGRADE (UPDATE) path against the destroyed
bot and failed permanently with DEVICE_NOT_FOUND.

- _should_upgrade_online: treat every gone/not-live baas status
  (RELEASED, STOPPED, STOPPING, FAILED), not just RELEASED, as
  first-release so the re-publish issues a fresh CREATE.
- operation_runner / bot_build_service.upgrade: classify DEVICE_NOT_FOUND
  alongside BOT_NOT_FOUND as "target bot gone" so an UPDATE that still
  hits a destroyed device self-heals into a first release instead of
  failing the publish.

Adds regression tests for the offline->re-publish cycle and both
gone-bot error codes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Service-bot offline→re-publish targets the destroyed online bot (STOPPED slips past _should_upgrade_online, causing permanent DEVICE_NOT_FOUND)

1 participant