# §28 — The workspace

A home screen where you choose, and a workspace where you work. The two-scope shape, and the one that is worth understanding before you change anything.

`AppState` is provided by the root and lives for the whole process. `WorkspaceState` is provided by the workspace view and lives only while a project is open — its entries, its selection, its active tab.

The root drops the workspace entity when the route goes home. That is what stops a closed project's state leaking into the next one, and what stops an in-flight load landing in a view that has moved on. Settings stay at the root, because ⌘, has to work on the home screen too.

## What you are carrying

- `model` — The project, and what a project contains.
- `store` — Projects on disk, one JSON document.
- `host` — Owns the active-project cursor, not the UI.
- `app` — Home ⇄ workspace routing, two state scopes.

## Start it

```bash
scripts/new.sh Acme ~/Dev/acme --template workspace
```

## What it looks like

`crates/app/src/root.rs`

```rust
match self.state.route.get(cx) {
    Route::Home => {
        // Dropping the entity here is what stops a closed project's signals
        // and in-flight loads from outliving it.
        self.workspace = None;
        div().size_full().child(self.home.clone())
    }
    Route::Workspace(id) => match self.state.host.active().filter(|p| p.id == id) {
        Some(project) => div().size_full().child(self.workspace_for(project, cx)),
        // The route says open and the host disagrees. An empty workspace
        // would strand the user, so fall back rather than render nothing.
        None => { self.state.route.set(cx, Route::Home); div().size_full().child(self.home.clone()) }
    },
}
```

## Where now

- Sign it and ship it — turn to §101 (Appendix B)
- Hand it to an agent — turn to §102 (Appendix C)
- Walk it again from the start — turn to §1
