User Journeys
Seven scenarios that test the full introduction lifecycle
These journeys cover the design space from our discussion of notebook-native introductions: dedicated introducer agents, agent-to-human escalation, public vs. private paths, social recovery, web of trust filtering, bootstrapping, and reputation feedback. Each scenario is implementation-guiding — the "what this tests" section maps directly to capabilities that need to exist.
1. Introducer Agent Brokers a Match
Setup
| Entity | Type | Initial state |
|---|---|---|
| introducer-agent | Dedicated introducer (open-source, runs on notebook router) | Own Matrix account. Subscribes to notebook entry pipeline. ed25519 key published on notebook. |
| hermes-of-alice | Alice's agent | Publishes entries about TEE attestation verification. Trust annotation on introducer: high. |
| hermes-of-carol | Carol's agent | Publishes entries about SGX remote attestation libraries. Trust annotation on introducer: high. |
| Alice | Human | ed25519 notebook key. Matrix account attested to notebook identity. |
| Carol | Human | ed25519 notebook key. Matrix account attested to notebook identity. |
Flow
sequenceDiagram
participant NB as Notebook Router
participant IA as introducer-agent
participant Matrix as Matrix Server
participant HA as hermes-of-alice
participant HC as hermes-of-carol
participant Alice as Alice (human)
Alice->>NB: publish entry: "Need someone who understands SGX quote parsing"
NB->>IA: entry pipeline trigger
IA->>IA: Match Alice's need against Carol's SGX entries
IA->>IA: Check: both annotated introducer as high trust
Note over IA,NB: Public path
IA->>NB: hermes_write_entry() — signed introduction record
Note over NB: Public ledger — no auth to view
Note over IA,Matrix: Private path
IA->>Matrix: Create room, invite hermes-of-alice + hermes-of-carol
IA->>Matrix: "About @alice: TEE attestation verification..."
IA->>Matrix: "About @carol: SGX remote attestation library..."
HC->>Matrix: sync() — auto-join, extract peer info
HA->>Matrix: sync() — auto-join, extract peer info
HA-->>Alice: "You've been introduced to Carol via the introducer.
She shipped an SGX attestation library. Reach out?"
Alice->>HA: "Yes"
HA->>Matrix: send message to Carol's agent
What this tests
- Dedicated introducer agent as a first-class participant — not built into the system, just an auditable agent using the same APIs
- Publish-time spark detection on the notebook router (server-side, not per-agent prefetch)
- Web of trust gate: introducer's suggestions only reach users who annotated it as
hightrust - Dual-path introduction: public notebook ledger entry + private Matrix room
- ed25519 signing of introduction records
The introducer agent has no special privileges. It uses the same
hermes_write_entry and Matrix room creation APIs any agent could use. It earns trust through match quality.2. Agent-to-Agent Discovery, Escalation to Users
Setup
| Entity | Type | Initial state |
|---|---|---|
| hermes-of-bob | Bob's agent | Knows Bob needs formal verification of a liquidation engine. Active in #etherea. |
| hermes-of-dave | Dave's agent | Dave is a formal verification expert. Active in #tees. |
| Bob | Human | DeFi developer. Matrix account separate from agent's account. No connection to Dave. |
| Dave | Human | Formal verification researcher. Matrix account separate from agent's account. No connection to Bob. |
Flow
sequenceDiagram
participant Bob as Bob (human)
participant HB as hermes-of-bob
participant Matrix as Matrix Server
participant HD as hermes-of-dave
participant Dave as Dave (human)
Note over HB: prefetch() — spark detection
HB->>HB: PeerSummary for Dave: {needs: "real DeFi use cases",
offers: "formal verification, Coq proofs"}
HB->>HB: Bob's profile: {needs: "formal verification of liquidation engine",
offers: "DeFi lending protocol codebase"}
HB->>HB: Spark fires — complementary needs/offers
HB-->>Bob: "Dave does formal verification for smart contracts
and wants real DeFi codebases. You need formal verification.
Should I introduce you?"
Bob->>HB: "Yes, go ahead"
HB->>Matrix: Create introduction room
HB->>Matrix: "About @bob: DeFi lending protocol, needs formal verification..."
HB->>Matrix: "About @dave: formal verification expert, looking for real codebases..."
HB->>Matrix: Invite hermes-of-dave
HD->>Matrix: sync() — auto-join, extract peer info
HD-->>Dave: "Bob's agent introduced itself. He's building a DeFi
lending protocol and needs formal verification. Schedule a call?"
Dave->>HD: "Yes"
HD->>Matrix: Send response to hermes-of-bob
Note over HB,HD: Agents now have a conversation thread
Note over HB,HD: Both act as social secretaries —
filter messages, escalate selectively to humans
HB->>Matrix: Invite Bob (human's Matrix account)
HD->>Matrix: Invite Dave (human's Matrix account)
Note over Bob,Dave: Humans now in the same room
What this tests
- Per-agent spark detection from accumulated PeerSummaries (existing
prefetch()mechanism) - Human approval gate before introduction — edge introductions are opt-in
- Agent creates introduction room (peer-to-peer, not via central introducer)
- Agent as social secretary: filters the firehose, escalates selectively
- Agent Matrix accounts are separate from user Matrix accounts — agents can invite their humans
- Escalation path: agent-to-agent → agent-to-human → human-to-human
Agents discover mutual benefit autonomously. Humans are only involved at the approval gate and when there is something worth their attention. Two agents that meet each other can introduce their respective users.
3. Public vs. Private Introduction
Setup
| Entity | Type | Initial state |
|---|---|---|
| introducer-agent | Dedicated introducer | Has matched Alice ↔ Bob and Eve ↔ Frank. |
| Alice | Human | Preference: prefer_public: true. Wants introductions on the public ledger. |
| Eve | Human | Preference: prefer_public: false (default). Sensitive business context. |
Public path (Alice)
sequenceDiagram
participant IA as introducer-agent
participant NB as Notebook Router (public)
participant Matrix as Matrix Server (auth required)
Note over IA: Alice has prefer_public: true
IA->>NB: hermes_write_entry() — signed introduction
Note over NB: {type: "introduction",
parties: ["@alice", "@bob"],
context: "TEE attestation",
introducer: "@introducer-agent",
signature: "ed25519:..."}
Note over NB: Genuinely public — no auth to view
Note over NB: Becomes a node in the visible trust graph
IA->>Matrix: Create private room for conversation
Note over Matrix: Auth required to access
Private path (Eve)
sequenceDiagram
participant IA as introducer-agent
participant Matrix as Matrix Server (auth required)
Note over IA: Eve has prefer_public: false
IA->>Matrix: Create encrypted room, invite agents
IA->>Matrix: Post context messages
Note over Matrix: No notebook entry written
Note over Matrix: Introduction exists only in the encrypted room
Note over Matrix: Requires Matrix auth to access
What this tests
- User-controlled visibility preference (
prefer_publicannotation) - Public notebook ledger as a trust graph building mechanism — genuinely public, no auth
- Private introductions via encrypted Matrix rooms — no public trace
- The introducer respects user preferences, does not unilaterally publish
- Same introduction mechanism, different visibility — controlled by the user, not the system
Public introductions should be encouraged — they build the visible reputation/trust graph. But the user controls visibility, and private introductions leave no public trace.
4. Social Recovery After Key Loss
Setup
| Entity | Type | Initial state |
|---|---|---|
| Bob | Human | ed25519 key K1. Introduced to Alice, Carol, and Dave by different introducers at different times. Each introduction is a signed notebook entry linking K1. |
| Alice, Carol, Dave | Humans | Each has independent introduction records involving Bob. |
Flow
sequenceDiagram
participant Bob as Bob (lost key K1)
participant NB as Notebook Router
participant HA as hermes-of-alice
participant HC as hermes-of-carol
participant HD as hermes-of-dave
Bob->>Bob: Generate new key K2
Bob->>NB: Recovery request: {old_key_hash: SHA256(K1),
new_key: K2, signed_by: K2}
Note over NB: Self-signed — anyone could claim this
NB->>NB: Look up all introduction records involving K1
NB->>HA: Notify: "Bob claims key loss, requests recovery"
NB->>HC: Notify: "Bob claims key loss, requests recovery"
NB->>HD: Notify: "Bob claims key loss, requests recovery"
HA-->>HA: Alice verifies out-of-band (knows Bob personally)
HA->>NB: Recovery vouch: {old_key_hash: SHA256(K1),
new_key: K2, signed_by: Alice_key}
HC-->>HC: Carol verifies out-of-band
HC->>NB: Recovery vouch: {old_key_hash: SHA256(K1),
new_key: K2, signed_by: Carol_key}
Note over HD: Dave is unavailable
NB->>NB: 2-of-3 vouches received — threshold met
NB->>NB: Record key rotation: {old: SHA256(K1), new: K2,
vouchers: [Alice, Carol], timestamp: ...}
Note over NB: All of Bob's introduction records
now linked to K2 via rotation record
What this tests
- Introduction graph as the recovery mechanism — not a separate system
- N-of-M threshold vouching (analogous to Ethereum social recovery wallets)
- Out-of-band verification as a human judgment step
- Key rotation records that preserve identity continuity
- Multiple independent introducers create redundancy — losing one voucher path does not block recovery
The introduction graph IS the recovery mechanism. A well-connected user has multiple independent recovery paths. The more introductions from different sources, the more resilient the identity.
5. Web of Trust Filtering
Setup
| Entity | Type | Initial state |
|---|---|---|
| introducer-alpha | Trusted introducer | Alice annotated as trust: high. Good track record. |
| introducer-beta | Unknown introducer | Alice has not annotated (or trust: low). Unknown track record. |
| Alice | Human | Web of trust filtering enabled (default). |
| Bob | Human | Genuine match for Alice. Introduced by introducer-alpha. |
| Mallory | Human | Spammer. Introduced by introducer-beta. |
Flow
sequenceDiagram
participant IA as introducer-alpha (trusted)
participant IB as introducer-beta (untrusted)
participant Matrix as Matrix Server
participant HA as hermes-of-alice
participant Alice as Alice (human)
IA->>Matrix: Create room, invite hermes-of-alice + hermes-of-bob
IB->>Matrix: Create room, invite hermes-of-alice + hermes-of-mallory
HA->>Matrix: sync() — sees both invites
HA->>HA: Evaluate introducer-alpha: trust annotation = high
HA->>Matrix: Join room (Bob introduction)
HA-->>Alice: "introducer-alpha introduced you to Bob.
He's working on auction mechanisms for compute."
HA->>HA: Evaluate introducer-beta: no trust annotation
HA->>HA: Filter — silently drop
Note over HA: Mallory's introduction never surfaces
Note over Alice: Alice never sees it
What this tests
- Trust annotations on introducers (not just on peers)
- Filtering at the agent level, not the server level — the server delivers all invites, the agent decides which to surface
- Untrusted introducers cannot reach users — enforced by the user's own agent
- New introducers must earn trust before their introductions get through
- Per-user annotations — Alice's filter is hers, not a global policy
Web of trust filtering is the default. Bad introductions are worse than no introductions. This is enforced by the user's own agent, not by a central authority.
6. Bootstrapping a New User
Setup
| Entity | Type | Initial state |
|---|---|---|
| Frank | Human (new) | Just generated ed25519 key. Has a Matrix account. Zero connections. Knows Alice outside the system. |
| Alice | Human (established) | Well-connected. Trusts introducer-agent. |
| introducer-agent | Dedicated introducer | Active, has visibility across the notebook. |
Flow
sequenceDiagram
participant Frank as Frank (new)
participant HF as hermes-of-frank
participant Matrix as Matrix Server
participant HA as hermes-of-alice
participant Alice as Alice
participant IA as introducer-agent
Frank->>Frank: Generate ed25519 key — pseudonym: Wandering Echo#4f2a1b
Frank->>Frank: Attest Matrix account to notebook key
Note over Frank,Alice: Bootstrap: direct connection (out-of-band)
HF->>Matrix: Direct connection request to hermes-of-alice
HA-->>Alice: "Frank is requesting a connection.
New user — no introduction records. Know him?"
Alice->>HA: "Yes, I know Frank"
HA->>HA: Annotate Frank: trust: high, labels: ["distributed-systems"]
Note over Alice,IA: Onboard to introducer
Alice->>HA: "Introduce Frank to the introducer-agent"
HA->>Matrix: Create introduction room (Frank + introducer-agent)
HF->>Matrix: sync() — discovers introducer-agent
Frank->>HF: Annotate introducer-agent: trust: high
Note over IA,HF: First introductions arrive
IA->>Matrix: Match 1: Frank meets peer with shared interests
IA->>Matrix: Match 2: another match from notebook entries
IA->>Matrix: Match 3: third match
Note over Frank: After one week:
1 direct connection (Alice)
1 trusted introducer
3 introduced peers
Spark detection now functional
What this tests
- Cold start: new user with zero connections
- Direct connection as out-of-band bootstrap (not via introducer)
- Platform attestation (Matrix account linked to notebook key)
- Introducer onboarding as a second step (recommended, not required)
- Trust annotations are always the user's own decision — Alice recommends the introducer, but Frank makes his own annotation
- Graph growth from 0 to functional in a short period
Bootstrapping requires exactly one trusted human connection. From that single edge, the introduction graph grows organically through trusted introducers.
7. Introduction Quality Feedback Loop
Setup
| Entity | Type | Initial state |
|---|---|---|
| introducer-agent | Trusted introducer | 20 introductions over the past month. Reputation: 0.8. |
| spammy-introducer | Untrusted introducer | 50 introductions, mostly low quality. Reputation: 0.2. |
| Alice | Human | Received intros from both. Annotated introducer-agent as high, spammy-introducer as low. |
| Frank | Human (new) | Evaluating which introducers to trust. |
Positive feedback
sequenceDiagram
participant IA as introducer-agent
participant Matrix as Matrix Server
participant HA as hermes-of-alice
participant NB as Notebook Router
IA->>Matrix: Introduce Alice to Carol
HA->>Matrix: sync() — join, discover Carol
Note over HA,Matrix: Productive exchange — 3 messages,
follow-up notebook entry
HA->>HA: Detect productive interaction
HA->>NB: Positive signal: {introduction_id: "...",
outcome: "productive", signed_by: Alice_key}
Note over NB: Public record — anyone can see Alice
rated this introduction positively
Note over IA: Reputation: 0.8 → 0.82
Negative feedback
sequenceDiagram
participant SI as spammy-introducer
participant Matrix as Matrix Server
participant HA as hermes-of-alice
SI->>Matrix: Introduce Alice to Mallory's bot
HA->>Matrix: sync() — join (low trust, but not blocked)
Note over HA: No messages after 7 days
HA->>HA: Record negative signal: {outcome: "ignored"}
Note over HA: 3rd ignored intro from spammy-introducer
HA->>HA: Auto-downgrade: trust low → blocked
Note over SI: Reputation: 0.2 → 0.15
Reputation discovery
sequenceDiagram
participant Frank as Frank (new user)
participant HF as hermes-of-frank
participant NB as Notebook Router
Frank->>HF: "Who should I trust for introductions?"
HF->>NB: Query introducer reputations
NB-->>HF: introducer-agent: 0.82 (20 intros, 15 productive)
spammy-introducer: 0.15 (50 intros, 40 ignored)
HF-->>Frank: "introducer-agent has strong track record.
spammy-introducer has mostly ignored intros."
Frank->>HF: Annotate introducer-agent: trust: high
What this tests
- Implicit quality signals from interaction patterns (message volume, follow-ups, time-to-engage)
- Signed feedback entries on the public notebook ledger
- Automatic trust downgrade after repeated poor introductions
- Public reputation as a discovery mechanism for new users choosing introducers
- The flywheel: good intros → reputation → more trust → more intros accepted
- Natural selection: bad introducers lose reach as users downgrade and block them
Introduction quality is measurable and public. Introducers compete on match quality. Bad introducers are naturally filtered out by the web of trust. This makes "competing introducers" viable without central moderation.
Evidence Map
| Capability | Tested in |
|---|---|
| Dedicated introducer agent as trusted hub | Scenarios 1, 3, 7 |
| Agents discover mutual benefit autonomously | Scenario 2 |
| Agent-to-human escalation (social secretary) | Scenario 2 |
| Public introduction ledger (notebook) | Scenarios 1, 3, 7 |
| Private introductions (Matrix) | Scenarios 1, 2, 3 |
| ed25519 as identity root | Scenarios 1, 3, 4 |
| Social recovery via introduction graph | Scenario 4 |
| Web of trust filtering | Scenario 5 |
| Cold start bootstrapping | Scenario 6 |
| Introduction quality feedback loop | Scenario 7 |
| Edge introductions are opt-in | Scenario 2 (approval gate) |
| User-controlled visibility | Scenario 3 |