Skip to the page

Invented example · built on Kindling · Why Kindling · The library · The spec · The Circular

Roomfula dating app that hosts no Pools

Open in

No app loads this, on purpose. A dating app that hosts no Pools of its own. It opens full, reading the Pools you already said yes to.

Under the hood

A client with no Pools of its own

What Roomful reads, how it finds it, what it honors, and where the v0.1 schemas can’t yet say what the spec means.

Our discovery file

Empty, on purpose

A domain that hosts Pools should publish a .well-known/kindling-pool file listing them §8.3 §10.1. We publish one too, with nothing in it. It says, in the protocol’s own format, that we host no Pools.

We host no Pools. We read yours. Read the file itself.

{
  "schema_version": "0.1",
  "pools": [],
  "operator": {
    "name": "Roomful, a dating app that hosts no Pools and reads the ones you joined",
    "contact": "hello@roomful.example",
    "url": "https://roomful.example"
  }
}

Settings, mapped to the spec

What we chose, and why

SettingValueSpecWhy Roomful chose it
Pools hostedNone. The discovery file lists an empty array.§3.1We are a client, not a Pool host. Hosting Pools would make them ours to keep.
DiscoveryEvery well-known file we can find, and any registry§8.3Well-known files are readable without asking; a registry is one reader of them, never the only way in (§8.4, §8.5).
Pools readPublic, active, tagged dating, whoever keeps them: a curator or another app§3.2Anybody may read a public Pool, including one another app keeps for its own people. We keep to dating ones and leave friendship Pools to friendship apps.
Same person, several PoolsShown once, behind the first door in the room’s order; the card names the other Pools§3.5Profiles and Pools are loosely coupled by URL, so one page can be in many Pools. Each Pool keeps its own yes; we only avoid showing a face twice.
Who you seePeople whose own page fits what yours says you’re looking for, and who are looking for someone like you. Everyone else is one choice away.§2.1Age, gender and who someone is looking for live on their page, not in the parsed profile. We read them there, never guess a blank, and say how many we left out and why.
Unlisted PoolsOnly with an address a person gave us, and only for that person§3.2Unlisted means the address travels by hand. We never show, count or hint at one to anyone else.
Invite-only PoolsNever read§3.2They are in no discovery file, and their own handshake is the only way in.
VerificationShown beside every profile, in words and with an icon§4.5A conforming client must show it. We also show it on who is asking.
OrderCurators’ doors (in town, then further out), then the apps’ own Pools, then unlisted; the curator’s own order inside§4.4Curators know their scene. We add no score and sell no placement.
Messaging rulesEach person’s own: accept_from, no_cold_messages; a Pool’s minimum sender level§7.2We check them before anything is sent, and say which rule held a message back.
Identity gatingUnverified senders are held back§7.1Stronger verification passes; the recipient decides the rest.
Block listsKindling’s public list and The Circular’s§7.3The same lists the Pools we read subscribe to, so safety travels with the people.
Leaving a PoolOne button, sent as a withdrawal to the Pool’s curator contact§5.3The Pool must act within 60 seconds. We forward it at once.
Adding anyoneImpossible. We can show a Pool’s request; we can’t make one.§5.1Silent inclusion is forbidden, and we have nothing to include anyone in.
Portraits and photosShown from each person’s own page, never stored§2.5Nothing of yours to delete when you leave. In this example every portrait is an illustration of an invented person.
NoindexRespected§2.7A page that says kindling-noindex is in no Pool, so it is never in our room either.
MessagesEmail underneath, with a thread in the app§6.1People without Roomful can still answer. Maya did.
CrawlingHonors Cache-Control, backs off on 429 and 5xx, identifies itself: Roomful/1.0 (+https://roomful.example/crawler)§10.3Hosts are small. We are polite.
VersionsReads newer minor versions; refuses a newer major one, and says so§12.2A manifest we can’t read correctly is one we don’t show.
MoneyNothing at the connection layer; thanks after an introduction worked, per the v0.2 draft§1.3Nobody pays to be introduced, or to see who is interested.

The Pools we read, and how

Discovery, step by step

  1. Fetch every .well-known/kindling-pool file we know of, and the Kindling registry’s list of them §8.3 §8.4. Nobody needs to give us permission to read these, and nobody pays to be in them. The files for the hosts below: Many Moons · Late Supper · Second Tide Books · Wren’s List · Card Catalog · Heartwood · Face Up · Sundial · Queer Harbor.
  2. Keep the Pools that are public, active and tagged dating, whoever keeps them. That is 8 Pools today: four kept by curators, and four that other apps keep for their own people (Card Catalog, Heartwood, Face Up and Sundial).
  3. Fetch each manifest, check it against pool_manifest.schema.json, and check its major version §12.2.
  4. Drop anyone whose page says noindex §2.7, and anyone on a block list we subscribe to §7.3.
  5. For a person who gives us an unlisted Pool’s address, read that Pool for them alone, and keep the address with their settings.
  6. Show each person once, behind the first door in the room’s order, and name their other Pools on their card §3.5.
  7. Read each person’s age, gender, who they’re looking for and portraits from their own page, which the parsed profile has no field for, and show a viewer only the people whose page and theirs fit each other, with everyone else one choice away §2.1 §2.5.
  8. Be polite to hosts: respect Cache-Control, back off on 429 and 5xx, and send a User-Agent with a contact URL §10.3.
PoolVisibilityTagsPeopleWhat we doManifest
Kept by curators
Many Moons
Many Moons: Harbor Counties
publicnon-monogamy, community, friendship, dating7Read for everyone: public, active, tagged datingharbor-counties.json
Late Supper
Late Supper Matchmakers
publicmatchmaking, dating1Read for everyone: public, active, tagged datingmatchmakers.json
Second Tide Books
The Singles Shelf
publicdating, books4Read for everyone: public, active, tagged datingsingles-shelf.json
Wren’s List
Date-Me Docs: Cascadia
publicdating, date-me-doc4Read for everyone: public, active, tagged datingdate-me-docs-cascadia.json
Kept by apps, for their own people
Card Catalog
Card Catalog: Cascadia
publicdating24Read for everyone: public, active, tagged dating. It is the Pool the app Card Catalog keeps for its own peoplecard-catalog-cascadia.json
Heartwood
Heartwood: Nearby
publicdating23Read for everyone: public, active, tagged dating. It is the Pool the app Heartwood keeps for its own peopleheartwood-nearby.json
Face Up
Face Up: Cascadia
publicdating22Read for everyone: public, active, tagged dating. It is the Pool the app Face Up keeps for its own peopleface-up-cascadia.json
Sundial
Sundial: Cascadia
publicdating20Read for everyone: public, active, tagged dating. It is the Pool the app Sundial keeps for its own peoplesundial-cascadia.json
Public, on the same hosts, and left alone
Many Moons
Solo Poly Supper Club
publicnon-monogamy, solo-poly, friendship2Readable, and left alone: not tagged datingsolo-poly-supper.json
Heartwood
Heartwood: Friends nearby
publicfriendship9Readable, and left alone: not tagged datingheartwood-friends.json
In no discovery file
Unlisted Pools
in no discovery file
unlistedNot shownNot countedRead only for the person who gave us the address. Today, 1 person has given us one.Address not printed
Invite-only Pools
in no discovery file
invite-onlyNot shownNot countedNever read, by us or any appNone

The discovery files of other hosts list 50 more public Pools, from 15 hosts including Ada Quillon, Cape Tarrow Alumni, Correo Lento and Drip Line. We read their entries in the discovery files and leave them alone: none is tagged dating.

For readers of this library only: to check our arithmetic, the unlisted manifests are here as files: Queer Harbor: queer-harbor-dating.json · Many Moons: orchard-street-household.json · Late Supper: tuesday-table.json · Late Supper: second-chapters.json. A real Roomful would never print those addresses, and in this example’s world it doesn’t.

Conformance

A compliant Pool UI

We are not a Pool host, so §11.1 doesn’t apply to us. §11.2 and §11.4 do.

  • Renders §4.5 verification levels alongside every profile. Every name card, every request, every sender line, in words and with an icon.
  • Honors the §7 spam layers. Identity gating, each person’s own rules, and two shared block lists, checked before anything is sent.
  • Supports §5.3 withdrawal. Leave this Pool is one button at the Pool’s door, and on the leave page.
  • Never performs silent inclusion. We host no Pools, so there is nothing to include anyone in, and we never send a request on a curator’s behalf.
  • And as a messaging client (§11.4): we validate envelopes against the schema, show the sender’s level, and apply §7.1 gating.

Safety that travels

The block lists we subscribe to

The same two lists every Pool we read subscribes to §7.3.

Kindling public block list

Version 3, published 20 September 2026. The list as JSON.

  • scrapekit/0.3 · implementation · scraping
  • promo-blast@mail.example · identity · spam

The Circular consortium block list

Version 8, published 27 September 2026. The list as JSON.

  • listed-them-anyway@mail.example · curator_identity · consent_violation
  • https://free-friends-now.example/pools/everyone.json · pool_url · consent_violation
  • bulk-intros@relay.example · identity · spam
  • scrapekit/0.3 · implementation · scraping

The messages this site shows are sample files, validated against the schema: an ask, a yes, a no, a first letter. The handshake Wren’s List sends Jonah: demo-request.json.

Honest limits

What the v0.1 schema can’t say yet

Where the spec text and a schema disagree, our JSON follows the schema. These are the gaps that touch a client like us.

  1. Verification level names (§4.5). The spec text names email-verified, oauth-verified, curator-vouched and unverified. The schemas use email, oauth, curator-vouched, unverified and cryptographic, and a curator is only ever email, oauth or cryptographic. Our JSON follows the schema; the screen shows words.
  2. Where a field came from (§2.3). The spec asks parsers to record which fields came from h-card and which were inferred, in an extraction_source field. parsed_profile.schema.json has no such field and forbids extra ones. For date-me docs, which rarely carry h-card, this matters: we can show a person their own provenance, and can’t pass it on.
  3. Age, gender and who someone is looking for (§2.4). parsed_profile.schema.json has no field for age, gender, who a person is looking for or what for, and forbids extra ones. It has photo_hints, image URLs only, with no alt text (§2.4, §2.5), and the Pools we read leave it empty. So a Pool can’t carry any of these, and every client reads them from the person’s own page, each time, in its own way. That keeps them where the person wrote them, but no Pool can vouch for them, and two clients may read the same page differently. We show what the page says in its own words, filter only on what it says, and never guess a blank.
  4. Mutual interest has no message (§7.2, §6.3). no-cold-messages means “require confirmed mutual interest”, but no message type says “I’d like to hear from you”. We send a system message with fixed text and no words from the sender, and treat a reply as the answer. Another client could do it differently.
  5. Message types (§6.3). The spec lists four types. kindling_message.schema.json has six, adding withdrawal and system. We use both.
  6. The Pool reference (§6.2). The spec calls it pool_ref; the schema calls it via_pool. Our messages use via_pool.
  7. The messaging rule names (§7.2). The spec names open-to-all, pool-mates-only, vouched-only, no-cold-messages and minimum-sender-verification. The profile schema has accept_from (anyone, verified, shared-pool, vouched, none) and a no_cold_messages flag, and no per-person minimum sender level; only a Pool can set one. We read the schema’s names.
  8. The discovery file (§10.2). The spec says it lists, for each Pool on a domain, pool_url and curator_contact among others. The schema has manifest_url, an optional operator for the whole file, and lists only discoverable Pools, so unlisted ones are left out. That suits a client: we learn nothing about an unlisted Pool from a discovery file.
  9. The version field (§12.1). The spec names kindling_version; every schema uses schema_version.
  10. Noindex is not privacy (§2.7). kindling_noindex: true means “don’t put me in any Pool”. Privacy inside a Pool comes from its visibility. A client must never treat noindex as “hide me from apps”, or visibility as consent.
  11. Thanks (v0.2 draft). Gratitude after an introduction is planned for v0.2 and has no field or message yet. Ours happens outside the protocol until it does.