Conversation
A standalone single-publisher profile of the design space SWIP-60 (PR #104) covers: one broker, one publisher, N subscribers, one hop. A cohort is a topic and a topic is a SOC address, so authorship needs no credential, no publisher list and no authenticated handshake — the ANCHOR address check re-establishes it from the signature on every message. The publisher role is bound to the opening stream and transfers on re-Open; the cohort's lifetime is that stream, which removes orphan cohorts and bounds Open as an allocation primitive. Specified standalone rather than as a profile of SWIP-60, with the protobuf inline and no compatibility claimed in either direction. It answers three questions SWIP-60 leaves open (dedup horizon, cohort lifetime, Open as an unbounded allocation primitive) and drops `closed` rather than restating a confidentiality claim an unauthenticated handshake cannot support. The two specs share the pubsub/1.0.0 protocol id, so the handshake carries the compatibility story: SWIP-60's field numbers are reserved, not reused, which is what lets a BPS-lite broker refuse a full-spec Open outright instead of silently decoding it with fields dropped. Note the one divergence that can fail silently for implementers: BPS-lite's ANCHOR applies its address constraint unconditionally, where SWIP-60 relaxes it under an explicit publisher regime. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E99KGsCW7dyKudy2WbpRco
zelig
left a comment
There was a problem hiding this comment.
review is not yet finished. submitting it so far nonetheless for discussion.
| ## Simple Summary | ||
|
|
||
| One broker, one publisher, many subscribers, one hop. A publisher opens a topic on a | ||
| broker and pushes single-owner chunks; everyone else connects and reads. Nothing else. |
There was a problem hiding this comment.
A publisher must explicitly connect to the broker and has the exlusuve right to publish messages. Just like with all subsequent modes, messages are of a shape of single owner chunks. In this specific case these chunks must be higher-index versions (updates) of a feed with the topic (the cohort topic bound to the feed). All other joiners of the cohort are subscribers.
|
|
||
| ## Abstract | ||
|
|
||
| BPS-lite is a real-time broadcast protocol in which a cohort is a topic and a topic is |
There was a problem hiding this comment.
BPS-lite is a real-time broadcast protocol a kind of push notifications on a channel that participants can subscribe to and a restricted set of participants can publish on.
Each channel defines its own cohort (a set of nodes), which are connected through a unique central broadcaster node, the broker. In BPS-lite, each node in the cohort will be directly connected to the broker, hence the moniker single-hop.
| a single-owner chunk address. The peer that opens a cohort is its publisher for as long | ||
| as that stream lives; every other peer is a read-only subscriber. Authorship needs no | ||
| credential, no publisher list and no handshake authentication: under the `ANCHOR` | ||
| binding the topic already names the only key that can produce a chunk hashing to it, so | ||
| authorship is re-established from the signature on every message. The cohort's lifetime | ||
| is its publisher's stream, which removes orphan cohorts and bounds `Open` as an | ||
| allocation primitive. |
There was a problem hiding this comment.
I am not sure i understand this (allocation primitive) but yes Open (open should be interpreted in terms of the connecting node, open connection to the channel, maybe we should call it Join) can create the channel for the broker.
Each channel is uniquely identified by a cohort specification. Turning it around, the cohort specification must contain all information that can distinguish channels, and exclude stuff that can change without changing the integrity of the cohort (secondary publishers).
Open message includes the cohort spec, if someone sends an Open message to the broker node, then the cohort spec is compared to existing open channels. IF one matches, then the candidate is trying to join if not then the channel is opened.
| is its publisher's stream, which removes orphan cohorts and bounds `Open` as an | ||
| allocation primitive. | ||
|
|
||
| It is a deliberate subset of the design space [SWIP-60][swip60] covers, specified as |
There was a problem hiding this comment.
subset it really is , and should not deviate though.
|
|
||
| It is a deliberate subset of the design space [SWIP-60][swip60] covers, specified as | ||
| its own document rather than as a profile: the wire format below is complete, and where | ||
| BPS-lite differs from SWIP-60 — most importantly in making `ANCHOR`'s address |
There was a problem hiding this comment.
No, so the ANCHOR first of should not be the first of all :) IT must be feed
What is relevant here is single explicit publisher in which case the messages are (supposed to be the ordered updates of a feed.
|
|
||
| ### Handshake | ||
|
|
||
| Publisher-first. The publisher fixes the cohort; subscribers join it. |
There was a problem hiding this comment.
no, anyone (so a subscriber also) can open, join a channel.
Note that if the joiners are not admins, they cannot publish (if they do, protocol violation), so the channel only has minimal resource demand, in fact only an entry in the broker nodes channels map.
There must be an inactivity deadline, so there is no trolling with opening a lot of channels and squat the broker node capacity with bogus idle cohorts.
If the subsciber has no active subscriptions, it can be disconnected.
Similarly, there must also be a maximum channel number per node connection so that a node cannot overwhelm the host broker with newly joined bogus channels while keeping a bonding legit one open.
|
|
||
| A `Publish` is accepted iff, in order: | ||
|
|
||
| 1. it arrived on the stream that opened the cohort; |
There was a problem hiding this comment.
A published SOC received by the broker is valid if
-!!! the ID of the SOC is an int > feed cursor
- suubstituting the ID with H(topic|int) the msg validates as a SOC
- and its owner is one of the publishers (in our case of singleton, the admin).
| 4. the wrapped CAC's BMT root matches its payload; | ||
| 5. the CAC address is not in the cohort's dedup window. | ||
|
|
||
| Failures 1–4 are protocol violations: the message is dropped, counted per peer, and |
There was a problem hiding this comment.
all failures are protocol violations and result in stream cleanup,
disconnect and blocklisting (ONLY if you are the broker).
| already failed. | ||
|
|
||
| On acceptance the broker enqueues a `Broadcast` on every subscriber stream in the | ||
| cohort, and on the publisher's own stream if it requested loopback. |
| orphan cohorts and any reclamation policy, and it bounds `Open` as an allocation | ||
| primitive: a peer can hold only as many live cohorts as it holds open streams. | ||
|
|
||
| ### Dedup |
There was a problem hiding this comment.
no dedup , see SWIP-65 how we handle missed items
…blisher over a feed
Rewrite of the first draft after review. BPS-lite is now a strict subset/base of
SWIP-60 rather than a divergent profile: the live-stream configuration with its wire
reduced to what it needs.
- cohort spec = {topic, FEED_TOPIC, admin}, and the spec is the cohort's identity
- one handshake frame, Join{CohortSpec, Auth?}: create-or-attach, anyone may do either;
no Hello/Open/Subscribe, no UNKNOWN_TOPIC
- Auth binds the identity to the stream, not the connection; a stream whose Auth
recovers to admin is a publisher stream, every other stream is read-only
- Ack{status} only: OK / FULL / REJECTED
- one Message{soc} frame both directions; the chunk as opaque chunk data with the bare
index in the id slot (SWIP-65 carriage)
- validation: publisher stream, index > cursor, valid SOC under keccak256(topic||index),
owner == admin; no dedup window, gaps allowed, retransmits counted not punished
- no loopback: deliveries to subscriber streams only
- lifetime by inactivity only — no service messages, no end-of-stream
- broker bounds: subscribers/cohort, cohorts/broker, cohorts/peer connection,
inactivity deadline, per-stream queue
- no history, no bandwidth incentive, no Bee API, one hop, one mode; implementation
section removed
- "Relation to SWIP-60" lists the amendments SWIP-60 needs to extend this wire
(Join, cohorts keyed by spec, no GENESIS, regime reduced to ALL, spectators
polarity, opaque chunk) and the one-line SWIP-65 exception
- number assigned: 74; file renamed to swip-74.md
One open point remains, marked (?): a second stream authenticating as the admin
while one is live.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…oth publisher streams A second stream authenticating as the admin while one is live is admitted as a publisher stream too; the per-cohort cursor arbitrates. No supersede rule, no refusal. No (?) marks remain. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
BPS-lite: counter-proposal@acud — thanks for the draft; the line comments above are the piecemeal version of this, The positionThe goal of PR #111 is right: a second-implementable target a tenth the size of SWIP-60,
Everything else follows. What BPS-lite is, in one paragraph:
The ladder: what each step addsCapability steps, not dated releases: each is a feature combination the family wants
Not on the ladder, orthogonal: bandwidth incentives (bps-bw-incentives, DISC: YES), Why Why the base has no end-of-stream: an end that is signed by the admin is a service What changes against PR #111, by section
Editorial: the file becomes Extra comments and clarifications
|
…SIS, regime = ALL, closed, opaque chunk SWIP-60 now extends the base wire of SWIP-74 (BPS-lite, PR #111) and changes nothing in it. bps.proto is revision 8, derived from SWIP-74's block. - one handshake frame, Join{CohortSpec, Auth?}; Hello/Open/Subscribe gone; cohorts keyed by the whole spec (create-or-attach, no UNKNOWN_TOPIC, squatting a topic under a wrong admin obtains nothing) - Ack is a status; the latest service SOC is delivered as the first Message on every newly attached stream not bound to the admin (marked open) - GENESIS gone: the spec is in every Join; the service feed starts at index 0 with the first ROSTER or END_OF_STREAM, and each service message carries its index - publisher regime reduced to the single value ALL; unset = the admin and whoever its roster ever names; ADMIN_ONLY and GRANTED gone; live-stream and spectator-jam are one spec - spectators (field 9) reverted to closed (field 8, unset = open audience) - one Message{soc} frame both directions, chunk as opaque chunk data; Publish, Broadcast and the field-level Soc gone; deliveries to every stream not bound to the publishing identity - Auth bound to the stream; a spectator carrying an identity is promoted in place when a roster names it; the admin's Join is admitted past the per-cohort bound - broker validation restated: duplicates are retransmits, never invalid; service SOCs recognised by id before the content path; a message from a non-publishing stream is a violation - the feed cursor stays SWIP-74's stricter special case; a full broker dedups on chunk address (several publisher feeds, SWIP-61 reordering) - ANCHOR under explicit authorship: no address check, topic is a rendezvous - capacity, streams and limits per cohort, not per topic; SWIP-74's bounds - API: spec parameters on every session, auth binds an identity, worked URLs updated, closed replaces spectators - conformance items 1, 2, 5, 6, 7, 8 updated; title, motivation, security and backwards compatibility aligned; SWIP-61 to be re-based on the Message frame Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A standalone single-publisher profile of the design space SWIP-60 (PR #104) covers: one broker, one publisher, N subscribers, one hop.
A cohort is a topic and a topic is a SOC address, so authorship needs no credential, no publisher list and no authenticated handshake — the ANCHOR address check re-establishes it from the signature on every message. The publisher role is bound to the opening stream and transfers on re-Open; the cohort's lifetime is that stream, which removes orphan cohorts and bounds Open as an allocation primitive.
Specified standalone rather than as a profile of SWIP-60, with the protobuf inline and no compatibility claimed in either direction. It answers three questions SWIP-60 leaves open (dedup horizon, cohort lifetime, Open as an unbounded allocation primitive) and drops
closedrather than restating a confidentiality claim an unauthenticated handshake cannot support.The two specs share the pubsub/1.0.0 protocol id, so the handshake carries the compatibility story: SWIP-60's field numbers are reserved, not reused, which is what lets a BPS-lite broker refuse a full-spec Open outright instead of silently decoding it with fields dropped.
Note the one divergence that can fail silently for implementers: BPS-lite's ANCHOR applies its address constraint unconditionally, where SWIP-60 relaxes it under an explicit publisher regime.