cocottetech/@platform/codebase/@features/ai-copilot/docs/AC-second-member-onboarding.brief.md
natalie 1b719e1fd7 chore(bootstrap): initial V4 commit
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>
2026-05-18 08:11:41 -07:00

18 KiB
Raw Blame History

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.db with org_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 org tag-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_actions row, audit-visible.

States to design

  1. AC1a — Roster drawer, admin's "Invite" affordance (idle).
  2. AC1b — Role picker sheet (Member / Viewer + role description).
  3. AC1c — Invite composer (recipient email, optional iMessage toggle, optional personal note from admin).
  4. AC1d — Invite-sent confirmation; pending-invites strip in roster drawer.
  5. AC2a — Invitee's email inbox preview (the wild-copy of the invitation message).
  6. AC2b — Optional iMessage preview (Demimonde-routed channel).
  7. AC2c — Invitee splash (warm hearth-leaning; names admin + org).
  8. AC3 — SSO device-link (reuses D1 states; no new design).
  9. AC4a — Pre-filled persona-seed Q1 (voice register chip pre-selected from org template, with org glyph).
  10. AC4b — Pre-filled persona-seed Q2 (off-limits inherited from org; "Add your own" affordance below inherited rows).
  11. AC4c — Pre-filled persona-seed Q3Q6 (surface roster, autonomy posture, quiet hours — all org-derived).
  12. AC4d — Override gesture (long-press an org-tagged row → "Make personal" → tag drops, row becomes editable).
  13. AC4e — Persona summary review (org-inherited vs personal items rendered in two grouped sections).
  14. AC5 — First-time mixed-scope explainer card (one-shot; dismisses on tap-acknowledge).
  15. AC6a — Admin's "first member completed onboarding" notification (working register).
  16. AC6b — Admin's audit-shadow view of invitee's first vigil (read-only, scoped to org-shared work per W7 admin audit).
  17. AC7a — First-week scaffolding offer (admin-side: "Share your curated content / contacts / blocklist with new member?").
  18. AC7b — Invitee-side acceptance of admin's scaffold (each scaffold-type independently toggleable).
  19. 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".
  20. 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_actions row action_type='org_invite_sent', scope org_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.

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 the org_invite_completed row.
  • 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.md when 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]
  • 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_actions rows; 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.