feat: add live config profile refresh

- Standardize built-in tool users for shared writable profile mounts
- Mount canonical non-Git profile sources across compatible instances
- Report restart-required outcomes and guard active profile deletion
- Surface restart feedback in config profile editing

Quality gates: frontend build passed; backend py_compile and LSP passed.
Skipped: backend pytest/Ruff unavailable; Docker/manual checks not approved.
This commit is contained in:
Developer
2026-07-21 11:12:41 +00:00
parent f9f9372ee7
commit add7c1b500
19 changed files with 546 additions and 160 deletions
@@ -0,0 +1,33 @@
# Live Config Profile Refresh
## Summary
Refresh profile-managed configuration for running tool instances when a Config Profile is saved, without recreating the container or terminal session.
## Scope
- Resolve the saved profile and refresh every running instance that selected it, including profiles that include it.
- Store non-Git profile configuration as a canonical, host-side working copy shared by every instance using the profile.
- Bind-mount canonical profile directories directly into their configured container targets and bind-mount canonical profile files individually under the container working directory, preserving the workspace mount.
- Allow UI and container-side edits to the same canonical files; last writer wins, with an overwrite warning when detectable.
- Defer Git mount refresh and Git-clone mutation to a separate commit-aware feature.
- Standardize all supported tool containers on one shared non-root user/group so canonical writable profile mounts remain accessible across instances.
- Return per-instance refresh results to the profile-save UI.
## Constraints
- Preserve running containers and terminal sessions.
- Preserve the workspace/repository mount.
- Docker bind-mount topology is immutable at runtime. Added, removed, retargeted, or mode-changed mounts MUST be reported as requiring restart, not partially applied.
- Desktop and mobile profile editors use the same save/refresh behavior.
- The standardized container user/group MUST be applied to built-in tool definitions, generated manifests, and image templates; legacy/incompatible tool images must report incompatible permissions rather than silently changing profile mount ownership.
## Acceptance Criteria
- [ ] Saving a profile refreshes every eligible running instance with a direct or transitive dependency on that profile.
- [ ] Canonical non-Git profile files and mount directories are shared writable working copies across compatible running instances.
- [ ] Container-side and UI-side changes become visible to all instances using the profile; last writer wins and detectable overwrites generate a warning.
- [ ] Git mount refresh and Git clone mutation are not performed by this feature.
- [ ] Built-in supported tool containers use a shared non-root user/group compatible with writable canonical profile mounts.
- [ ] Topology changes return a restart-required result without recreating the instance.
- [ ] Terminal WebSocket sessions remain connected throughout a successful refresh.
@@ -0,0 +1,17 @@
# Design: Live Config Profile Refresh
## Canonical working copies
Each non-Git Config Profile owns canonical host-side storage. Directory mounts use canonical profile directories; each top-level profile file uses a canonical host file bind-mounted under the container working directory. All compatible instances selected for the profile mount the same sources, so UI and container edits are immediately shared.
## Container compatibility
Supported built-in tools standardize on one non-root user/group. Existing instances retain their current image/user and report `restart_required`. Custom tools are not rewritten; tools that do not opt into the shared user/group return `incompatible_permissions`.
## Save behavior
A profile save writes canonical profile files atomically per file. The save response reports affected compatible instances, `restart_required` topology/runtime changes, `incompatible_permissions`, and detectable overwrite warnings. Last writer wins; no merge or lock protocol is imposed.
## Scope boundaries
Git mount mutation is explicitly deferred. Workspace/repository mounts are never changed. Profile deletion is rejected while running instances still use the profile.
@@ -0,0 +1,19 @@
# Implementation Plan: Live Config Profile Refresh
1. Standardize built-in tool user/group definitions and remove ownership-changing behavior for shared profile sources.
2. Add canonical profile storage and bind-mount compilation for profile directories and individual working-directory files.
3. Add compatibility/topology analysis, running-instance discovery, save-result schema, and deletion guard.
4. Wire desktop/mobile profile save results into immediate status/warning feedback.
5. Add unit, API, manifest/image, and frontend coverage; run quality gates and manual two-instance QA.
## Delivery order
1. Container-user compatibility
2. Canonical non-Git profile mounts
3. API and deletion semantics
4. UI feedback
5. Verification and commit
## Deferred
Git mount refresh and Git clone mutation require a commit-aware follow-up change.
@@ -0,0 +1,32 @@
# Live Config Profile Refresh — Tasks
## Review Workload Forecast
| Field | Value |
| --- | --- |
| Estimated changed lines | 500750 |
| 400-line budget risk | High |
| Chained PRs recommended | Yes |
| Suggested split | Container-user standardization → canonical profile mounts → API/UI feedback → verification |
| Delivery strategy | feature-branch-chain |
| Chain strategy | feature-branch-chain |
Decision needed before apply: No
Chained PRs recommended: Yes
Chain strategy: feature-branch-chain
400-line budget risk: High
## Tasks
- [ ] **RED/GREEN — shared container user:** standardize built-in tool images, manifests, and permission handling on one shared non-root user/group; detect incompatible legacy images.
- [ ] **RED/GREEN — canonical profile storage:** create canonical host-side directories/files per profile and mount them directly into compatible instances, without masking workspace mounts.
- [ ] **TRIANGULATE — writable sharing:** prove UI and container edits are shared across instances, with last-writer-wins overwrite warnings.
- [ ] **RED/GREEN — topology/API contract:** return restart-required or incompatible-permissions outcomes for paths that cannot mount live; defer Git mount mutation.
- [ ] **RED/GREEN — UI feedback:** show shared-working-copy, warning, restart-required, and incompatible-permissions results in desktop and mobile profile editors.
- [ ] **Verify:** run targeted backend/frontend tests, typecheck, lint, image/manifest checks, and manual multi-instance permission tests.
## Verification Notes
- Passed: frontend production build (`npm run build`), Python compilation for changed backend modules, and targeted LSP diagnostics.
- Skipped: backend pytest and Ruff; this environment has no project-managed Python runner, system Python lacks those packages, and the user declined system-package installation.
- Skipped: Docker/Compose and manual multi-instance checks; explicit Docker approval was not granted.
@@ -0,0 +1,28 @@
# Test Plan: Live Config Profile Refresh
## Backend
- Canonical file and directory paths are profile-scoped and reject traversal.
- Two compatible instances receive the same host mount source.
- A container-side file edit is visible through the profile read API and another instance mount.
- A profile save updates canonical content and returns overwrite warnings when applicable.
- Topology, environment, runtime, and legacy-instance changes return `restart_required`.
- Incompatible users return `incompatible_permissions`.
- Deleting a profile with running dependents is rejected with their instance identifiers.
- Git mount content is unchanged by this feature.
## Container/image compatibility
- Each built-in supported image uses the common non-root UID/GID.
- Generated manifest Dockerfiles and entrypoints retain that user and writable mount access.
- Existing instances are not mutated until restart/recreation.
## Frontend
- Desktop and mobile save flows display refreshed/shared-working-copy, overwrite-warning, restart-required, and incompatible-permissions results.
## Manual QA
- Open two compatible instances using one profile; edit a mounted file in one terminal and verify it in the other.
- Save a profile edit and verify both running instances see it without terminal disconnection.
- Verify profile deletion is blocked while either instance is running.