Skip to the page

Invented app · built on Kindling · Why Kindling · The apps · The library · The spec

Bellows

Under the hood

How Bellows follows Kindling v0.1

Bellows is a client. It hosts no Pools and reads the ones the library keeps, by each Pool’s visibility and each person’s rules, with the shared kit’s canMessage and autoAccept. Every setting below links to the spec.

SettingValueSpecWhy
Pools hostedNone§10Bellows is a client. Its well-known file lists no Pools, and it owns no list of people.
Which Pools it readsPublic Pools for asks and offers, for anyone; unlisted Pools only for their members; never invite-only§3.2Visibility is the owner’s and the curator’s choice. An unlisted Pool’s address travels between members, so only a member’s client reads it.
Pools it never readsThe Check-In Circle, Midspan Students, and any Pool a site names for no app§3.2Foul Weather Friends and Midspan said so. A site’s word about its own Pool is final.
Who an ask is shown toPeople whose intent tags or about text fit the ask, in the Pools the asker chose§2.4What someone can give is on their own page. Bellows reads it and says which words were read.
Messaging rulesKindlingDemo.canMessage for each person and Pool: identity, accept_from, no_cold_messages, block lists§7.2A person’s rules decide. A held ask is not sent, and the reason is shown to the asker.
Pool sender floorEach Pool’s minimum_sender_verification is honored§7.1Friday Subs asks senders to be signed in with OAuth. Maggie is email verified, so a drum sub from her is held there.
Standing yesAuto-accept rules answer an ask at once when its tags include every tag in the rule, the Pool’s keeper is verified enough, and the Pool’s visibility is allowed§5.5Never silent: the owner gets a system message in the same minute and can undo it. At most five rules.
Ask windowUntil you need it, or the Pool’s own window, whichever ends first§5.2Friday Subs closes asks after 48 hours, from its governance_rules. Other Pools use the default 14 days.
TransportEvery ask, reply and notice is an ordinary message by email§6.1Leaving Bellows leaves your conversations where they are: in your mailbox.
Asks through a curatorSeen Work Curators, Harbor Trades, Midspan Mentors and Meals When It’s Hard route asks to their keeper§4.4Their charters say so. A vouch is local to one Pool, so the curator who saw the work does the asking.
VerificationShown in words and with an icon beside every person§4.5Everyone can see who is asking and who is answering.
PhotosNever copied. Portraits are illustrations described on each person’s own page§2.5Everyone here is invented, so nobody is photographed.
LeavingOne action. Bellows deletes what it holds; your Pools are untouched§5.3Leaving an app is not leaving a Pool. Withdrawing from a Pool is on that Pool’s own site.
Dormant and archived PoolsDormant Pools are still read; archived Pools take no new asks§9.4Continuity belongs to the Pool’s members, not to an app.
Loading a productindex.html#load-<product key>, from the Kindling registry, embedded when the app is built§8.3Asks, offers and Pools are scoped to that product’s Pools, and routed the same way: standing yeses, each Pool’s window, and curators where the Pool says so. Clear it and everything is as before.

The Pools it reads

17 Pools, linked to their files

Chosen from the data each time the app is built: Pools a site names for Bellows, the Pools in its brief, and public Pools tagged for asks and offers. The full library, with reasons, is on the About page.

PoolSiteVisibilityAsks goWindowSenders
Friday SubsFerry Room Playerspublicto each person48 hoursoauth
Horns and Strings for RecordsFerry Room Playerspublicto each personup to 14 daysany verified
Session PlayersSlack Waterpublicto each personup to 14 daysany verified
Fix-It Friday VolunteersThe Boardpublicto each personup to 14 daysany verified
Door and Sound CrewFerry Room Playerspublicto each personup to 14 daysany verified
Belay PartnersDrip Linepublicto each personup to 14 daysemail
The Saturday RunDrip Linepublicto each personup to 14 daysany verified
Big Game DayRain Checkpublicto each personup to 14 daysemail
Carpool to the CoastThe Boardpublicto each personup to 14 daysany verified
Rides to AppointmentsFoul Weather Friendspublicto each personup to 14 daysemail
Rides HomeSlack Waterpublicto each personup to 14 daysany verified
Lend and BorrowFoul Weather Friendspublicto each personup to 14 daysany verified
Meals When It’s HardFoul Weather Friendspublicto the curatorup to 14 daysany verified
Seen Work: Harbor TradesSeen Workunlistedto the curatorup to 14 daysemail
Seen Work CuratorsSeen Workpublicto the curatorup to 14 daysany verified
Cape Tarrow First-Gen AlumniCape Tarrow Alumnipublicto each personup to 14 daysany verified
Midspan MentorsMidspanpublicto the curatorup to 14 daysany verified

