From 70c9f7254c286568f382655fca183a7cd58ca006 Mon Sep 17 00:00:00 2001 From: "didericis (claude)" Date: Tue, 2 Jun 2026 10:28:16 -0400 Subject: [PATCH] docs: add PRD 0040 --- ...0040-backend-aware-resume-and-dashboard.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 docs/prds/0040-backend-aware-resume-and-dashboard.md diff --git a/docs/prds/0040-backend-aware-resume-and-dashboard.md b/docs/prds/0040-backend-aware-resume-and-dashboard.md new file mode 100644 index 0000000..bc22412 --- /dev/null +++ b/docs/prds/0040-backend-aware-resume-and-dashboard.md @@ -0,0 +1,87 @@ +# PRD 0040: Backend-Aware Resume and Dashboard Reattach + +- **Status:** Draft +- **Author:** didericis-codex +- **Created:** 2026-06-02 +- **Issue:** #137 + +## Summary + +Persist the backend name in `BottleMetadata` and thread it through `resume` and +dashboard reattach so both flows construct the correct backend bottle without +relying on env overrides or defaulting to Docker. + +## Problem + +`BottleMetadata` records identity, agent, cwd, started_at, and compose project, +but not the backend name. Without it: + +- `cli/resume.py` cannot select the right backend from a preserved state dir + alone; operators must remember to set `BOT_BOTTLE_BACKEND=smolmachines` + separately. +- `cli/dashboard.py` `_bottle_for_slug` constructs a `DockerBottle` for any + externally discovered slug, so reattaching to a live smolmachines agent + from the dashboard sends Docker commands to a smolvm machine. + +## Goals / Success Criteria + +- `BottleMetadata` includes the backend name, written at bottle creation time + for both Docker and smolmachines. +- `cli resume` reads the persisted backend name and constructs the correct + bottle type without requiring an env override. +- Dashboard reattach (`_bottle_for_slug`) reads the persisted backend name and + constructs the correct bottle type. +- Existing Docker bottles without a persisted backend name fall back to Docker + (backward-compatible default). +- Unit tests cover write, read, backward-compatible fallback, and both + resume/reattach code paths. + +## Non-goals + +- No changes to manifest or egress configuration. +- No new CLI flags (backend selection at resume time should be automatic). +- No smolmachines capability-apply implementation (see PRD 0039). + +## Scope + +In scope: + +- `bot_bottle/backend/docker/bottle_state.py` `BottleMetadata` schema and + write path. +- `bot_bottle/backend/docker/bottle.py` and + `bot_bottle/backend/smolmachines/bottle.py` metadata write at creation. +- `bot_bottle/cli/resume.py` backend selection from metadata. +- `bot_bottle/cli/dashboard.py` `_bottle_for_slug` backend selection. +- Unit tests covering the above. + +Out of scope: + +- Migration tooling for existing state dirs. +- Integration tests that exercise full resume across process restarts. + +## Design + +Add a `backend` field to `BottleMetadata` with a default of `"docker"` for +backward compatibility. Both `DockerBottle` and `SmolmachinesBottle` write +their backend name into metadata at creation time. + +`resume` reads the metadata before constructing the bottle object and selects +the appropriate backend class. `_bottle_for_slug` does the same. A helper +function in the metadata module can encapsulate the backend-name-to-class +mapping so the logic is not duplicated. + +## Testing Strategy + +- Unit tests for `BottleMetadata` serialisation with and without the backend + field. +- Unit tests for the backward-compatible default. +- Unit tests for `resume` selecting smolmachines vs Docker from metadata. +- Unit tests for `_bottle_for_slug` selecting smolmachines vs Docker. + +Run: + +- `python3 -m unittest discover -s tests/unit` + +## Open Questions + +None.