flower
/
All briefs
complete draft note flower

Track worktree/environment isolation metadata (DB-isolated vs code-only) in flower

canonical · plan

Spec

markdown

async · awaiting you

Open questions

flower from brief #275 for · flower-orchestrator

Merge #275 now?

#275 fleet/roster UI build is DONE and green — 6 PRs on flower/275-build (design doc + PR-1..6), full suite 1381 pass / 3 skip / 0 fail, pint clean. It's the /roster → node → environment → agents Fleet tree + /environments table + recall_environments MCP tool + dispatch env-picker with a shared-main∧migration warn-with-confirm gate. Migrations are additive (new runtime_environments table + nullable runtime_environment_id FK on daemon_agents — backward-compatible, existing check-ins unaffected). Design was already blessed via the design loop + your decisions #75/#76. Since you wanted to EYEBALL the control surface, how do you want to review it? (Separately, one open policy call the worker deferred: hard-block vs warn for agent-initiated shared-DB migrations — MVP shipped warn-with-confirm; tell me if you want it flipped to hard-block and I'll file it.)

hand-off · dispatch

Dispatch

Auto-dispatch

when it reaches planned

Design-loop

design pass before build

This brief is complete — dispatch is closed.

#148 done fresh flower
You are being dispatched from flower Brief #275: Track worktree/environment isolation metadata (DB-isolated vs code-only) in flower

Recall pointer:
- Use recall_brief with id 275 for the full folder if you need provenance.

Target:
- project: flower (/Users/mikeferrara/Documents/code/flower)
- branch: choose an appropriate branch
- worktree: not specified
- kind: fresh

Current brief spec:
# Track worktree/environment isolation metadata in flower

## Problem (operator, 2026-07-05)
We run many git worktrees across projects with DIFFERENT isolation levels — some fully isolated (own `DB_DATABASE` / `REDIS_PREFIX` / `.env` / Meili index), some code-only or frontend-only sharing MAIN's DB/Redis/Meili. Today an agent/orchestrator can't reliably KNOW a worktree's isolation level; it infers from `.env` diffs, `REDIS_PREFIX`, or the worktree-manager lifecycle mode — error-prone (see the flower CLAUDE.md `.env`-drift + "worktrees share MAIN's Meili/Redis" caveats).

## Why it matters (orchestrator pain this solves)
- **Safe dispatch/merge:** a shared-DB worktree means a migration is live on MAIN *immediately*; an isolated one doesn't. The auto-dispatch worktree-reuse picker must know this BEFORE it dispatches.
- **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN.
- **`.env` drift awareness:** flag a worktree whose `.env` is a stale snapshot missing MAIN keys.
- **Reuse hygiene:** reuse a FREE isolated worktree instead of sprawling new ones.

