---
title: Mission Control — workspaces, people and publishing (part 3)
---

# Mission Control — workspaces, people and publishing (part 3)

## What it is

This is part 3 of the [Mission Control](mission-control.md) page. It covers who can see and change a board, and the structures that sit above one.

## Where to find it

Inside **Mission Control**: workspace and member controls live in the workspace's own settings, the sharing actions on a board's menu, and goals and portfolios in the left navigation.

## How it behaves

### Workspaces functionality (post-Phase-4 fast-follow)

A pixel-near rebuild of monday's **Workspaces** across three surfaces. **(1) Left-nav header** — the plain `<select>` became a monday workspace block: a colored icon tile (initial + home glyph; tint from a new `workspaces.color` or a deterministic id-hash fallback), a name + switcher popover, and a **⋯ actions menu** (`WorkspaceMenu`) — Manage workspace, Edit workspace (icon-color + name + description modal), Sort workspace (a per-workspace localStorage display order), Add new workspace, Browse all workspaces, View archive/trash, and a confirm-gated Delete (disabled for the Main/last workspace). **(2) Manage-workspace page** (`/workspace/:id`, rebuilt `WorkspacePage`) — a banner (large icon, name, inline-editable **description**, Feedback (inert) / **Members** → `/users` / ⋯) over **Recents · Content · Permissions** tabs: Content is a boards+dashboards asset table (creator avatar, creation date, **Last modified**, folder, search, selection-delete, a real **Cleanup mode** that flags assets unmodified 30+ days; the AI-summary column is intentionally dropped); Recents reuses the Home recent-visit locators + favorite stars; Permissions sets the workspace access level (Open/Closed via `workspaces.kind`), manages **workspace owners** (people only — add/remove, last owner is guarded), and — for a **closed** workspace — the specific **members & teams with access** (an open workspace just reads "everyone in your account"), all via a searchable `PrincipalPicker` over the account directory + teams. **(3) User-management page** (`/users`, `UserManagementPage`) — the account directory as a full table with an editable **role** dropdown (`PATCH /members/:id`), a **Products** multi-select (real, seeded with `work_management`), **status**, **Teams** chips, joined/invited dates, an **Invite** dialog (reuses the member invite), and a **Manage teams** modal over a real **Teams** subsystem.

Backend (`amc-back`): migration **0012** adds `workspaces.color` + `description` (flow through `/nav/tree`); **0013** adds `boards.updatedAt` + `dashboards.updatedAt` ("Last modified" — auto-bumped via Drizzle `$onUpdateFn` on row edits and via `touchBoard()` at the `publish()` realtime chokepoint on content edits); **0014** adds the `teams` + `team_members` tables + a `teamsRoutes` module (account-scoped CRUD + membership); **0015** adds `users.products` (jsonb) + extends `PATCH /members/:id` (role/products) and the member payload (products, joinedAt, invitedAt). `PATCH /workspaces/:id` gained color/description/kind. Migration **0016** adds the `workspace_principals` table (polymorphic user|team rows, `owner`|`member` role) backing the Permissions tab — seeded so every workspace keeps a real owner (the creator on `POST /workspaces` + register; the account's earliest user in the migration backfill) — with `GET/POST/DELETE /workspaces/:id/principals` (owners-are-users, never-zero-owners 409, and account-isolation guards). Boards gained `GET /boards/archived` + `/boards/trash` listings and a `POST /boards/:id/restore` (clears archived + soft-delete; ownership via the board→workspace→account join). Pure Content-tab + Permissions helpers (asset shaping + staleness; owner-removal + picker-candidate filtering) are unit-tested (`tests/unit/plugins/mission-control/manage-workspace.test.ts`, `workspace-permissions.test.ts`); every route has bun coverage (the backend package’s workspace-permissions bun test, not tracked in this repo). Design specs `docs/superpowers/specs/mission-control-workspaces-design.md`, `mission-control-workspace-permissions-design.md`.

### Account & passwords (parity fast-follow)

The login screen gained a **"Forgot password?"** link: enter your email and you get a **neutral** confirmation ("if that email exists, we've sent a reset link") that never reveals whether the address is registered. Because the plugin runs on an **in-memory router** — email links can't deep-link into it, the same constraint that puts the invitation-accept pages on the backend — the reset itself happens on a **backend-served HTML page** the emailed link points to. The reset token is **single-use, expires in one hour**, and a fresh request **supersedes** any earlier link; completing a reset **signs out all existing sessions**.

Signed in, the top-right **account menu** (the avatar) adds **"Change password"** — a modal that requires your **current password** and a new one of **at least 8 characters**. Changing it **signs out all your OTHER devices** while the current one stays signed in.

**Logout is now server-side** — signing out revokes the session on the backend too (not just a local token wipe), so it takes effect even after a long idle. (There is still **no email verification** on signup — accounts are usable immediately.)

### Board sharing & private-board enforcement (parity fast-follow)

The board header gained a **Share** button → a modal with a **copyable join link** and the board's **member list**. The join link points at a **backend-served join page** (same pattern as reset/invite — the in-memory router can't be deep-linked); another user on the **same account** signs in there and is added to the board as an **editor**. Private boards are now **enforced end-to-end**: only a board's **members** — owner / editor / viewer principals, held directly or via a **team** — can see a board in listings or open it. Only the **board owner** can **mint, rotate, or revoke** the share link or **add/remove members**.

