Version. v0.1 · Date. 2026-06-27 · Branch. loomworks feat-companion-surface.
Against. loomworks-companion-build-spec-v0_1.md §"ACROSS-ENGAGEMENTS HOME" + mockups …-home-desktop-… (3) and …-home-mobile-… (4), read as a spec.
Replaces. the prior three-column engagement-navigation list (Personal/Workspaces/Cross-cutting + "All engagements" table).
Verification. Vitest 378 / 74 files green (8 new home tests incl. relativeTime + nav-loop round trip) + live tunnel render at loomworks-dev.dunin7.com/operator/engagement-navigation (desktop + mobile) with the real Operator's 8 engagements (Needs-you badge = 9, real per-engagement attention).
Legend: ✅ CONFORMS · ◐ CONFORMS w/ honest real-data fill · ⚠ DEVIATION (reason)
| # | Element / behavior | Status | Note |
|---|---|---|---|
| H1 | Header: "Loomworks" + Operator name + avatar right | ✅ | Live: "Loomworks · Marvin Percival · MP". "Loomworks" is also the nav-loop home link (see HL). |
| H2 | Lens tabs: My engagements (active) · Needs you {n} (warning badge) · Recent | ✅ | Live badge = 9 (real needs_you count). Active = bordered pill. |
| H3 | Voice-hint line | ✅ | "“open a project” · “what needs me”" (generic, not the mockup's example names). |
| H4 | Your space zone — Personal card (info-blue left border, P avatar, "Personal 0 · E0030", caption) | ◐ | Real. The mockup's "N things known" count is omitted — the personal engagement's assertions endpoint 422s; honest-omit rather than fake. |
| H5 | Your engagements zone — ecards: per-Operator number (mono, right-aligned, min-w) + name + E#### + state chip | ✅ | Live: 7·Goosey·E0007·"6 waiting", 14·Houseplant·"3 waiting", others "Up to date". |
| H6 | State chip: warning-bg if attention, secondary-bg if quiet | ◐ | Derived from needs_you counts: ">N waiting" (warning) / "Up to date" (secondary). The mockup's "quiet 12 days" staleness isn't available (no last-activity timestamp). |
| H7 | Shared zone — Loomworks commons card (L avatar) | ◐ | Identified by title === BRAND.productName (no visibility field on /engagements); member count omitted (no endpoint). See DEV-H1. |
| H8 | Administrative (E0001) deliberately absent | ✅ | Hidden by display_identifier. |
| H9 | Needs you view — warning dot + what + eng·E#### + action button | ✅ | Action = "Open ↗"; click opens that engagement (unified open). |
| H10 | Recent view — success check + what + eng + when | ✅ | "when" via relativeTime (2h ago / yesterday / N days ago). |
| H11 | Lens tab click switches the view | ✅ | Tested + live. |
| H12 | Engagement card click = unified open (navigate + set focus) | ✅ | setFocus({engagementId}) + router.push(/operator/engagement/{E####}). |
| # | Element / behavior | Status | Note |
|---|---|---|---|
| M1 | Personal pinned ABOVE the swipe plane (always visible) | ✅ | Rendered shrink-0 above the lens nav. |
| M2 | Lens name + dots + chevrons | ✅ | Active dot wider/info. |
| M3 | Swipe between lenses (\|dx\|>50 && \|dx\|>\|dy\|) | ✅ | Same touchend rule as the in-engagement room swipe; tested. |
| M4 | Scroll = move within the lens list | ✅ | Stack is the only overflow-y-auto region. |
| M5 | Anchored bottom bar with mic (never scrolls) | ✅ | shrink-0 sibling; mic info-blue → iron-oxide on listening (see DEV-H4). |
| Requirement | Status | |---|---| | Identity number + name + E####, never UUID | ✅ (asserted: no UUID in DOM) | | Only-show-what's-available | ✅ (Admin hidden; no faked member/things-known counts) | | Responsive on WIDTH | ✅ (verified 1280 + 390) | | Template-clean (tokens; strings registry; type scale) | ✅ | | Companion is the entity; AI invisible | ✅ |
| # | Item | Status |
|---|---|---|
| HL | In-engagement "Loomworks" header text → home | ✅ link to /operator/engagement-navigation |
| HX | In-engagement focus-chip × → home | ✅ (navigates; does not clear focus — "close" stays an explicit spoken act) |
| HM | Mobile in-engagement ‹ back chevron → home | ✅ |
| — | Round trip home → open → back | ✅ verified live (home → E0007 → Loomworks/× → home) |
/engagements carries no visibility field, so the commons is identified by title === BRAND.productName (single white-label-keyed predicate). A real visibility='automatic' signal (engine projection) would replace it; if no engagement matches, Shared is empty and that engagement stays under Your engagements (graceful). Queued.--danger); kept consistent with the in-engagement surface, per that surface's stated behaviour.DUNIN7 — Done In Seven LLC — Miami, Florida Companion across-engagements home — conformance checklist — v0_1 — 2026-06-27