# Single Instance + Task Isolation
Date: 2026-04-01
Status: Foundation, cloud-owned inventory, freshness hardening, replacement/rollback hardening, broader bundle regression coverage, and lifecycle smoke are implemented

## 1. Intent
The goal is a single desktop app instance with isolated project execution.

Isolation means:
- each session is bound to a project
- prompts are prepared with that project's context only
- execution routing stays inside the selected project's boundaries
- project state should not leak across sessions or projects

## 2. What is implemented
### Project and session model
- Projects exist in local workspace state.
- Sessions are created per project.
- Active project selection is real.
- Session to project binding is real.

### Cloud-owned inventory behavior
- No project means no implicit local `default` project.
- Session listing returns `[]` when inventory is empty.
- Creating a session while waiting for the first cloud project returns `Waiting for cloud project bundle sync.`.
- The first synced bundle-backed project becomes active without local fallback recreation.

### Project context model
- `ProjectContextService` builds snapshots from project root files.
- `SOUL.md`, `USER.md`, `README.md`, and tracked memory files are included.
- Snapshot caching, invalidation, and refresh are implemented.
- `session.contextSnapshotId` rebinding is implemented.

### Execution routing
The router can choose:
- `workspace-entry`
- `skill`
- `chat-fallback`

All three routes are project-aware.

### Cloud bundle path
- Cloud payload can define zip-backed projects.
- Bundles are downloaded and materialized locally.
- Shared bundle assets can also be materialized.
- Stale bundle-managed projects and shared assets can be removed when the expected cloud bundle set changes.
- Same-URL bundle changes can now trigger re-download through HTTP freshness metadata.
- Same-`projectId` bundle replacement now uses explicit stage/commit/finalize-or-rollback handling.
- If replacement fails after commit but before metadata sync completes, the previous project root and shared assets are restored.

### Current protocol boundary
- The current backend payload returns a `skills` array.
- Each `skills[]` object carries one project zip through its single `skill.download_url` string field.
- Multi-project inventory is currently expressed by multiple `skills[]` objects, one project download URL per object.
- If the backend later changes this field to an array or set, that must be treated as a separate protocol and implementation change.
- That protocol upgrade has not started yet.

## 3. Current default chat behavior
Default chat is no longer a special weak path.

Current behavior:
- it reads the latest available project snapshot before each request
- it injects project context into prepared prompt content
- after a `chat-fallback` turn completes, it queues project context refresh in the background
- when refresh succeeds, `session.contextSnapshotId` is rebound to the refreshed snapshot
- the next request reuses the refreshed snapshot

The refresh remains asynchronous so reply delivery is not blocked.

## 4. Verified coverage
Current repo smoke coverage includes:
- `workspace-entry-smoke.ps1`
- `cloud-bundle-smoke.ps1`
- `project-context-refresh-smoke.ps1`
- `default-chat-smoke.ps1`
- `project-empty-inventory-smoke.ps1`
- `project-bundle-reconcile-smoke.ps1`
- `project-bundle-freshness-smoke.ps1`
- `project-bundle-replacement-smoke.ps1`
- `project-bundle-churn-smoke.ps1`
- `project-isolation-smoke.ps1`

Additional verified points:
- cloud bundle smoke passes with freshness probing enabled
- cloud bundle smoke now validates same-`projectId` replacement through the Electron UI/main chain
- service-level replacement smoke validates rollback injection and recovery on the next sync
- service-level churn smoke validates multi-project survivor/replacement/removal/addition behavior
- `project-isolation-smoke.ps1` now aggregates reconcile, freshness, replacement, and multi-project churn coverage into the broader project-isolation gate
- Electron smoke validates workspace-agent status history instead of relying on the final status label only

## 5. Important current limitations
### Broad UI regression breadth is still selective
The targeted Electron lifecycle smoke for cloud bundle replacement now exists, but the full UI regression matrix is still intentionally selective rather than exhaustive.

### Stress breadth can still expand
The current replacement and churn coverage is strong for deterministic paths, but future changes may still need larger randomized multi-project stress coverage.

## 6. What has been completed so far
Completed enough to count as real implementation:
- project-bound session model
- cloud-owned inventory enforcement
- project context snapshot model
- cloud zip materialization path
- project-aware execution routing
- default chat refresh alignment with other project-aware paths
- stale bundle-managed cleanup for project/skill/cron/manifest state
- bundle freshness hardening using remote metadata probe
- replacement / rollback hardening for same-project bundle updates
- broader service-level churn coverage for multi-project inventory transitions
- smoke coverage for empty inventory, removal, freshness, replacement, churn, and Electron lifecycle validation

This project is no longer at the design-only stage.

## 7. What should happen next
Recommended next work:
1. Keep the current smoke set green as adjacent runtime work lands.
2. Use `project-isolation-smoke.ps1` plus `cloud-bundle-smoke.ps1` as the main higher-level regression gate pair.
3. Expand breadth only when upcoming product changes introduce new isolation surfaces.
4. If backend protocol changes from single `download_url` to a multi-value form, handle it as a separate compatibility task instead of folding it into unrelated hardening work.

## 8. Final summary
The single-instance plus task-isolation foundation is implemented.
The earlier main gaps around cloud-owned inventory, replacement/rollback hardening, and lifecycle smoke have been closed.
The remaining work is mostly broader regression breadth and future protocol evolution, not missing core behavior.