**Local board sharing (push-then-share):** Boards created via the local SQLite fallback (when the backend is unreachable) carry `sync_status = 'local_pending'`. When a user clicks Share on such a board, the share modal automatically pushes it to the backend first via the `PM_ENSURE_BOARD_SYNCED` IPC channel before showing the share UI. If the backend assigns a different board ID, a `swapBoardId` atomically updates all FK tables and the modal uses the resolved ID for all subsequent share operations. The same pre-sync guard runs on the CLI share routes (`GET/POST/DELETE /pm/boards/:id/share`). If the push fails, a clear error is shown and sharing is disabled until connectivity is restored.

### Workspace invite link (parity fast-follow)

The workspace **⋯ menu** gained **"Copy invite link."** It **reuses the workspace's existing invite link** and only **mints a new one when none exists yet**, so the link stays stable across copies. Only **workspace owners** can manage the link.

### Role-Based Entry Points (G14, in-development)

Extends the setup wizard (G12) with **three onboarding lanes** and a **12-combination
default surface matrix** that auto-picks a preset from two questions. Gated behind
the `pm-role-entry-points` unreleased feature. When the gate is off, the existing
wizard auto-open behavior is preserved.

**Three lanes (plain language, no jargon):**

- **Quick start** (Lane 1) — two questions only (AI comfort + org role), then
  `getDefaultSurface(comfort, role)` auto-applies the preset from the matrix.
  Under 60 seconds.
- **Guided setup** (Lane 2) — the existing 5-step PmSetupWizard. Unchanged.
- **Build with AI** (Lane 3) — a 10-15 minute AI conversation that infers
  comfort, role, and preset via structured output (`{"pmSetup":{...}}`
  in a fenced JSON block).

**12-combination matrix** (`default-surface-matrix.ts`): maps every (comfort x role)
pair — 3 comfort levels (low, medium, high) × 4 org roles (tasks, team,
department, engineering) — to a `PmDefaultSurface` with preset, defaultView,
aiBehavior (7 per-cell levels: off / minimal / basic / balanced / full /
proactive / max), and autoFeatures. Null inputs default to medium/tasks.

**G11 signal wiring:** `buildG11Context()` in `pm-session-context-provider.ts`
injects comfort, role, and aiBehavior into ALL PM-project sessions (before the
pmItemId guard), so every PM session knows the user's profile.

**Admin-assigned onboarding (same-machine):** a manager can pre-fill Lane 2
answers for another user via CLI (`POST /pm/onboarding/assign`). The target
user's PM opens with those answers applied. Silently ignored if the user already
completed setup. Stored in `pm_admin_onboarding` SQLite table.

**Peer inference:** `inferPeerFeatures(db)` queries the local SQLite mirror
(columns, views, automations, boards) and returns suggested features based on
team usage patterns. Additive only; empty mirror returns empty suggestions.