## DECIDED (operator Mike, 2026-07-05 — decisions #75 / #76)
- **Q1 Model scope → GENERIC ENVIRONMENT.** A generic `environment` record with a `kind` (main | local-worktree | remote-lxc). Local worktrees are the only populated kind at MVP; remote Proxmox LXCs (#263/#265) reuse the SAME model — no schema rebuild later.
- **Q2 MVP boundary → ALL-IN-ONE.** Ship the full slice in THIS brief: record + populate/refresh + `recall_*` tool + the bloom `/environments` UI + the auto-dispatch worktree-reuse-picker integration. (No deferral to a follow-up.)

## Data model
A first-class `environments` record (extends flower's existing worktree notion — sessions already carry `worktree_id`), per environment:
- **identity:** path (or host+path), project, git_branch, `kind` (main | local-worktree | remote-lxc)
- **isolation:** lifecycle_mode (isolated | shared | bare | code-only), `db_isolation` (own DB_DATABASE vs shared-MAIN), redis_prefix, meili_index (shared | isolated), horizon/daemon-runner status
- **env health:** `.env` present? drift status (missing MAIN keys vs MAIN's `.env`?), last_synced_at
- **availability:** free/busy, last_seen
- **(remote-lxc extras, populated when #263/#265 lands):** node, CT id, tailscale addr, reachable?

## Deliverables (all-in-one, per #76)
1. **`environments` table + model** (+ relation to sessions' `worktree_id`; MAIN is a row too).
2. **Populate/refresh:** an artisan sweep (scheduled like `sync-solo`) + on-demand command; a bounded reconciler that reads `~/.worktree-config.json` + `git worktree list` + per-worktree `.env` (DB_DATABASE / REDIS_PREFIX / key-diff vs MAIN) and reconciles add/remove.
3. **`recall_environments` MCP tool:** agents query "is env X DB-isolated? free? `.env` drifted? live-verify-capable?" before dispatching/verifying.
4. **bloom `/environments` UI view** (config-as-data table, dark bloom system).
5. **Dispatch integration:** the auto-dispatch worktree-reuse picker consults isolation metadata to choose a FREE appropriate env + warn on shared-DB migrations.

## Populate / refresh sources
`~/.worktree-config.json` (worktree-manager, lifecycle modes) + `git worktree list` + per-worktree `.env` inspection. Mirror the existing bounded-reconciler + scheduled-sweep patterns.

## Relationships
- Extends flower's existing worktree notion (`worktree_id` on sessions).
- worktree-manager (`~/.worktree-config.json`, lifecycle modes) + `_worktrees-playbook.md`.
- **#263 / #265** — remote LXC environments reuse the generic model (decision #75).
- Supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl).

## Provenance
Operator musing while dispatching #248 (2026-07-05); orchestrator agreed + flagged auto-dispatch. Refined by flower-refine; generic-environment framing from the #263 tie; scope decided by Mike — #75 (generic) + #76 (all-in-one) — 2026-07-05.

**Disposition:** `planned` — model + scope decided; build-ready end-to-end. Medium-large build (migration + reconciler/sweep + `recall_environments` tool + `/environments` UI + dispatch-picker integration). Auto-dispatch flagged → flows to build; orchestrator owns dispatch.

Recent/key trace events:
[10] operator_answer operator:mike: {"choice":"all_in_one"}
[11] spec_snapshot flower-refine: # Track worktree/environment isolation metadata in flower

## Problem (operator, 2026-07-05)
We run many git worktrees across projects with DIFFERENT isolation levels — some fully isolated (own `DB_DATABASE` / `REDIS_PREFIX` / `.env` / Meili index), some code-only or frontend-only sharing MAIN's DB/Redis/Meili. Today an agent/orchestrator can't reliably KNOW a worktree's isolation level; it infers from `.env` diffs, `REDIS_PREFIX`, or the worktree-manager lifecycle mode — error-prone (see the flower CLAUDE.md `.env`-drift + "worktrees share MAIN's Meili/Redis" caveats).

## Why it matters (orchestrator pain this solves)
- **Safe dispatch/merge:** a shared-DB worktree means a migration is live on MAIN *immediately*; an isolated one doesn't. The auto-dispatch worktree-reuse picker must know this BEFORE it dispatches.
- **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN.
- **`.env` drift awareness:** flag a worktree whose `.env` is a stale snapshot missing MAIN keys.
- **Reuse hygiene:** reuse a FREE isolated worktree instead of sprawling new ones.

## Scope decision — worktree vs generic ENVIRONMENT (→ operator steer, Q1)
Epic #263 (Solo-decoupling) is moving toward **parallel worktree-environments incl. remote Proxmox LXCs** (each an isolated env running flower-only agents; see #263 fold 2026-07-05). A remote LXC is just another isolation class, and the SAME questions ("is env X DB-isolated? free/busy? can it run live verification?") answer for both a local worktree and a remote LXC. **Recommendation:** model a generic **`environment`** record with a `kind` (main | local-worktree | remote-lxc); local worktrees are the only populated kind at MVP, remote-lxc slots in when #263/#265 lands — so we don't rebuild the model later.

## Data model (proposed)
A first-class `environments` record (extends flower's existing worktree notion — sessions already carry `worktree_id`), per environment:
- **identity:** path (or host+path), project, git_branch, `kind` (main | local-worktree | remote-lxc)
- **isolation:** lifecycle_mode (isolated | shared | bare | code-only), `db_isolation` (own DB_DATABASE vs shared-MAIN), redis_prefix, meili_index (shared | isolated), horizon/daemon-runner status
- **env health:** `.env` present? drift status (missing MAIN keys?), last_synced_at
- **availability:** free/busy, last_seen
- **(remote-lxc extras, later):** node, CT id, tailscale addr, reachable?

## Populate / refresh
- **Sources:** worktree-manager config (`~/.worktree-config.json`) + `git worktree list` + per-worktree `.env` inspection (DB_DATABASE / REDIS_PREFIX / key-diff vs MAIN).
- **Refresh:** a scheduled sweep (mirrors the existing sync-solo pattern) + an on-demand artisan command; reconcile add/remove like the other bounded reconcilers.

## Surfaces
- **`recall_*` MCP tool** (e.g. `recall_environments`): agents query "is env X DB-isolated? free? `.env` drifted?" before dispatching/verifying. **MVP-critical — this is what the orchestrator consumes.**
- **bloom `/environments` UI view** (config-as-data table, dark bloom system). *(Follow-up.)*
- **Dispatch integration:** the auto-dispatch worktree-reuse picker consults isolation metadata to pick an appropriate FREE env + warn on shared-DB migrations. *(Follow-up / phase 2.)*

## MVP boundary (→ operator steer, Q2)
**Recommend MVP** = the `environments` record + populate/refresh from worktree-config/`.env`/git + the `recall_*` tool (the orchestrator's actual need), **deferring** the UI view + dispatch-picker auto-integration to a follow-up. (Alternative: ship it all in one.)

## Relationships
- Extends flower's existing worktree notion (`worktree_id` on sessions).
- worktree-manager (`~/.worktree-config.json`, lifecycle modes) + `_worktrees-playbook.md`.
- **#263 / #265** — remote LXC environments (drives the generic-environment scope decision above).
- Supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl).

## Provenance
Operator musing while dispatching #248 (2026-07-05); orchestrator agreed + flagged auto-dispatch. Refined by flower-refine; generic-environment framing added from the #263 tie.

**Disposition:** `refining` — sharpened + build-ready pending two scope steers (Q1 environment-abstraction, Q2 MVP boundary), then `planned`.
[12] refinement flower-refine: # Track worktree/environment isolation metadata in flower

## Problem (operator, 2026-07-05)
We run many git worktrees across projects with DIFFERENT isolation levels — some fully isolated (own `DB_DATABASE` / `REDIS_PREFIX` / `.env` / Meili index), some code-only or frontend-only sharing MAIN's DB/Redis/Meili. Today an agent/orchestrator can't reliably KNOW a worktree's isolation level; it infers from `.env` diffs, `REDIS_PREFIX`, or the worktree-manager lifecycle mode — error-prone (see the flower CLAUDE.md `.env`-drift + "worktrees share MAIN's Meili/Redis" caveats).

## Why it matters (orchestrator pain this solves)
- **Safe dispatch/merge:** a shared-DB worktree means a migration is live on MAIN *immediately*; an isolated one doesn't. The auto-dispatch worktree-reuse picker must know this BEFORE it dispatches.
- **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN.
- **`.env` drift awareness:** flag a worktree whose `.env` is a stale snapshot missing MAIN keys.
- **Reuse hygiene:** reuse a FREE isolated worktree instead of sprawling new ones.

## DECIDED (operator Mike, 2026-07-05 — decisions #75 / #76)
- **Q1 Model scope → GENERIC ENVIRONMENT.** A generic `environment` record with a `kind` (main | local-worktree | remote-lxc). Local worktrees are the only populated kind at MVP; remote Proxmox LXCs (#263/#265) reuse the SAME model — no schema rebuild later.
- **Q2 MVP boundary → ALL-IN-ONE.** Ship the full slice in THIS brief: record + populate/refresh + `recall_*` tool + the bloom `/environments` UI + the auto-dispatch worktree-reuse-picker integration. (No deferral to a follow-up.)

## Data model
A first-class `environments` record (extends flower's existing worktree notion — sessions already carry `worktree_id`), per environment:
- **identity:** path (or host+path), project, git_branch, `kind` (main | local-worktree | remote-lxc)
- **isolation:** lifecycle_mode (isolated | shared | bare | code-only), `db_isolation` (own DB_DATABASE vs shared-MAIN), redis_prefix, meili_index (shared | isolated), horizon/daemon-runner status
- **env health:** `.env` present? drift status (missing MAIN keys vs MAIN's `.env`?), last_synced_at
- **availability:** free/busy, last_seen
- **(remote-lxc extras, populated when #263/#265 lands):** node, CT id, tailscale addr, reachable?

## Deliverables (all-in-one, per #76)
1. **`environments` table + model** (+ relation to sessions' `worktree_id`; MAIN is a row too).
2. **Populate/refresh:** an artisan sweep (scheduled like `sync-solo`) + on-demand command; a bounded reconciler that reads `~/.worktree-config.json` + `git worktree list` + per-worktree `.env` (DB_DATABASE / REDIS_PREFIX / key-diff vs MAIN) and reconciles add/remove.
3. **`recall_environments` MCP tool:** agents query "is env X DB-isolated? free? `.env` drifted? live-verify-capable?" before dispatching/verifying.
4. **bloom `/environments` UI view** (config-as-data table, dark bloom system).
5. **Dispatch integration:** the auto-dispatch worktree-reuse picker consults isolation metadata to choose a FREE appropriate env + warn on shared-DB migrations.

## Populate / refresh sources
`~/.worktree-config.json` (worktree-manager, lifecycle modes) + `git worktree list` + per-worktree `.env` inspection. Mirror the existing bounded-reconciler + scheduled-sweep patterns.

## Relationships
- Extends flower's existing worktree notion (`worktree_id` on sessions).
- worktree-manager (`~/.worktree-config.json`, lifecycle modes) + `_worktrees-playbook.md`.
- **#263 / #265** — remote LXC environments reuse the generic model (decision #75).
- Supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl).

## Provenance
Operator musing while dispatching #248 (2026-07-05); orchestrator agreed + flagged auto-dispatch. Refined by flower-refine; generic-environment framing from the #263 tie; scope decided by Mike — #75 (generic) + #76 (all-in-one) — 2026-07-05.

**Disposition:** `planned` — model + scope decided; build-ready end-to-end. Medium-large build (migration + reconciler/sweep + `recall_environments` tool + `/environments` UI + dispatch-picker integration). Auto-dispatch flagged → flows to build; orchestrator owns dispatch.
[13] status_change flower-refine: (no body)
[14] status_change flower-orchestrator: (no body)
[15] dispatched flower-orchestrator: Design-loop dispatch request #146 queued for flower.
[16] refinement flower-refine: **Finalize for the design worker (req #146) — decisions locked + grounding pointers.**

Decisions are locked: **#75 generic `environment` (kind: main | local-worktree | remote-lxc)** + **#76 all-in-one** (record + reconciler/sweep + `recall_environments` + `/environments` UI + dispatch-picker). The spec above is the canonical input; this note just points at existing patterns so the design loop reuses rather than reinvents.

**Reuse these existing flower patterns (don't reinvent):**
- **`recall_environments` MCP tool** → model on the existing read tools in `app/Mcp/Tools` (shape/registration like `recall_roster` / `recall_active`); register in `app/Mcp/Servers`. Make `environment` a lightweight readable record, not a chunkable/searchable type (it's live infra state, not corpus).
- **`/environments` UI** → the config-as-data dark-bloom table pattern used by `/roster` and `/briefs` (`resources/views/components/ui/*`); per-project grouping + isolation/free-busy/drift badges reads naturally there.
- **Populate/refresh** → mirror the existing **sync-solo** reconciler + scheduled sweep (bounded, idempotent add/remove reconcile), scheduled in `config/`/the scheduler like the other sweeps.
- **`.env` drift detection** → diff a worktree's `.env` keys against MAIN's `.env` (the flower CLAUDE.md documents this exact drift: worktree `.env` is a point-in-time snapshot that isn't backfilled when MAIN gains keys). `db_isolation` = worktree `DB_DATABASE` != MAIN's; shared-Redis = same `REDIS_PREFIX`/no prefix.
- **Source of truth** = `~/.worktree-config.json` (worktree-manager) + `git worktree list`; sessions already carry `worktree_id` — relate `environment` to that, don't duplicate it.

**Design-sensitive calls for the loop to resolve (my flags, not answers):**
1. `recall_environments` contract — filters (project, kind, free/busy, db-isolated) + response fields; does it return a single env by path or a list?
2. `/environments` layout — grouping (by project? by host/node?), which badges, and how free/busy + `.env`-drift surface at a glance.
3. Dispatch-picker integration — the free-env selection heuristic + the **shared-DB-migration warning** UX (warn vs block when a brief with a migration targets a shared-DB worktree).
4. free/busy signal — derive from active sessions/daemons on the worktree (roster) vs a separate lock?

No status change from me — #275 is orchestrator-owned now (dispatched → design leg). Flagging only; the design worker owns the resolutions.
[17] participant_joined flower-275-design: (no body)
[18] comment flower-275-design: ## Design leg complete — Fleet / Roster UI + environment-isolation metadata (dispatch req #146)

**Doc:** `docs/design/275-fleet-roster-ui.md` on branch `flower/275-design` (commit `94c8900`, trailer `Brief: #275`). NOT merged — orchestrator owns merges.

**Method:** Ran the `/design` writer↔reviewer loop to **CONSENSUS in 3 rounds**. Both sub-agents used `frontend-design`; the reviewer ground-truthed every code claim (tokens, props, service methods, field names) against the real repo. 4 blockers in round 1 → fixed → 2 new safety-logic blockers in round 2 → fixed → CONSENSUS round 3 (0 blockers).

### Design direction (the UI is the heart, per the operator's emphasis)
Evolve the flat, project-grouped `/roster` into a **fleet tree `node(host) → environment(checkout/LXC) → agents`**, built entirely from existing bloom primitives (`<x-ui.card flush>` + `divide-y` + the `.nav-subtree` guide-rail + server-driven disclosure) — the agent leaf row is `daemon-row` reused verbatim. A dusk-quiet deck whose **only two loud marks are the *moving* live pulse and the *high-contrast* red SHARED-MAIN-DB seal** — the one safety-critical fact a migration can hurt on.

### Resolutions of the must-resolve items
- **Naming collision** → new model **`RuntimeEnvironment`** (table `runtime_environments`); the existing Forge `Environment` stays the deploy-target concept, untouched but its `projects/show` card relabeled `forge · deploy targets`. Operator/MCP noun stays "environment", tool stays `recall_environments` — the collision is solved only at the PHP class layer. *(One naming confirm flagged: keep "environment" vs rename everywhere to "Workspace" — pure copy/rename, nothing structural rides on it.)*
- **agent→environment link** → layered: read-time `daemon.session_id → session.worktree_id → runtime_environment` is the source of truth; a denormalized nullable `runtime_environment_id` FK on `daemon_agents` (stamped at spawn/check-in, backfilled by the reconciler) is the fast/stable fallback; `— unplaced —` bucket for the rest.
- **Tree structure** → **environment is the primary grouping** (a worktree *is* project+branch, so project/role become filters, not levels); local worktrees are children of the MAIN node; the platform daemons live in the accent-treated MAIN environment; node collapses to one slim band today, remote LXCs add sibling bands later.
- **`db_isolation` (the safety field)** → four states `main | isolated | shared_main | unknown`, computed **identity-first** (MAIN can never false-red) *and* **fail-safe** (an unreadable `.env` → `unknown`, never false-green; `unknown` is excluded from the safe set and warns like shared). Three-seal ramp: `db · MAIN` (accent) / `db · isolated` (green) / `⚠ db · SHARED MAIN` (red) / `? unverified` (muted).
- **`recall_environments`** → roster-shaped read tool mirroring `RecallRosterTool`; one call answers isolated/free/drifted/live-verify-capable; free/busy derived from `livenessFor` (busy = ≥1 agent `alive|parked|expected`, closing the double-spawn hole) — no separate lock; `warnings[]` flags live-agent-on-shared-DB.
- **Dispatch picker** → ranked free/isolated candidates on the brief Dispatch form; **warn-with-required-confirm, never block** when a migration targets a `shared_main`/`unknown` DB; auto-dispatch reuse calls the same read service for parity.
- **Nav/route** → `/roster` evolves in place, relabeled **Fleet** (`icon="flame"`); **Environments** infra `.data-table` added as a `.nav-subtree` child, cross-linked both ways.

### Sequenced PR plan (all-in-one per #76, dependency-ordered)
1. **PR-1** — `RuntimeEnvironment` record + `runtime_environment_id` FK on `daemon_agents` + Forge card relabel.
2. **PR-2** — Reconciler (worktree-config + `git worktree list` + `.env` inspection) + scheduled sweep; identity-first *and* fail-safe `db_isolation`; mark-stale-never-prune; FK backfill. *(largest backend; 2-commit split.)*
3. **PR-3** — `recall_environments` MCP tool + `RuntimeEnvironmentRosterService`.
4. **PR-4** — Fleet tree UI (node band → env-header partial with seals+rollup+**server-driven disclosure** → `daemon-row` leaf), env-level actions, drop the dead `LIVENESS_META['idle']`, new `requestWinddownForEnvironment()`. *(largest PR; 2-commit split.)*
5. **PR-5** — `/environments` infra table + cross-links + nav sublink.
6. **PR-6** — Dispatch picker + migration warn-with-confirm + auto-dispatch parity.

PR-1..3 are non-visible substrate (not a tracer bullet — honestly flagged); first visual proof is PR-4 (optional "PR-3.5" one-row seal render if earlier proof is wanted).

### Open questions carried for the BUILD leg (in the doc)
UI noun confirm (environment vs Workspace) · migration-detection source for the warning (`has_migration` flag vs keyword scan vs diff) · whether an **agent**-initiated shared-DB migration should be hard-blocked (not just warned) since no human is present · spawn-into path resolution (branch key sufficient, or need a `target_path` override) · stamping `runtime_environment_id` at check-in vs reconciler-only · node identity/field completeness for remote-LXC.

Ready for a BUILD-leg dispatch against this spec.
[19] dispatched flower-275-design: Dispatch request #146 marked done.
[20] note_added flower-275-design: Design loop complete — needs_design_loop cleared; brief is build-ready. The build leg now follows the brief's normal dispatch policy.
[21] status_change flower-275-design: (no body)

Recommended linked context:
{
    "todos": [],
    "scratchpads": []
}

Execution notes:
- Treat the brief as the source of truth.
- Keep work scoped to this dispatch request.
- Use brief_append / brief_update_status when reporting material progress; as your final dispatched-worker step, call brief_dispatch_complete with dispatch_request_id (or brief_id) and actor_ref.
- Codex workers should verify mutating Flower tools with tool_search query `brief_append brief_dispatch_complete flower_feedback` (limit 20) when tool availability is in doubt; report raw SEE/LOAD vs NOT visible instead of silently using local fallbacks.
- Add a git commit trailer `Brief: #275` to every commit for this brief so flower can exact-link commits back to the brief.
- Need an operator call while working this brief? A question ABOUT THIS BRIEF -> brief_ask(275, ...); a standalone decision not tied to the brief -> decision_ask(...). Both expose the full affordance set (confirm | single_choice | multi_choice | text, options + recommended, allow_write_in); prefer async questions over blocking and set is_blocking only when you truly cannot proceed.
- Cited-refs index (Brief #244): when a report / checkpoint / DONE summary cites numbered entities, append a compact `Refs:` block at the END mapping each `#N` to its REAL stored title + status — `#<num>: <title> (<status>)`, one per line (typed prefixes: bare `#N` = brief, `fb#N` feedback, `dec#N` decision, `sess#N` session, `dr#N` dispatch_request). Resolve any title you did not already pull with recall_refs instead of guessing; skip the block on trivial one-liners.
#146 done fresh flower
⚑ DESIGN-LOOP LEG (Brief #248) — this is a design-first pass, NOT the build.

This brief is flagged `needs_design_loop`. Your job here is the DESIGN pass only:
1. Run the existing `/design` skill (writer↔reviewer design-loop → design doc + PR plan)
   against this brief's spec. Reuse it — do not reinvent a design process.
2. Fold the resolved design (the design doc + sequenced PR plan) back into the brief
   spec with `brief_update_spec` so the build worker inherits a build-ready plan.
3. Complete THIS dispatch with `brief_dispatch_complete` when the design pass is done.
   Completing a design-leg dispatch automatically clears `needs_design_loop` and rolls
   the brief back to `planned` (build-ready) — the build leg then follows the brief's
   normal dispatch policy (auto if `auto_dispatch_on_planned`, else orchestrator/operator).

Do NOT build the feature in this pass. If the brief turns out to be trivial / not
actually design-sensitive, still complete the design dispatch (clearing the flag) and
note that in the spec so it drops straight to build.

You are being dispatched from flower Brief #275: Track worktree/environment isolation metadata (DB-isolated vs code-only) in flower

Recall pointer:
- Use recall_brief with id 275 for the full folder if you need provenance.

Target:
- project: flower (/Users/mikeferrara/Documents/code/flower)
- branch: choose an appropriate branch
- worktree: not specified
- kind: fresh

Current brief spec:
# Track worktree/environment isolation metadata in flower

## Problem (operator, 2026-07-05)
We run many git worktrees across projects with DIFFERENT isolation levels — some fully isolated (own `DB_DATABASE` / `REDIS_PREFIX` / `.env` / Meili index), some code-only or frontend-only sharing MAIN's DB/Redis/Meili. Today an agent/orchestrator can't reliably KNOW a worktree's isolation level; it infers from `.env` diffs, `REDIS_PREFIX`, or the worktree-manager lifecycle mode — error-prone (see the flower CLAUDE.md `.env`-drift + "worktrees share MAIN's Meili/Redis" caveats).

## Why it matters (orchestrator pain this solves)
- **Safe dispatch/merge:** a shared-DB worktree means a migration is live on MAIN *immediately*; an isolated one doesn't. The auto-dispatch worktree-reuse picker must know this BEFORE it dispatches.
- **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN.
- **`.env` drift awareness:** flag a worktree whose `.env` is a stale snapshot missing MAIN keys.
- **Reuse hygiene:** reuse a FREE isolated worktree instead of sprawling new ones.

## DECIDED (operator Mike, 2026-07-05 — decisions #75 / #76)
- **Q1 Model scope → GENERIC ENVIRONMENT.** A generic `environment` record with a `kind` (main | local-worktree | remote-lxc). Local worktrees are the only populated kind at MVP; remote Proxmox LXCs (#263/#265) reuse the SAME model — no schema rebuild later.
- **Q2 MVP boundary → ALL-IN-ONE.** Ship the full slice in THIS brief: record + populate/refresh + `recall_*` tool + the bloom `/environments` UI + the auto-dispatch worktree-reuse-picker integration. (No deferral to a follow-up.)

## Data model
A first-class `environments` record (extends flower's existing worktree notion — sessions already carry `worktree_id`), per environment:
- **identity:** path (or host+path), project, git_branch, `kind` (main | local-worktree | remote-lxc)
- **isolation:** lifecycle_mode (isolated | shared | bare | code-only), `db_isolation` (own DB_DATABASE vs shared-MAIN), redis_prefix, meili_index (shared | isolated), horizon/daemon-runner status
- **env health:** `.env` present? drift status (missing MAIN keys vs MAIN's `.env`?), last_synced_at
- **availability:** free/busy, last_seen
- **(remote-lxc extras, populated when #263/#265 lands):** node, CT id, tailscale addr, reachable?

## Deliverables (all-in-one, per #76)
1. **`environments` table + model** (+ relation to sessions' `worktree_id`; MAIN is a row too).
2. **Populate/refresh:** an artisan sweep (scheduled like `sync-solo`) + on-demand command; a bounded reconciler that reads `~/.worktree-config.json` + `git worktree list` + per-worktree `.env` (DB_DATABASE / REDIS_PREFIX / key-diff vs MAIN) and reconciles add/remove.
3. **`recall_environments` MCP tool:** agents query "is env X DB-isolated? free? `.env` drifted? live-verify-capable?" before dispatching/verifying.
4. **bloom `/environments` UI view** (config-as-data table, dark bloom system).
5. **Dispatch integration:** the auto-dispatch worktree-reuse picker consults isolation metadata to choose a FREE appropriate env + warn on shared-DB migrations.

## Populate / refresh sources
`~/.worktree-config.json` (worktree-manager, lifecycle modes) + `git worktree list` + per-worktree `.env` inspection. Mirror the existing bounded-reconciler + scheduled-sweep patterns.

## Relationships
- Extends flower's existing worktree notion (`worktree_id` on sessions).
- worktree-manager (`~/.worktree-config.json`, lifecycle modes) + `_worktrees-playbook.md`.
- **#263 / #265** — remote LXC environments reuse the generic model (decision #75).
- Supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl).

## Provenance
Operator musing while dispatching #248 (2026-07-05); orchestrator agreed + flagged auto-dispatch. Refined by flower-refine; generic-environment framing from the #263 tie; scope decided by Mike — #75 (generic) + #76 (all-in-one) — 2026-07-05.

**Disposition:** `planned` — model + scope decided; build-ready end-to-end. Medium-large build (migration + reconciler/sweep + `recall_environments` tool + `/environments` UI + dispatch-picker integration). Auto-dispatch flagged → flows to build; orchestrator owns dispatch.

Recent/key trace events:
[2] note_added flower-orchestrator: ## Operator idea (Mike, 2026-07-05)
We now run **many git worktrees** across projects, and they differ in how isolated they are: **some have independent databases, some don't** (some are full env isolation — own DB/Redis-prefix/.env; others are code-only or frontend-only isolation sharing MAIN's DB/Meili/Redis). Today an agent/orchestrator can't reliably *know* a given worktree's isolation level — it has to infer from `.env` diffs, REDIS_PREFIX, or the worktree-manager lifecycle mode, which is error-prone (see the flower CLAUDE.md `.env` drift + "worktrees share MAIN's Meili/Redis" caveats).

## Why it matters (orchestrator pain this solves)
- **Safe dispatch/merge decisions:** when I auto-dispatch a build worker into a worktree, I need to know whether its migrations/data land in an isolated DB or hit MAIN's shared DB (a shared-DB worktree means a migration is live immediately; an isolated one doesn't).
- **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN.
- **`.env` drift awareness:** flag when a worktree's `.env` is a stale snapshot missing MAIN keys.
- **Reuse hygiene:** the operator wants to REUSE free worktrees rather than create new ones — knowing each worktree's isolation + free/busy state makes reuse safe and automatable.

## Proposed shape (for refine to sharpen)
- A first-class **worktrees/environments** record in flower's DB capturing, per worktree: path, project, git branch, lifecycle mode (isolated | shared | bare | code-only), **DB isolation** (own DB_DATABASE vs shared), REDIS_PREFIX, Meili index sharing, `.env` present/drift status, Horizon/daemon-runner status, last-seen free/busy.
- Populate from the worktree-manager config (`~/.worktree-config.json`) + `.env` inspection + git worktree list; refresh on a schedule (like sync-solo) or on demand.
- Surface in the bloom UI (a /worktrees or /environments view) and via a `recall_*` MCP tool so agents can query "is worktree X DB-isolated?" before dispatching/verifying there.
- Integrate with dispatch: the auto-dispatch worktree-reuse picker consults isolation metadata to choose an appropriate free worktree and warn on shared-DB migrations.

## Relationships
- flower already tracks `worktree_id` on sessions + a worktrees notion; this extends it with **isolation/environment metadata**.
- Ties to worktree-manager (`~/.worktree-config.json`, lifecycle modes) and the `_worktrees-playbook.md`.
- Directly supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl).

## Provenance
Operator musing while dispatching #248 (2026-07-05): "some of these worktrees have independent databases and some don't … worth tracking worktrees/environments and their metadata so we/you can KNOW when a worktree is properly isolated vs code/frontend isolation." Orchestrator (flower-orchestrator) agrees it's worth doing → briefed for refine, flagged auto-dispatch so it flows to build after refinement.
[3] participant_joined operator:mike: (no body)
[4] status_change operator:mike: (no body)
[5] participant_joined flower-refine: (no body)
[6] plan_proposed flower-refine: # Track worktree/environment isolation metadata in flower

## Problem (operator, 2026-07-05)
We run many git worktrees across projects with DIFFERENT isolation levels — some fully isolated (own `DB_DATABASE` / `REDIS_PREFIX` / `.env` / Meili index), some code-only or frontend-only sharing MAIN's DB/Redis/Meili. Today an agent/orchestrator can't reliably KNOW a worktree's isolation level; it infers from `.env` diffs, `REDIS_PREFIX`, or the worktree-manager lifecycle mode — error-prone (see the flower CLAUDE.md `.env`-drift + "worktrees share MAIN's Meili/Redis" caveats).

## Why it matters (orchestrator pain this solves)
- **Safe dispatch/merge:** a shared-DB worktree means a migration is live on MAIN *immediately*; an isolated one doesn't. The auto-dispatch worktree-reuse picker must know this BEFORE it dispatches.
- **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN.
- **`.env` drift awareness:** flag a worktree whose `.env` is a stale snapshot missing MAIN keys.
- **Reuse hygiene:** reuse a FREE isolated worktree instead of sprawling new ones.

## Scope decision — worktree vs generic ENVIRONMENT (→ operator steer, Q1)
Epic #263 (Solo-decoupling) is moving toward **parallel worktree-environments incl. remote Proxmox LXCs** (each an isolated env running flower-only agents; see #263 fold 2026-07-05). A remote LXC is just another isolation class, and the SAME questions ("is env X DB-isolated? free/busy? can it run live verification?") answer for both a local worktree and a remote LXC. **Recommendation:** model a generic **`environment`** record with a `kind` (main | local-worktree | remote-lxc); local worktrees are the only populated kind at MVP, remote-lxc slots in when #263/#265 lands — so we don't rebuild the model later.

## Data model (proposed)
A first-class `environments` record (extends flower's existing worktree notion — sessions already carry `worktree_id`), per environment:
- **identity:** path (or host+path), project, git_branch, `kind` (main | local-worktree | remote-lxc)
- **isolation:** lifecycle_mode (isolated | shared | bare | code-only), `db_isolation` (own DB_DATABASE vs shared-MAIN), redis_prefix, meili_index (shared | isolated), horizon/daemon-runner status
- **env health:** `.env` present? drift status (missing MAIN keys?), last_synced_at
- **availability:** free/busy, last_seen
- **(remote-lxc extras, later):** node, CT id, tailscale addr, reachable?

## Populate / refresh
- **Sources:** worktree-manager config (`~/.worktree-config.json`) + `git worktree list` + per-worktree `.env` inspection (DB_DATABASE / REDIS_PREFIX / key-diff vs MAIN).
- **Refresh:** a scheduled sweep (mirrors the existing sync-solo pattern) + an on-demand artisan command; reconcile add/remove like the other bounded reconcilers.

## Surfaces
- **`recall_*` MCP tool** (e.g. `recall_environments`): agents query "is env X DB-isolated? free? `.env` drifted?" before dispatching/verifying. **MVP-critical — this is what the orchestrator consumes.**
- **bloom `/environments` UI view** (config-as-data table, dark bloom system). *(Follow-up.)*
- **Dispatch integration:** the auto-dispatch worktree-reuse picker consults isolation metadata to pick an appropriate FREE env + warn on shared-DB migrations. *(Follow-up / phase 2.)*

## MVP boundary (→ operator steer, Q2)
**Recommend MVP** = the `environments` record + populate/refresh from worktree-config/`.env`/git + the `recall_*` tool (the orchestrator's actual need), **deferring** the UI view + dispatch-picker auto-integration to a follow-up. (Alternative: ship it all in one.)

## Relationships
- Extends flower's existing worktree notion (`worktree_id` on sessions).
- worktree-manager (`~/.worktree-config.json`, lifecycle modes) + `_worktrees-playbook.md`.
- **#263 / #265** — remote LXC environments (drives the generic-environment scope decision above).
- Supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl).

## Provenance
Operator musing while dispatching #248 (2026-07-05); orchestrator agreed + flagged auto-dispatch. Refined by flower-refine; generic-environment framing added from the #263 tie.

**Disposition:** `refining` — sharpened + build-ready pending two scope steers (Q1 environment-abstraction, Q2 MVP boundary), then `planned`.
[7] agent_question flower-refine: Model this as a generic `environment` record (kind: main | local-worktree | remote-lxc) so remote Proxmox LXCs (#263/#265) reuse it, or keep it worktree-only for now?
[8] agent_question flower-refine: What's in the first shippable slice for #275?
[9] operator_answer operator:mike: {"choice":"generic_env"}
[10] operator_answer operator:mike: {"choice":"all_in_one"}
[11] spec_snapshot flower-refine: # Track worktree/environment isolation metadata in flower

## Problem (operator, 2026-07-05)
We run many git worktrees across projects with DIFFERENT isolation levels — some fully isolated (own `DB_DATABASE` / `REDIS_PREFIX` / `.env` / Meili index), some code-only or frontend-only sharing MAIN's DB/Redis/Meili. Today an agent/orchestrator can't reliably KNOW a worktree's isolation level; it infers from `.env` diffs, `REDIS_PREFIX`, or the worktree-manager lifecycle mode — error-prone (see the flower CLAUDE.md `.env`-drift + "worktrees share MAIN's Meili/Redis" caveats).

## Why it matters (orchestrator pain this solves)
- **Safe dispatch/merge:** a shared-DB worktree means a migration is live on MAIN *immediately*; an isolated one doesn't. The auto-dispatch worktree-reuse picker must know this BEFORE it dispatches.
- **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN.
- **`.env` drift awareness:** flag a worktree whose `.env` is a stale snapshot missing MAIN keys.
- **Reuse hygiene:** reuse a FREE isolated worktree instead of sprawling new ones.

## Scope decision — worktree vs generic ENVIRONMENT (→ operator steer, Q1)
Epic #263 (Solo-decoupling) is moving toward **parallel worktree-environments incl. remote Proxmox LXCs** (each an isolated env running flower-only agents; see #263 fold 2026-07-05). A remote LXC is just another isolation class, and the SAME questions ("is env X DB-isolated? free/busy? can it run live verification?") answer for both a local worktree and a remote LXC. **Recommendation:** model a generic **`environment`** record with a `kind` (main | local-worktree | remote-lxc); local worktrees are the only populated kind at MVP, remote-lxc slots in when #263/#265 lands — so we don't rebuild the model later.

## Data model (proposed)
A first-class `environments` record (extends flower's existing worktree notion — sessions already carry `worktree_id`), per environment:
- **identity:** path (or host+path), project, git_branch, `kind` (main | local-worktree | remote-lxc)
- **isolation:** lifecycle_mode (isolated | shared | bare | code-only), `db_isolation` (own DB_DATABASE vs shared-MAIN), redis_prefix, meili_index (shared | isolated), horizon/daemon-runner status
- **env health:** `.env` present? drift status (missing MAIN keys?), last_synced_at
- **availability:** free/busy, last_seen
- **(remote-lxc extras, later):** node, CT id, tailscale addr, reachable?

## Populate / refresh
- **Sources:** worktree-manager config (`~/.worktree-config.json`) + `git worktree list` + per-worktree `.env` inspection (DB_DATABASE / REDIS_PREFIX / key-diff vs MAIN).
- **Refresh:** a scheduled sweep (mirrors the existing sync-solo pattern) + an on-demand artisan command; reconcile add/remove like the other bounded reconcilers.

## Surfaces
- **`recall_*` MCP tool** (e.g. `recall_environments`): agents query "is env X DB-isolated? free? `.env` drifted?" before dispatching/verifying. **MVP-critical — this is what the orchestrator consumes.**
- **bloom `/environments` UI view** (config-as-data table, dark bloom system). *(Follow-up.)*
- **Dispatch integration:** the auto-dispatch worktree-reuse picker consults isolation metadata to pick an appropriate FREE env + warn on shared-DB migrations. *(Follow-up / phase 2.)*

## MVP boundary (→ operator steer, Q2)
**Recommend MVP** = the `environments` record + populate/refresh from worktree-config/`.env`/git + the `recall_*` tool (the orchestrator's actual need), **deferring** the UI view + dispatch-picker auto-integration to a follow-up. (Alternative: ship it all in one.)

## Relationships
- Extends flower's existing worktree notion (`worktree_id` on sessions).
- worktree-manager (`~/.worktree-config.json`, lifecycle modes) + `_worktrees-playbook.md`.
- **#263 / #265** — remote LXC environments (drives the generic-environment scope decision above).
- Supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl).

## Provenance
Operator musing while dispatching #248 (2026-07-05); orchestrator agreed + flagged auto-dispatch. Refined by flower-refine; generic-environment framing added from the #263 tie.

**Disposition:** `refining` — sharpened + build-ready pending two scope steers (Q1 environment-abstraction, Q2 MVP boundary), then `planned`.
[12] refinement flower-refine: # Track worktree/environment isolation metadata in flower

## Problem (operator, 2026-07-05)
We run many git worktrees across projects with DIFFERENT isolation levels — some fully isolated (own `DB_DATABASE` / `REDIS_PREFIX` / `.env` / Meili index), some code-only or frontend-only sharing MAIN's DB/Redis/Meili. Today an agent/orchestrator can't reliably KNOW a worktree's isolation level; it infers from `.env` diffs, `REDIS_PREFIX`, or the worktree-manager lifecycle mode — error-prone (see the flower CLAUDE.md `.env`-drift + "worktrees share MAIN's Meili/Redis" caveats).

## Why it matters (orchestrator pain this solves)
- **Safe dispatch/merge:** a shared-DB worktree means a migration is live on MAIN *immediately*; an isolated one doesn't. The auto-dispatch worktree-reuse picker must know this BEFORE it dispatches.
- **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN.
- **`.env` drift awareness:** flag a worktree whose `.env` is a stale snapshot missing MAIN keys.
- **Reuse hygiene:** reuse a FREE isolated worktree instead of sprawling new ones.

## DECIDED (operator Mike, 2026-07-05 — decisions #75 / #76)
- **Q1 Model scope → GENERIC ENVIRONMENT.** A generic `environment` record with a `kind` (main | local-worktree | remote-lxc). Local worktrees are the only populated kind at MVP; remote Proxmox LXCs (#263/#265) reuse the SAME model — no schema rebuild later.
- **Q2 MVP boundary → ALL-IN-ONE.** Ship the full slice in THIS brief: record + populate/refresh + `recall_*` tool + the bloom `/environments` UI + the auto-dispatch worktree-reuse-picker integration. (No deferral to a follow-up.)

## Data model
A first-class `environments` record (extends flower's existing worktree notion — sessions already carry `worktree_id`), per environment:
- **identity:** path (or host+path), project, git_branch, `kind` (main | local-worktree | remote-lxc)
- **isolation:** lifecycle_mode (isolated | shared | bare | code-only), `db_isolation` (own DB_DATABASE vs shared-MAIN), redis_prefix, meili_index (shared | isolated), horizon/daemon-runner status
- **env health:** `.env` present? drift status (missing MAIN keys vs MAIN's `.env`?), last_synced_at
- **availability:** free/busy, last_seen
- **(remote-lxc extras, populated when #263/#265 lands):** node, CT id, tailscale addr, reachable?

## Deliverables (all-in-one, per #76)
1. **`environments` table + model** (+ relation to sessions' `worktree_id`; MAIN is a row too).
2. **Populate/refresh:** an artisan sweep (scheduled like `sync-solo`) + on-demand command; a bounded reconciler that reads `~/.worktree-config.json` + `git worktree list` + per-worktree `.env` (DB_DATABASE / REDIS_PREFIX / key-diff vs MAIN) and reconciles add/remove.
3. **`recall_environments` MCP tool:** agents query "is env X DB-isolated? free? `.env` drifted? live-verify-capable?" before dispatching/verifying.
4. **bloom `/environments` UI view** (config-as-data table, dark bloom system).
5. **Dispatch integration:** the auto-dispatch worktree-reuse picker consults isolation metadata to choose a FREE appropriate env + warn on shared-DB migrations.

## Populate / refresh sources
`~/.worktree-config.json` (worktree-manager, lifecycle modes) + `git worktree list` + per-worktree `.env` inspection. Mirror the existing bounded-reconciler + scheduled-sweep patterns.

## Relationships
- Extends flower's existing worktree notion (`worktree_id` on sessions).
- worktree-manager (`~/.worktree-config.json`, lifecycle modes) + `_worktrees-playbook.md`.
- **#263 / #265** — remote LXC environments reuse the generic model (decision #75).
- Supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl).

## Provenance
Operator musing while dispatching #248 (2026-07-05); orchestrator agreed + flagged auto-dispatch. Refined by flower-refine; generic-environment framing from the #263 tie; scope decided by Mike — #75 (generic) + #76 (all-in-one) — 2026-07-05.

**Disposition:** `planned` — model + scope decided; build-ready end-to-end. Medium-large build (migration + reconciler/sweep + `recall_environments` tool + `/environments` UI + dispatch-picker integration). Auto-dispatch flagged → flows to build; orchestrator owns dispatch.
[13] status_change flower-refine: (no body)

Recommended linked context:
{
    "todos": [],
    "scratchpads": []
}

Execution notes:
- Treat the brief as the source of truth.
- Keep work scoped to this dispatch request.
- Use brief_append / brief_update_status when reporting material progress; as your final dispatched-worker step, call brief_dispatch_complete with dispatch_request_id (or brief_id) and actor_ref.
- Codex workers should verify mutating Flower tools with tool_search query `brief_append brief_dispatch_complete flower_feedback` (limit 20) when tool availability is in doubt; report raw SEE/LOAD vs NOT visible instead of silently using local fallbacks.
- Add a git commit trailer `Brief: #275` to every commit for this brief so flower can exact-link commits back to the brief.
- Need an operator call while working this brief? A question ABOUT THIS BRIEF -> brief_ask(275, ...); a standalone decision not tied to the brief -> decision_ask(...). Both expose the full affordance set (confirm | single_choice | multi_choice | text, options + recommended, allow_write_in); prefer async questions over blocking and set is_blocking only when you truly cannot proceed.
- Cited-refs index (Brief #244): when a report / checkpoint / DONE summary cites numbered entities, append a compact `Refs:` block at the END mapping each `#N` to its REAL stored title + status — `#<num>: <title> (<status>)`, one per line (typed prefixes: bare `#N` = brief, `fb#N` feedback, `dec#N` decision, `sess#N` session, `dr#N` dispatch_request). Resolve any title you did not already pull with recall_refs instead of guessing; skip the block on trivial one-liners.

provenance · append-only

Trace

live
or paste a screenshot uploading…
  1. agent question 1h ago

    #275 fleet/roster UI build is DONE and green — 6 PRs on flower/275-build (design doc + PR-1..6), full suite 1381 pass / 3 skip / 0 fail, pint clean. It's the /roster → node → environment → agents Fleet tree + /environments table + recall_environments MCP tool + dispatch env-picker with a shared-main∧migration warn-with-confirm gate. Migrations are additive (new runtime_environments table + nullable runtime_environment_id FK on daemon_agents — backward-compatible, existing check-ins unaffected). Design was already blessed via the design loop + your decisions #75/#76. Since you wanted to EYEBALL the control surface, how do you want to review it? (Separately, one open policy call the worker deferred: hard-block vs warn for agent-initiated shared-DB migrations — MVP shipped warn-with-confirm; tell me if you want it flipped to hard-block and I'll file it.)

    agent · flower-orchestrator
  2. status change 1h ago
    agent · flower-275-build
  3. dispatched 1h ago

    Dispatch request #148 marked done.

    agent · flower-275-build
  4. comment 1h ago

    ## BUILD leg complete — Fleet/Roster UI + environment-isolation metadata (dispatch req #148) Implemented the design (`docs/design/275-fleet-roster-ui.md`) **all-in-one per decision #76**, as six dependency-ordered, independently-reviewable commits on `flower/275-build` (trailer `Brief: #275`). **NOT merged** — orchestrator owns MAIN merges. Full suite **green (1381 passing / 3 skipped / 0 failures)**; pint clean on every touched file. ### Commits - **PR-1** `6c507f5` — `RuntimeEnvironment` record + enums (`RuntimeEnvironmentKind`, `DbIsolation` with the identity-first + fail-safe `classify()` ladder + `isSafe()`/`warnsForMigration()`, `LifecycleMode`, `EnvDrift`) + nullable `runtime_environment_id` FK on `daemon_agents` + Forge `projects/show` card relabel → "forge · deploy targets". - **PR-2** `b405242` — `RuntimeEnvironmentReconciler` (reads `~/.worktree-config.json` + registry + per-checkout `.env`; identity-first **and fail-safe** `db_isolation` — absent/unreadable `.env` → `unknown`, never `isolated`; drift diff; mark-stale-never-prune via the linked worktree's `missing_at`; idempotent; daemon FK backfill from the session→worktree chain) + `flower:sync-environments` scheduled `everyFiveMinutes` beside `sync-solo`. Adds `EnvFile` (fail-soft `.env` reader) + `WorktreeManagerConfig::projects()`. - **PR-3** `3f0de20` — `recall_environments` MCP tool + `RuntimeEnvironmentRosterService` (availability derived from `livenessFor` — busy counts alive+parked+expected, `free_idle` = stale-only; layered placement; `live_verify_capable = db-safe ∧ reachable!==false`; `warnings[]` for live-agent-on-shared-DB). Registered in `FlowerServer`. - **PR-4** `fade6c1` — **Fleet tree** (the control surface): `/roster` evolves into node → environment → agents; isolation seals (kind + db_isolation + drift); **server-driven disclosure** (MAIN + attention-bearing auto-expand, re-evaluated every render so it survives a broadcast morph, manual toggle authoritative); env actions (spawn-into / refresh-metadata / wind-down-env) + `DaemonRosterService::requestWinddownForEnvironment()`; `daemon-row` reused verbatim; unplaced daemons fall back to project-grouped cards (non-regressive). Dropped the vestigial `LIVENESS_META['idle']`; nav relabel **Roster → Fleet**. `placeAgents` reuses the roster's loaded daemon set → +2 bounded queries (audit budget 5→7). - **PR-5** `3e2c50c` — `/environments` infra `.data-table` (filters mirror `recall_environments`) + Fleet↔Environments cross-links + `Environments` `.nav-sublink` under Fleet. - **PR-6** `9afef1c` — Dispatch **Environment picker** (ranked candidates, seals + why-line, top pre-selected) + the `((shared_main ∨ unknown) ∧ carriesMigration)` **warn-with-required-confirm** gate (never hard-block); `Brief::carriesMigration()` heuristic (spec scan + `meta.has_migration` override); **auto-dispatch parity** — reuses a FREE isolated worktree when the target is open (migration-safe by construction), degrades to today's behavior with no envs. ### Naming collision — resolved as designed New model **`RuntimeEnvironment`** (table `runtime_environments`); the Forge `Environment` (deploy target) is untouched beyond the one-line card relabel. Operator/MCP noun stays "environment"; `recall_environments` unchanged. ### Deferred to follow-up (nothing MVP-critical; mostly design-flagged as "wired later / disabled stub") 1. **Remote-LXC node band UI** — the `remote-lxc` kind + fields are fully modeled and the record/reconciler/recall/table handle them, but the fleet tree renders only the MAIN node band; the disabled remote-node stub band (R710/5800X3D) is **not** rendered. Lands with #263/#265. 2. **Sticky node/env header offsets + `--fleet-node-h` CSS var** — server-driven disclosure + expand/collapse-all shipped; the sticky-positioning CSS polish (§"Edge — M×N dense") is not. 3. **Migration detection** stays the keyword-scan heuristic (design open question) — a richer explicit `has_migration` flag UI / diff-at-dispatch deferred. 4. **Agent-initiated shared-DB *hard-block* policy** (design open question) — I implemented safe-reuse for auto-dispatch (only ever reuses isolated worktrees) rather than a hard block; the "should an agent-initiated shared-DB migration be blocked, not just warned" call remains open for the operator. 5. UI-noun "environment vs Workspace" left as "environment" per the design's recommendation. ### Verification Unit + feature tests only (worktree policy — no Horizon/Reverb here; live real-data verification left to MAIN). The Livewire feature tests render the Fleet tree, `/environments` table, and the Dispatch form end-to-end (real blades compile + render). New test files: `DbIsolationTest`, `RuntimeEnvironmentTest`, `RuntimeEnvironmentReconcilerTest`, `SyncRuntimeEnvironmentsCommandTest`, `RecallEnvironmentsToolTest`, `FleetTreeTest`, `EnvironmentsIndexTest`, `BriefMigrationHeuristicTest`, `DispatchCandidatesTest`, `DispatchEnvironmentPickerTest`, `AutoDispatchReuseTest` (+ updated `EnsureDaemonsRosterTest`, `QueryEfficiencyAuditTest`).

    agent · flower-275-build
  5. participant joined 1h ago
    system · flower-275-build
  6. dispatched 2h ago

    Dispatch request #148 queued for flower.

    agent · flower-orchestrator
  7. status change 2h ago
    agent · flower-orchestrator
  8. status change 3h ago
    agent · flower-275-design
  9. note added 3h ago

    Design loop complete — needs_design_loop cleared; brief is build-ready. The build leg now follows the brief's normal dispatch policy.

    agent · flower-275-design
  10. dispatched 3h ago

    Dispatch request #146 marked done.

    agent · flower-275-design
  11. comment 3h ago

    ## Design leg complete — Fleet / Roster UI + environment-isolation metadata (dispatch req #146) **Doc:** `docs/design/275-fleet-roster-ui.md` on branch `flower/275-design` (commit `94c8900`, trailer `Brief: #275`). NOT merged — orchestrator owns merges. **Method:** Ran the `/design` writer↔reviewer loop to **CONSENSUS in 3 rounds**. Both sub-agents used `frontend-design`; the reviewer ground-truthed every code claim (tokens, props, service methods, field names) against the real repo. 4 blockers in round 1 → fixed → 2 new safety-logic blockers in round 2 → fixed → CONSENSUS round 3 (0 blockers). ### Design direction (the UI is the heart, per the operator's emphasis) Evolve the flat, project-grouped `/roster` into a **fleet tree `node(host) → environment(checkout/LXC) → agents`**, built entirely from existing bloom primitives (`<x-ui.card flush>` + `divide-y` + the `.nav-subtree` guide-rail + server-driven disclosure) — the agent leaf row is `daemon-row` reused verbatim. A dusk-quiet deck whose **only two loud marks are the *moving* live pulse and the *high-contrast* red SHARED-MAIN-DB seal** — the one safety-critical fact a migration can hurt on. ### Resolutions of the must-resolve items - **Naming collision** → new model **`RuntimeEnvironment`** (table `runtime_environments`); the existing Forge `Environment` stays the deploy-target concept, untouched but its `projects/show` card relabeled `forge · deploy targets`. Operator/MCP noun stays "environment", tool stays `recall_environments` — the collision is solved only at the PHP class layer. *(One naming confirm flagged: keep "environment" vs rename everywhere to "Workspace" — pure copy/rename, nothing structural rides on it.)* - **agent→environment link** → layered: read-time `daemon.session_id → session.worktree_id → runtime_environment` is the source of truth; a denormalized nullable `runtime_environment_id` FK on `daemon_agents` (stamped at spawn/check-in, backfilled by the reconciler) is the fast/stable fallback; `— unplaced —` bucket for the rest. - **Tree structure** → **environment is the primary grouping** (a worktree *is* project+branch, so project/role become filters, not levels); local worktrees are children of the MAIN node; the platform daemons live in the accent-treated MAIN environment; node collapses to one slim band today, remote LXCs add sibling bands later. - **`db_isolation` (the safety field)** → four states `main | isolated | shared_main | unknown`, computed **identity-first** (MAIN can never false-red) *and* **fail-safe** (an unreadable `.env` → `unknown`, never false-green; `unknown` is excluded from the safe set and warns like shared). Three-seal ramp: `db · MAIN` (accent) / `db · isolated` (green) / `⚠ db · SHARED MAIN` (red) / `? unverified` (muted). - **`recall_environments`** → roster-shaped read tool mirroring `RecallRosterTool`; one call answers isolated/free/drifted/live-verify-capable; free/busy derived from `livenessFor` (busy = ≥1 agent `alive|parked|expected`, closing the double-spawn hole) — no separate lock; `warnings[]` flags live-agent-on-shared-DB. - **Dispatch picker** → ranked free/isolated candidates on the brief Dispatch form; **warn-with-required-confirm, never block** when a migration targets a `shared_main`/`unknown` DB; auto-dispatch reuse calls the same read service for parity. - **Nav/route** → `/roster` evolves in place, relabeled **Fleet** (`icon="flame"`); **Environments** infra `.data-table` added as a `.nav-subtree` child, cross-linked both ways. ### Sequenced PR plan (all-in-one per #76, dependency-ordered) 1. **PR-1** — `RuntimeEnvironment` record + `runtime_environment_id` FK on `daemon_agents` + Forge card relabel. 2. **PR-2** — Reconciler (worktree-config + `git worktree list` + `.env` inspection) + scheduled sweep; identity-first *and* fail-safe `db_isolation`; mark-stale-never-prune; FK backfill. *(largest backend; 2-commit split.)* 3. **PR-3** — `recall_environments` MCP tool + `RuntimeEnvironmentRosterService`. 4. **PR-4** — Fleet tree UI (node band → env-header partial with seals+rollup+**server-driven disclosure** → `daemon-row` leaf), env-level actions, drop the dead `LIVENESS_META['idle']`, new `requestWinddownForEnvironment()`. *(largest PR; 2-commit split.)* 5. **PR-5** — `/environments` infra table + cross-links + nav sublink. 6. **PR-6** — Dispatch picker + migration warn-with-confirm + auto-dispatch parity. PR-1..3 are non-visible substrate (not a tracer bullet — honestly flagged); first visual proof is PR-4 (optional "PR-3.5" one-row seal render if earlier proof is wanted). ### Open questions carried for the BUILD leg (in the doc) UI noun confirm (environment vs Workspace) · migration-detection source for the warning (`has_migration` flag vs keyword scan vs diff) · whether an **agent**-initiated shared-DB migration should be hard-blocked (not just warned) since no human is present · spawn-into path resolution (branch key sufficient, or need a `target_path` override) · stamping `runtime_environment_id` at check-in vs reconciler-only · node identity/field completeness for remote-LXC. Ready for a BUILD-leg dispatch against this spec.

    agent · flower-275-design
  12. participant joined 3h ago
    system · flower-275-design
  13. refinement 4h ago

    **Finalize for the design worker (req #146) — decisions locked + grounding pointers.** Decisions are locked: **#75 generic `environment` (kind: main | local-worktree | remote-lxc)** + **#76 all-in-one** (record + reconciler/sweep + `recall_environments` + `/environments` UI + dispatch-picker). The spec above is the canonical input; this note just points at existing patterns so the design loop reuses rather than reinvents. **Reuse these existing flower patterns (don't reinvent):** - **`recall_environments` MCP tool** → model on the existing read tools in `app/Mcp/Tools` (shape/registration like `recall_roster` / `recall_active`); register in `app/Mcp/Servers`. Make `environment` a lightweight readable record, not a chunkable/searchable type (it's live infra state, not corpus). - **`/environments` UI** → the config-as-data dark-bloom table pattern used by `/roster` and `/briefs` (`resources/views/components/ui/*`); per-project grouping + isolation/free-busy/drift badges reads naturally there. - **Populate/refresh** → mirror the existing **sync-solo** reconciler + scheduled sweep (bounded, idempotent add/remove reconcile), scheduled in `config/`/the scheduler like the other sweeps. - **`.env` drift detection** → diff a worktree's `.env` keys against MAIN's `.env` (the flower CLAUDE.md documents this exact drift: worktree `.env` is a point-in-time snapshot that isn't backfilled when MAIN gains keys). `db_isolation` = worktree `DB_DATABASE` != MAIN's; shared-Redis = same `REDIS_PREFIX`/no prefix. - **Source of truth** = `~/.worktree-config.json` (worktree-manager) + `git worktree list`; sessions already carry `worktree_id` — relate `environment` to that, don't duplicate it. **Design-sensitive calls for the loop to resolve (my flags, not answers):** 1. `recall_environments` contract — filters (project, kind, free/busy, db-isolated) + response fields; does it return a single env by path or a list? 2. `/environments` layout — grouping (by project? by host/node?), which badges, and how free/busy + `.env`-drift surface at a glance. 3. Dispatch-picker integration — the free-env selection heuristic + the **shared-DB-migration warning** UX (warn vs block when a brief with a migration targets a shared-DB worktree). 4. free/busy signal — derive from active sessions/daemons on the worktree (roster) vs a separate lock? No status change from me — #275 is orchestrator-owned now (dispatched → design leg). Flagging only; the design worker owns the resolutions.

    agent · flower-refine
  14. dispatched 4h ago

    Design-loop dispatch request #146 queued for flower.

    agent · flower-orchestrator
  15. status change 4h ago
    agent · flower-orchestrator
  16. status change 4h ago
    agent · flower-refine
  17. refinement 4h ago

    # Track worktree/environment isolation metadata in flower ## Problem (operator, 2026-07-05) We run many git worktrees across projects with DIFFERENT isolation levels — some fully isolated (own `DB_DATABASE` / `REDIS_PREFIX` / `.env` / Meili index), some code-only or frontend-only sharing MAIN's DB/Redis/Meili. Today an agent/orchestrator can't reliably KNOW a worktree's isolation level; it infers from `.env` diffs, `REDIS_PREFIX`, or the worktree-manager lifecycle mode — error-prone (see the flower CLAUDE.md `.env`-drift + "worktrees share MAIN's Meili/Redis" caveats). ## Why it matters (orchestrator pain this solves) - **Safe dispatch/merge:** a shared-DB worktree means a migration is live on MAIN *immediately*; an isolated one doesn't. The auto-dispatch worktree-reuse picker must know this BEFORE it dispatches. - **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN. - **`.env` drift awareness:** flag a worktree whose `.env` is a stale snapshot missing MAIN keys. - **Reuse hygiene:** reuse a FREE isolated worktree instead of sprawling new ones. ## DECIDED (operator Mike, 2026-07-05 — decisions #75 / #76) - **Q1 Model scope → GENERIC ENVIRONMENT.** A generic `environment` record with a `kind` (main | local-worktree | remote-lxc). Local worktrees are the only populated kind at MVP; remote Proxmox LXCs (#263/#265) reuse the SAME model — no schema rebuild later. - **Q2 MVP boundary → ALL-IN-ONE.** Ship the full slice in THIS brief: record + populate/refresh + `recall_*` tool + the bloom `/environments` UI + the auto-dispatch worktree-reuse-picker integration. (No deferral to a follow-up.) ## Data model A first-class `environments` record (extends flower's existing worktree notion — sessions already carry `worktree_id`), per environment: - **identity:** path (or host+path), project, git_branch, `kind` (main | local-worktree | remote-lxc) - **isolation:** lifecycle_mode (isolated | shared | bare | code-only), `db_isolation` (own DB_DATABASE vs shared-MAIN), redis_prefix, meili_index (shared | isolated), horizon/daemon-runner status - **env health:** `.env` present? drift status (missing MAIN keys vs MAIN's `.env`?), last_synced_at - **availability:** free/busy, last_seen - **(remote-lxc extras, populated when #263/#265 lands):** node, CT id, tailscale addr, reachable? ## Deliverables (all-in-one, per #76) 1. **`environments` table + model** (+ relation to sessions' `worktree_id`; MAIN is a row too). 2. **Populate/refresh:** an artisan sweep (scheduled like `sync-solo`) + on-demand command; a bounded reconciler that reads `~/.worktree-config.json` + `git worktree list` + per-worktree `.env` (DB_DATABASE / REDIS_PREFIX / key-diff vs MAIN) and reconciles add/remove. 3. **`recall_environments` MCP tool:** agents query "is env X DB-isolated? free? `.env` drifted? live-verify-capable?" before dispatching/verifying. 4. **bloom `/environments` UI view** (config-as-data table, dark bloom system). 5. **Dispatch integration:** the auto-dispatch worktree-reuse picker consults isolation metadata to choose a FREE appropriate env + warn on shared-DB migrations. ## Populate / refresh sources `~/.worktree-config.json` (worktree-manager, lifecycle modes) + `git worktree list` + per-worktree `.env` inspection. Mirror the existing bounded-reconciler + scheduled-sweep patterns. ## Relationships - Extends flower's existing worktree notion (`worktree_id` on sessions). - worktree-manager (`~/.worktree-config.json`, lifecycle modes) + `_worktrees-playbook.md`. - **#263 / #265** — remote LXC environments reuse the generic model (decision #75). - Supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl). ## Provenance Operator musing while dispatching #248 (2026-07-05); orchestrator agreed + flagged auto-dispatch. Refined by flower-refine; generic-environment framing from the #263 tie; scope decided by Mike — #75 (generic) + #76 (all-in-one) — 2026-07-05. **Disposition:** `planned` — model + scope decided; build-ready end-to-end. Medium-large build (migration + reconciler/sweep + `recall_environments` tool + `/environments` UI + dispatch-picker integration). Auto-dispatch flagged → flows to build; orchestrator owns dispatch.

    agent · flower-refine
  18. spec snapshot 4h ago

    # Track worktree/environment isolation metadata in flower ## Problem (operator, 2026-07-05) We run many git worktrees across projects with DIFFERENT isolation levels — some fully isolated (own `DB_DATABASE` / `REDIS_PREFIX` / `.env` / Meili index), some code-only or frontend-only sharing MAIN's DB/Redis/Meili. Today an agent/orchestrator can't reliably KNOW a worktree's isolation level; it infers from `.env` diffs, `REDIS_PREFIX`, or the worktree-manager lifecycle mode — error-prone (see the flower CLAUDE.md `.env`-drift + "worktrees share MAIN's Meili/Redis" caveats). ## Why it matters (orchestrator pain this solves) - **Safe dispatch/merge:** a shared-DB worktree means a migration is live on MAIN *immediately*; an isolated one doesn't. The auto-dispatch worktree-reuse picker must know this BEFORE it dispatches. - **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN. - **`.env` drift awareness:** flag a worktree whose `.env` is a stale snapshot missing MAIN keys. - **Reuse hygiene:** reuse a FREE isolated worktree instead of sprawling new ones. ## Scope decision — worktree vs generic ENVIRONMENT (→ operator steer, Q1) Epic #263 (Solo-decoupling) is moving toward **parallel worktree-environments incl. remote Proxmox LXCs** (each an isolated env running flower-only agents; see #263 fold 2026-07-05). A remote LXC is just another isolation class, and the SAME questions ("is env X DB-isolated? free/busy? can it run live verification?") answer for both a local worktree and a remote LXC. **Recommendation:** model a generic **`environment`** record with a `kind` (main | local-worktree | remote-lxc); local worktrees are the only populated kind at MVP, remote-lxc slots in when #263/#265 lands — so we don't rebuild the model later. ## Data model (proposed) A first-class `environments` record (extends flower's existing worktree notion — sessions already carry `worktree_id`), per environment: - **identity:** path (or host+path), project, git_branch, `kind` (main | local-worktree | remote-lxc) - **isolation:** lifecycle_mode (isolated | shared | bare | code-only), `db_isolation` (own DB_DATABASE vs shared-MAIN), redis_prefix, meili_index (shared | isolated), horizon/daemon-runner status - **env health:** `.env` present? drift status (missing MAIN keys?), last_synced_at - **availability:** free/busy, last_seen - **(remote-lxc extras, later):** node, CT id, tailscale addr, reachable? ## Populate / refresh - **Sources:** worktree-manager config (`~/.worktree-config.json`) + `git worktree list` + per-worktree `.env` inspection (DB_DATABASE / REDIS_PREFIX / key-diff vs MAIN). - **Refresh:** a scheduled sweep (mirrors the existing sync-solo pattern) + an on-demand artisan command; reconcile add/remove like the other bounded reconcilers. ## Surfaces - **`recall_*` MCP tool** (e.g. `recall_environments`): agents query "is env X DB-isolated? free? `.env` drifted?" before dispatching/verifying. **MVP-critical — this is what the orchestrator consumes.** - **bloom `/environments` UI view** (config-as-data table, dark bloom system). *(Follow-up.)* - **Dispatch integration:** the auto-dispatch worktree-reuse picker consults isolation metadata to pick an appropriate FREE env + warn on shared-DB migrations. *(Follow-up / phase 2.)* ## MVP boundary (→ operator steer, Q2) **Recommend MVP** = the `environments` record + populate/refresh from worktree-config/`.env`/git + the `recall_*` tool (the orchestrator's actual need), **deferring** the UI view + dispatch-picker auto-integration to a follow-up. (Alternative: ship it all in one.) ## Relationships - Extends flower's existing worktree notion (`worktree_id` on sessions). - worktree-manager (`~/.worktree-config.json`, lifecycle modes) + `_worktrees-playbook.md`. - **#263 / #265** — remote LXC environments (drives the generic-environment scope decision above). - Supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl). ## Provenance Operator musing while dispatching #248 (2026-07-05); orchestrator agreed + flagged auto-dispatch. Refined by flower-refine; generic-environment framing added from the #263 tie. **Disposition:** `refining` — sharpened + build-ready pending two scope steers (Q1 environment-abstraction, Q2 MVP boundary), then `planned`.

    system · flower-refine
  19. operator answer 4h ago

    {"choice":"all_in_one"}

    operator · operator:mike
  20. operator answer 4h ago

    {"choice":"generic_env"}

    operator · operator:mike
  21. agent question 4h ago

    What's in the first shippable slice for #275?

    agent · flower-refine
  22. agent question 4h ago

    Model this as a generic `environment` record (kind: main | local-worktree | remote-lxc) so remote Proxmox LXCs (#263/#265) reuse it, or keep it worktree-only for now?

    agent · flower-refine
  23. plan proposed 4h ago

    # Track worktree/environment isolation metadata in flower ## Problem (operator, 2026-07-05) We run many git worktrees across projects with DIFFERENT isolation levels — some fully isolated (own `DB_DATABASE` / `REDIS_PREFIX` / `.env` / Meili index), some code-only or frontend-only sharing MAIN's DB/Redis/Meili. Today an agent/orchestrator can't reliably KNOW a worktree's isolation level; it infers from `.env` diffs, `REDIS_PREFIX`, or the worktree-manager lifecycle mode — error-prone (see the flower CLAUDE.md `.env`-drift + "worktrees share MAIN's Meili/Redis" caveats). ## Why it matters (orchestrator pain this solves) - **Safe dispatch/merge:** a shared-DB worktree means a migration is live on MAIN *immediately*; an isolated one doesn't. The auto-dispatch worktree-reuse picker must know this BEFORE it dispatches. - **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN. - **`.env` drift awareness:** flag a worktree whose `.env` is a stale snapshot missing MAIN keys. - **Reuse hygiene:** reuse a FREE isolated worktree instead of sprawling new ones. ## Scope decision — worktree vs generic ENVIRONMENT (→ operator steer, Q1) Epic #263 (Solo-decoupling) is moving toward **parallel worktree-environments incl. remote Proxmox LXCs** (each an isolated env running flower-only agents; see #263 fold 2026-07-05). A remote LXC is just another isolation class, and the SAME questions ("is env X DB-isolated? free/busy? can it run live verification?") answer for both a local worktree and a remote LXC. **Recommendation:** model a generic **`environment`** record with a `kind` (main | local-worktree | remote-lxc); local worktrees are the only populated kind at MVP, remote-lxc slots in when #263/#265 lands — so we don't rebuild the model later. ## Data model (proposed) A first-class `environments` record (extends flower's existing worktree notion — sessions already carry `worktree_id`), per environment: - **identity:** path (or host+path), project, git_branch, `kind` (main | local-worktree | remote-lxc) - **isolation:** lifecycle_mode (isolated | shared | bare | code-only), `db_isolation` (own DB_DATABASE vs shared-MAIN), redis_prefix, meili_index (shared | isolated), horizon/daemon-runner status - **env health:** `.env` present? drift status (missing MAIN keys?), last_synced_at - **availability:** free/busy, last_seen - **(remote-lxc extras, later):** node, CT id, tailscale addr, reachable? ## Populate / refresh - **Sources:** worktree-manager config (`~/.worktree-config.json`) + `git worktree list` + per-worktree `.env` inspection (DB_DATABASE / REDIS_PREFIX / key-diff vs MAIN). - **Refresh:** a scheduled sweep (mirrors the existing sync-solo pattern) + an on-demand artisan command; reconcile add/remove like the other bounded reconcilers. ## Surfaces - **`recall_*` MCP tool** (e.g. `recall_environments`): agents query "is env X DB-isolated? free? `.env` drifted?" before dispatching/verifying. **MVP-critical — this is what the orchestrator consumes.** - **bloom `/environments` UI view** (config-as-data table, dark bloom system). *(Follow-up.)* - **Dispatch integration:** the auto-dispatch worktree-reuse picker consults isolation metadata to pick an appropriate FREE env + warn on shared-DB migrations. *(Follow-up / phase 2.)* ## MVP boundary (→ operator steer, Q2) **Recommend MVP** = the `environments` record + populate/refresh from worktree-config/`.env`/git + the `recall_*` tool (the orchestrator's actual need), **deferring** the UI view + dispatch-picker auto-integration to a follow-up. (Alternative: ship it all in one.) ## Relationships - Extends flower's existing worktree notion (`worktree_id` on sessions). - worktree-manager (`~/.worktree-config.json`, lifecycle modes) + `_worktrees-playbook.md`. - **#263 / #265** — remote LXC environments (drives the generic-environment scope decision above). - Supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl). ## Provenance Operator musing while dispatching #248 (2026-07-05); orchestrator agreed + flagged auto-dispatch. Refined by flower-refine; generic-environment framing added from the #263 tie. **Disposition:** `refining` — sharpened + build-ready pending two scope steers (Q1 environment-abstraction, Q2 MVP boundary), then `planned`.

    agent · flower-refine
  24. participant joined 4h ago
    system · flower-refine
  25. status change 4h ago
    agent · operator:mike
  26. participant joined 4h ago
    system · operator:mike
  27. note added 9h ago

    ## Operator idea (Mike, 2026-07-05) We now run **many git worktrees** across projects, and they differ in how isolated they are: **some have independent databases, some don't** (some are full env isolation — own DB/Redis-prefix/.env; others are code-only or frontend-only isolation sharing MAIN's DB/Meili/Redis). Today an agent/orchestrator can't reliably *know* a given worktree's isolation level — it has to infer from `.env` diffs, REDIS_PREFIX, or the worktree-manager lifecycle mode, which is error-prone (see the flower CLAUDE.md `.env` drift + "worktrees share MAIN's Meili/Redis" caveats). ## Why it matters (orchestrator pain this solves) - **Safe dispatch/merge decisions:** when I auto-dispatch a build worker into a worktree, I need to know whether its migrations/data land in an isolated DB or hit MAIN's shared DB (a shared-DB worktree means a migration is live immediately; an isolated one doesn't). - **Where to run live verification:** isolated worktrees can run live LLM/embed/real-MySQL work; code-only ones must defer real-data verification to MAIN. - **`.env` drift awareness:** flag when a worktree's `.env` is a stale snapshot missing MAIN keys. - **Reuse hygiene:** the operator wants to REUSE free worktrees rather than create new ones — knowing each worktree's isolation + free/busy state makes reuse safe and automatable. ## Proposed shape (for refine to sharpen) - A first-class **worktrees/environments** record in flower's DB capturing, per worktree: path, project, git branch, lifecycle mode (isolated | shared | bare | code-only), **DB isolation** (own DB_DATABASE vs shared), REDIS_PREFIX, Meili index sharing, `.env` present/drift status, Horizon/daemon-runner status, last-seen free/busy. - Populate from the worktree-manager config (`~/.worktree-config.json`) + `.env` inspection + git worktree list; refresh on a schedule (like sync-solo) or on demand. - Surface in the bloom UI (a /worktrees or /environments view) and via a `recall_*` MCP tool so agents can query "is worktree X DB-isolated?" before dispatching/verifying there. - Integrate with dispatch: the auto-dispatch worktree-reuse picker consults isolation metadata to choose an appropriate free worktree and warn on shared-DB migrations. ## Relationships - flower already tracks `worktree_id` on sessions + a worktrees notion; this extends it with **isolation/environment metadata**. - Ties to worktree-manager (`~/.worktree-config.json`, lifecycle modes) and the `_worktrees-playbook.md`. - Directly supports the orchestrator worktree-REUSE workflow (avoid new-worktree sprawl). ## Provenance Operator musing while dispatching #248 (2026-07-05): "some of these worktrees have independent databases and some don't … worth tracking worktrees/environments and their metadata so we/you can KNOW when a worktree is properly isolated vs code/frontend isolation." Orchestrator (flower-orchestrator) agrees it's worth doing → briefed for refine, flagged auto-dispatch so it flows to build after refinement.

    agent · flower-orchestrator
  28. participant joined 9h ago
    system · flower-orchestrator

epic · dependencies

Relationships

epic parent

depends on

No dependencies — dispatchable once planned.

agents · waves

Participants

  • flower-orchestrator participant · active
  • operator:mike participant · active
  • flower-refine participant · active
  • flower-275-design participant · active
  • flower-275-build participant · active

trace · graph

Links

No links yet — they accrue as agents work the brief.

scope

Projects

  • flower · primary

dogfood · read-only

Agent’s-eye view

The literal recall_brief payload an agent gets — same service path as the MCP tool.