Manifests and the well-known file

No Pools of its own

Bellows hosts no Pool, so it has no manifest. Its well-known file says so, and names who runs the app §10.2. .well-known/kindling-pool

{
  "schema_version": "0.1",
  "pools": [],
  "operator": {
    "name": "Bellows, asks and offers from the Pools you belong to",
    "contact": "hello@bellows.example",
    "url": "https://bellows.example"
  }
}

Messages

What an ask looks like on the wire

An ask is an intro message through one Pool; a standing yes sends its owner a system message; a reply is a reply §6.2. Each file validates against kindling_message.schema.json.

messages/ask-horn-sub-to-kofi.json

{
  "schema_version": "0.1",
  "message_id": "msg-bellows-horn-sub-kofi",
  "type": "intro",
  "sender": {
    "identity": "lena@mail.example",
    "display_name": "Lena Brightwater",
    "verification_level": "oauth",
    "profile_url": "https://lena-books-the-ferry.carrd.example"
  },
  "recipient": {
    "identity": "kofi@mail.example",
    "profile_url": "https://kofi-mensah.example"
  },
  "via_pool": {
    "url": "https://ferryroom.example/pools/horns-and-strings.json",
    "id": "horns-and-strings",
    "name": "Horns and Strings for Records"
  },
  "sent_at": "2026-09-28T09:00:00Z",
  "subject": "A horn sub for Friday",
  "body": {
    "content_type": "text/plain",
    "content": "A horn sub for Friday. Needed Fri 2 Oct, 8:00 pm, the Ferry Room, Pier 3. Friday 2 October, the late set, doors at seven. Charts by email ahead of time. Paid by the band, never by the Pool. Lena Brightwater"
  },
  "transport": {
    "type": "email",
    "message_headers": {
      "X-Bellows-Ask": "a1",
      "X-Bellows-Needed-By": "2026-10-02T20:00:00Z",
      "X-Bellows-Expires-At": "2026-10-02T20:00:00Z"
    }
  }
}

messages/rule-notice-to-mae.json

{
  "schema_version": "0.1",
  "message_id": "msg-bellows-drum-sub-mae-rule",
  "type": "system",
  "sender": {
    "identity": "hello@bellows.example",
    "display_name": "Bellows",
    "verification_level": "email"
  },
  "recipient": {
    "identity": "mae@mail.example"
  },
  "via_pool": {
    "url": "https://ferryroom.example/pools/friday-subs.json",
    "id": "friday-subs",
    "name": "Friday Subs"
  },
  "sent_at": "2026-09-28T09:00:00Z",
  "subject": "Your rule said yes to Lena Brightwater’s ask for you",
  "body": {
    "content_type": "text/plain",
    "content": "Your auto-accept rule 1 (drums + sub, from curators signed in with OAuth, public Pools only) said yes for you to Lena Brightwater’s ask in Friday Subs: A drum sub for Friday, needed Fri 2 Oct, 8:00 pm. Lena knows you said yes and can write to you by email. You can undo it at any time, and Lena is told at once."
  },
  "transport": {
    "type": "email"
  }
}

messages/ask-drum-sub-to-mae.json