**Retake flow:** "Redo Setup" in MissionControlSettings reopens the lane selector (not
the wizard directly) when the role-entry-points gate is on.

- **Contract:** [pm-setup-wizard-contract.md](../../.claude/memory/contracts/pm-setup-wizard-contract.md) (the G14 lane rules: `lane-selector-exclusivity`, `three-onboarding-lanes`, `twelve-combination-default-surface`, `deep-interview-structured-output`, `admin-assigned-onboarding-guarded`, `retake-respects-lane-gate`)
- **Key files:** `src/shared/pm-composability/default-surface-matrix.ts` (matrix),
  `src/shared/pm-composability/deep-interview-prompt.ts` (AI prompt + parser),
  `src/renderer/src/features/mission-control/setup/OnboardingLaneSelector.tsx` (lane picker),
  `src/renderer/src/features/mission-control/setup/QuickPickWizard.tsx` (Lane 1),
  `src/main/services/pm/onboarding/pm-deep-interview.ts` (Lane 3),
  `src/main/services/pm/onboarding/pm-admin-onboarding.ts` (admin assignment),
  src/shared/pm-composability/peer-inference-types.ts (peer inference types — no longer present in the current tree; `inferPeerFeatures(db)` above is likewise not implemented today)

### Comment Visibility (in-development — `pm-comment-visibility` flag)

Item comments carry a **visibility** field (`internal` or `external`) controlling who can see them. Internal comments are visible only to board owners and members; external comments are visible to all roles including viewers and guests. Defaults to `internal` (team-only).

**Role-based filtering:** `getCommentsForItemFiltered(db, itemId, role)` checks `canViewInternalComments(role)` — owners and members see all comments; viewers, guests, and unauthenticated users see only `external` comments. The visibility filter is applied at the query level.

**UI:** the comment compose area has a visibility toggle (pill button) that switches between "Internal" (default, `surface-600` muted) and "External" (`status-needs-you` amber). A tooltip explains the distinction. Each rendered comment row shows a visibility badge. Board owners/members can change visibility on existing comments via `pm:item-comments:set-visibility`.

**Sync safety:** `upsertComment` uses `ON CONFLICT … DO UPDATE` that preserves the existing `visibility` value when syncing from an external source (the external source does not carry visibility), preventing sync from overwriting local visibility choices.

**IPC:** 3 channels (`pm:item-comments:list`, `pm:item-comments:add`, `pm:item-comments:set-visibility`), Zod-validated, feature-gated on `missionControlEnabled` + `pmCommentVisibilityEnabled`. All three BLOCKED in `web-access-ws-channels.ts` (desktop-only until the feature ships). CLI-parity: add and set-visibility are `feature-scoped-surface` exemptions; list is auto-excluded (query verb).

**Key files:** `src/main/services/pm/pm-comment-queries.ts` (queries + role check), `src/main/ipc/pm-comment-handlers.ts` (IPC handlers), `src/renderer/src/features/mission-control/PmItemComments.tsx` (UI), `src/shared/ipc-schemas/pm-comments.ts` (Zod schemas), `src/shared/ipc-response-map/pm-comments.ts` (response types), `tests/unit/services/pm/pm-comment-queries.test.ts` (24 tests).

### Summarizing a comment thread (shipped, metered — `pm-comment-summary`)

Summarizing a comment thread is a **paid AI call** — a small Haiku model over the thread's text, on demand, from the comment pane or from the CLI (`POST /pm/items/:id/comments/summarize`). It is metered, and the meter is a hard **$0.50/day** ceiling charged against the `pm-comment-summary` cost label over a local-midnight day; there is no setting for it, so it does not appear in the settings reference or in Cost Control. If you summarize a lot in one day, the summaries simply stop being generated until the next day — nothing else in the comments feature is affected. Distinct from the **Comment Visibility** gate in the section just above: that one is in-development and this one ships.

### Item History + Undo/Rollback (G8, unreleased — `pm-item-history` flag)

Every PM field change is tracked in `pm_item_history` (item_id, column_id, old_value, new_value, actor_type, actor_id, session_id, session_turn, bulk_action_id, cross_board_correlation_id, caused_by_id, timestamp). Actor types: `human`, `agent`, `automation`, `import`, `api`. Recording is **fail-safe** (try/catch, never breaks the parent mutation). Sync-path (import) records only actual changes via diff check.

