Getting started and Connections
A person who has just signed up should end up with an assistant that can actually do something for them. That takes a few steps — connect their mail and calendar, find their learning path — and those steps are offered in one flow, not as separate cards from separate modules.
Getting started: one list, three places
There is one ordered list of steps per person. Where it shows:
| Where | What | When |
|---|---|---|
| After onboarding | the Getting-started page, /{you}/GettingStarted — every open step, in order, with Start and Not now |
once, right after the sign-up form (unless the person arrived through a deep link, which wins) |
| Every new chat | one line: the next open step | while any step is open |
| Every new chat | one tip line — today: type /feedback to tell us anything |
until the person dismisses it |
A step never returns once the person did it or clicked Not now; the next one moves up. The
per-person record is AiSettings.DoneNudges on their own {you}/_Memex/AiSettings node — a
dictionary, for the same merge-safety reason as User.CompletedLogonActions.
Where steps come from
- Modules contribute them in code —
IChatNudgeSource, registered from DI (AddSingleton), the same lane as agent plugins. A source emits its step only while it applies and an empty list once it does not; it never throws. Built in: Connect your accounts (while nothing is connected and the installation offers at least one connection) and the/feedbacktip. The Learning Roadmap contributes Find your learning path (Edu module,MeshWeaver.Courses). - Admins declare them as data — a
ChatNudgenode atAdmin/_ChatNudge/{id}, like logon actions: no code, no release. Read as the system identity (users have no grant underAdmin, and an RLS-filtered read would silently come back empty). - Each step has an
Order, an optionalTranslations["de"], what choosing it does (open a page, or put a slash command into the chat composer — never send it), and whether choosing it already counts as done (DoneWhenChosen, off when "opened" is not "finished").
Connections
Four sign-in flows existed before this layer — Microsoft (the Executive Assistant's consent),
LinkedIn, GitHub, instance-to-instance — each storing its credential its own way, and one kept an
access token unencrypted (SocialMedia#174). Connections is the one layer every provider now plugs
into, in MeshWeaver.AI.Connections so both compiled modules and node-native packages can bind it.
- A module registers an
IConnectionProvider: name, icon, what it enables, its kind, who may own it (a person, or a Space — one company account for a team), whether this installation configured it, a status probe, aVerifyfor "Test connection", and where "Connect" leads. - Four states, never guessed: Connected · Not connected · Rejected (the provider refused) · Couldn't tell. "Couldn't tell" is never folded into "not connected" — that tells a connected person to reconnect.
- Three credential kinds: OAuth (sign in with the provider), a credential set (named fields, some secret, with per-connection endpoints such as a test host), and a device link (WhatsApp's code).
- Stored at
{owner}/_Connections/{provider}as aConnectionCredential. Every secret goes throughConnectionSecrets.Prepare: a secret that cannot be encrypted is refused, never stored in the clear; a blank field keeps what is stored; the record'sToStringis redacted. - Agents use typed tools, never a free-form "call any URL with my token", and anything
irreversible is off until the installation turns it on (the
Teams:AgentSendpattern). - The Connections page,
/{you}/Connections, shows one tile per provider with its state and the single action that state calls for (Connect, Fix, Retry, Manage).
The first providers: Microsoft 365 and Teams, wrapping the existing consent — nobody reconnects. Next: WhatsApp (#1664), DeepSign (#1668), then mail for everyone (Gmail, iCloud, IMAP via MailKit) into the existing Email inbox, where a Space-owned mail connection is the team's shared inbox.
The recipe for adding a provider is the built-in skill /build-a-connection; the user-facing
guide is /connect.
What was decided, and why
- One flow, not two cards. The Learning Roadmap's standalone "take your educational journey" card was withdrawn in favour of a step in this list (coordinated with its session, PR #1625).
- Show on every new chat, not only the Executive Assistant's — new chats default to the generic Assistant, so gating on the EA would hide the steps from most people.
- Onboarding is untouched except its last redirect. It is a single form whose completion is the Active user node; the Getting-started page is reached after it, on the new person's own node.
- Every surface renders only for its owner. The areas live on the user node and show nothing to a visitor, so embedding them can never show one person's steps or connections to another.