{
  "schema_version": "0.1",
  "message_id": "msg-bellows-drum-sub-mae",
  "type": "intro",
  "sender": {
    "identity": "lena@mail.example",
    "display_name": "Lena Brightwater",
    "verification_level": "oauth",
    "profile_url": "https://lena-books-the-ferry.carrd.example"
  },
  "recipient": {
    "identity": "mae@mail.example",
    "profile_url": "https://maecastellano.bandcamp.example"
  },
  "via_pool": {
    "url": "https://ferryroom.example/pools/friday-subs.json",
    "id": "friday-subs",
    "name": "Friday Subs"
  },
  "sent_at": "2026-09-28T09:00:00Z",
  "subject": "A drum sub for Friday",
  "body": {
    "content_type": "text/plain",
    "content": "A drum sub for Friday. Needed Fri 2 Oct, 8:00 pm, the Ferry Room, Pier 3. Friday 2 October, the early set. Paid by the door. Lena Brightwater"
  },
  "transport": {
    "type": "email",
    "message_headers": {
      "X-Bellows-Ask": "a2",
      "X-Bellows-Needed-By": "2026-10-02T20:00:00Z",
      "X-Bellows-Expires-At": "2026-09-30T09:00:00Z"
    }
  }
}

messages/referral-to-delphine.json

{
  "schema_version": "0.1",
  "message_id": "msg-bellows-electrician-delphine",
  "type": "intro",
  "sender": {
    "identity": "wendell@mail.example",
    "display_name": "Wendell Ashby",
    "verification_level": "oauth",
    "profile_url": "https://ashby-and-daughter.example"
  },
  "recipient": {
    "identity": "delphine@mail.example",
    "profile_url": "https://delphine-arceneaux.example"
  },
  "via_pool": {
    "url": "https://seenwork.example/pools/seen-work-curators.json",
    "id": "seen-work-curators",
    "name": "Seen Work Curators"
  },
  "sent_at": "2026-09-28T09:00:00Z",
  "subject": "A vouched electrician",
  "body": {
    "content_type": "text/plain",
    "content": "Delphine, could you ask the people you know? A vouched electrician. Needed Mon 12 Oct, 8:00 am, the Net Loft, Cannery Wharf. A subpanel and six new circuits for the workshop floor, two or three days from 12 October. Pay by the day, agreed between us, paid by Ashby and Daughter directly. Wendell Ashby"
  },
  "transport": {
    "type": "email",
    "message_headers": {
      "X-Bellows-Ask": "a3",
      "X-Bellows-Route": "curator",
      "X-Bellows-Needed-By": "2026-10-12T08:00:00Z",
      "X-Bellows-Expires-At": "2026-10-12T08:00:00Z"
    }
  }
}

messages/yes-from-june.json

{
  "schema_version": "0.1",
  "message_id": "msg-bellows-generator-june-yes",
  "type": "reply",
  "in_reply_to": "msg-bellows-generator-june",
  "sender": {
    "identity": "june@mail.example",
    "display_name": "June Okafor",
    "verification_level": "email",
    "profile_url": "https://june-okafor.notion.example/lend"
  },
  "recipient": {
    "identity": "maggie@mail.example"
  },
  "via_pool": {
    "url": "https://foulweatherfriends.example/pools/lend-and-borrow.json",
    "id": "lend-and-borrow",
    "name": "Lend and Borrow"
  },
  "sent_at": "2026-09-28T09:12:00Z",
  "subject": "Re: A generator, today",
  "body": {
    "content_type": "text/plain",
    "content": "Yes. I will bring it round at noon with the cords, and set it up outside, well away from her windows. June"
  },
  "transport": {
    "type": "email"
  }
}

messages/not-this-time-from-wes.json

{
  "schema_version": "0.1",
  "message_id": "msg-bellows-generator-wes-no",
  "type": "reply",
  "in_reply_to": "msg-bellows-generator-wes",
  "sender": {
    "identity": "wes@mail.example",
    "display_name": "Wes Adeyemi",
    "verification_level": "oauth",
    "profile_url": "https://wes-mixes.example/lend"
  },
  "recipient": {
    "identity": "maggie@mail.example"
  },
  "via_pool": {
    "url": "https://foulweatherfriends.example/pools/lend-and-borrow.json",
    "id": "lend-and-borrow",
    "name": "Lend and Borrow"
  },
  "sent_at": "2026-09-28T09:40:00Z",
  "subject": "Re: A generator, today",
  "body": {
    "content_type": "text/plain",
    "content": "Not this time. Mine is running the kitchen at the Mariners’ Hall until the power is back. Wes"
  },
  "transport": {
    "type": "email"
  }
}