**Undo** (`PmUndoService`): reverts the last change for a field (column value, name, create, delete). Synced boards route mutations through the Mission Control REST API then update the local mirror via authorized writers; local boards use authorized writers directly. Deletion undo restores from a JSON snapshot. Every undo creates a new forward history entry with `caused_by_id` linking to the undone entry. Both `executeUndo` and `executeRollback` are async (return Promises).

**Rollback** (`PmRollbackService`): `planRollback(itemId, targetHistoryId)` builds a plan showing which fields to revert plus conflict flags (a field changed more than once after the target point has `hasConflict: true`). `executeRollback` applies the plan with stale-plan detection (rejects if the item was modified after `plan.generatedAt`). Conflict resolution: `revert_to_target` (apply the revert) or `keep_current` (skip conflicting fields only).

**Forward-only invariant**: undo and rollback create new history entries, never erase old ones. **Retention**: 180-day cleanup in `data-retention.ts`.

**Frontend**: `PmHistoryTab` in the item card (gated by `isPmHistoryEnabled()`), showing a timeline of changes with color-coded actor badges, old-to-new value chips, relative timestamps, and per-entry Undo buttons. Bridge API via `window.__AMC_PM_HISTORY__` installed by `MissionControlPanel.tsx`.

**IPC**: 6 channels (`pm:item-history:list`, `pm:board-history:list`, `pm:session-pm-changes`, `pm:item-history:undo`, `pm:item-history:rollback-plan`, `pm:item-history:rollback-execute`), Zod-validated. **CLI**: 6 matching routes. Mutation channels blocked in `BLOCKED_CHANNELS`; read channels baselined.

**Key files**: `src/main/services/pm/history/pm-history-queries.ts` (SQL), `src/main/services/pm/history/pm-history-service.ts` (fail-safe wrappers), `src/main/services/pm/pm-undo-service.ts`, `src/main/services/pm/pm-rollback-service.ts`, `src/main/ipc/pm-history-handlers.ts`, `src/main/services/cli/pm/pm-cli-history-ctx.ts` (CLI auth → `PmHistoryContext` mapper), `src/plugins/mission-control/web/features/board/PmHistoryTab.tsx`, `src/shared/ipc-schemas/pm-history.ts`, `tests/integration/pm-history.test.ts` (19 tests).

### Cross-entity linking

PM board items can be linked to **14 entity types**: KMS vault notes, mind maps, flowcharts, whiteboards, sessions, writer documents, URLs, email threads, meetings, **GitHub PRs**, **GitHub commits**, **GitHub branches**, and **GitHub issues**. Links are bidirectional:

- **Item card Links tab** (`LinksTab.tsx` in `plugins/mission-control/web/features/board/`) groups linked entities by type with icons, showing a hover-reveal unlink action. GitHub commit links display the short SHA and a commit message excerpt. The tab communicates via bridge methods on `window.__AMC_MISSION_CONTROL_SESSION__` (`listItemLinks`, `createItemLink`, `deleteItemLink`, `navigateToEntity`, `createGitHubBranch`), installed by `MissionControlPanel.tsx`.
- **"Link to Board Item" action** in each visual tool's toolbar or context menu opens `PmItemPicker` (a `DialogShell` with debounced search over all boards+items).
- **Backlink chips** (`PmBacklinkChips.tsx`) appear in KMS, mind map, flowchart, and whiteboard headers, auto-refreshing on `PM_ITEM_LINKS_CHANGED` push events.
- **GitHub branch creation** — a "Create GitHub Branch" button on the Links tab creates a branch named after the item (slugified via `slugifyForBranch`, e.g. `feat/my-item-name`) on the first GitHub-connected project, then auto-links it back. Feature-gated behind `github-mc-branch-creation` unreleased feature. IPC: `GITHUB_MC_CREATE_BRANCH` in `src/shared/ipc-channels/github-mc.ts`, handler in `src/main/ipc/github-mc-handlers.ts`, service in `src/main/services/github-mc/github-mc-branch-service.ts`.
- **Clicking a GitHub commit link** opens the commit on GitHub in the browser (URL constructed from the `entityId` format `owner/repo:sha`).

