diff --git a/DEVLOG.md b/DEVLOG.md
index 388f3057..1fb168f8 100644
--- a/DEVLOG.md
+++ b/DEVLOG.md
@@ -13619,3 +13619,42 @@ PR #49 passed GitHub's lint, typecheck, unit, and both Playwright shards. Bumped
the application version to 0.24.0 and curated the in-app changelog around the
Mission Control attention lifecycle, inspectable cross-workspace surfaces,
concurrent run capacity, agent-page scrolling, and semantic navigation.
+
+---
+
+## 2026-07-16 — Personal workspace experience
+
+Added a settings-driven `WorkspaceExperienceProfile` so one tenant model can
+present either the full project/team system or a calmer personal task system.
+Personal creation seeds home/work/errand/waiting labels, assigns new tasks to
+their creator by default, and skips the initial sprint; team creation retains
+the existing project defaults and now consistently names the first iteration
+Sprint 1. Owners and admins can switch profiles later without migrating or
+losing projects, issues, notes, routines, agents, or delivery history.
+
+Personal workspaces now open on a responsive Today dashboard with fast task
+capture, Today/overdue/upcoming grouping, completion, personal notes, planning
+handoff to agent chat, and a narrow collapsible agent companion. The companion
+uses real assigned-task state and update times instead of invented progress.
+Navigation becomes Today, Inbox, Tasks, Upcoming, Notes, Chat, Routines, and
+Agents while preserving full agent management and all underlying routes.
+
+Verification: Prisma generation and migration deployment passed; lint passed
+with existing repository warnings; typecheck and the production Next build
+passed; the personal navigation unit suite passed 11 tests; and the new
+Playwright journey passed workspace creation, task add/complete, note capture,
+companion collapse, and settled-route console checks. The broad Vitest run
+passed 1,322 of 1,323 runnable tests with one intentional live skip; its single
+parallel stale-work failure passed immediately in isolation (9/9), confirming
+test interference rather than a feature regression. Desktop and 390px mobile
+captures passed design QA against the selected mockup; see `design-qa.md`.
+
+Review follow-up made workspace settings propagate committed shell fields into
+the live workspace context before refreshing the server component tree, so a
+Personal ↔ Team profile change updates navigation and dashboard behavior
+immediately. Personal Notes no longer advertises the shell-reserved `G N`
+initiative chord. Lint passed with existing warnings; typecheck passed after
+refreshing the lockfile-specified dependencies; the focused navigation suite
+passed 12 tests; the production build passed; and the isolated personal
+Playwright journey passed the task/note flow, both profile transitions, and the
+Notes shortcut contract.
diff --git a/design-qa.md b/design-qa.md
index da4c494d..6ec65776 100644
--- a/design-qa.md
+++ b/design-qa.md
@@ -1,73 +1,75 @@
-# Mission Control operations — design QA
+# Personal workspace — design QA
-## Source and implementation evidence
+## Evidence
-### Workspace Operations Shelf
+- Source visual truth: `/home/bailey/.codex/generated_images/019f684f-8ec0-7312-8d0f-026f4ced54b3/exec-de9fe713-1cdf-4721-8d57-366afeef5114.png`
+- Browser-rendered implementation: `/home/bailey/.codex/visualizations/2026/07/16/019f684f-8ec0-7312-8d0f-026f4ced54b3/personal-dashboard-implemented-2.png`
+- Full-view comparison: `/home/bailey/.codex/visualizations/2026/07/16/019f684f-8ec0-7312-8d0f-026f4ced54b3/personal-dashboard-comparison.png`
+- Mobile implementation: `/home/bailey/.codex/visualizations/2026/07/16/019f684f-8ec0-7312-8d0f-026f4ced54b3/personal-dashboard-mobile.png`
+- Desktop viewport: 1440 × 1024, light theme, authenticated personal workspace, agent companion expanded, realistic tasks/notes/delegated work.
+- Mobile viewport: 390 × 844, light theme, authenticated personal workspace.
-- Source visual truth: `C:\Users\Bailey\Documents\Codex\2026-07-13\forge-mission-control-audit\outputs\forge-mission-control-audit\11-direction-3.png`
-- Desktop implementation: `C:\Users\Bailey\Documents\Codex\2026-07-13\forge-mission-control-audit\outputs\forge-mission-control-audit\21-workspace-operations-desktop.png`
-- Mobile implementation: `C:\Users\Bailey\Documents\Codex\2026-07-13\forge-mission-control-audit\outputs\forge-mission-control-audit\22-workspace-operations-mobile.png`
-- Full-view comparison: `C:\Users\Bailey\Documents\Codex\2026-07-13\forge-mission-control-audit\outputs\forge-mission-control-audit\24-workspace-qa-comparison.png`
-- Viewports: 1536 x 1024 desktop; 390 x 844 mobile
-- State: Forge workspace Dashboard, Mission Control expanded, Queue selected, seeded local data loaded
+The comparison image normalizes the 1487 × 1058 generated source to the
+implementation viewport. It was inspected at its original 2880 × 1024 output,
+where navigation, task rows, capture controls, note cards, agent states, and
+icons remained readable. A separate focused crop was not needed because the
+full-resolution side-by-side preserved those details without downsampling.
-The full-view comparison preserves each 1536 x 1024 frame at native scale. It shows the selected bottom operations-shelf composition beside the browser-rendered implementation. Both reflow the dashboard above a bottom-attached shelf, use summary / queue / agent-presence zones, keep Queue selected, expose one ember primary action, and retain Forge's warm-earthy dark tokens and compact typography.
-
-The implementation intentionally omits the mock's speculative filter, sort, and inline assignee controls because the current quick-access query is read-only and deep-links to the durable issue surface. It uses honest dispatch-state copy and canonical issue links instead. This is an expected product constraint rather than unresolved visual drift.
-
-### Global Mission Control
-
-- Source desktop baseline: `C:\Users\Bailey\Documents\Codex\2026-07-13\forge-mission-control-audit\outputs\forge-mission-control-audit\01-global-desktop-accepted.png`
-- Source mobile baseline: `C:\Users\Bailey\Documents\Codex\2026-07-13\forge-mission-control-audit\outputs\forge-mission-control-audit\02-global-mobile-accepted.jpg`
-- Desktop implementation: `C:\Users\Bailey\Documents\Codex\2026-07-13\forge-mission-control-audit\outputs\forge-mission-control-audit\19-global-operations-desktop.png`
-- Mobile implementation: `C:\Users\Bailey\Documents\Codex\2026-07-13\forge-mission-control-audit\outputs\forge-mission-control-audit\20-global-operations-mobile.png`
-- Lower mobile implementation: `C:\Users\Bailey\Documents\Codex\2026-07-13\forge-mission-control-audit\outputs\forge-mission-control-audit\20b-global-operations-mobile-lower.png`
-- Full-view comparison: `C:\Users\Bailey\Documents\Codex\2026-07-13\forge-mission-control-audit\outputs\forge-mission-control-audit\23-global-qa-comparison.png`
-- Viewports: 1536 x 1024 desktop; 390 x 844 mobile
-- State: cross-workspace overview with seeded Forge workspace, zero registered runtimes, 19 open issues, no assigned attention, three offline agents, and recent activity
-
-The baseline and implementation comparison confirms the redesign preserves the global shell, real data, existing tokens, density, navigation destinations, and read-only contract while replacing the undifferentiated card grid with the selected direction's operator hierarchy. Runtime and dispatch posture now leads; workspace queue and assigned attention are the primary work plane; agent presence, runtime coverage, and activity follow as supporting evidence.
-
-## Required fidelity surfaces
-
-- **Fonts and typography:** Both surfaces use Forge's existing font stack and density-aware scale. Section labels, headings, metrics, issue keys, and row copy establish the same compact operational hierarchy without a parallel type system.
-- **Spacing and layout:** The workspace shelf attaches to the bottom of the content flow and never covers the dashboard. The global surface uses one posture banner, a 2:1 primary work grid, then three supporting columns. Mobile collapses both surfaces into one readable vertical sequence with no clipped controls or horizontal overflow.
-- **Colors and tokens:** Existing `background`, `card`, `border`, `ember`, `warning`, `danger`, `success`, `foreground`, and `muted-foreground` tokens are used throughout. No hard-coded palette, gradients, or new design system were introduced.
-- **Images and icons:** Neither target requires raster imagery. All interface icons use Forge's existing Lucide dependency; no placeholder asset, handcrafted SVG, CSS drawing, or generated substitute was added.
-- **Copy and content:** Mission Control terminology remains consistent. Workspace issue keys use canonical `FRG-*` references. The global runtime CTA appears only when setup is required, Queue remains distinct from assigned Attention, and Sprint terminology elsewhere remains unchanged.
-
-## States, interaction, and accessibility
+## Findings
-- Live, Queue, Agents, and Chat expose `tablist`, `tab`, `aria-selected`, `aria-controls`, and `tabpanel` semantics.
-- Numeric shortcuts 1–4 switch workspace tabs and Escape collapses the shelf. The primary Assign next action opens the oldest unassigned issue; issue and agent rows deep-link to their durable surfaces.
-- The global workspace row, issue-queue action, inbox, activity, agent settings, and runtime settings navigation were exercised from the rendered page.
-- Workspace Queue and Agent Presence provide explicit loading, empty, and error states. Every global query region has a bounded loading state, empty state, and retry action without hiding the rest of Mission Control.
-- Mobile workspace tabs, Settings, and Collapse meet a 44 px target. Global mobile interactive rows and actions meet at least 40 px, preserve visible focus styles from existing components, and wrap long content without collision.
-- Desktop and mobile document widths match their viewport widths. Browser log review found no warnings or errors attributable to the implementation.
+No actionable P0, P1, or P2 differences remain.
+
+- Typography: the implementation preserves Forge's sans/mono system, close
+ display hierarchy, compact metadata, and identifier treatment. Dynamic
+ workspace/task text wraps or truncates without collision.
+- Spacing and layout: the task-first main column, persistent workspace rail,
+ narrow companion rail, capture bar, task groups, and notes retain the source
+ hierarchy. The narrower agent rail is the explicitly selected refinement.
+- Colors and tokens: all surfaces use Forge's warm background, graphite text,
+ ember action/state color, and existing border/card tokens; no ad-hoc palette
+ or gradient was introduced.
+- Image and icon fidelity: the source contains no raster product imagery. All
+ visible UI symbols use the repository's existing Lucide and AgentAvatar
+ components; there are no placeholder images, custom SVGs, emoji stand-ins,
+ or CSS illustrations in the implementation.
+- Copy and content: personal terminology is consistent (`Today`, `Tasks`,
+ `Upcoming`, `Notes`, `Routines`) while `Agents` remains directly available.
+ The companion reports real assignment state and update time rather than the
+ mock's illustrative progress timeline or percentage.
+- Interaction and accessibility: browser coverage passed workspace creation,
+ task add/complete, note capture, companion collapse/reopen, accessible labels,
+ keyboard-capable controls, and a settled-route console check. At 390px the
+ desktop sidebar becomes the existing bottom navigation, task content remains
+ readable, and there is no horizontal clipping.
## Comparison history
-### Iteration 1
-
-- **[P2] Workspace mobile controls were 24–40 px.** Settings, tabs, and Collapse did not meet the intended touch target. Fixed by increasing mobile controls to 44 px while retaining compact desktop sizing.
-- **[P1] The collapsed workspace pill could sit behind mobile navigation.** Fixed by applying bottom-navigation safe clearance to bottom-corner pill and glance states.
-- **[P1] Global runtime health was buried below workspace volume.** Fixed by replacing the equal-weight card grid with a derived runtime and dispatch posture banner, keeping registration failure visible before queue triage.
-- **[P2] Queue, attention, presence, and activity competed at the same level globally.** Fixed by separating actionable workspace queue and personal attention from supporting coverage and recency evidence.
-
-### Iteration 2
-
-- Post-fix mobile measurement confirms the workspace controls meet 44 px and neither surface overflows at 390 x 844.
-- Post-fix desktop captures confirm the workspace shelf remains in layout and the global scan begins with runtime posture, queue, and attention.
-- Combined comparisons contain no actionable P0, P1, or P2 differences against the approved direction, captured product baseline, and existing Forge conventions.
-
-## Findings
-
-No actionable P0, P1, or P2 findings remain.
+1. The first implementation capture contained transient black compositor
+ blocks while the page was still settling. No source-code visual change was
+ made; the same state was recaptured after the heading and companion loaded
+ and a five-second settle. The stable post-capture evidence is
+ `personal-dashboard-implemented-2.png`.
+2. Full-view comparison found no P0/P1/P2 design mismatch. The visible
+ deviations are intentional product constraints: existing Forge component
+ vocabulary, the user-requested narrower companion, and honest activity
+ state instead of invented progress.
## Follow-up polish
-- **P3:** If Forge later exposes safe quick-assignment mutations and queue sort/filter contracts, the workspace shelf can adopt inline controls without changing its structure.
-
-## Final result
+- [P3] The generated source uses nearly borderless task rows, while Forge's
+ implementation uses its established rounded group cards. This is acceptable
+ system consistency; it can be revisited if the whole task surface adopts a
+ flatter row treatment later.
+- [P3] The source includes more quick-date chips beneath capture. The working
+ implementation keeps the core Today/Tomorrow/Someday picker to reduce density.
+
+## Implementation checklist
+
+- [x] Profile-aware workspace creation and defaults
+- [x] Personal navigation and Today dashboard
+- [x] Persisted task and note interactions
+- [x] Real delegated-agent activity with collapsible rail
+- [x] Desktop and mobile browser verification
+- [x] Same-state source/implementation comparison
final result: passed
diff --git a/prisma/migrations/20260716130000_workspace_experience_profile/migration.sql b/prisma/migrations/20260716130000_workspace_experience_profile/migration.sql
new file mode 100644
index 00000000..3ec2c146
--- /dev/null
+++ b/prisma/migrations/20260716130000_workspace_experience_profile/migration.sql
@@ -0,0 +1,6 @@
+-- Add a presentation/defaults profile without changing workspace tenancy or
+-- capability. Existing workspaces remain TEAM; new PERSONAL workspaces opt in.
+CREATE TYPE "WorkspaceExperienceProfile" AS ENUM ('TEAM', 'PERSONAL');
+
+ALTER TABLE "Workspace"
+ADD COLUMN "experienceProfile" "WorkspaceExperienceProfile" NOT NULL DEFAULT 'TEAM';
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 55eaca4a..755fc5b4 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -32,6 +32,14 @@ enum Role {
GUEST
}
+/// Presentation and default-provisioning profile for a workspace. This does
+/// not change tenancy, permissions, or agent capability: PERSONAL keeps the
+/// same underlying work model while simplifying the default experience.
+enum WorkspaceExperienceProfile {
+ TEAM
+ PERSONAL
+}
+
/// Instance-wide role, distinct from the per-workspace {@link Role}. An
/// INSTANCE_ADMIN administers the whole self-hosted instance (tenants,
/// users, instance-wide runtimes, audit, system info) and can create
@@ -912,6 +920,7 @@ model Workspace {
/// Short key used for issue identifiers: e.g. `FRG-123`.
key String @unique
avatarUrl String?
+ experienceProfile WorkspaceExperienceProfile @default(TEAM)
/// Default cycle length (days). Overridable per cycle at create time.
cycleLengthDays Int @default(7)
/// Default rest/cooldown days between cycles (0 = back-to-back).
diff --git a/src/app/(app)/settings/workspaces/page.tsx b/src/app/(app)/settings/workspaces/page.tsx
index b5314b6d..e05c3c58 100644
--- a/src/app/(app)/settings/workspaces/page.tsx
+++ b/src/app/(app)/settings/workspaces/page.tsx
@@ -3,7 +3,7 @@ import { useMemo, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
-import { Plus, ArrowRight, AlertTriangle } from "lucide-react";
+import { Plus, ArrowRight, AlertTriangle, UserRound, UsersRound } from "lucide-react";
import { Topbar } from "@/components/topbar";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
@@ -20,8 +20,8 @@ import { workspaceColor } from "@/lib/workspace-color";
* zone) live under `/w/[slug]/settings/workspace`; this page is about
* moving *between* workspaces plus creating new ones.
*
- * NOTE: `workspace.create` today seeds only defaults + statuses. Agent C
- * will extend it with MinIO bucket seeding and broader onboarding.
+ * `workspace.create` seeds profile-aware labels and defaults. Personal
+ * workspaces intentionally skip the initial sprint.
*/
export default function WorkspacesPage() {
const router = useRouter();
@@ -210,6 +210,7 @@ function CreateDialog({
const [slug, setSlug] = useState("");
const [cycleLengthDays, setCycleLengthDays] = useState(7);
const [timeTrackingEnabled, setTimeTrackingEnabled] = useState(false);
+ const [experienceProfile, setExperienceProfile] = useState<"TEAM" | "PERSONAL">("TEAM");
const create = trpc.workspace.create.useMutation({
onSuccess: (ws) => {
@@ -227,6 +228,7 @@ function CreateDialog({
setSlug("");
setCycleLengthDays(7);
setTimeTrackingEnabled(false);
+ setExperienceProfile("TEAM");
}
function onNameChange(v: string) {
@@ -248,7 +250,9 @@ function CreateDialog({
.slice(0, 3)
.map((w) => w[0]?.toUpperCase() ?? "")
.join("");
+ const singleWord = v.replace(/[^a-zA-Z]/g, "").slice(0, 3).toUpperCase();
if (suggested.length >= 2) setKey(suggested.slice(0, 5));
+ else if (singleWord.length >= 2) setKey(singleWord);
}
}
@@ -260,10 +264,10 @@ function CreateDialog({
if (!/^[a-z0-9-]{2,48}$/.test(slug))
errs.push("Slug must be 2–48 lowercase alphanumeric chars or dashes.");
else if (existingSlugs.has(slug)) errs.push(`Slug ${slug} is already in use.`);
- if (cycleLengthDays < 1 || cycleLengthDays > 90)
+ if (experienceProfile === "TEAM" && (cycleLengthDays < 1 || cycleLengthDays > 90))
errs.push("Sprint length must be between 1 and 90 days.");
return errs;
- }, [name, key, slug, cycleLengthDays, existingKeys, existingSlugs]);
+ }, [name, key, slug, cycleLengthDays, experienceProfile, existingKeys, existingSlugs]);
return (