Clean successor to V3 (forge: lilith/atlilith). Seeded from local Mac working tree at ~/Code/@projects/@cocottetech/. node_modules and build artifacts excluded via .gitignore. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
18 KiB
AC — Second-member onboarding (Demimonde admin invites)
Goal
Get a second human into an existing org — invited by an admin (Quinn-as-Demimonde-admin) rather than walking in cold — from invitation to a working CocotteAI seat in under 5 minutes, with the org's context, templates, and shared scaffolding pre-filling everything the new member would otherwise have to discover. The defining contrast: D is the cold first-run for a stranger (the org doesn't exist yet); Y is a cross-org stranger discovering Demimonde on the open marketplace; AC is the warm path — admin already trusts the invitee, the org already exists, and most of the persona-seed work has been done at the org level and merely needs to be inherited, distinguished, and where appropriate overridden.
Designer skim
- Headline UX: Admin pulls up the W3 roster drawer → "Invite" → role picker (Member / Viewer) → composer for email + optional iMessage (routed through Demimonde-owned channel, never the admin's personal number). Invitee receives a warm splash that names the org and the admin, taps through SSO device-link (same component as D1), then lands in a pre-filled persona-seed interview where org-template defaults occupy the chip slots and the composer. Invitee can accept-as-is, edit, or fully override. Voice register working throughout (operational, not cold-stranger hearth); the splash gets one slightly warmer line for first-impression.
- Key invariant vs D: persona is not blank. Org has already established voice register, off-limits, surface roster, autonomy posture. Invitee inherits these as defaults, sees them visually distinguished from anything they personalize, and can opt into copying admin's curated content / contacts / blocklist for a first-week scaffold.
- Pair-with:
persona-seed-interview.screen.md(the underlying screen, in pre-filled mode);D-onboarding.brief.md(cold counterpart);W-org-overlay.brief.md§W3 roster, §W2 mixed-scope, §W5 voice shift. - Blocking Qs: AC-Q1 default role, AC-Q2 invite expiry default.
Constraints
- Org context exists before invitee opens the app. Demimonde's persona, off-limits, surface roster, content guidelines, and admin-curated blocklist are already in
platform.dbwithorg_id=demimonde. The invitee's first session reads these as inherited templates, not as a blank slate. - Persona-seed is pre-filled with org-template defaults. Every D-screen question lands with org-derived values in the chips and composer. Invitee taps Continue to accept, edits to refine, or clears to override entirely.
- Org-shared facets vs personal facets are visually distinguished. Org-inherited values render with a small
orgtag-glyph + a slightly muted background tint (per W4's subtle background-material shift). Anything the invitee writes themselves loses the tag and reads as personal. - Invite delivery uses Demimonde-routed channels only — never the admin's personal Proton, personal iMessage, or personal handle. Email comes from
invites@demimonde.cocotte.maison; iMessage (if enabled) comes from the Demimonde mac-sync queue per~/Code/@applications/@mac-sync/. This keeps the admin's identity boundary clean (per W9 privacy invariants). - Default role is decided at invite time, not at signup. Admin picks Member or Viewer; invitee cannot upgrade themselves. (See AC-Q1.)
- SSO device-link reuses D1 unchanged. The auth flow is auth-provider-agnostic; what differs is what loads after device-link.
- First-time mixed-scope explainer fires once per invitee, the first time Quinn-2 sees a context chip with both personal and org options (per W §W2).
- Admin notifications routed through brief C — the admin gets a working-register receipt when invitee completes onboarding; this is a normal
agent_actionsrow, audit-visible.
States to design
- AC1a — Roster drawer, admin's "Invite" affordance (idle).
- AC1b — Role picker sheet (Member / Viewer + role description).
- AC1c — Invite composer (recipient email, optional iMessage toggle, optional personal note from admin).
- AC1d — Invite-sent confirmation; pending-invites strip in roster drawer.
- AC2a — Invitee's email inbox preview (the wild-copy of the invitation message).
- AC2b — Optional iMessage preview (Demimonde-routed channel).
- AC2c — Invitee splash (warm hearth-leaning; names admin + org).
- AC3 — SSO device-link (reuses D1 states; no new design).
- AC4a — Pre-filled persona-seed Q1 (voice register chip pre-selected from org template, with
orgglyph). - AC4b — Pre-filled persona-seed Q2 (off-limits inherited from org; "Add your own" affordance below inherited rows).
- AC4c — Pre-filled persona-seed Q3–Q6 (surface roster, autonomy posture, quiet hours — all org-derived).
- AC4d — Override gesture (long-press an org-tagged row → "Make personal" → tag drops, row becomes editable).
- AC4e — Persona summary review (org-inherited vs personal items rendered in two grouped sections).
- AC5 — First-time mixed-scope explainer card (one-shot; dismisses on tap-acknowledge).
- AC6a — Admin's "first member completed onboarding" notification (working register).
- AC6b — Admin's audit-shadow view of invitee's first vigil (read-only, scoped to org-shared work per W7 admin audit).
- AC7a — First-week scaffolding offer (admin-side: "Share your curated content / contacts / blocklist with new member?").
- AC7b — Invitee-side acceptance of admin's scaffold (each scaffold-type independently toggleable).
- AC7c — Drift indicator (subtle, in audit drawer) — shows when invitee's persona has drifted from the org template enough to no longer count as "inherited".
- AC error states — invite expired · invitee already has CocotteAI account under different SSO · admin removed role mid-onboarding · org membership cap hit.
AC1 — Admin sends invite
Reached from Settings → S1 → Demimonde row → Org roster (W3) → Invite + button.
Role picker sheet:
Invite to Demimonde
Role
● Member
Own work + org-shared work. Cannot see other
members' personal work. Can act on shared
prospects, drafts, surfaces.
○ Viewer
Read-only on org-shared work. Useful for
contractors, accountants, oversight.
(Admin requires admin to set — not selectable here.)
Composer:
- Recipient email (required).
- iMessage toggle — "Also send via iMessage (Demimonde channel)" with hint "Sent from invites@demimonde, not your personal number."
- Optional admin note — free text, ~280 chars, woven into the wild-copy invitation.
- Send button → emits
agent_actionsrowaction_type='org_invite_sent', scopeorg_id=demimonde.
After send, the row lands in a Pending invites strip at the top of the roster drawer with status (sent · opened · linked · completed · expired). Admin can revoke from this strip.
AC2 — Invitee receives invite
Email arrives from invites@demimonde.cocotte.maison. Optional iMessage arrives from the Demimonde-routed channel via mac-sync's send-queue. Both include the same one-time link.
Tapping the link opens CocotteAI on a phone that has the app (App Store deep-link if not). Splash is warmer than D's splash — names the admin and the org explicitly, because the invitee already trusts both.
AC3 — Invitee SSO device-link
Identical to D1. QR / code → trusted-device scan → JWT → Keychain. The only difference is that on link-success, the user record is created with an existing org_memberships row (role from AC1, status pending_seed). No additional invitee action.
AC4 — Modified persona-seed (the key difference from D)
Same screen as persona-seed-interview.screen.md, same 8 questions, same chip + composer layout — but every question lands with org-template values pre-selected and visually tagged.
Pre-fill behavior per question:
| # | Question | Pre-fill source | Override path |
|---|---|---|---|
| 1 | Voice register | Org's personas.voice_register template |
Long-press chip → Make personal → edit |
| 2 | Off-limits phrases | Org's safety_blocklist entries (org-scoped only) |
Add personal rows below the org rows; cannot delete org rows |
| 3 | Brands operated | Org-managed surfaces appear pre-checked + tagged; invitee adds personal surfaces alongside | Tap an org-tagged surface → see "managed by Demimonde" detail; cannot uncheck |
| 4 | Tours / travel posture | Org's tours.config default lead-times |
Override per-personal-trip; org defaults remain for org-organized tours |
| 5 | Autonomy comfort | Org's per-specialist policy rows |
Invitee dials their own initial threshold, but it cannot exceed org cap (admin sets ceiling) |
| 6 | Quiet hours | None inherited (always personal) | Invitee answers from scratch — this is a personal-only setting |
| 7 | Coop membership | Org's coop participation status shown as context (read-only); invitee not auto-enrolled at personal level | Personal-coop opt-in is a separate personal decision |
| 8 | Anything else | None inherited | Free-text personal seed only |
Visual distinction: org-tagged rows render with a 12pt org glyph at row-leading + a 4% background tint of --surface-org-overlay. Personal rows render at default --surface-base. The persona drawer (B5) inherits the same two-tier rendering post-onboarding.
Override gesture: long-press any org-tagged row → action sheet with "Make personal" (drops tag, row becomes editable) and "Why is this org-managed?" (opens an explainer sheet showing which admin set it + when). Q2 off-limits is a special case — invitee can add personal entries but cannot remove org-enforced ones (per K's hard-edge guarantee).
Summary review (AC4e): rather than D's flat summary, AC4e splits into two stacked sections:
Inherited from Demimonde
· Voice: editorial · slightly literary
· Off-limits: 4 phrases · 2 topics
· Surfaces: OF, X, Tryst (org-managed)
· Tour lead-time: 14 days minimum
Personal additions
· Off-limits: 1 phrase (you added)
· Surfaces: IG (your handle)
· Quiet hours: 11pm – 8am
Save → writes personas row with inherited_from_org=true flag, plus standard agent_actions row.
AC5 — First-time mixed-scope explainer
First time the invitee sees the context chip on chat-home post-onboarding, a one-shot card slides in:
Two contexts, one app. Personal is your work — your journal, your persona, your prospects. Demimonde is the org's work — shared content, shared prospects, org-wide audit. Tap the chip up top any time. Cocotte shifts her voice slightly when you're in org mode so you'll hear the switch, not just see it.
Dismissable; logged once per user so it doesn't repeat. Per W §W2.
AC6 — Admin approval / completion confirmation
When invitee finishes AC4e save:
- Admin receives a push (working register) per brief C: "Quinn-2 finished setting up in Demimonde. Roster updated."
- Admin's audit drawer (brief I, scoped to
org_id=demimonde) gets theorg_invite_completedrow. - Admin can tap the row → lands in roster drawer, pending-invites strip is gone, invitee is now in the active-members list with role + last-active.
- Admin can opt to see invitee's first vigil (read-only on org-shared work per W9) from a "View first vigil" affordance on the just-completed row.
No admin approval gate is required to complete onboarding — admin's act of inviting is the approval. (See AC-Q3 for whether admin can preview the persona mid-seed.)
AC7 — First-week scaffolding
After AC6, admin gets a one-time follow-up card:
Demimonde scaffolding — want to share your curated content / contacts / blocklist with Quinn-2's first week? She can copy and drift, or skip.
Three independent toggles:
- Content — admin's recent approved drafts, posting cadence, asset library refs (read-only references; she can copy into her own).
- Contacts — admin's prospects flagged as org-shareable (per W6 cross-context handoff semantics; admin picks which).
- Blocklist — admin's personal blocklist offered as a starting set; invitee accepts per-row.
On invitee side, each accepted scaffold-type seeds her workspace with copies, not references — she can drift freely. Audit row records what was copied and when, so drift is observable (AC7c).
In-the-wild copy
Invitation email (working register, slightly warm — first impression of the org, not the brand):
Subject: Quinn invited you to Demimonde
Demimonde is the back-office where your work gets tended to. Quinn set you up as a Member — own work, org-shared work, room to drift. The phone link below opens CocotteAI on your device and finishes the setup in about five minutes.
Open CocotteAI →
One-time link. Expires in 7 days. Sent on behalf of Demimonde, not from Quinn's personal address.
Invitation iMessage (working, compact):
Demimonde invite from Quinn. Open CocotteAI: [link]. Expires in 7 days.
Invitee splash (hearth, dialed slightly warmer — strongest first-impression moment):
Welcome. Quinn set the kitchen up for you. Sign in to finish — Demimonde's already in good order, you just need a seat.
Persona-seed Q1 opener (working — invitee is reviewing, not creating from scratch):
Demimonde already has a house voice — editorial, slightly literary. Keep it for yours, or set your own underneath.
Override prompt (working — long-press → Make personal):
Make this personal? Demimonde's value stays in the org; yours becomes the override Cocotte uses when she's writing as you.
Persona summary review header (working):
Two sections — what Demimonde brings, what you brought. Save and start, or rework either side.
Admin completion notification (working — operational receipt):
Quinn-2 is set up in Demimonde. Persona inherited from the org with 1 personal off-limit and IG as a personal surface. Roster's updated.
Admin first-vigil view header (working):
Quinn-2's first vigil — org-shared work only. Drafts and replies she ran under personal stay personal.
First-week scaffolding offer (working):
Demimonde scaffolding — share your curated content, contacts, or blocklist with Quinn-2's first week? She can copy and drift, or skip.
Out of scope
- Cross-org invite — a stranger discovering Demimonde on the open marketplace and asking to join, or a member of another org being cross-invited. That's Y territory (
Y-cross-org-marketplace.brief.mdwhen written). AC assumes the invitee has no prior CocotteAI org affiliation. - Admin removing a member — W3 roster drawer territory. AC ends at successful onboarding.
- Role escalation (Member → Admin) — settings / roster drawer, governed by W3 + an admin-promotion flow not yet briefed.
- Bulk invite (>1 person at a time) — current brief assumes one-at-a-time, matching W's small-org assumption (Demimonde = Quinn + maybe one staff at P5). Bulk is a later brief.
- Re-invite after expiry — handled by AC1 again from scratch with the same composer; not a distinct flow.
- Org-side billing impact of new seat — deferred to platform-admin brief.
- Member-initiated departure — separate flow; touches V data-portability + W roster + audit-shadow handoff.
Open questions
- AC-Q1 Default role on the AC1b picker — Member or Viewer? Lean: Member, since Viewer is the conservative-but-rare case (contractors, oversight) and Demimonde's near-term invitees are operational staff. Admin overrides if needed.
[blocking] - AC-Q2 Invite expiry default — 7 days, 14 days, or 30? Lean: 7 days for tighter security boundary; admin can re-invite trivially. Auto-expired invites still leave an audit row.
[blocking] - AC-Q3 Admin visibility into invitee's persona — sees during AC4 mid-seed (real-time, can suggest edits) or only post-completion (privacy-respecting, invitee owns her seed)? Lean: only post-completion — protects invitee's autonomy even though she's joining the org. Admin can suggest edits in chat later if needed.
[blocking] - AC-Q4 Should AC7 scaffolding offer fire automatically or be on-demand from admin? Lean: automatic one-shot card 24h post-completion, dismissible — captures the moment when admin is most willing to share without nagging.
[nice-to-have] - AC-Q5 When invitee long-presses an org-tagged off-limits row (Q2), should "Make personal" be allowed? Lean: no — org-enforced off-limits are a hard floor per K; invitee can add personal restrictions but cannot loosen org rules. UI should explain rather than offer the gesture.
[exploratory]
Related
- D — Onboarding — the cold first-run; AC inherits D1 SSO device-link verbatim and modifies D2 persona-seed.
- W — Org overlay — W3 roster drawer is AC's entry point; W2 mixed-scope explainer fires in AC5; W5 voice shift is what AC5 hints at; W6 cross-context handoff is how AC7 contact-scaffolding is structured.
- S — Settings IA §S1 — org switcher / roster entry point.
persona-seed-interview.screen.md— the screen this brief modifies into "pre-filled mode."- C — Notifications — admin's completion push routes through C.
- I — Audit-trust-replay — every AC step emits
agent_actionsrows; admin's first-vigil view is a scoped audit drawer. - K — Safety / blocklist — Q2 inheritance + org-floor invariant.
- Y — Cross-org marketplace (future brief) — contrasted: Y is the stranger path, AC is the admin-invited path. Same screen output (a working CocotteAI seat) via fundamentally different trust assumptions.