**GitHub commit scanner** (in-development, `github-commit-linking` unreleased feature): a 5-minute polling service (`github-commit-scanner.ts`) that automatically detects `MC-N` references in recent git commit messages and creates `github_commit` links on the matching board items. The scanner discovers repos from Omniscio project folder paths, fetches the last 100 commits per repo via the `gh` CLI, parses item references with a configurable prefix (default `MC`), and resolves them against `pm_items.item_number`. Commit metadata (SHA, message first line, author, date, URL) is stored in a companion table (`github_commit_links`) with a FK to `pm_item_links`. Deduplication is via unique constraints on both the link and companion tables.

**Data model:** `pm_item_links` table (entity_type + entity_id + item_id, partial unique index) with an optional companion table per entity type (`github_pr_links` for PR metadata, `github_commit_links` for rich commit metadata). Five link IPC channels (`PM_ITEM_LINKS_LIST/CREATE/DELETE/FOR_ENTITY/SEARCH_ITEMS`), all desktop-only (WS-blocked). The LIST handler enriches `github_pr` links with `prMetadata` and `github_commit` links with `commitMetadata` from their companion tables. GitHub branch creation uses a separate channel (`GITHUB_MC_CREATE_BRANCH`).

**GitHub PR review requests** (unreleased, `github-mc-review-notifications`): when a `github_pr` link exists on an item, a background poller (`createInboxPoller`, 10-min interval) fetches review state via `gh api` and caches it in `pm_github_review_requests`. The LinksTab shows a `ReviewRequestSection` with per-reviewer state badges (approved/changes requested/pending/dismissed/commented). State changes raise inbox alerts via `raiseAgentAlert`. Kill switch: `AMC_DISABLE_GITHUB_REVIEW_POLL=1`. Key files: `src/main/services/pm/github-review-request-service.ts` (poller), `src/main/services/pm/github-review-utils.ts` (pure logic), `src/main/services/pm/pm-queries-github-reviews.ts` (DB queries), `src/plugins/mission-control/web/features/board/ReviewRequestSection.tsx` (UI).

- **Contract:** [pm-cross-entity-link-contract.md](../../.claude/memory/contracts/pm-cross-entity-link-contract.md)
- **Key files:** `src/main/ipc/pm-item-links-handlers.ts` (IPC), `src/main/ipc/github-mc-handlers.ts` (GitHub branch IPC), `src/main/services/github-mc/github-mc-branch-service.ts` (branch creation service), `src/plugins/mission-control/web/features/board/LinksTab.tsx` (item card tab), `src/renderer/src/features/pm/PmItemPicker.tsx` (search dialog), `src/renderer/src/features/pm/PmBacklinkChips.tsx` (backlink chips), `src/renderer/src/features/pm/useLinkToItem.ts` (link hook), `src/main/services/pm/github-commit-scanner.ts` (polling scanner), `src/shared/mc-item-reference-parser.ts` (reference parser), `src/main/services/pm/pm-queries-github-commit-links.ts` (companion table queries), `src/renderer/src/features/mission-control/bridges/content-bridge.ts` (commit navigation)

### Goals

Hierarchical goal tracking scoped to a workspace. A goal has a title, description, status (`on_track`/`at_risk`/`off_track`/`achieved`), optional target date, progress percentage (0-100), progress mode (`auto`/`manual`), and optional parent goal for nesting. Goals can link to boards via a junction table, and every mutation records an activity log entry.

**UI**: `/goals` list page (status-filter pills: All/On Track/At Risk/Off Track/Achieved; empty state), `/goal/:goalId` detail page (status pill, progress bar, linked boards section with a manage-boards modal, child goals, paginated activity feed), a shared `CreateGoalModal` (create + edit). The home page surfaces active (non-achieved) goals in a `GoalsSummaryWidget` (collapsible, shows up to 5 with inline progress bars; "See all" link when more exist). Left-nav adds a "Goals" section between Dashboards and Trash.

