The premise
Islands and bridges
Five slides used to greet you on your first visit to Vellby. The carousel has been retired; the argument it made is still the foundation, so it leads here.
The premise
The primitives
From the six-step product tour, also retired. Everything in Vellby is built from four entity types — like stem cells, each can be shaped into the other, each carrying its own set of attributes.
Context
A bounded space — a project, community, or situation.
Person
An individual with identity, roles, and relationships.
Thing
An object, idea, resource, or artefact.
Relationship
A named bond that connects any two entities.
Connection rules
The key difference between entity types is the rules that govern how they can connect.
- Context Can connect with any entity type
- Relationship Can connect with any entity except another relationship
- Person & Thing Can only connect with relationship or context entities
Multiple descriptions
Every entity can carry multiple descriptions — each capturing a different facet. When you connect two entities, you choose which description applies to that specific connection.
Example
Alex has: “lead engineer”, “open-source contributor”, “team mentor”.
In Engineering Team → connects as “lead engineer”.
In Community → connects as “open-source contributor”.
Play sessions
A play session is a space where an entity can loosen its usual patterns and boundaries. Open any entity to create or resume a play session.
Product
Capability map
The user-facing capability list the web app renders. In the app each row's status is derived live from that node's feature flags, so it is never stale. Here it is static, so the badge reports whether a flag exists to turn it on — not whether any given node has it on.
Communication
Send direct messages to anyone on this node.
Hop on a live video call with someone.
Plan hangouts ahead and see them on a shared calendar.
Entity types
Find the people you know and keep them all in one place.
Organize the people you know into circles — work, family, communities.
Form groups out of the people and contexts you have.
Save and share artifacts — links, docs, anything worth keeping.
AI agents
Chat with an AI agent that knows the people, contexts, and things around you.
An AI agent splits a hangout into breakout rooms and lightly facilitates each one.
Put two or more entities next to each other and let an agent surface what they share, where they differ, and how each one looks from the point of view of the other.
The agent runs searches on a schedule in the background and surfaces short-lived insights from across the node.
Remix people into new relationships against a criterion — balanced on something like gender or industry, or deliberately split along it — each run seeded differently, so a regrouping is an experiment you can re-roll.
Across nodes
Connect, message, and call across Vellby nodes, not just within one.
Two rows deliberately have no flag. When they ship they should get dedicated
ones — feature_agent_schedules and feature_regrouper —
rather than riding feature_agent_chat: a node running chat does not
thereby want background searches running, or its relationships reshuffled.
Product
Rollout phases
The engineering sequencing view — a different object from the capability map above. This one carries dependencies and the code lever that opens each phase. No dates, not commitments.
| Phase | Unlocks | Code lever | Depends on |
|---|---|---|---|
| 0 — Foundation | Person entity, messaging, 1:1/basic video hangout | enabled_entity_types=person, feature_messaging=true |
— |
| 1 — Context | Organize people into contexts (spaces/circles) | enabled_entity_types += context |
Phase 0 stable |
| 2 — Relationship | Group formation (many-to-many hub connecting people) | enabled_entity_types += relationship |
Phase 1 stable |
| 3 — Thing | Artifacts (docs/links/objects) attached to contexts/relationships | enabled_entity_types += thing (= full Tier 3) |
Phase 2 stable |
| 4 — Play | AI chat agent (Gemini-backed), operates over entities | feature_agent_chat=true |
Independent flag — can land any time once entities exist to chat about |
| 5 — Federation | Cross-node connections, messaging, hangouts, search | federation_enabled=true |
Phase 0–3 stable on this node |
| 6 — Hangout Facilitator | AI-orchestrated breakout rooms (e.g. “1 from context A, 2 from context B”) with simple in-room facilitation | feature_hangout_facilitator=true |
Shipped behind the flag (2026-09) — routes at pods/hangouts/facilitator_routes.py, defaults off per node |
| 7 — Scheduled insights | The agent runs searches on a cron-like schedule in the background, surfacing ephemeral node-wide insights | no flag yet — needs feature_agent_schedules |
Phase 4 (the agent + its tools), plus a scheduler and a decision on where ephemeral results live |
| 8 — Side-by-siding | Place two or more entities (incl. across nodes) next to each other; the agent surfaces commonalities, differences, and describes each from the other's perspective | feature_side_by_side=true |
Phase 1 shipped behind the flag (2026-09) — same-node, 2-entity, ephemeral-only compare_entities tool, defaults off. Persistence, N>2, and the cross-node case are Phase 2, deferred |
The two dimensions
Format — where the user experiences Vellby: web app, iOS,
Android, Chrome extension, and an always-ahead internal/dogfood node.
Phase — the order entities and feature-sets unlock, driven by
the per-node feature flags in config.py plus new flags this plan
implies.
Those flags already exist to express pricing tiers across different
self-hosted nodes. This roadmap reuses the same mechanism but points it
at a single timeline for app.vellby.com itself — the flags on the
primary node move forward over time as one cohort, rather than varying
node-to-node.
The capstone
The Hangout AI Facilitator is the first feature that composes every primitive: Person (who's on the call), Context (the “1 from A, 2 from B” grouping rule), Relationship (call/group membership), Play (in-room facilitation logic), and Hangouts (the call itself). Good narrative — “the AI facilitator is what all the other pieces were building toward” — but it also means it should ship last among the non-federation phases, since it has the most dependencies.
Two build items it needs that don't exist yet, distinct from a config flag:
- Multi-room LiveKit orchestration + moving participants between rooms.
- An admin-facing composition rule (context-based split ratios) and a simple facilitation script/prompt the agent runs per breakout.
Product
Format × phase
| Format | P0 | P1 Context | P2 Relationship | P3 Thing | P4 Play | P5 Federation | P6 Facilitator |
|---|---|---|---|---|---|---|---|
| Web app | Full | Full | Full | Full | Full | Full | Full — the reference implementation |
| iOS / Android | Full (messaging + hangout are mobile-native, ship day one) | Subset — likely view/switch contexts, not heavy admin | Subset — join/view groups, defer creation/admin UI | Subset — view/attach things, defer authoring | Full once web-stable | Subset — probably read/search only at first | Join breakout as participant only; admin controls stay web |
| Chrome extension | Migration/import assist + auth bridge | n/a | n/a | Primary feature activates here — capture-URL-as-Thing | Lightweight Play in side panel, mirrored from web | Passive — show which node content lands on | Out of scope |
| Internal/dogfood node | All flags on ahead of public | Staff test breakout logic before it's real | |||||
Mobile's “subset” column is a placeholder shape, not a final call. The default pattern: mobile always gets the consumption/communication surfaces (view, join, chat, call) on day one of a phase; creation/admin surfaces lag until the web UI for that phase has proven out.
Product
Chrome extension — a two-job product
Unlike mobile, the extension doesn't just mirror web on a delay. It has distinct jobs that map onto different points in the phase timeline.
- Migration companion (from Phase 0) — help someone bring contacts/relationships from another platform into Vellby as Person entities, plus session/auth bridging. Useful from the very first public release, independent of which phase the web app is in.
- Thing capture (from Phase 3) — “save this URL as a Thing” is the extension's natural marquee feature, and it can't do anything useful until the Thing entity ships. This is its real reason to exist long-term.
- Play companion (from Phase 4) — once Play ships on web, a lightweight version in the side panel becomes a nice-to-have, not core.
So its release plan is really: ship the migration/import job at launch, go mostly quiet until Phase 3, then become the primary Thing-capture surface. Open: whether it is public from Phase 0 or held back until closer to Phase 3, when it has a stronger reason to install.
Product
Signaling the roadmap to users
How users learn what's coming without overpromising or committing to dates — roughly in order of cheapest to build.
- Public roadmap page — the phase list, no dates, ordered milestones. Cheap, sets expectations, easy to keep honest by reordering rows as reality shifts.
- In-app “what's new” ribbon tied to each phase release, ending with a one-line “Next up: Contexts” teaser. Reinforces the phase story at the moment it's most credible — right after something shipped.
- Locked nav teasers (“Contexts — coming next”) for the immediately next phase only. Hold off until Phase 2+ has shipped, so it reads as near-term rather than vaporware.
- Early-access opt-in for power users into the dogfood node/flags, once the entitlement layer exists — turns internal-only testing into a visible signal that the roadmap is real and moving.
Recommendation on record: start with (1) + (2) only. They're nearly free and don't require the entitlement layer. Add (3) once Phase 2 ships; treat (4) as a later unlock tied to the entitlement work.
Product
In flight
Side-by-siding — entities seen from each other
Put two or more entities next to each other and let an agent do three things: commonalities (what they share), differences (where they diverge), and reciprocal description — describe A from B's point of view, and B from A's.
Why it's Vellby-shaped: requisite variety — only variety can absorb variety. Islands and bridges — a bridge is only interesting if the far side is genuinely different. Side-by-siding is the mechanic that makes a bridge legible: not “here is another island” but “here is what your island looks like from theirs.” It is also the natural companion to federation: once entities cross nodes, the interesting question stops being can I see it and becomes what does it mean next to mine.
Status: Phase 1 shipped 2026-09-14 behind feature_side_by_side, off
by default — same-node, 2-entity, ephemeral-only. Phase 2 (persistence, N>2,
cross-node pairs, a dedicated UI surface) is deferred.
Promotion — turning conversation into entities
Messaging is a stream: present-tense, scroll-ordered, read-it-now-or-lose-it. Right for coordinating inside a context, wrong for retrieval. Six months later a decision made in a channel is unfindable — there is no topic address for it.
A forum is the usual answer, and the wrong one here: it would sit beside the entity graph and need search, connections and federation rebuilt inside it. Everything durable in Vellby is an entity; conversation is the one thing that isn't. Promotion is the alternative — let a conversation become an entity, and let entities carry conversation. Nothing new sits beside the graph.
MessageChannel is keyed by
entity_id, and a Thing is an entity. So “comment threads on Things”
is not a feature — it's removing a restriction.
Status: proposal, written 2026-09-14, not started.
Business
The layer map
Vellby is a closed-federation platform. Each architectural layer is a distinct place to capture — or deliberately not capture — value.
- 6Ecosystem / app layermarketplace, developer platform (cross-cutting)
- 5Network governanceconsortium dues, certification
- 4Protocol layermembership, identity, trust, interconnect
- 3Pods (value layer)agent, messaging, hangouts, analytics, SSO/admin
- 2Core nodesearch + connections
- 1Hostingwho runs the node
The pod packages under apps/backend/app/pods/ (agent, messaging,
hangouts) and the federation protocol layer are what make this split real: they
let the value features be gated, metered, and one day deployed independently of
the core.
Business
Monetization by layer
1 · Hosting
- Managed SaaS hosting (per seat / per org).
- Self-hosted / open-core (license, or free + paid support).
- Hybrid: free to self-host, pay for managed hosting and updates.
- Support / SLA / professional services.
2 · Core node (search + connections)
Deliberately free / base tier. It is the adoption driver and the reason to be on the network. Monetizing it directly undercuts that.
3 · Pods — the main revenue lever
- Per-pod subscription (turn on agent / messaging / hangouts / analytics / SSO+admin).
- Usage-based tiers (agent credits, hangout minutes).
- Tiered bundles (Free = core; Pro = + messaging + hangouts; Enterprise = + SSO + admin + analytics).
- SSO + admin as the dedicated enterprise pod.
- Amplifiers inside pods (recording, transcription, large rooms, AI-in-call, archive/compliance).
- Agent: managed inference vs bring-your-own-key platform fee.
4 · Protocol layer (federation / identity / trust)
- Membership fees (be a vouched node, be in the directory) — the paid foundation.
- Identity / registration fees (
did:vellbyissuance and anchoring). - Trust / certification tiers (verified node, conformance).
- Directory / discovery placement (premium listing and ranking).
- Interconnect / metering, used sparingly: only for resource-heavy consumption.
- Settlement / clearing fees (long-term: rights or content exchange between member orgs; needs validation with the orgs involved).
5 · Network governance
- Consortium / foundation membership dues.
- Certification and conformance-testing fees.
- Reference implementation / reference-node hosting.
- Accreditation and dispute-resolution services.
6 · Ecosystem / app layer
- Third-party pod marketplace with a take-rate.
- Developer platform with tiered API access.
- Revenue share with external pod builders.
Cross-cutting pricing mechanics: per-seat, per-org, usage/metered, tiered/freemium, open-core, marketplace take-rate, hosting markup, license/entitlement caps. Real products mix two or three.
Business
Guiding principle
Revenue concentrates in four places:
- The gate — membership + identity (everything “free” is free to members).
- Amplifiers — quality, recording, transcription, AI, compliance, SLA, premium placement.
- Heavy consumption — federated search at scale, usage beyond fair-use caps.
- The layers above core — pods, hosting, ecosystem.
Everything that binds the network together — connections, messaging, hangouts, baseline discovery and search — stays free at point of use, so growth is never taxed.
Promote vs monetize: cross-node activities
| Cross-node activity | Core action | Why | Monetize around it |
|---|---|---|---|
| Handshake / peer trust | Free | Pure plumbing, ~0 cost, enables everything | Nothing |
| Discovery / directory | Free baseline | More discoverable = more valuable; drives connections | Premium placement / ranking |
| Cross-node connections | Free | This is the network effect; ~0 cost | Bulk/org management (minor) |
| Cross-node messaging | Free verb | High stickiness; modest cost | Archive, compliance, search at scale |
| Cross-node hangouts | Free verb, fair-use cap | Strong network binder; real LiveKit cost | Recording, transcription, large rooms, AI-in-call, SLA |
| Federated search | Free baseline, meter at scale | Drives discovery, but extracts value and loads every peer | High-volume / API access, advanced ranking |
The one non-obvious call is federated search: it is the only cross-node activity that both extracts value (rather than creating it) and imposes a cost externality on every peer. That makes a fair-use cap plus paid overage defensible — it protects the other operators, not just our margin.
Business
Hosting strategy
Self-host the core, centralize the value pods. The strongest shape is a data-plane / control-plane split: the customer self-hosts the core (their data, their identity), and the high-value pods are centrally hosted and called into over an authenticated channel.
| Component | Where | Why |
|---|---|---|
| Core: search + connections + data + identity | Self-hosted | System of record stays theirs (sovereignty) |
| Basic messaging (free verb) | Self-hosted | Network-binding, keeps content local |
| Agent | Central | High value, metered, calls Gemini anyway |
| LiveKit routing / hangouts orchestration | Central | Shared service; media never touches the core |
| Analytics, premium amplifiers | Central | Billable add-ons; we own the meter |
Why this resolves the tensions at once:
- Sovereignty — the customer's data lives on their node.
- Metering / billing — we operate the paid features, so usage is measured directly. The self-reported-usage trust problem disappears.
- Margin capture — the highest-value capabilities stay under our control.
- Network effects — self-hosted cores still federate with each other.
Honest caveat. A centrally hosted agent reads node data and forwards some to Gemini, so: “data at rest stays local, but data in use transits our cloud for opted-in features.” Clean for most buyers; the strictest air-gapped customers need fully self-hosted pods (licensed, with local entitlement caps). Offer both as SKUs — central pods (default, easy, metered) and self-hosted pods (enterprise/air-gapped, license-based).
Implementation note: LiveKit centralization already has a pattern in the code —
federation/livekit.py lets a node ask a home server to mint a token
for a remote entity. Generalizing “home server” to “central token service” is the
same shape. The agent's write path already routes through a service seam; its
read tools would need to become authenticated calls back to the node's API (the
deferred read-SPI work).
Business
Who pays, and how
Decisions reached.
- Be opinionated. Do not offer a billing-model menu. A clear price closes faster and is simpler to operate. Optionality is earned into later, per segment.
- The org pays, not individual end users. End users on a node are the org's own people; the org holds the contract.
- Flat per-node base fee + usage tiers for the variable-cost features (agent credits, hangout minutes). The flat base gives procurement a predictable line item; the tiers cover our variable COGS.
- Different generosity per feature. Hangouts get a generous included baseline (the promote-feature); the agent gets a leaner one (higher COGS).
- No surprise overage. Notify at 80%, upgrade to continue. Allowances pool at the node level and reset annually.
- Enterprise is negotiated.
Audience note: public-service media procurement strongly prefers fixed, annual, budgetable costs over variable bills. The flat base + capped tiers + annual pooling is designed for that.
Business
Usage statistics from self-hosted nodes
Two distinct goals with different best practices.
| Goal | Approach | Tolerance |
|---|---|---|
| Product/usage analytics | Aggregate counts, best-effort phone-home | Opt-out OK, no PII |
| Billing/metering | Reliable, attributable | Must be tamper-resistant |
- Aggregate locally (counts, not event streams; no PII; instance-level not user-level), then push a small signed report on a schedule, reusing the federation server keypair for authenticity.
- Resilient and non-blocking (queue, batch, retry, tolerate offline). Inspectable payload and a published schema build the trust that makes opt-out telemetry acceptable.
- For billing, enforce locally rather than measure remotely — tie billing to a license/entitlement with caps the node enforces itself; the phone-home then just confirms the license is alive and reconciles. Signing proves integrity in transit, not honest counting, so high-value deals add audit rights.
For centrally hosted pods this is moot — we meter directly.
Money
Draft tier sheet
Every number here is an illustrative placeholder, not validated pricing. The structure and logic are the deliverable; replace the figures once real COGS are plugged in. Draft v0, 2026-06-25.
The model in one line: a flat node fee (sized by node) that includes a baseline of both features, plus upgrade packs for agent credits and hangout minutes.
Node base license (flat, annual)
| Tier | Active users | Flat fee /yr | Included hangouts participant-min/yr | Included agent credits/yr | Support |
|---|---|---|---|---|---|
| Starter | up to 25 | €6,000 | 5,000 | 2,500 | Community + email |
| Team | up to 100 | €18,000 | 25,000 | 12,000 | Business hours |
| Org | up to 500 | €60,000 | 120,000 | 50,000 | Priority + SLA |
| Enterprise | 500+ / BYOC / air-gapped | Custom | Negotiated | Negotiated | Dedicated + DPA |
The fee is still “flat per node”, just banded by node size so a 400-person org is not priced like a 20-person one. Hangout baselines are deliberately generous (the feature we want to promote); agent baselines are leaner (higher COGS).
Assumptions (replace before quoting)
- Currency EUR; annual contracts; billed to the org (one contract per node, no end-user self-pay).
- “Typical node” = a media org of 25–500 active users.
- Target gross margin on the variable features ≈ 75%.
- Allowances pool at the node level (not per seat) and reset annually (not per month).
- Cap behavior: notify at 80%, then prompt to upgrade to continue — no silent metered overage.
- Agent and hangouts are centrally hosted by default. A self-hosted / air-gapped pod variant is licensed separately.
Money
Upgrade packs
Pooled, annual, upgrade-to-continue.
Agent
Unit = 1 AI credit ≈ one agent conversation/action (mapped internally to tokens; customers never see raw tokens).
| Pack | Added credits/yr | Price /yr |
|---|---|---|
| +S | 10,000 | €4,000 |
| +M | 50,000 | €16,000 |
| +L | 200,000 | €55,000 |
Hangouts
Unit = participant-minute (one person in a room for one minute). This is how the SFU bills us, so it protects margin; show it clearly to the buyer.
| Pack | Added participant-min/yr | Price /yr |
|---|---|---|
| +S | 50,000 | €2,500 |
| +M | 250,000 | €10,000 |
| +L | 1,000,000 | €32,000 |
Policy
- Pooling: node-level, shared across all users; annual pool (a busy month does not trip a wall).
- At the cap: notify at 80%, then upgrade a pack to continue. No surprise overage billing.
- Units: agent in AI credits (not tokens); hangouts in participant-minutes.
- Who pays: the org. No end-user self-pay.
- Hosting: central pods by default. Self-hosted pods (air-gapped / sovereignty) = a per-node license with locally enforced caps, priced at a premium over the central equivalent (no metering trust, higher support burden).
- Enterprise: everything negotiable above the Org tier.
How to set the variable-feature prices
pack price >= (included allowance x unit COGS) / (1 - target margin)
Worked example (agent +M, illustrative): if a credit costs €0.08 in inference and the margin target is 75%:
50,000 x €0.08 / (1 - 0.75) = €4,000 / 0.25 = €16,000
That is where the €16,000 above came from. The same formula sets the hangout packs from the per-participant-minute SFU cost. Then size each tier's baseline so roughly 80% of nodes never exhaust it.
Money
Validate before you quote
Do not ship these numbers as-is.
- Agent COGS is doubly unverified. It depends on the real per-token price of the model, and the model ID itself (set in
pods/agent/service.py) is still unconfirmed. Pin the model, then its token price. - LiveKit per-participant-minute cost at the expected concurrency.
- Real usage data to size baselines for the “80% stay in tier” target. Until then the allowances are guesses.
- Define a credit precisely (tokens-per-credit) and keep it stable, or customers cannot forecast.
- Currency, VAT, and procurement format for EU/Swiss public-media buyers (annual PO, fixed line items).
Absolute euro levels are arbitrary placeholders; the ratios are internally consistent, but do not anchor on the absolute numbers.
Loose ends
What is not built yet
None of the business model is enforced in code. The pods + federation architecture makes these packageable; they are the next build, not done.
Before any of it bills:
- An entitlement / feature-gate layer (which pods/tiers an org has).
- Usage metering and quotas per pod (agent credits, hangout minutes).
- Billing integration wired to entitlements and metering.
- For true per-pod pricing and the central/self-hosted split: the deferred deployment split (independently deployable pods) and the data-ownership move (pod-owned tables instead of state on the core
Entity). - For the self-hosted central-pods model: an authenticated node API for central pods to call back, plus node-to-service auth via
did:vellby/ federation signing.
Loose ends
Open questions
Roadmap
-
Per-node timeline vs. per-user cohort. The existing flags are
one
Settingsobject per node (deploy-time env var) — they can't currently show Phase 2 to some users and Phase 0 to others on the same node. If “slowly let users in” means a single global timeline forapp.vellby.com, the existing mechanism is sufficient. If you want a beta cohort/waitlist within one node, that's a new per-user entitlement layer — already flagged as unbuilt. - Where does the internal dogfood node live? A separate deployed node with all flags true, or a flag override for staff accounts on the prod node? The former exists today “for free” (same mechanism as self-hosted tiers); the latter needs the entitlement layer.
- Is the Chrome extension public from Phase 0, or held back until closer to Phase 3 when it has a stronger reason to install?
Pricing
- Absolute euro levels are placeholders; only the ratios are internally consistent.
- Agent economics cannot be finalized until the model question is closed.
- Whether to bundle the agent/hangout baselines into the node tiers (as drafted) or sell them as fully independent add-ons.
Loose ends
Sources
Where each part of this page came from, and when it was last touched.
| Source | Feeds | As of |
|---|---|---|
docs/roadmap.md | Rollout phases, format × phase, extension, signaling, roadmap open questions | 2026-08-16 |
docs/business-model.md | Layer map, monetization, guiding principle, hosting, who pays, telemetry, not-built-yet | 2026-06-25 |
docs/pricing-draft.md | Tier sheet, upgrade packs, policy, validation | 2026-06-25 |
docs/side-by-siding.md | In flight — side-by-siding | 2026-09-14 |
docs/promotion.md | In flight — promotion | 2026-09-14 |
apps/web/src/roadmapData.js | Capability map (groups, copy, flag wiring) | current |
apps/web/src/components/Roadmap/LegacyRoadmapPage.jsx | Islands and bridges, the primitives — retired intro carousel + product tour | current |
Not pulled in, deliberately — these are operational rather than narrative:
node-ttl.md, observability.md,
legal-docs-todo.md.