messages/no-longer-needed-to-wes.json

{
  "schema_version": "0.1",
  "message_id": "msg-bellows-generator-wes-covered",
  "type": "system",
  "sender": {
    "identity": "hello@bellows.example",
    "display_name": "Bellows",
    "verification_level": "email"
  },
  "recipient": {
    "identity": "wes@mail.example"
  },
  "via_pool": {
    "url": "https://foulweatherfriends.example/pools/lend-and-borrow.json",
    "id": "lend-and-borrow",
    "name": "Lend and Borrow"
  },
  "sent_at": "2026-09-28T09:12:00Z",
  "subject": "No longer needed: A generator, today",
  "body": {
    "content_type": "text/plain",
    "content": "Maggie O’Rourke has what she needed: June said yes. There is nothing for you to do, and nothing was recorded about you. Thank you for being on the list."
  },
  "transport": {
    "type": "email"
  }
}

Block lists

Honored for every Pool that subscribes

Every Pool Bellows reads subscribes to both lists below, and Bellows checks each one before an ask is sent §7.3.

  • Kindling public block list, version 3, 2 entries. The file. The block list the Kindling project will publish under SPEC.md §7.3, for identities and implementations with confirmed abuse. The entries here are illustrative until the registry opens. No personal details are ever published.
  • The Circular consortium block list, version 8, 4 entries. The file. Shared by every member of the Circular consortium. Each member subscribes; any member may propose an entry, and two others must second it.

What the v0.1 schema can’t say yet

Where Bellows reads sentences instead of fields

  • There is no ask or offer in v0.1. An ask is an ordinary intro message sent through a Pool (§6.3). What someone can give lives in their page’s intent tags and about text; there is no field for an offer, how many, or when.
  • A message has no expires_at. The handshake has one; a message does not. Bellows carries the window in a transport header, X-Bellows-Expires-At, and in words in the body. The schema allows headers, so the files stay valid.
  • Auto-accept is defined for handshakes, not asks. §5.5 says a rule answers a request to join a Pool. Bellows reads the same rule as a standing yes to an ask whose tags include every tag in the rule, from a Pool whose keeper is verified enough and whose visibility the rule allows. The owner is always told, as §5.5 requires. There is no field to say a rule covers asks too.
  • A Pool’s window has no field. §5.2 calls the 14-day window configurable per Pool, and the manifest has no field for it. Friday Subs says “48 hours” in governance_rules, and Bellows reads that sentence.
  • “Ask the curator” has no field. Seen Work, Midspan and Meals When It’s Hard say in their charters that asks go to a keeper. Bellows reads their words; v0.1 cannot say it in a machine-readable way.
  • Is a keeper a pool-mate? pool-mates-only (accept_from: shared-pool) does not say whether a Pool’s curator counts as in the Pool. Bellows counts the curators a manifest lists, so Lena, who keeps Horns and Strings, can reach Kofi through it.
  • Verification level names differ. §4.5 says email-verified and oauth-verified; the schemas say email and oauth, and add cryptographic. The JSON follows the schemas.
  • Six message types, not four. §6.3 lists four. The schema has six, adding withdrawal and system. A standing yes’s notice is a system message.
  • No extraction_source. §2.3 names a provenance field that parsed_profile.schema.json does not have. Bellows says which words it read in its own interface instead.
  • Copies of a Pool have no field. Foul Weather Friends copies its Pools to the library each hour. v0.1 cannot say so except in a sentence; Bellows names the original address in via_pool.

Times in this example are UTC, as written in the files.

Keys

On a keyboard

A for a new ask. 1 to 5 for Your asks, Asks to you, Offers, Pools and You. J and K to move through a list. Y and N to answer an ask to you. Escape closes the ask you are writing. Every key has a button beside it.