**Data**: `pm_goals`, `pm_goal_boards`, `pm_goal_activity` tables (local-authority SQLite, session bridge pattern). Status pill uses `status-*` design tokens. Cycle detection on parent_goal_id updates (recursive CTE walks ancestors).

**IPC**: 15 channels (`pm:goal:list` through `pm:goal-children:list`, plus goal-comments channels for list/add/delete, `pm:goal-comments:changed`, and `pm:goals:changed`), Zod-validated. Response map fragments in `src/shared/ipc-response-map/pm-goals.ts`.

**Key files**: `src/main/db/queries-pm-goals.ts`, `src/main/ipc/pm-goals-handlers.ts`, `src/plugins/mission-control/web/features/goals/` (6 components), `src/plugins/mission-control/web/lib/session-bridge-goals.ts`, `src/shared/ipc-schemas/pm-goals.ts`.

### Portfolios

A named collection of boards scoped to a workspace. A portfolio has a title, description, and links to boards via a junction table. Simpler than goals (no hierarchy, status, or activity log).

**UI**: `/portfolios` list page (with SVG empty state), `/portfolio/:portfolioId` detail page (linked board rows with unlink action, inline board-linking picker). Left-nav adds a "Portfolios" section after Goals.

**Data**: `pm_portfolios`, `pm_portfolio_boards` tables (local-authority SQLite, session bridge pattern). Board item-level data (status counts, health) comes from `authedFetch` (not session bridge) and is deferred to a follow-up.

**IPC**: 9 channels (`pm:portfolio:list` through `pm:portfolios:changed`), Zod-validated. Response map fragments in `src/shared/ipc-response-map/pm-portfolios.ts`.

**Key files**: `src/main/db/queries-pm-portfolios.ts`, `src/main/ipc/pm-portfolios-handlers.ts`, `src/plugins/mission-control/web/features/portfolios/` (5 components), `src/plugins/mission-control/web/lib/session-bridge-portfolios.ts`, `src/shared/ipc-schemas/pm-portfolios.ts`.

### Publish to Web (Phase 9b)

Boards and dashboards can be published as read-only web snapshots through the Omniscio Shares pipeline. The MC plugin renders a self-contained HTML document server-side (inline CSS, no external resources, light/dark theme via `data-theme` attribute) and pushes it through `publishArtifact()` to GCS, producing a public URL at `shares.omniscio.com/s/<token>`.

**What can be published**: any of the board view types (table, kanban, calendar, chart, timeline, roadmap, form, workload, map) plus dashboards (widget grid with numbers/chart/battery/table widgets; sprint-history widgets render placeholders). Form views show an explanatory empty state. Re-publishing the same unchanged content returns the same URL (content-hash dedup). Revoking follows the RT-F016 durable-intent pattern.

**UI**: `BoardPublishButton` in the board toolbar, `DashboardPublishButton` in the dashboard header. Both open a modal with publish/update-snapshot/revoke-link controls. Password and expiry are set post-publish via the Shares panel (matches the Decks pattern).

**IPC**: 3 channels (`MC_BOARD_PUBLISH`, `MC_DASHBOARD_PUBLISH`, `MC_BOARD_UNPUBLISH`), Zod-validated. All three BLOCKED in `web-access-ws-channels.ts` (desktop-only).

**ShareArtifactKind**: `'mc-board'` added to the union, with `sourceType: 'mc-board-publish'`, included in `FULL_BLEED_KINDS`.

**Key files**: `src/main/services/mission-control/mc-board-render.ts` (entry point + document shell), `mc-board-render-views.ts` (re-export barrel) + `render/mc-view-*.ts` (7 per-view renderers) + `render/mc-render-helpers.ts` (shared helpers + `renderCellValue`), `mc-board-render-styles.ts` (CSS), `mc-dashboard-render.ts` (dashboard orchestrator) + `render/mc-dashboard-data.ts` (bucketing) + `render/mc-dashboard-styles.ts` (CSS) + `render/mc-chart-renderers.ts` (chart SVG), `src/main/ipc/mission-control-publish-handlers.ts` (IPC handlers), `src/plugins/mission-control/web/features/board/BoardPublishButton.tsx`, `src/plugins/mission-control/web/features/dashboard/DashboardPublishButton.tsx`, `src/plugins/mission-control/web/lib/publish-api.ts` (IPC bridge).

