49 — The Portal System — one fractal, clean anatomy at every altitude (envisioning)
Envisioning / redesign doc. Governed by
00-ROADMAP.md— defer to it on conflict. Created 2026-06-29 (owner-raised: "in Project I saw Portals so complex and so messy it looks like it requires a re-design… and I don't see it in Workspace/Roster, Artist, Track, Configure"). The two observations are one root cause: there is no Portal system — each portal is a bespoke, hand-stacked file, and the fractal principle locked in [doc-47 §6] ("one Portal grammar at every altitude") was never built.2 decisions locked with the owner (2026-06-29):
- Envision the Portal System first (this doc), then build.
- Full ladder incl. the Workspace root — Workspace ("cloud root space") → Artist → Project → Track → File all share one clean Portal shell.
Reconciled by [doc-50] (2026-06-29): the app's center of gravity is now action-first — Portals are the substrate you land on when you act, not the daily entry. This redesign stays valuable (a calm, fractal substrate) but sequences after the action-first Home leads (doc-50 §6).
Needs confirmation (§9 open questions).
1. The problem — audit of today's portals (verified)
Portalis just a container.DesignSystem/Components/Portal.swift= a.sheet(medium/large detents, Liquid-Glass) wrapping aScrollView { VStack(spacing: lg) { content } }. It imposes no anatomy — whatever sections the caller stacks, in whatever order, is the portal.- The Project Portal flat-stacks ~11 heterogeneous sections (
ProjectPortalContent.swift): header · release-readiness headline · workflow pipeline · metadata · album art · tracklist · team · share · team-share · notes · my-tag · delete. No grouping, no hierarchy, no progressive disclosure → the "messy, complex" feel. Every feature we shipped bolted another section on. - Sections are hand-duplicated across entities.
ArtistPortalContentandProjectPortalContenteach re-implement image / notes / team / team-share / share / my-tag / delete. Shared bits (PortalTeamSection,PortalShareSection,PortalNotesSection,PortalTeamShareSection) exist but the composition is copy-pasted per file. - Coverage is partial.
Track has no Portal(correction 2026-06-30: Track does have a Portal —Features/Review/TrackPortalContent.swift, reached from the player; the audit missed it by surveying onlyBrowse/. It was the same flat wall and is now zoned, slice 3.) Workspace and Roster have none. - The fractal is on paper only. [doc-47 §6] decided "one grammar at every altitude"; the codebase has bespoke per-entity portals instead. This doc makes the principle real.
2. Diagnosis
Two symptoms, one cause: there is no designed Portal anatomy and no shared composition. Fixing it once — a clean, ordered set of zones that every Portal renders (filling in only what applies), built from shared zone components instead of bespoke files — fixes the mess and the missing-altitudes gap together.
3. The Portal anatomy (the fix)
Every Portal, at every altitude, is the same ordered set of zones. A zone renders only if the node has content for it. Calm by default (doc-47 §7): each zone is a summary that expands; rarely-used actions go to an overflow menu.
| # | Zone | What it is | Progressive disclosure |
|---|---|---|---|
| 1 | Identity | name · type · key art · status/health pill · provenance breadcrumb (doc-36) | always shown, compact |
| 2 | Health | the at-a-glance: release-readiness / lifecycle / counts | summary chip → expand for the breakdown |
| 3 | Content | the node's reason for being (varies by altitude — §4) | the primary, always-expanded zone |
| 4 | Workflow / Config | the doc-48 process for this node: pipeline · inherited-vs-custom · level-appropriate config (incl. doc-43 attributes later) | summary line → expand pipeline |
| 5 | Relationships | team · sharing · cross-links / variants (doc-28) · membership | collapsed groups |
| 6 | Notes | node-anchored annotations (doc-33) | summary count → expand |
| 7 | Personal | my-tag, my view prefs | collapsed |
| 8 | Manage | edit · lifecycle · danger/delete | tucked at the bottom / overflow |
This turns the Project Portal's 11 flat sections into ~8 predictable zones, most collapsed — the same mental model on every screen.
4. The fractal — what each altitude's Content zone holds
Zones 1–2 and 4–8 are constant; only Content (zone 3) changes by altitude. That's what makes it a fractal and not eight different screens.
| Altitude | Content zone | Notes |
|---|---|---|
| Workspace (root / "cloud space") | studio identity · studio defaults (workflow — doc-48; attributes later) · roster overview (the lens) · asset cloud (doc-45) · members | NEW — top of the ladder; the "cloud root space" the owner sensed. Entry from Configure / a Workspace affordance |
| Artist | the artist's projects · roster tag · (future) artist-level workflow default override (doc-48 rung 2) | exists; re-home onto the shell |
| Project | tracklist · release-readiness + workflow pipeline (inherited/custom) · album art | exists — the redesign reference (worst offender) |
| Track | versions / player · per-track readiness steps · variants & cross-links (doc-28) · attachments | NEW as a Portal (today it's the PlayerView) |
| File | the asset · review status (doc-29) · metadata | later phase |
Roster vs Workspace (resolves the owner's conflation, per doc-48): Roster is a tag/lens, not a container — it has no Portal of its own; it appears as a grouping inside the Workspace Portal and as a Browse lens. Workspace is the tenant root — that gets the root Portal ("cloud space").
5. Composition — how this kills the mess structurally
One shared PortalScaffold renders zones 1–8 in order; each entity supplies a small content builder per zone (most reused verbatim — team, share, notes, my-tag, danger are already shared components). No more bespoke per-entity portal files duplicating sections. Adding a new altitude = supply its Content zone; everything else is inherited. This is the doc-47 §6 "one grammar" made literal in code, and it's what stops the next feature from "bolting on another section."
6. The Project Portal redesign (reference implementation)
Map today → the anatomy (grouping + disclosure, nothing lost):
| Today (flat) | New zone |
|---|---|
| header | Identity |
| release-readiness headline | Health (summary) |
| tracklist · album art | Content |
| workflow pipeline · readiness items | Workflow/Config (summary → expand) |
| team · share · team-share | Relationships (collapsed groups) |
| notes | Notes |
| my-tag | Personal |
| metadata · edit · delete | Manage (tucked) |
Eleven stacked sections → eight predictable zones, most collapsed. Same data, calm surface.
7. Open questions (confirm before building)
- Sheet vs full-screen. Today Portal is a
.sheet(medium/large). A Workspace/root portal with an asset cloud may want full-screen / its own tab. Mixed? (Lean: keep node portals as sheets; Workspace root is a destination in Configure or its own surface.) - Where does the Workspace Portal live? A Configure entry ("Workspace")? A dedicated affordance? (ties to doc-47 account-corner vs Configure split.)
- Track: Portal vs keep PlayerView. Add a Track Portal alongside the player, or fold the player into the Track Portal's Content zone? (Lean: Track Portal whose Content embeds the player.)
- How aggressive is progressive disclosure — default-collapsed everything but Content, or keep Health+Workflow expanded? (Owner taste.)
Resolved by doc-54 (2026-07-04) — start almost empty (doc-47 §7 principle 7): Identity + Content expanded; Health + Workflow collapse to one-line summary chips; everything else collapsed; and a zone with no content doesn't render at all (mirror of doc-37 §2.1) — a single "+" affordance at the Portal foot offers the unfilled zones instead.
- File-level Portal — in this pass or deferred?
8. Sequencing (after confirmation)
- Confirm the anatomy + §7 forks (this doc).
Build the zone primitive✅PortalZoneBUILT 2026-06-30 (xcodebuildgreen) — collapsible, progressive-disclosure zone (DesignSystem/Components/PortalZone.swift).Re-group the Project Portal✅ slice 1 done 2026-06-30 — primary zones (Identity · Health · Content · Workflow) visible, secondary (Team & sharing · Notes · My tag · Manage) collapsed. The 11-section wall → ~5 visible + tidy collapsed groups. (Full zone-header normalization of the remaining self-headed sections + extracting the shared zone components = follow-up.)Roll the shell to Artist + Track✅ Artist (slice 2) + Track (slice 3) done 2026-06-30 — both re-grouped ontoPortalZone; the Track Portal already existed (inReview/, notBrowse/— audit miss, §1 corrected). Slice 3 also surfaced doc-28 variant chips (variantType + cross-links + appearances) — the long-standing iOS gap. Project · Artist · Track now share the anatomy.Build the Workspace root Portal✅ slice 4 done 2026-06-30 (xcodebuildgreen) —WorkspacePortalView(Configure ▸ Workspace, Soon→live): Identity · Portfolio KPIs · Studio defaults (doc-48) · Roster overview. Composes existing reads (overview/workspace/templates/matrix). THE FRACTAL IS COMPLETE — Workspace → Artist → Project → Track all share the zone anatomy. (Asset cloud / doc-45 deferred.)File Portal✅ slice 5 done 2026-06-30 (xcodebuildgreen) —FilePortalContent(leaf altitude): Identity · Asset (image preview + metadata) · Review (doc-29, read-only) · Notes (.file). Entry = long-press a version in the player's version switcher. ALL FIVE ALTITUDES NOW SHARE THE ANATOMY (Workspace → Artist → Project → Track → File). Remaining: full zone-header normalization + extract shared zone components · more discoverable File-Portal entry · doc-28 variant authoring · asset cloud (doc-45).
This is UI-layer work over mostly existing endpoints (workspace, project, track, workflow, comments, collaboration); net-new backend is small (Workspace asset cloud ties to doc-45, deferred). It directly "achieves success": the messy Project Portal becomes calm, and the fractal finally exists end-to-end.
9. Cross-references
- Fractal principle + three zones:
47-PRODUCT-NORTH-STAR.md§6 - Config per altitude (Workspace default, inherited/custom):
48-CONFIG-ACROSS-HIERARCHY.md - Workflow pipeline in the Workflow/Config zone:
46-WORKFLOW-ENGINE.md - Asset "cloud" / motion covers (Workspace + Project Content):
45-RELEASE-PIPELINE-ASSETS.md - Identity / Roster-as-lens / Roster-Portal thread + provenance:
26-IDENTITY-SHARING-NAVIGATION.md·36-INTERACTION-PATTERNS.md - Variants/cross-links (Track Content):
28-RECORDINGS-VARIANTS-RELEASES.md - Notes zone:
33-NOTES-ANNOTATIONS.md· File review (File Content):29-VERSION-SCOPED-APPROVAL.md - Workspace tenant container:
44-RBAC-TEAMS-PERMISSIONS.md· Design system:22-IOS-DESIGN-SYSTEM.md