42 — mgmt.ctrl — Management Command Center (envisioning)
Working label
mgmt.ctrl(short form ofmanagement.ctrl; used interchangeably below). Not a user-facing commitment — revisit against Sonnance branding before any public string.Envisioning doc — needs confirmation. Governed by
00-ROADMAP.md. Created 2026-06-27 (owner-raised). The ask: a Power-BI-grade eagle-view for managers / A&R / project planners / admins / execs to read the health of the whole catalog (roster → artist → project → track → version) — status, pending approvals, release-readiness, notes, listening engagement — without drilling node-by-node — and to act on it (add / edit / delete, in bulk) from the same surface. Not a per-user-type home; the manager lens on the one dashboard (doc-20). Placement: top-nav destination (Home is being re-designed concurrently).Six decisions locked at envisioning (2026-06-27, owner):
- New doc that extends doc-38. doc-38 is the analytics engine (telemetry backbone, engagement bands, heatmap, privacy); doc-42 is the eagle-view product surface that consumes it. doc-38's role-gated "Workspace Insights" is the embryo this grows into.
- One unified surface — operational + analytical envisioned & shipped together (not phased apart). Honest dependency: analytical widgets light up only when doc-38 capture exists; operational widgets run on today's schema.
- Platform-agnostic envisioning — calm stacked cards on phone that densify into a matrix/grid on wide screens; lead platform chosen at build-slice time (respects iOS-first without forcing a dense BI grid onto a phone).
- Hero = the cross-catalog Activity Command Timeline — a live feed where every row is a navigable portal to its source with a provenance breadcrumb (doc-36 peek-then-go).
- Read and WRITE (incl. bulk) — inline-edit one record · per-row decision actions · bulk actions across a filtered/multi-select set. Wraps existing mutation endpoints; no new write semantics.
- "LEGO" configurable attributes = companion, out of scope here → future doc-43. This surface reads/writes whatever attributes exist (fixed today, configurable later), so it does not block on the attribute engine. See §8.
Lineage — this is doc-17 §5, revived
management.ctrl is not greenfield. It is the modern realization of 17-UX-ARCHITECTURE-ACTOR-DRIVEN.md §1 "The Lego OS" and §5 "Hierarchical Management Control" — a write-capable /manage route (hierarchy tree + detail panel, drill-down, edit at every level), parked there as "Phase 3+" and shelved by doc-20 for the MVP. doc-42 revives, modernizes, and supersedes doc-17 §5, reconciled with everything shipped since (roster + lenses doc-26, approval-as-a-dimension doc-32, provenance/peek-then-go doc-36, analytics doc-38, sort/filter doc-40, records/audit/status doc-41). The doc-17 conglomerate fantasy (Organization › Label › Artist) is not required: roster (doc-26) is the soft grouping facet we actually have, and management.ctrl is the synthesis layer above it.
One line: Portals (doc-26 Layer 4) are the bottom-up ingredient — one node's detail. This is the top-down synthesis of many nodes. Roster is the one hierarchy level without a portal yet; management.ctrl is effectively the roster-and-above portal, plus cross-catalog analytics and bulk action.
What triggered this
The owner wants a place to take decisions from data — to see, in one surface, "the notes pending to approve on this track," "the status of this project," "where in the timeline a comment landed and who replied," "the listening heatmap of v2 vs v1," "the health of a whole roster or a filtered selection" — without going track-by-track, artist-by-artist. The reference points are Power BI, but "even more dynamic and UX-friendly, with WOW impact" — analytical, executive, creative, and actionable: not a read-only report, but a command center you also operate from.
Relationship to the existing docs (reconciliation)
doc-42 invents no new telemetry and no new status semantics. It composes existing axes into a cross-catalog read+write surface. Boundaries:
| Doc | Relationship to management.ctrl |
|---|---|
| doc-17 §1/§5 | Origin. doc-42 revives & supersedes the "Lego OS" / /manage Management Control vision. |
| doc-38 Analytics | Engine it consumes. Events backbone, engagement bands, waveform heatmap, privacy model. doc-38's "Workspace Insights" is the embryo. |
| doc-37 Home | Sibling, not the same. Home = "what needs my attention" triage (top-N + "see all"). management.ctrl = "the whole catalog's state, cross-actor" — an eagle-view destination reached from Home, not Home itself. |
| doc-20 UI simplification | The framing law. One dashboard, role-driven content — management.ctrl is the manager/Owner/Admin lens, role-gated, not a per-user-type home. |
| doc-26 Identity/Sharing/Nav | Lenses + roster. Reuses the roster grouping + access lenses (hierarchy/role/status/tag/share-direction). |
| doc-32 / doc-29 Approval | Per-dimension approval state (audio/cover/tracklist/metadata) is what the health matrix + approvals queue read. |
| doc-33 Notes | Rolled-up unresolved notes (digest, not firehose) per node. |
| doc-36 Interaction | Provenance + peek-then-go. Every row carries roster › artist › project › track › V# and is a portal to its source. |
| doc-40 Sort/Filter/Search | The lens/filter bar scoping the eagle-view (whole workspace / one roster / one artist / a selection). |
| doc-41 Records/Audit/Status | Lifecycle statusCode, state, audit createdBy/modifiedBy are the operational columns; bulk writes stamp modifiedBy. |
| doc-43 (proposed) | Configurable "LEGO" attributes — the long-term substrate management.ctrl reads/writes. Out of scope here (§8). |
The two data dimensions — one surface
management.ctrl reads two kinds of signal and presents them as one surface. The split matters only for build feasibility, not for the user's mental model.
A. Operational — buildable on today's schema (no telemetry needed):
- Lifecycle
statusCode— Artist active/archived · Project draft/active/released/archived · Track draft/published/archived (doc-41,src/shared/lifecycle-status.ts). - Approval state per dimension —
Track.releaseStatus.{title,version,cover}, per-versionFile.reviewStatus(+ by/at),Project.tracklistStatusrelease gate (doc-32/29). - Release-readiness rollup — read-time computation: every final audio Approved + cover Approved + tracklist locked + metadata complete (doc-32).
- Notes — rolled-up unresolved/tagged counts per node (
CommentService.getUserRollup, doc-33). - Audit —
createdBy/modifiedBy/updatedAt, soft-delete stateisDeleted(doc-41). - Roster grouping (doc-26).
B. Analytical — rides the doc-38 telemetry backbone (lights up when capture ships):
- Plays · unique listeners · listen-through % · minutes · opens.
- Engagement bands — impression / sample / listen / complete → hook-rate, skip/completion-rate (doc-38).
- Most-listened-part heatmaps on the waveform; version-vs-version comparison.
- Guest/cohort breakdown (link-attributed, coarse location, opt-in identified — doc-38 privacy).
Every analytical widget is rendered with a clear "needs doc-38 telemetry" state until the backbone lands — the surface ships whole, the engagement cells fill in when the engine is wired.
The surface — hero + orbiting widgets
Platform-agnostic: on a phone these are calm stacked cards; on a wide screen they densify into a matrix / multi-pane grid. Lead platform chosen at slice time.
HERO — Activity Command Timeline (cross-catalog)
A live, filterable feed of everything happening across the catalog. Each row = what · who · when + provenance breadcrumb, and is a portal to its source (doc-36 peek-then-go: tap → expand in place → "Open in {location} →").
ACTIVITY · whole workspace ▾ [roster ▾] [artist ▾] [type ▾] [today ▾]
──────────────────────────────────────────────────────────────────────────
▲ Ben uploaded v4 audio Pop › Ava › LP1 › "Tidewater" 3m
✎ Cy requested changes · cover Urban › Cy › "Single" 1h [open]
✓ Mara approved · final mix Pop › Ava › LP1 › "Tidewater" v4 2h
◷ Tracklist submitted Pop › Ben › EP 5h [✓][✗]
♪ 3 plays from Berlin (link) Urban › Cy › "Single" v2 6h ·doc-38·
──────────────────────────────────────────────────────────────────────────Sources: domain writes (uploads/approvals/comments — already persisted) + notifications (doc-35) now; true listen events when doc-38 lands. (See §9 on the interim feed source.)
Catalog Health Matrix — "mission control"
A roster → artist → project → track grid; every cell encodes status + approval + release-readiness as colour + glyph. Scan the whole catalog's health in one glance; drill into any cell.
ROSTER ARTIST PROJECT REVIEW STATUS READY? PLAYS·doc-38
─────────────────────────────────────────────────────────────────────────
Pop Ava LP1 ●●◐○ active ▓▓▓░ 72% 1.2k ▁▂▅█▇▅▂
Pop Ben EP ●●●● released ▓▓▓▓ ✓ 4.0k ▁▂▃▂▁
Urban Cy Single ◐ draft ▓░░░ 25% 310 ▁▁▅█▇
● approved ◐ under review ○ draft/noneApprovals Command Queue — "inbox for decisions"
Cross-catalog, prioritized queue of everything awaiting a decision, with requester + age + one-tap actions. Extends today's single-user GET /mobile/dashboard pendingApprovals to the manager's full owned + collaborator + shared set.
PENDING DECISIONS · cross-catalog sort: oldest ▾
──────────────────────────────────────────────────────────
◷ Cover v3 Pop › Ava › LP1 2d [✓ approve][✗]
◷ Final mix Pop › Ben › EP › "Run" 5h [✓ approve][✗]
◷ Tracklist Urban › Cy › Single 1d [lock][✗]
──────────────────────────────────────────────────────────
☑ select all under "Pop" → [ Approve 4 ] ← bulk (see §6)Release-Readiness board
Per-project release-gate rollup (doc-32, read-time): what's blocking each project from release, across the selection. The headline managers chase to ship.
Engagement board (doc-38-gated)
Heatmaps, hook/skip rates, version-vs-version listen-through, listener cohorts. The most novel "BI wow", rendered in a needs-telemetry state until doc-38 capture ships.
Filter / lens bar
Reuses doc-26 lenses + doc-40 view-config (roster / role / status / tag / type / date), scoped to whole workspace · one roster · one artist · a saved selection. Saved Views persist server-side (doc-26); display prefs persist per-device (doc-40).
View modes & the action model — composable, open (not hooked-in)
The widgets above are not a fixed wall of panels — mgmt.ctrl is a multi-view command center with a view switcher, a scope/group control, and a contextual action model. The design intent (owner, 2026-06-27): keep the view/action set open and composable — driven by a registry, not hard-wired — so views, widgets, and actions can be added/removed/reordered (and later per-workspace configured, doc-43) without rewiring the surface. This is the LEGO ethos applied to the cockpit itself, and it does not depend on doc-43 — a static default registry ships first.
1 · View switcher (the modes). Segmented control; Timeline is the default. Each mode is the same data through a different lens:
| Mode | Question it answers | Primary widget |
|---|---|---|
| ◷ Timeline (default) | "What's happening across the catalog?" | Activity Command Timeline (hero) |
| ▦ Matrix | "What's the health of everything at a glance?" | Catalog Health Matrix |
| ☑ Queue | "What needs a decision from me / my team?" | Approvals Command Queue |
| ▤ Board | "What's blocking each project from release?" | Release-Readiness board |
| ♪ Insights (doc-38-gated) | "What's engaging listeners?" | Engagement heatmaps / cohorts |
| ★ Saved | "My pinned cross-cutting views" | any of the above + a stored lens (doc-26/40) |
2 · Scope + Group-by + Filter (shared across modes). A persistent control bar: Scope (whole workspace · roster · artist · selection), Group-by (roster · artist · project · status · owner · date), Filter/lens (doc-26/40 chips), Search (.searchable, incl. comments/notes). Changing mode keeps the active scope/filter — you re-frame the same slice, you don't lose it.
3 · Action model (three altitudes, all role-gated, doc-20).
GLOBAL (toolbar) new saved view · export · refresh · configure widgets ▸
│
ROW (per node) open ▸ (peek-then-go, doc-36) · set status · approve/reject ·
│ assign · resolve note · edit inline
│
BULK (multi-select / "select all in filter")
set status · approve · assign · archive · retag · export
→ confirmation + undo + partial-failure report (§6)4 · "Open, not hooked-in" — the composability contract. Views, widgets, and actions are declared in a registry (a list the surface renders), each entry carrying its id, the read endpoint it binds to, the actions it exposes, and the role gate. Consequences: a new widget = a new registry entry, not a refactor; a mode the workspace doesn't use can be hidden; placeholder/fixture data (see §12) plugs in at the binding layer so the whole surface is designable/testable before any /management/* endpoint exists. When doc-43 lands, the registry becomes per-workspace configurable — the same seam, no rewrite. Keep widgets decoupled (each fetches its own slice, fails independently — a dead Insights tile never blanks the Timeline).
6. It writes, too — read+write command center
management.ctrl is not read-only BI. Three write tiers, all from the eagle view, all reusing existing endpoints — doc-42 adds a batch wrapper + cross-workspace selection, not new write semantics:
| Tier | What | Reuses |
|---|---|---|
| a. Inline edit | Rename, set lifecycle status, edit metadata on one record without leaving the surface | status/metadata PUTs |
| b. Per-row decision | Approve / reject a version, lock tracklist, resolve a note | PATCH /track/:id/release-status, per-file PATCH /track/:trackId/file/:fileId/review-status, comment resolve |
| c. Bulk action | Set status / approve / assign / archive / retag across a multi-select or filtered set | a new batch wrapper that fans out to the above |
Guardrails (must be in the doc): role-gated per node (a bulk op silently skips nodes the actor can't write — doc-20 cascade); every write stamps modifiedBy (doc-41); confirmation + undo for destructive bulk ops (archive/delete); partial-failure reporting ("approved 11 of 14; 3 skipped — no permission"). Bulk = orchestration over per-node permission checks, never a permission bypass.
7. Actors & use cases
Role-gated per doc-20 (one dashboard, role-driven). management.ctrl is the manager lens — surfaced to Owner/Admin (and manager-shaped collaborators); Editors/Viewers see Home, not this.
| Actor | Comes for | Lands on |
|---|---|---|
| Manager / label ops | Whole-roster health, what's blocking release, who's behind | Health Matrix + Release-Readiness |
| A&R | Which projects/tracks engage listeners; signal to act on | Engagement board + Activity |
| Admin / coordinator | Clear the approvals backlog, bulk-advance status | Approvals Queue + bulk actions |
| Exec | One-glance portfolio state; data for decisions | Health Matrix (rolled to roster level) |
| Creative director | Cover/art approvals across releases | Approvals Queue (cover dimension) |
Higher altitude shows less, louder (digest, not firehose — doc-33 principle).
8. Companion — the "LEGO" configurable-attribute model (out of scope here → doc-43)
The owner's "LEGO software" idea: entities carry different attribute sets; the same attribute can live at different hierarchy levels per workspace; catalogs are per-workspace definable — and management.ctrl manages not just the data but, eventually, which attributes exist where. This is the right long-term substrate for a command center (Airtable/Dataverse-style composability).
Finding — it is net-new, with no foundation today:
- All schemas are fixed
@Prop;src/main.tsforbidNonWhitelisted: trueactively rejects unknown fields on write. - Only seeds: an unused
File.metadata: any(file.schema.ts:68) and freeformtags[]. - The lifecycle catalog is hard-coded with a deferral note: "a per-workspace custom catalog is a deferred layer" (
lifecycle-status.ts:6). - Already the deferred customization layer across doc-17 (Lego OS), doc-20 §4 (templates/saved views/theming), doc-41 (per-workspace status catalog), doc-31 (customization ≈ future premium / monetization-deferred).
Posture: management.ctrl is designed to consume whatever attribute model exists — fixed defaults today, a configurable catalog later — so it does not block on this. The configurable-attribute engine (attribute definitions, per-workspace catalogs, attribute-at-any-level, the validation rework around forbidNonWhitelisted, and migration) is its own concern — now specified in 43-CONFIGURABLE-ATTRIBUTES.md (authored 2026-06-27: typed attributes bag + per-workspace AttributeDefinition catalog · global presets + workspace override · quick-add here + full Workspace Settings editor). When it lands, the mgmt.ctrl view/widget/action registry becomes per-workspace configurable through the same seam — no surface rewrite.
9. Backend implications (the real net-new work — name, don't build)
- No cross-workspace aggregation exists today. Queries are per-resource; the only aggregate is
GET /mobile/dashboard(mobile.service.ts), and only for one user's own tracks. management.ctrl needs cross-roster/artist/project aggregation endpoints — e.g.GET /management/overview,/management/matrix,/management/approvals,/management/activity— composing existing services (ArtistSpaceService.getDistinctRosters,TrackService.findAllByUser,CommentService.getUserRollup, theMobileServicepending-approvals logic atmobile.service.ts:87–130) over the caller's full owned + collaborator + shared set. - Bulk-write endpoint — a batch wrapper (e.g.
PATCH /management/bulk) that fans out to existing per-node mutations with per-node role checks + partial-failure results. No new write semantics. - Activity Timeline needs an event log. Today only
createdBy/modifiedByaudit fields + the notification stream exist. Interim: derive the feed from notifications + audit timestamps. Proper: the doc-38 events backbone becomes the activity SoT once it lands (this is the hero's hard dependency — see §Sequencing). - Engagement widgets ⇒ doc-38
Eventstore +GET /track/:id/insights+GET /analytics/workspace. - Scale lever (doc-14): aggregate-on-read first; materialized rollups only if the matrix/timeline queries get slow at volume.
10. Privacy & calm posture
Inherits doc-38 wholesale: aggregate-by-default, identified visibility opt-in + role-gated via the Teams/Role model, guest plays attributed to the share link with coarse city/country (derived location, not raw IP — GDPR), raw events TTL'd. Framed per doc-31 professional calm / no-surveillance — this is a decision-support cockpit, not a monitoring tool. Higher altitude = digest, not firehose (doc-33).
11. Decisions resolved (2026-06-27, owner) + remaining
Resolved this round:
- Naming — working label is
mgmt.ctrl(short form ofmanagement.ctrl) "for now." Not a user-facing commitment yet; revisit against Sonnance branding before any public string. - Placement — top-nav destination for now. Home is being re-designed concurrently, so the eventual Home→
mgmt.ctrlentry point (pulse line / drawer) is settled when that redesign lands; until then it stands on its own in top-nav. - View/action model — owner deferred to recommendation: build it open/composable (view + widget + action registry, decoupled widgets) rather than a fixed panel wall — see §"View modes & the action model." Default mode = Timeline.
- Interim data — placeholder/fixture data first. Design and test the whole surface against mock
/management/*responses now (plugged in at the registry binding layer), so UI work proceeds ahead of the real aggregation + doc-38 telemetry. The interim real activity feed (notifications + audit) and the doc-38 event log swap in behind the same bindings later.
Remaining / to confirm:
- MVP mode subset — if "one surface" is too large to ship atomically, the minimum-lovable centre is Timeline + Queue (both buildable pre-telemetry). Confirm at slice time.
- doc-43 greenlight — the LEGO configurable-attribute model is not clearly specified by current docs (scattered/deferred across doc-17/20/41/31, no engine designed), so a dedicated
43-CONFIGURABLE-ATTRIBUTES.mdis warranted. Owner's "makes sense if not clear" → greenlit; author it as the next envisioning (separate task, does not blockmgmt.ctrl).
12. Sequencing
Placeholder-data-first. The surface is built and tested against fixture data at the registry binding layer, so design/UX proceeds immediately — independent of backend readiness. Real data swaps in behind the same bindings, per widget, as it lands.
The fully-live surface slots after the active doc-37 (Home redesign) + the standing first-byte perf priority + the doc-38 telemetry backbone (consistent with the roadmap). Operational read+write widgets could go live before telemetry, but the owner chose one unified surface, so the doc-38 engine gates the fully-live release (engagement cells render in a needs-telemetry state until then). doc-43 (LEGO attributes) is independent / parallel — mgmt.ctrl does not wait on it; when it lands, the view/widget/action registry becomes per-workspace configurable through the same seam.
13. iOS MVP slice — requirements (locked 2026-06-27, owner)
The first built mgmt.ctrl surface. iOS is the priority; web is deferred to a phase after the iOS MVP. Backend is complete (Activity · Approvals · Overview · Matrix · Board · Insights + bulk).
- Placement & gating: a native SwiftUI screen reached from the avatar drawer as a new
AppSection.mgmtCtrl("management.ctrl"), role-gated to Owner/Admin via the dashboarduserRole→ the drawer'sallowedSections. A separate screen from Home (Home stays the personal "what needs my attention"; this is the cross-catalog manager lens). - Views (4 of 6 this slice): an Overview KPI header (always on top) + a segmented switcher over Timeline · Queue · Board. Matrix (dense roster→track grid, not phone-native) and Insights (heatmaps, needs accumulated telemetry) are deferred to a later iOS slice.
- Overview ←
GET /management/overview→ KPI tiles (artists · projects · tracks · pending · ready · notes). - Timeline ←
GET /management/activity→ calm rows (what · who · when + provenance breadcrumb); tap → open the source track (peek-then-go, doc-36). - Queue ←
GET /management/approvals→ rows (dimensions + requestedBy + age). - Board ←
GET /management/board→ per-project readiness cards (ready? + audio/cover/tracklist), most-blocked first.
- Overview ←
- Actions: per-row approve / request-changes from the Queue (
PATCH /track/:id/release-status, already owner/admin-gated) + multi-select bulk (PATCH /management/bulk) with a bulk action bar; partial-failure surfaced (succeeded / skipped / failed). - Data & form: live
/management/*viaAPIClient;LoadState(loading/empty/error) + pull-to- refresh; calm cards on the phone, composed only fromDesignSystem(TrackRow · SectionHeader · StatusPill · LifecycleStatusPill · ApproveBar · ScreenBackground ·.snCard· Tokens). NewDecodablemodels mirror the backend shapes (nonisolated struct … Sendable). - Bulk RBAC prerequisite (decided): bulk's per-node
can()only needs the resolver to know the caller's role — it does not require flipping the globalPERMISSION_ENFORCE. To make it correct for all resources (incl. ones created after a backfill),PermissionServicegains a grant-or-legacy fallback (grant first, else the resource'sowner/collaborators). Hazard flagged: flipping global enforce before write-paths create grants would 403 new resources — the fallback removes that hazard, so backfill + enforce flip stay optional hardening, not a blocker. - Out of this slice: Matrix grid, Insights heatmap UI, web (post-iOS-MVP), bulk write-path grant creation (the fallback covers the transition).
§13 follow-ups (noted 2026-06-27, owner — after first live run)
- Richer activity provenance — created / updated / deleted with who · what · when. The interim
/management/activity(notifications + one coarsetrack:updatedper track, actor name often missing) is too thin. Fix = granular domain events through the doc-38 event store ("action events" — create / update / delete on Artist/Project/Track/File/Comment), resolving the actor name and the what (field/dimension changed), grounded in doc-41createdBy/modifiedBy/timestamps. Upgrades the hero feed from a digest to a true audit timeline. - Filter · search · order-by on every view (doc-40). mgmt.ctrl needs the per-view view-config — filter (roster / artist / status / date / who), sort (recently updated, oldest pending, plays), and search — applied across Timeline / Queue / Board (and Matrix). Reuse the doc-40
LensBarmodel.
Status: envisioning + ▶ iOS MVP slice building (2026-06-27). Backend complete; iOS Overview + Timeline + Queue + Board with per-row + bulk actions is the active build (§13). doc-43 recommended, not yet authored.