**Tests**: `tests/unit/mc-board-render.test.ts` (48 tests), `tests/unit/mc-dashboard-render.test.ts` (18 tests), `tests/unit/mc-board-share-type.test.ts` (7 tests).

### Setup Wizard (G12, in-development)

A 5-step onboarding wizard that recommends a PM preset (Tasks / Projects /
Operations / Engineering-Linear / Engineering-Jira) based on the user's answers.
Gated behind the `pm-setup-wizard` unreleased feature (Settings → Lab toggle
or `AMC_SHOW_PM_SETUP_WIZARD=1`).

**How to use it:** enable Mission Control, then enable the PM setup wizard feature flag.
The wizard auto-opens when `pmSetupComplete` is false. Five steps: AI comfort
level (low/medium/high), organizational role (tasks/team/department/engineering),
feature checklist (10 items), optional free text, and the preset picker. Each step
saves to AppSettings on Continue. Skipping applies sensible defaults
(medium / tasks / Tasks preset).

**Preset recommendation (DL65):** role = engineering → Engineering-Linear by
default (Engineering-Jira if `sourceToolId` is 'jira'); any checklist item 1-9
checked → Operations; item 10 (AI integration) is a confidence signal only,
never triggers Operations; role = team|department + zero checked → Projects;
otherwise → Tasks. The recommendation highlights one card but the user can
override.

**Presets (pure data records — PDR8):**

Three core "lane" presets shown in the wizard picker:

- **Tasks** — personal (like Todoist): 4 columns, Table view, column picker
- **Projects** — team (like Trello): 7 columns, Table view, Forms + team infra
- **Operations** — department (like Monday.com): 10 columns, all 8 views,
  Dashboards + Automations + Formulas

Two engineering presets routed via the engineering org role:

- **Engineering (Linear)** — cycles, triage, velocity (22 features): 8 columns,
  4 views, Dashboards + Chart widgets + Cross-board relations
- **Engineering (Jira)** — issues, sprints, epics (25 features): 9 columns,
  5 views, adds Automations + Workspaces + Timeline over Linear

Eight platform presets assigned via the Persona C import flow (single-platform
selection maps to the matching preset; multi-platform maps to Operations):

- **First-Agent-Board / Trello / Jira / Asana / Linear / Notion / ClickUp / Airtable** — each
  with platform-specific columns, views, and features tailored to that tool's
  paradigm. Defined in `PM_PRESETS` alongside the lane and engineering presets.

All 13 presets are entries in `PM_PRESET_IDS` / `PM_PRESETS` in
`src/shared/types/pm-setup.ts`. Presets control surface area, not access (PDR8).

**Settings integration:** once setup is complete, a "PM Setup" section appears
in Settings → Mission Control showing the active preset, feature counts, a "Change
Preset" button (dialog with all preset cards), and a "Retake Interview"
button that reopens the wizard.

**How it works (internals):** the wizard uses the shared `<Wizard>` +
`WizardStepLayout` + `createWizardStore` pattern. Steps are lazy-loaded via
`retryDynamicImport`. Preset data lives in `src/shared/types/pm-setup.ts` as a
`Record<PmPresetId, PmPresetRecord>`. Seven `pmSetup*` fields in
`missionControlSettingsSchema` persist the interview answers and completion state.

- **Contract:** [pm-setup-wizard-contract.md](../../.claude/memory/contracts/pm-setup-wizard-contract.md)
- **Key files:** `src/shared/types/pm-setup.ts` (preset data + recommendation),
  `src/renderer/src/features/mission-control/setup/` (wizard components),
  `src/renderer/src/features/settings/sections/mission-control/MissionControlSettings.tsx`
  (settings section)

## Related

- [Mission Control](mission-control.md) — the overview page this continues.
- [pm-goals.md](pm-goals.md) and [pm-portfolios.md](pm-portfolios.md) — the goals and portfolio surfaces in more detail.
- [pm-agent-trust.md](pm-agent-trust.md) — the trust levels that decide what an agent may change on a board.

