DRAFT 0.3.0 · definitions of the BSA kinds are a draft (round 5); two pilot circles run on test infrastructure · last checked 27 Oct 2026
On this page

The ledger on the relays: technical specification DRAFT 0.3.0

Plain-words text · Technical specification · All documents

English text rendered from the project's source documents. The Slovene original is on lananostr.site. Where this text and the definitions differ, the definitions win.

Precedence: where this document and definitions 0.3.0 differ, the definitions (docs/bsa-records-0.3.0.json) win; the difference is a bug to fix in this document. The definitions pin a frozen copy of this text (docs/0.3.0/) by its sha256 (meta.normative_spec); this living text may change afterwards, and a change reaches the definitions only when they are generated again, which then needs a new yes.

0. Status, markers, scope#

  • Status. Draft for definitions 0.3.0. Nothing is built, nothing is published, no EVENT has been sent. RELAY_PUBLISH_OFF=1 stays until the definitions are published (KIND 42893 by the Lana authority) and the project owner says yes (P7, proposal: one yes per definitions version and one per kind switched on). 0.2.0 was never published and is superseded.
  • Governing text. docs/nacela-razvoja.md (six principles, the project owner, 16 Oct 2026). A design that breaks one of them is wrong.
  • Markers. [Decided, date] = the project owner's decision · [Decided 16 Oct 2026, An] = the project owner's answer to question n of 16 Oct 2026 (source: _reports/2026-10-16-knjiga-na-relejih/odlocitve-2026-10-16.md) · [Decided 16 Oct 2026, 4a / 6a / 8a / 8b / 8c / 8e / 8f / 8i / 8j / start source] = the project owner's answer, the same afternoon, to a point the answers 1–9 had left open (same source file, section "Odgovori na odprte točke"); 6b fell with 6a · [Decided 16 Oct 2026, 6c] = the project owner's later answer the same day to the new open point 6c (»6c, da«; same source file, section "Odgovor na 6c") · [Decided 17 Oct 2026, C1 … C7] = the project owner's answers of 17 Oct 2026 to phase C (»1. DA - parametre shrani v posebni KIND … · 2. DA · 3. DA · 4. DA · … · 6. DA«; same source file, section "Odgovori na fazo C") and, after the explanation of points 5 and 1, »7 Da, Lahko narediš vse skupaj v fazi D …« (section "Odgovor na pojasnilo točk 5 in 1"): C1 the world rules (43920 BSA Rules; replaced on 23 Oct 2026 by E-1), C2 payments never pause for the morning (visit before touch), C3 refusals of non-members not booked, ACT_TTL_S and REJ_PER_AUTHOR_PER_DAY (circle parameters since E-1: act_ttl_s, rej_per_author_per_day), C4 no Heart member rejects a project alone, C5 the circle id and the replaceable circle key, C6 the first-seen rule in the letter to the relay owner (extra safety), C7 tz, morning hour and tzdata fixed at founding · [Decided 17 Oct 2026 (evening), 1A / 2A / 3A] = the project owner's answers of the evening of 17 Oct 2026 to three questions after phase D (»vsi da« to the proposal »1A, 2A, 3A«; same source file, section "Odgovori na tri vprašanja po fazi D"): 1A for now only the rules authority's one key signs 43920, several signatures (for example 3 of 5) before the first circle the project owner does not run joins, who the signers are: open (dropped on 23 Oct 2026 with E-1); 2A the tzdata version pinned at founding (part of C7), and witnesses compute the boundaries with it, never with a newer one of their own; 3A the transition (transition_days) runs per account from its own first receipt · [Decided 23 Oct 2026, E-1 … E-9] = the project owner's answers of 23 Oct 2026 before phase E (same source file, section "Odgovori pred fazo E" with its subsections "Dopolnitev" (E-5's duration confirmed, E-7 witnesses by lot, the accounting of closing an account confirmed) and "Referenca" (E-9, which replaces the "odpustnica" of the Dopolnitev)): E-1 the time values and limits are circle parameters, 43920 and the rules authority are retired (replaces C1, drops 1A, and makes C5's fixed 72 h a default), E-2 the Circle Heart (SL Srce kroga; one person: Heart member, SL član Srca; formerly "stewards"; members never vote on it), E-3 exclusion, readmission and closing old accounts, E-4 the Heart leads OWN processes, E-5 consensus votes instead of approvals and objections (replaces 8c), E-6 joining (open, by invitation, a maximum with a waiting list), E-7 witnesses by lot (the direction for phase I) and the Heart's vote only for exceptions, E-8 founding only by a member, one circle per founder key, one circle at a time, E-9 the reference (43921); D8 the acts for Heart and witness changes accepted; [Decided 23 Oct 2026, E-n Dopolnitev] = the same day's supplement · [Decided 23 Oct 2026, E-9 (a) / (b)] = the project owner's two answers on the reference (same source file, section "Odgovora na vprašanji o referenci") · [Consequence] = follows from the 16 Oct principles or answers, no new decision needed · (Open 3a, 8g, 8h) = a point still open, written as a proposal; 8d (no receiving project: the inflow stays in the reserve) is not open, it follows from decision 8 [A8] · (Qn) = proposal tied to open question n, waiting for the project owner's yes · anything unmarked is part of the recommended design and is also a proposal.
  • Number labels. [M] measured on 16 Oct 2026 · [C] relay configuration read on 16 Oct 2026 · [R] earlier report or memory · [E] estimate; the constants are in §10.1 so the arithmetic can be re-run.
  • Scope. This document is the ledger: the ledger rule, roles as they touch the ledger, the event model, the write path, reads, the daily checkpoint, gravity and duties, projects and the reserve, restore, the ledger relays, sizes and capacity. Governance rules for acts (the Circle Heart, witnesses, projects and votes, parameters, exclusion, readmission, closing accounts, recovery): docs/upravljanje-kroga.md. Cross-circle details: docs/releji-svetovna-mreza.md. Rates: docs/valute-in-tecaji.md. BSA ID and KIND 0: docs/bsa-id.md.
  • Glossary. witness = signer; node = the witness that proposes and orders blocks (the proposer); majority of witnesses = quorum q of n (3 of 4); Circle Heart (SL Srce kroga; formerly "stewards") = the circle's m Heart members (SL član Srca), k of whom act together (live circle: m = 4, the founder and three other Heart members [Decided 16 Oct 2026, 4a; the name: Decided 23 Oct 2026, E-2; the English names: Proposal]; a project needs at least project_approvals Heart "for" votes, 3 by default and never fewer, and no "against" [E-1, E-5]; k for other Heart acts: proposal, 3 of 4; for the circle key 3 of 4 [Decided 17 Oct 2026, C5]); the technical names stay: the act types steward_*, the tags steward and stewards_required, the act signer role value steward [Proposal, E-2]; there is no custodian (no deposits [Decided 16 Oct 2026, 6a]); circle id (rojstna številka) = the event id of the circle's found act (43916, t = found), the circle's name for ever [Decided 17 Oct 2026, C5]; genesis digest = the digest of block 1 (§3.1 rule 9); circle key = the key that stamps the 30910 mirror [Proposal], replaceable by circle_key_change [C5]; circle parameters (SL nastavitve kroga) = the time values and limits each circle sets within the bounds of the definitions (§3.1 rule 11) [Decided 23 Oct 2026, E-1]; there is no world rules record and no rules authority any more (43920 retired, its number reserved) [E-1]; act = 43916; statement = 43924; block = 43911 v3; daily seal = 43917 v3; snapshot chunk = 43918; circle head = 30915 v3; circle record (mirror) = 30910 v3, d = the circle id, signed by the circle key that the ledger's mirror at its mirror_of names (§3.7); member home = 30916 v3; rate quote (ponudba tečaja) = 43919 v3, signed by the node of the seller's (receiving) circle; project (projekt) = a public plan with an amount, opened by a project_propose act; project wallet (denarnica projekta) = the keyless system account written project:<id> (its point is derived in §3.8); reserve (rezerva) = the keyless system account reserve; vote (glas) = a vote act, "for" or "against" (an "against" with its short public reason) [E-5]; motion (predlog Srca) = a Heart member's proposal without money, put to a vote [E-5]; reference (referenca) = 43921, issued by itself after a member's "I want to leave" when its conditions hold [E-9]; exclusion (izključitev) = member_exclude [E-3]; parent circle (matični krog) = the circle a new circle grows from [E-8]; there are no objections (ugovor) any more [E-5].

1. The ledger rule [Decided 16 Oct 2026; Consequence]#

The circle's log on its relays is the ledger. A booking exists when its block carries the witness quorum and at least three of the circle's relays have stored that exact signed event [Decided 16 Oct 2026, A1]. Anything a computer holds that is not a private key, a few bytes of witness safety state, or a block in flight for seconds is a cache that can be thrown away and rebuilt from the relays, and that rebuild is tested every day.

1.1 On the relays (all public, all permanent) [Consequence]. Every payment note; every act (membership, invitation, vouch, rules acceptance, payment request, projects, motions and every vote signed by the voter's key (Q21) [E-5], exclusions and readmissions [E-3], account closes [E-3], the opening and closing of OWN processes, with no content [E-4; Proposal], parameter and cap changes, Heart, witness, rate-source and circle-key changes); every booking with every touched account's balance, wave, cap, carry, debt and counters after it; every move into and out of a project wallet or the reserve; every morning gravity line; every refusal with its reason; every daily seal and full snapshot; every rate quote the circle issued or relied on; every circle record version; every reference (43921) the circle issued [Decided 23 Oct 2026, E-9]; every member home (newest version); every witness's daily statement. Nothing is salted; no count is withheld; no threshold hides small circles.

1.2 Never published, never sent; not in BSA at all.

WhatWhyNote
Members' private keys (BSA WIF) [Decided 16 Oct 2026]the key is the accountbrowser memory only, as today
Witness, node, Heart member and circle-key private keyswhoever holds a key signson their holders' machines, file mode 600; never on a relay. The circle key only stamps the 30910 mirror [Proposal]; a stolen or lost one is replaced by circle_key_change (k Heart members, change_notice_s of notice, 72 h by default) [Decided 17 Oct 2026, C5; the notice a circle parameter: Decided 23 Oct 2026, E-1]. There is no rate-publisher key any more [Decided 16 Oct 2026, A7]
Session tokens, sign-in challenges, KIND 27235 login proofsa token is a loginalready local
Bank account numbers, IBANs, bank statements: not in BSA at all [Decided 16 Oct 2026, A6]BSA has no payouts ("the funds are never paid out"); bank matters belong to Lanano longer an exception to principle 1: the data does not exist in the system. There are no deposits either [Decided 16 Oct 2026, 6a], so no reference code and no confirmation of money paid in exists; no event and no setting carries bank data
The server address in the relay-owner letteroperational security, not ledgerstays only in the letter that is sent

Names [Decided 16 Oct 2026, A5]. The ledger refers to people only by HEX key (BSA ID). A name exists only in KIND 0 and in the member home 30916; both are replaceable by the person, and a relay keeps only the newest version. No ledger event (43910, 43911, 43916, 43917, 43918, 43919, 43921, 43924) ever copies a name; the join entry carries only the key. Said openly, not as a question: a name can remain in old copies of a profile that someone saved, and in free text that someone writes; the ledger itself does not carry it. Every free-text field (payment purpose, the reason of an "against" vote, an exclusion's reason, a motion's title and text, project title and description) shows "public for ever; do not write names, personal or bank data".

1.3 Irreducible local state (allowed).

WhatWhereSize, lifetimeIf lost
Sign-guard: per witness key, the highest height signed and its digesteach witness host, fsync'd before any signature is releasedtens of bytesthe key never signs again; a new key epoch is opened (§4.6)
Write-ahead log of signed blocks not yet on 3 relaysnode host (and every witness in quorum mode)secondsonly non-final blocks; members' apps resend the same note (same id, same answer)
Private keys§1.2—key loss rules: docs/upravljanje-kroga.md; a lost circle key: circle_key_change (§3.4) [C5]

1.4 Disposable caches (rebuilt from the relays, never the copy of record). The app's whole SQLite database (every ledger, support, request, project, seal, profile, relay-list and settings table; only the session columns of the user table are local by nature); day files, which become a local copy of the published snapshot chunks; database backups (only for a faster restart); phone caches (IndexedDB); read-gateway and CDN caches; witness memory.

1.5 Removed from the current design. [Consequence]: the seal salt secret and salted s1 lines; the 20-account threshold for counts and gravity totals; the standby's encrypted daily export of balances; phones' encrypted proof backups; member-only proofs; payment requests as local rows deleted after 30 days; "a new relay gets only the newest circle record"; outbox held meaning "never sent, so switching on does not send the backlog" (now: held until the project owner's yes, then the whole backlog from genesis, §9.4). [Decided 16 Oct 2026]: the money cap while single-witness (A3); the legal-review gate before the first entry and 43925 free text beside the chain (A5); payout acts (payout_request, payout_cancel, payout_sent, payout_reject), the pout entry, the held_out field, the reserve bank statement and the payout circuit breaker (A6; the payout code was removed from the app by plan step D0 on 17 October 2026, after a copy of the live database showed no deposit and no payout); the hourly rate of one key for every circle and the rate panel with a median (A7); the single common-good account, the fund key and paying orders from it (A8); the founder gate of P3 (A9). [Decided 16 Oct 2026, afternoon]: deposits (6a: "a different system altogether"): the acts deposit_declare, deposit_cancel, deposit_attest, deposit_reject, deposit_correct, the dep and corr entries, the custodian role and custodian_name, the paid_in field (it counted only deposits less payouts, so with neither it has nothing to count), the main account (system:main booked only deposits, deposit corrections and payouts), question 12, the deposit alarm and 6b; the wave grows only with what a member receives. The deposit code was removed from the app by plan step D0 on 17 October 2026, after a copy of the live database showed no deposit. 8j: the xrefund entry and the refund to a payer by public decision; the project limits carried over from orders (8b). [Decided 23 Oct 2026]: the world rules record 43920 BSA Rules (retired before it was ever published; its number stays reserved and is never reused, reserved_unused [Consequence]), the rules authority (meta.rules_authority), meta.rule_values, the constant RULES_NOTICE_S, the rules tag of the found act, of seals and of heads, the line g3|rules, the rule entry rules_adopt and the restorer's 43920 records (E-1; decision 1A goes with them); project_approve, project_object, project_object_withdraw, project_answer, the status stopped, the line o3|objection and the refusal reasons objection_window, notice, objection_stands, unanswered and no_consent (E-5, which replaces 8c); steward_nominate and steward_vote (E-2: members never vote on the Heart); param_approve, param_object, step_approve and the lines o3|param and o3|step (E-1, E-5); "at most three circles per founder" (E-8).

2. Roles as they touch the ledger#

RoleHow manyHoldsSignsTrusted for
Memberanyown key (BSA WIF)43910 notes, 43916 acts (its votes among them [E-5]), own 30916own acts only
Witness [Decided 16 Oct 2026, A3]n = 3f+1 per circle: default 4 (f = 1, q = 3) [A3]; 7 (q = 5) above about 10,000 members [Proposal, Open 3a]; bootstrap n = 1, labelled, no money cap [A3]; until there are enough circles to draw from, one witness, the circle's own computer, publicly labelled; later drawn by lot among the circles' computers (the direction for phase I) [Decided 23 Oct 2026, E-7]witness key, sign-guard, write-ahead log, a relay with the circle's full historyblock digests, daily statementscollectively: at most f of n faulty; individually nothing
Node (proposer)one witness per height (phase 1: fixed, the circle's box; phase 2: rotating, same format [Proposal])samethe block event itself; the circle's 43919 rate quotes as seller [Decided 16 Oct 2026, A7]nothing: every other witness re-checks every number; a quote binds only the node's own circle and the payer accepts or refuses it
Heart member (the Circle Heart, SL Srce kroga; formerly "steward"; the technical role value stays steward [Proposal]) [Decided 16 Oct 2026, A4 and 4a; the name: Decided 23 Oct 2026, E-2]live circle: m = 4, the founder and three other Heart members [4a]; k for other acts: proposal, 3 of 4; the founder seats the first Heart in the found act; the Heart adds and removes Heart members (k, with change_notice_s); members never vote on the Heart [E-2]own keyacts needing human judgement: Heart and witness changes (a witness change also fails on one Heart "against" and is only for exceptions [E-7]), parameter changes within the bounds (param_propose, k [E-1]), motions [E-5], exclusions and readmissions and account closes (the larger of k and 3 [E-3, E-10]), the opening (any member [E-10]) and closing (one Heart member) of OWN processes [E-4; the acts: Proposal], project closings (8e), rate-source changes (proposal), circle-key changes (circle_key_change, k of m with change_notice_s of notice, 72 h by default [Decided 17 Oct 2026, C5; Decided 23 Oct 2026, E-1]), recovery (k, and no Heart "against" [E-7]); every member votes on projects and motions, and a project needs at least project_approvals Heart "for" votes and no "against" [E-5]collectively, inside public rules with notice periods
Verifier, auditoranyonenothing secret43924 statementsnothing: a statement carries its evidence
Circle relays [Decided 16 Oct 2026, A2]; bootstrap operators (Q14)≥ 4 per circle, ≥ 3 operators (bootstrap ≥ 2, Q14)the circle's eventsnothingstorage only; never trusted for completeness
Archive relaysanywhole histories, no 10-year lower limit, no expirynothingextra copies
Root relays [Decided 14 Sep 2026; A2]the relays in KIND 38888 (four today)the directory (§9.1)nothingdiscovery only
Rate source [Decided 16 Oct 2026, A7]one per circle, chosen by the circle itself [A7]: an outside service, some day a record on the relays; changed by a Heart act rate_source_set [Proposal]; start [Decided 16 Oct 2026, start source]: the ECB daily reference rate, its date shown in the app, quotes valid 10 minutes (quote_ttl_s, a parameter of the quoting circle: 600 s by default [E-1])nothingnothing in BSA: the node reads it and signs its own quotenothing beyond the seller circle's own quote, which the payer accepts or refuses
Gateways, indexersanyonecachesnothingspeed and name search; can hide, never forge
Circle key [Decided 17 Oct 2026, C5: replaceable; what it signs: Proposal, follows from A3 and A8, not confirmed by the project owner; would replace the part of P2 about what it signs]one in office per circle (held by the app and the creator [Decided 16 Oct 2026]; P2, still a proposal: the founder's browser plus a paper copy); the first one is named in the found act; replaced by circle_key_change (k Heart members, change_notice_s of public notice (72 h by default [E-1]), a roles entry booked by the witnesses) [C5], with the new key's proof of possession and in office from the next block [Proposal]; never the founder's, a witness's or a Heart member's key [Proposal]keythe 30910 mirror only, and once the binding of the found act in block 1 (circle_sig) [Proposal]alone, nothing: a mirror counts only if it is signed by the circle key that the ledger's mirror at its mirror_of names (at the height of a key change already the new key; for blocks it is in office from the next height), its tags without g equal that mirror and its g names the pinned genesis digest; after a replacement a record by the old key with a mirror_of at or above the change never counts

Where witnesses come from [Decided 16 Oct 2026, A3; the direction: Decided 23 Oct 2026, E-7]. Witnesses are computers. The direction for phase I (docs only, no code in 0.3.0) [E-7]: witnesses are drawn by lot among the circles' computers, from a public random number (for example a block of the Lana chain); the draw is known in advance and changes regularly; a new witness loads the circle from its latest seal; open for phase I: fake circles, matching the load, absent witnesses. Until there are enough circles to draw from, a circle has one witness, its own computer, publicly labelled (decision 3, unchanged for 0.3.0); the acts that add, replace or remove a witness stay in 0.3.0 and are for exceptions (for example removing a misbehaving witness until the next draw): signer_propose, signer_replace, signer_remove and recovery need the larger of k and 3 Heart members "for" (the endorsement form; a Heart of fewer than three cannot make them) and no Heart "against" (§3.4) [E-7; the threshold: Decided 23 Oct 2026, E-10]. Rule in the ledger: at most one witness per operator [Decided A3]; whether a seven-witness circle may allow two per operator is Open 3a (proposal, see docs/upravljanje-kroga.md); "fewer than q" is not enough for safety; witnesses are named publicly with their operator; any witness can be replaced by the circle's own governance. "Independent" (principle 5) means "can replace any particular partner", not "needs nobody".

3. Event model (definitions 0.3.0)#

3.1 Rules for every kind#

  1. Ledger facts are regular events in 40000+ (strfry stores them as regular events on all four root relays [C]). "Newest" pointers are addressable (30000–39999) and every version of 30910 is also an entry in the ledger, and every 30915 mirrors a 43917 seal, which is kept for ever. 30916 is the exception: it carries name words, so its versions are never copied into the ledger; the ledger holds only the join entry with the key [Decided 16 Oct 2026, A5]. Never 10000–19999 (replaceable: 166 definitions once collapsed into one [R]) or 20000–29999 (ephemeral, 300 s [C]).

  2. No expiration tag, no NIP-70 - tag on any BSA kind; readers treat such events as invalid. Ledger keys never sign KIND 5 or KIND 62.

  3. Byte budget: every event ≤ 100,000 bytes serialized (relay limit 131,072 [C]) and ≤ 1,000 tags (limit 5,000 [C]), tested at maximum field lengths (180-character purpose, 15-digit amounts). Multi-account events are cut by bytes, never by a count.

  4. Integers only: amounts in minor units as base-10 strings, at most 15 digits, BigInt end to end (today's checks allow 16 digits and compare as floating point; this changes); carry in micro-units; times in unix seconds; rates in whole ppm.

  5. Indexed single-letter tags only where a reader queries (all single-letter tags are indexed on all four relays [M]): c circle id (every BSA event names its circle by ["c", <circle id>]; the found act by ["c", ""], because its own id is the circle id; a payment note by ["c", <circle id>, "", "from" | "to"]; the 30910 and 30915 carry the circle id as d; no BSA kind uses the a tag) [Decided 17 Oct 2026, C5: the circle id; the tag shapes: Proposal], h height, m day, i chunk, p party, e reference, t type, d pointer, n name words in 30916 (x, a content hash for 43925, is no longer used [A5]). The payer counter n in 43910 is single-letter too, so relays index it although no reader queries it. Signatures and chain fields use multi-letter tags (qs, prev, seq, at, root, genesis), which strfry does not index.

  6. Tag values are scoped to the circle: scope16 = the first 16 hex characters of the circle id (test_vectors.circle_id); h = <scope16>:<height>, m = <scope16>:<YYYY-MM-DD>, i = <scope16>:<YYYY-MM-DD>:<index> (unscoped values would match every circle on a shared relay).

  7. HEX only, never npub. Canonical JSON (RFC 8785) for every content; every number in a content is a base-10 string. Text [Proposal]: every free text is one line, without control characters, bidirectional controls or broken Unicode, within its length (purpose 180, act text (a motion's text and the reason of a vote or an exclusion among them) and statement text 500, project and motion title 100, circle name 80, rate-source description 300); values that enter state lines never contain |; idem is 32 lowercase hex made by the app, never typed by a person.

  8. Trust anchor (Q10) [Decided 17 Oct 2026, C5 and C6; the details: Proposal]: the circle id together with the genesis digest. The circle id is the NIP-01 event id of the circle's found act (43916, t = found, first tag ["c", ""]), signed by the founder: the circle's name for ever. It is a fingerprint, not a key: nobody can steal it, and another found act is another circle, so a thief cannot found a false circle under the same name (his found act has another id). The genesis digest is the digest of block 1 (rule 9), whose genesis entry embeds that found act. The circle link and QR carry the circle id, at least two relay hints and the genesis digest as an extra pin. A reader accepts a chain only if its block 1 embeds the found act whose id is the circle id and its digest is the pinned genesis (from the link, or the first g it saw for the circle id); it never follows another. The circle key can be replaced [C5]: it only stamps the 30910 mirror (and, once, the binding of the found act in block 1, circle_sig) [Proposal]; k Heart members sign circle_key_change [C5] with the new key's proof of possession [Proposal], and after change_notice_s of public notice (72 h by default; no longer fixed [Decided 23 Oct 2026, E-1]) a roles entry, booked by the witnesses [C5], puts the new key in office from the next block [Proposal] (§3.4, §3.5); from then on a 30910 by the old key with a mirror_of at or above the change never counts, and every seal and 30915 head names the circle key of the newest mirror at or below the seal's last block (at the height of a key change already the new key) [Proposal]. A stolen and a lost key are replaced the same way; the circle id never changes. Said openly: anyone can publish a 30910 that names a circle id; only the one signed by the circle key that the ledger's mirror at its mirror_of names (at the height of a key change already the new key; for blocks it is in office from the next height), whose tags without g equal that mirror and whose g names the pinned genesis digest, counts. The first-seen rule of the root relays (keep the first g and founder per circle id; relay/ledger-write-policy.py, mode root, pins them only when the relay holds the circle's found act and the record's founder is its author (or, for a circle configured on the relay, when its configured circle key signed the record), after every plugin of the relay accepted the record, so nobody can claim a circle id first: Proposal, §9.2) is a request in the letter to the Lana relay owner (plan phase G) and is now only extra safety [Decided 17 Oct 2026, C6].

  9. Identity by digest [Proposal]. A block or seal is named by its digest = the NIP-01 hash of [0, pubkey, created_at, kind, tags without the qs tags, content], never by its event id (the id changes with the set and order of witness signatures). Two digests at one height, each with a valid quorum of the witnesses in office there, or two valid seals for one day, are a fork; a block without such a quorum is not the circle's and is ignored [Proposal]. Witnesses sign sha256("lb-block/3|" ‖ digest) for a block and sha256("lb-seal/3|" ‖ digest) for a seal, never the digest itself, so a witness signature is never a valid Nostr signature of a stripped copy; qs tags are sorted by witness HEX. Every reference to a digest also says where to find it: a block by its height, a seal by its day; NIP-10 e tags carry only event ids.

  10. Booking windows [Proposal; the act's validity: Decided 17 Oct 2026, C3; a circle parameter: Decided 23 Oct 2026, E-1]. A note or an act is booked only at created_at − AT_TOLERANCE_S (5 s, a constant) ≤ at ≤ its expires; an event id is booked at most once (duplicate). Every act carries expires, at most act_ttl_s after it was signed (a circle parameter: 604,800 s = 7 days by default [C3, E-1]), judged by the parameters in force at its booking [Proposal, E-1; this replaces the earlier reading "the version in force at its signing"]; during a parameter change's notice apps sign with the stricter of the two values [Proposal]. Booked act ids (and note ids, §3.8) stay in the state (a3 lines) until they expire, so an old act can never be booked again, also not by a reader that starts from a seal.

  11. Circle parameters [Decided 23 Oct 2026, E-1: the time values and limits are set per circle, the values of the definitions are only defaults, and the Circle Heart changes them within the bounds; the bounds and how a change takes effect: Proposal]. There are no world rules any more: KIND 43920 (BSA Rules) is retired, its number stays reserved and is never reused (reserved_unused) [Consequence], and with it go the rules authority (meta.rules_authority), meta.rule_values, the constant RULES_NOTICE_S, the found act's rules tag, the seal's and head's rules tag, the line g3|rules, the rule entry rules_adopt, the restorer's 43920 records and decision 1A (no world signer) [E-1]. Fixed for every circle (definitions, not parameters) [E-1]: a project needs at least 3 Heart "for" votes and no "against" (project_approvals ≥ 3, §3.9); the money and gravity computation; the constants XCHECK_MARGIN_S 60, AT_TOLERANCE_S 5, QUOTE_MARGIN_S 120 and RATE_STALE_ALERT_S 432,000 (their values: proposal; clock margins and the node's own timing; changing one needs a new definitions version). The circle parameters, in this order (the found act and param_propose carry all of them, each ["param", <name>, "<integer>"]; a value outside its range, vote_min_s > vote_max_s, or vote_max_s ≥ open_lapse_s is bad_template; units and ranges also in meta.circle_parameters of the definitions):

    ParameterStart (default)Bounds [Proposal]MeaningDecided
    band_ppm_day330 ppm/day0 – 330gravity on the plus up to the wave (§7.3); never stronger than today's23 Oct 2026, E-11
    excess_ppm_day22,840 ppm/day0 – 22,840gravity on the plus above the wave; never stronger than today's (half in 30 days)23 Oct 2026, E-11
    transition_days60 days60 – 3,650the transition after an account's first receipt (3A); never shorter than today's23 Oct 2026, E-11
    rest_after_days183 days0 (off), or 183 – 3,650resting after days without giving; never sooner than today's (1 to 182 is invalid)23 Oct 2026, E-11
    wave_cap100,000,000 minor1 – 999,999,999,999,999a member's cap, set at its member_joinas before
    w_max_s1 s1 – 10a block's longest at span (§3.5)as before
    vote_min_s259,200 s (72 h)86,400 – 2,592,000the shortest vote23 Oct 2026, E-5 Dopolnitev (72 h by default, a circle setting)
    vote_max_s1,209,600 s (14 days)86,400 – 2,592,000; below open_lapse_sthe longest voteproposal
    project_approvals33 – 9Heart members whose "for" a project needs (never the proposer's or the recipient's)23 Oct 2026, E-1 (at least 3; a circle may require more)
    close_notice_s259,200 s (72 h)86,400 – 2,592,000between the k-th project_close and the project_return16 Oct 2026, 8e; a circle setting: E-1
    receive_lapse_s7,776,000 s (90 days)604,800 – 31,536,000a receiving project not full this long after it opened lapses16 Oct 2026, 8e; E-1
    open_lapse_s2,592,000 s (30 days)604,800 – 31,536,000a project not opened this long after publication lapsesproposal; E-1
    change_notice_s259,200 s (72 h)86,400 – 2,592,000the notice of a change of the circle key, witnesses, Heart members, k, relays, recovery and parameters, and of a resignation23 Oct 2026, E-1 (72 h is a default, not fixed)
    xcheck_s604,800 s (7 days)86,400 – 2,592,000the 8j check after an xout without xdone or xundo16 Oct 2026, 8j; E-1
    quote_ttl_s600 s300 – 3,600a rate quote's expires ≤ created_at + this (the quoting circle's value)16 Oct 2026, start source; E-1
    note_ttl_s600 s60 – 3,600a 43910's expires ≤ created_at + this (each circle its own, §4.5)decided (10 minutes); E-1
    act_ttl_s604,800 s (7 days)86,400 – 2,592,000a 43916's expires ≤ created_at + this17 Oct 2026, C3; E-1
    rej_per_author_per_day201 – 1,000refusals of one author booked per morning day (from one morning boundary to the next, §3.5); above it the intake answers 429 and books nothing17 Oct 2026, C3; E-1
    exclusion_s7,776,000 s (90 days)86,400 – 31,536,000how long an exclusion runs23 Oct 2026, E-3 (3 months, a default); 90 days: proposal
    invite_ttl_s604,800 s (7 days)3,600 – 2,592,000how long an invitation is valid23 Oct 2026, E-6 (invitations); 7 days and one-time: proposal
    invite_only00 – 11: a join needs an open invitation (an excluded key's application excepted)23 Oct 2026, E-6
    max_members0 (no limit)0 – 999,999,999the most members (status member or frozen); 0 = no limit; above it the waiting list23 Oct 2026, E-6; 0 = no limit: proposal

    How a parameter changes [Decided 23 Oct 2026, E-1: the Heart changes them within the bounds; the act's shape and the notice: Proposal]: param_propose is a Heart act in the endorsement form (§3.4): the first act carries the full new set, endorsements name it, k Heart members in office; at most one is open at a time (a second proposing act is repeated). With k signers in office the notice starts: notice end = the k-th act's at + max(change_notice_s, the old value of every parameter in seconds whose value changes) [Proposal, E-1: a change of a time value takes effect only after the time it replaces has run out, never retroactively; so a stolen key cannot skip the warning]. Its o3|change line (type param_propose) has expires = the notice end. At the notice end it is a duty: the first block whose first at reaches it starts (after the morning header) with the rule entry params_effective (in [the param_propose id]); from that entry on the block is under the new parameters, and the g3|param:<name> lines and g3|params_h (= that height) change. If fewer than k of its signers are in office then, it is void (the line ends, no entry). Never for a time before the notice end [completed 24 Oct 2026, plan step E4x; E-1: never retroactive]: the change waits while a missed morning whose boundary is at or before its notice end has not opened yet (catch-up after an outage, §7.4) and while a duty due before its notice end is due at the block; those mornings and duties are booked first, under the parameters in force before the change, and params_effective is the first entry of the first block start at which neither holds. An 8j check, an xdone or a reference_return is never such a duty (the node books them when it has read the other circle, and a hold's check at was fixed at its xout), so none of them holds params_effective back [clarification, 25 Oct 2026, D4 N22]. Said openly: when the node was down at the notice end, a change takes effect a block or a morning later than its notice end, never earlier, and a duty due after the notice end that the same waiting block books is booked under the old parameters too [review of E4x, 24 Oct 2026]. param_approve, param_object and the effective tag are gone. Running deadlines keep their length (never retroactive [Consequence of E-1; as before]): each is recorded as a due time when it starts, with the parameters in force then: a vote's end, a project's open lapse and receive lapse, a close's due, a hold's check, an exclusion's end, an invitation's end, a change's notice end (the lines of §3.8). Example: a project opened under a 90-day receive lapse keeps 90 days even if the parameter later says 30. A member's cap stays when wave_cap changes. TTL checks (act_ttl_s, note_ttl_s, quote_ttl_s, the refusal limit) use the parameters in force at the booking; during a parameter change's notice apps sign with the stricter of the two values [Proposal]. Across circles each circle applies its own values to what it books (note_ttl_s, quote_ttl_s and xcheck_s: §4.5); a mismatch can only end in a refusal and a return to the payer, so nothing is lost and both sums stay 0 [Proposal, E-1].

  12. Encodings [clarification, 17 Oct 2026 (D4 review)]. A domain-separated message is sha256 of an ASCII prefix followed by the 32 raw bytes of the digest or id for "lb-block/3|", "lb-seal/3|" and "lb-found/3|" (the found act's id), and by text for "lb-genesis/3|", "lb-circle-key/3|", "lb-home/3|" and "lb-system/3|" (ids, digests and keys as 64 lowercase hex characters, numbers in decimal, fields joined by |); the examples confirm both. An event's size (rule 3) is the number of UTF-8 bytes of JSON.stringify({id, pubkey, created_at, kind, tags, content, sig}) in that key order, without spaces. Every character limit (rule 7) counts Unicode code points. BSA text holds no control characters (rule 7), so the NIP-01 serialization of a valid BSA event equals JSON.stringify of the array [0, pubkey, created_at, kind, tags, content].

3.2 The kinds#

KindNameClassSignerLives onSize [E]
0Lana profile (exists; minimal: key + name; lanaWalletID filled by the app) [Decided 16 Oct 2026]replaceablememberroot (Lana)~0.5 KB
38888Lana System Parameters (exists; only relay tags read) [Decided 14 Sep / 15 Oct 2026]addressableLana authorityroot—
42893Kind definitions (exists) (Q20)regularLana authorityroot—
30910 v3Circle Record: a mirror of the governance state; d = the circle idaddressablethe circle key that the ledger's mirror at its mirror_of names (the key its circle_key tag names)root + circle relays; every version also in the ledger1.5–2.5 KB
30915 v3Circle Head: the newest seal, for discovery; d = the circle idaddressablethe seal's node, with quorumroot + circle relays~2.5 KB
30916 v3Member Home (mandatory) [Decided 16 Oct 2026]; replaceable by the member, never copied into the ledger [A5]addressablemember, attested by a witnesscircle relays; root while borrowed (Q16)~0.8 KB [M 739 B]
43910 v3Payment Noteregularpayerembedded in 43911; standalone only as censorship evidence0.8–1.0 KB standalone, ~0.37 KB embedded
43911 v3Circle Block: the ledgerregularnode, with ≥ q witness signatures insidecircle relays (≥ 4) + archives (+ Lana relays while borrowed)1.9 KB (one payment, one witness) to ≤ 100 KB
43916Circle Actregularthe acting personembedded in 43911; standalone copy optional0.5–1.2 KB
43917 v3Day Seal (checkpoint)regularnode, with quorumcircle relays~2 KB
43918Snapshot Chunkregularnode (valid through the seal's roots)circle relays≤ 100 KB, ~450 lines
43919 v3Rate Quote (repurposed; no longer an hourly rate reference) [Decided 16 Oct 2026, A7]regularthe node of the seller's (receiving) circlethe seller circle's relays; the payer's circle republishes every quote its blocks rely on; archives~0.5 KB [E]
43920retired: BSA Rules, the world-wide rule values, never published [Decided 23 Oct 2026, E-1]; the number stays reserved and is never reused (reserved_unused) [Consequence]————
43921Reference (new) [Decided 23 Oct 2026, E-9: a new kind; the number and the format: Proposal]regularthe node of the circle the person leaves, right after the block that books the reference entry has its quorumthat circle's relays; the new circle republishes a reference its member_join names [Proposal]~0.7 KB; up to ~18 KB with 100 + 100 project ids [E]
43924Statement (attestation or challenge)regularany witness, verifier, auditorcircle relays (+ partners)~0.7 KB + evidence ids
30917 (optional, later)Service Offer (relay, witness, archive, index operator)addressableoperatorroot~1 KB
  • Retired for good from 0.1.0: 30911–30914, 43912–43915. 43910 and 43911 are not retired: they return as v3. 0.2.0's "retire 43910/43911" is withdrawn.
  • 43925 is not defined: the free text beside the chain was dropped with the legal-review gate [Decided 16 Oct 2026, A5]. Free text stays inside the signed note or act, public, with the field warning.
  • 0 events of 43910–43919 and 23910 exist on any Lana relay today [M]; the local catalogues define none of 43916–43999 [R]; 43920 was checked free on the four Lana relays and in kinds.json on 17 Oct 2026 [M] (now retired, never published, kept reserved [E-1]); 43921 was checked free on 23 Oct 2026: 0 events on the four relays of 38888, no definition, not in kinds.json 2.88.0 [M]. Every number is re-checked against the live kinds.json and all four relays (COUNT, read only) before publication.

3.3 43910 v3 Payment Note (member-signed cause)#

kind 43910, pubkey = payer HEX, created_at = signing time
content: purpose, ≤ 180 characters, PUBLIC FOREVER; the field warns
         "public for ever; do not write names, personal or bank data" [Decided 16 Oct 2026, A5]
tags, in this exact order (the canonical template; the app emits exactly this):
  ["p", <receiver HEX or system address>]
  ["c", <payer circle id>, "", "from"]
  ["c", <receiver circle id>, "", "to"]                 only across circles
  ["amount", "<minor>"] ["currency", "<payer currency>"]
  ["to_amount", "<minor>", "<receiver currency>"]       only across circles: the payer signs both amounts
  ["e", <43919 quote id>, "", "quote"]                  only across currencies: exactly one, the seller
                                                        circle's quote the payer accepted [Decided 16 Oct 2026, A7]
  ["n", "<payer's own counter: 1, 2, …>"]
  ["prev", "<payer's previous note id in this circle> | genesis"]
  ["expires", "<unix, ≤ created_at + note_ttl_s>"]      note_ttl_s: a circle parameter, 600 s by default
                                                        [E-1]; each circle judges it by its own (§4.5)
  ["idem", "<32 lowercase hex, made by the app>"]       optional
  ["e", <request act id>, "", "request"]                optional; the booked purpose is this note's content
  ["e", <project act id>, "", "project"]                optional; a contribution names its project here
  ["v", "3"]
  • Embedding: inside a block the note is stored in a compact canonical form (the variable fields plus created_at and sig) from which the exact NIP-01 serialization, id and signature are rebuilt. The node rebuilds and verifies every note before booking it; a note that does not round-trip the frozen v3 template is refused (bad_template), never repaired. The template is frozen per definitions version for ever.
  • A member's KIND 5 can delete only a standalone copy, never the block that embeds the note.
  • After expires an unbooked note can never be booked. A note is booked only at created_at − 5 s ≤ at ≤ expires, and its id at most once. Its expires is checked against note_ttl_s of the parameters in force at the booking, in each circle by its own value (the payer's circle at the xout, the receiving circle at the xin; a smaller value there refuses the note, and the payer gets the held amount back, §4.5) [Proposal, E-1]; during a parameter change's notice, and across circles, the app signs with the smaller of the two values [Proposal].
  • Across currencies the note's expires is never later than the quote's expires (§3.7), and to_amount is the quote's conversion of amount, exactly.

3.4 43916 Circle Act (person-signed cause)#

kind 43916, pubkey = the actor (member, invitee, Heart member, witness, founder)
tags: ["c", <circle id>]   the found act: ["c", ""], because its own id is the circle id [C5]
      ["t", <act type>]
      the type's tags in act_types order (["e", <ref>, "", <role>]… ["p", <subject HEX>]… typed value tags:
      amount, parameter name/value …)
      ["after", "<height>"] (optional) ["expires", "<unix, ≤ created_at + act_ttl_s>"] (always)   validity window;
      act_ttl_s is a circle parameter (604,800 s = 7 days by default) [C3, E-1]
      ["idem", …] (optional) ["v", "3"]
content: human text where the type has one (≤ 500 characters, PUBLIC, with the field warning; the app
         never puts a name into it [Decided 16 Oct 2026, A5])
GroupAct typesSigned by
Foundingfound (first tag ["c", ""]: its event id is the circle id, the circle's name for ever [Decided 17 Oct 2026, C5]; then, in this order: name, code, circle_key (the first circle key; never the founder's, a witness's or a Heart member's key [Proposal]), currency, tz, tzdata, morning hour (tz, morning hour and tzdata fixed at founding for 0.3.0 [Decided 17 Oct 2026, C7]), the first witness set, quorum, proposer, the first Heart (steward tags: the founder seats it [E-2]) and k, relays, archives, an optional ["bootstrap", "Q14"] label (open question 14, not decided), rate source, api, every circle parameter in the order of §3.1 rule 11 (["param", <name>, "<integer>"]) [E-1], the start, ["parent", <parent circle id>, <parent genesis digest>] (required except for the root, the live circle [Decided 23 Oct 2026, E-8; the tag: Proposal]) and right after it ["e", <the founder's 43921 id>, "", "reference"] (the founder's reference from the parent circle; required with parent [Proposal; that the founder needs it: a consequence of E-8 and E-9]), definitions version (Q20)); signed by the founder and bound to the first circle key by that key's signature in block 1 (circle_sig, §3.5); there is no rules tag any more: the world rules are retired, and the quote validity and the number of project approvals are circle parameters [E-1]; no money cap [Decided 16 Oct 2026, A3]founder
Membership [invite and join: Decided 23 Oct 2026, E-6 and E-9; the tags: Proposal]invite (["p", <HEX>]; one-time; booked as o3|invite, valid invite_ttl_s [E-6]), vouch, join (the key only, never a name [A5]; optional ["e", <invite id>, "", "invite"] and ["e", <43921 id>, "", "reference"]; how it is judged and admitted: §3.11), leave (a member's "I want to leave": member_leave, then the reference when its conditions hold [E-9]; an excluded key's: only its leaving line; an applicant's: it withdraws its o3|join; §3.11), rulesmembers / invitee
Exclusion and readmission [Decided 23 Oct 2026, E-3]member_exclude (["p", <member HEX>], optional ["e", <OWN case event id>, "", "own"] [Proposal, E-4]; text required: a short public reason [Proposal]; the larger of k and 3 Heart members [E-10], the endorsement form, no notice: effective at the act that reaches them; the excluded key never counts toward its own exclusion) · member_readmit (["e", <join act id>, "", "join"]; the larger of k and 3 Heart members [E-10], no notice; membership only, never a Heart seat [E-3]) (§3.11)Heart members
Closing an old account [Decided 23 Oct 2026, E-3; the accounting confirmed 23 Oct 2026]account_close (["p", <HEX>], text required: the public reason [Decided 23 Oct 2026, E-10 4A]; max(k, 3) Heart members [E-10], the endorsement form, no notice) (§3.11)Heart members
Requestspay_request (amount, text, expiry)receiver
Projects [Decided 16 Oct 2026, A8; details 8a, 8b, 8e, 8j; the vote: Decided 23 Oct 2026, E-5; Open 8g, 8h]project_propose (title, description, amount, recipient (a member when the act is booked, Open 8h: a recipient who left, never joined, is frozen or is excluded is refused not_member [clarification, 19 Oct 2026 (D3 review)]; for a step raise [8j] the circle's world-step [Proposal]), ["duration", "<seconds>"] right after p (vote_min_s ≤ duration ≤ vote_max_s of the parameters in force at its booking, else not_allowed; set at publication, never changed [Decided 23 Oct 2026, E-5, confirmed 23 Oct 2026]), ["img", sha256, url] (Q24)) · project_consent, project_decline (the recipient's consent, as today for an order [Proposal]; none for a step raise, whose recipient is keyless; a proposer who is the recipient consented with the project_propose itself, so no project_consent is needed and one is refused repeated [clarification, 19 Oct 2026 (D3 review)]) · project_withdraw · project_close (k Heart members; the project returns its money to the reserve after close_notice_s, 72 h of public notice by default [8e, E-1]). A project is decided by a vote (vote, next row) [E-5]: project_approve, project_object, project_object_withdraw and project_answer are gone. No Heart member rejects a project alone: there is no project_reject [Decided 17 Oct 2026, C4]proposer / recipient / proposer / Heart members
Votes and motions [Decided 23 Oct 2026, E-5; the tags: Proposal]vote (["e", <project_propose, motion or witness change id>, "", "proposal"], ["vote", "for"] or ["vote", "against"]; "against" requires its short public reason as text, "for" carries none; one vote per member per proposal: the newest counts, changeable until the vote end; the same choice again is repeated; booked only with at < the vote end, else vote_ended; on a witness change only Heart members in office vote [E-7]) · motion (a Heart member puts any other proposal to a vote: ["title", <≤ 100 characters>], ["duration", "<seconds>"]; text required: the proposal) (§3.9)any member (a witness change: a Heart member) / a Heart member
Step outwardraise: a project [Decided 16 Oct 2026, 8j], a project_propose whose recipient is world-step (row above) [Proposal]; lower: step_propose (negative amount), decided by a vote like a project [E-5]; the builder does not book a lowering in 0.3.0 (no complete rule) [Proposal]; step_approve is gonemember
Parametersparam_propose (the full new set of circle parameters, §3.1 rule 11; a Heart act in the endorsement form, k Heart members; at most one open at a time) [Decided 23 Oct 2026, E-1: the Heart changes them within the bounds; the shape: Proposal]; param_approve and param_object are goneHeart members
Rolessteward_accept (signed by the new Heart member: its consent to a steward_add, naming that act), steward_resign, signer_propose, signer_accept, signer_resign, signer_remove, signer_replace, steward_add, steward_remove, stewards_required_set (the last five: proposal (D4 review, round 3, 17 Oct 2026), accepted with the acts for Heart and witness changes [Decided 23 Oct 2026, D8]; upravljanje-kroga.md; signer_propose, signer_replace and signer_remove also fail on one Heart "against" [E-7]), proposer_swap, relay_change, rate_source_set (source id and public description; the quote validity is the circle parameter quote_ttl_s, 600 s by default [E-1]; replaces rate_panel_set; who signs and when: proposal), refusal_list_set (by circle id), circle_key_change (tags key and pop, given below the table; text optional; k Heart members by the endorsement form, change_notice_s of notice (72 h by default [E-1]) from the k-th act; then a roles entry puts the new key in office from the next block; refused if pop does not verify (bad_template), or if the new key is the key in office, the founder's, a witness's or a Heart member's key [Decided 17 Oct 2026, C5; the proof of possession, the act shape, the new key in office from the next block and the rule that the new key is not the key in office, the founder's, a witness's or a Heart member's key: Proposal]). steward_nominate and steward_vote are gone: members never vote on the Heart; the Heart adds and removes Heart members [Decided 23 Oct 2026, E-2]the new Heart member / Heart members / witness
Recoveryrecovery (new witness set, last height found anywhere; it also fails on one Heart "against" [E-7])the larger of k and 3 Heart members [E-10]
OWN processes [Decided 23 Oct 2026, E-4: the Heart leads them and only a decision reaches the ledger; who opens and closes: Decided 23 Oct 2026, E-10]own_open (["p", <HEX>], optional ["e", <OWN case id>, "", "own"]; any member, alone, at once; books o3|own) · own_close (one Heart member in office; ["e", <own_open id>, "", "open"]); no content of a process ever reaches the ledgerHeart members / one Heart member
Member safety (Q11)guardians_set, freeze, key_movemember / the guardians the member named

circle_key_change tags [Decided 17 Oct 2026, C5; the shape and the proof of possession: Proposal]: ["key", <HEX of the new circle key>], ["pop", <the new key's BIP-340 signature over sha256("lb-circle-key/3|" + circle id + "|" + new key HEX + "|" + created_at)>], created_at being the act's own, in decimal (proof of possession: nobody can name a key someone else holds; and since an act is booked only within act_ttl_s of its created_at, a pop is good for its own act only, so an old one can never be used again).

There are no payout acts and no reserve statement act [Decided 16 Oct 2026, A6], no deposit acts and no custodian_name [Decided 16 Oct 2026, 6a], and no act for a refund decision [Decided 16 Oct 2026, 8j], and no project_reject: no Heart member rejects a project alone [Decided 17 Oct 2026, C4]; and no approval, objection or answer act [E-5], no steward_nominate or steward_vote [E-2], and no param_approve, param_object or step_approve [E-1, E-5]. An act has effect only once booked; it is judged by the actor's role at the booking height. The rules each act type follows (notice periods, who may approve, limits) are in docs/upravljanje-kroga.md.

Changes that need k Heart members (relay_change, rate_source_set, refusal_list_set, signer_propose, signer_remove, signer_replace, steward_add, steward_remove, stewards_required_set, proposer_swap, recovery, circle_key_change, project_close, param_propose [E-1], member_exclude, member_readmit and account_close [E-3]; for member_exclude, member_readmit, account_close and the witness exceptions signer_propose, signer_replace, signer_remove and recovery the threshold is the larger of k and 3, and a Heart of fewer than three members cannot propose them (not_allowed) [Decided 23 Oct 2026, E-10]; own_open is no Heart change since E-10 (any member books it alone); a Heart member in office who leaves the circle loses the seat: a roles entry with acts = [its leave act] right after the leave's entries (all of them: member_leave, the returns of its receiving projects with their drains and openings, and the leave's end-of-entry work, its own reference when issued at once, an account close or an admission from the waiting list among it; that leave is never cut by size) [clarification, 25 Oct 2026, D4 N21], k lowered to the number left when above it; the last Heart member cannot leave (not_allowed), and in a block that holds a roles entry already the leave is answered roles_taken [Decided 23 Oct 2026, E-11]; one open change per subject: a second proposing member_exclude or account_close of one key while one collects is refused repeated [D4 N28]; every act of an exclusion, a readmission or an account close, the proposing act and each endorsement, is judged against what it names at its booking (an endorsement after the target changed is refused) [D4 N29; clarifications of 25 Oct 2026]; the five acts of the D4 review and a person's own steward_resign or signer_resign, a change of its own committed change_notice_s later as a duty: proposal (D4 review, round 3, 17 Oct 2026), accepted [Decided 23 Oct 2026, D8]) [Proposal; k distinct Heart members: ruling of 16 Oct 2026; for circle_key_change: Decided 17 Oct 2026, C5; for an exclusion: Decided 23 Oct 2026, E-3, and its threshold, the larger of k and 3: Decided 23 Oct 2026, E-10]: one Heart member's proposing act carries the change; each further Heart member signs the same act type with only ["e", <proposing act id>, "", "proposal"], booked before the proposing act expires. An endorsement never names another endorsement. The change is committed (a roles entry; for project_close the project_return after its notice; for param_propose the params_effective at its notice end; for member_exclude, member_readmit, account_close and own_open their own entries at the k-th act, §3.11) only with the proposing act and endorsements from at least k distinct current Heart members, and for signer_propose, signer_remove, signer_replace, steward_add, steward_remove, stewards_required_set, relay_change, recovery and circle_key_change only after change_notice_s of notice from the k-th act (a circle parameter, 72 h by default, no longer fixed [Decided 23 Oct 2026, E-1; formerly C5]); for param_propose the notice of §3.1 rule 11; member_exclude, member_readmit, account_close and own_open have no notice: they take effect at the k-th act [E-3; for own_open: Proposal]; signer_propose, signer_replace, signer_remove and recovery are committed only while no Heart member in office has "against" as the newest vote naming the change (otherwise their roles entry is refused, answered not_allowed) [Decided 23 Oct 2026, E-7]; each act is used once; the o3|change line (§3.8) tracks the collection, the notice (from the act with which k Heart members in office were reached) and the time left to commit. Who is in office at a height [Ruling of 16 Oct 2026]: the circle key, the witnesses (with their since_h and until_h), the quorum, the node, the Heart and k are read from the ledger itself: the genesis mirror for block 1, then the mirror of each roles entry from the next block on (a block books at most one roles entry, and block 1 books none: its genesis mirror is the mirror of height 1 [Proposal]; so a height names one mirror, height 1 too). A roles entry changes the circle key only when its proposing act is circle_key_change, and then to exactly the key that act names [Decided 17 Oct 2026, C5]. A block is signed by a quorum of the witnesses in office at its height, a day seal by a quorum of the office after its last block (§3.6) [Proposal]; a Heart act counts only if its author was a Heart member in office when it was booked, and a roles entry needs k such Heart members still in office at the roles entry (k as in office there), except the roles entry of a resignation, which needs none (proposal (D4 review, round 3, 17 Oct 2026)). A due resignation that can no longer take effect (the person was removed meanwhile, or it would leave no Heart member or witness) is void: its line goes without an entry, so a resignation never halts a circle (proposal (D4 review, round 3, 17 Oct 2026)); void resignations are dropped first at a block start, and the earliest of the others takes the block [clarification, 19 Oct 2026 (D3 review)]. A due resignation's roles entry goes in a block of its own, before that morning's morning block (§7.4), and a second resignation of the same role by the same key while its first is open is refused repeated [proposal (D3 review, 19 Oct 2026)]. A reader that checks a run of blocks that does not start at block 1 takes the office from the mirror of the newest genesis or roles entry below its first height and the circle parameters in force from the newest genesis or params_effective below it (the found act, or the param_propose it names, carries the full set) [Consequence of E-1], both read from the ledger, never from a circle record (a record can be older or newer than the part it checks); without them what depends on them is unverifiable, never assumed, and a witness never signs what it cannot verify. What began before the run is unverifiable too, never refused and never passed: an endorsement whose proposing act, a roles entry whose acts, an xdone or xundo whose hold, a project_open whose project, or a refusal whose key's membership lies before the run; a witness checks those against its own state below the run [Proposal]. The run is judged block by block, each block under the parameters in force for it: each params_effective in it must name a param_propose whose notice end its block's first at reaches, with k of its signers in office; each note's and act's TTL is judged by the parameters in force at its booking [Proposal, E-1], and each running deadline by the due time recorded when it started [Consequence of E-1: never retroactive].

3.5 43911 v3 Circle Block (the ledger)#

kind 43911, pubkey = node of this height (a member of the witness set S(h))
created_at = at_last
tags:
  ["c", <circle id>]
  ["h", "<scope16>:<height>"]                         gap-free from 1 (genesis)
  ["prev", "<digest of block h-1>"]                  "" for h = 1; the hash chain
  ["genesis", "<genesis digest>"]                    with the circle id the trust anchor (§3.1 rule 8), on every block; "" in block 1 itself (multi-letter: not indexed)
  ["seq", "<first>", "<last>"]                       circle-wide entry numbers, gap-free
  ["at", "<first>", "<last>"]                        booking times, unix seconds, never decreasing (first: the first entry's at, last: the last entry's; clarification, 19 Oct 2026, D3 review)
  ["root", "<entries root>", "<lines root>", "<state root>"]
        entries root: RFC 6962 over the canonical entries of this block
        lines root:   RFC 6962 over the leaves (s3 lines with full HEX, last_h from before the block, §3.8)
                      of the accounts touched here
        state root:   sparse Merkle root over the whole decision state after this block (§3.8), which holds
                      the circle key in office (g3|circle_key) and the circle parameters in force
                      (g3|param:<name>, g3|params_h), so every block names them
  ["p", <party HEX>]…                                every party touched, incl. keyless system parties
  ["m", "<scope16>:<date>"] ["morning", <date>, <boundary_unix>, <cutoff_seq>, <params_h>, <tzdata>]   every block that books a grav entry
  ["more", <trigger_seq>, <work_seq>, <leaver HEX or "">, <"leave"|"exclude"|"">, <act id or "">]       only a block the size rule closed with work left (the block split, below)
  ["qs", <witness HEX>, <BIP-340 signature over sha256("lb-block/3|" ‖ digest)>] × ≥ q, sorted by witness HEX   (the node's own included)
  ["v", "3"]
content (canonical JSON): {"e": [entries…], "l": [lines…]}
  • Digest = sha256 of the NIP-01 serialization [0, pubkey, created_at, 43911, tags without the qs tags, content]. It covers the party list, every entry and every line, so a gateway cannot reassign a line to another party. The event id and the node's event signature then cover the qs tags too. The digest names the block (prev, genesis, src, the seal's head); the event id does not, because it changes with the set and order of qs signatures.
  • Lines in content refer to parties by their index in the p list; the leaves that the lines root and the state root are computed over carry the full HEX, so a light client's Merkle path binds its own key. The p list is in the order in which the entries first name the parties (inside an entry: party first, then each move's from and to).
  • Closing rule: a block closes at the first of: the intake queue is empty (an idle circle books one entry per block at once); W_max seconds after its first entry (the circle parameter w_max_s: 1 s at founding; proposal: a circle above about 10,000 members raises it to 2 s by param_propose); 100,000 bytes serialized (about 90 ordinary payments, 38 at maximum field lengths, measured on the 0.3.0 examples); a block whose work would pass 100,000 bytes closes after its last whole step and the next block continues it (the block split, below). A block never spans a morning boundary: the open block closes at the boundary. So a block's at span is at most W_max (the parameter w_max_s; a check without the parameter lines uses 10 s, the top of its range), and no block can hold a whole notice or vote (the parameters' lower bounds are one day) [a consequence of this rule; the check: Proposal].
  • The block split [completed 24 Oct 2026, plan step E4x: the size rule of every block (this section, §3.9 "Size"); the form: Proposal]. A block is at most 100,000 bytes, and its work never stops the circle: no duty, drain or admission is ever refused or left out because it does not fit, and there is no intake limit on projects [8b]. The work of a block is a fixed sequence of steps: each duty of its start (one entry), and in the end-of-entry work of every entry (§3.9) one reserve_move with the project_full, the recipient's visit and the project_pay it brings (a project an entry filled exactly, by a give or by a visit's deduct, is paid without a step of its own when the drain reaches it in the opening order; a cut before an older project's reserve_move leaves it receiving and full, which is allowed only while work is carried, and the continuation pays it [review of E4x, 24 Oct 2026]), one project_open, one account_close, one reference, one member_join with its reference_grant, and one project_return of a person who leaves, is excluded or whose account closes (with its own drain and openings). When the next step would take the block over 100,000 bytes, the node closes the block after its last whole step: the block carries ["more", <trigger>, <work>, <leaver>, <via>, <act>] (the trigger the carried end-of-entry work names, the seq of the newest entry booked outside end-of-entry work, and the person whose receiving projects are still to be returned, with how the person went and the act; "" when none; a cut right after a people step, an account_close, a reference or a member_join from the waiting list, carries the trigger of the work in progress, never that step's own seq [D4 N23]; a cut between whole entries (between the duties of a block's start, or between a person's returns) has no work in progress: trigger = work [D4 N27]; the returns of an account close of a member line are a leave's: via leave and the proposing account_close act [D4 N24]; clarifications of 25 Oct 2026) and books nothing else (a later cause waits for a later block, answered block_full). The next block starts at the cut block's last at, so nothing new falls due in between; it opens no morning and books no params_effective (the next block without carried work does); it begins with the carried work, exactly where it stopped and in the same order: the person's remaining project returns, each with its drain and openings; the rest of the end-of-entry work, naming the same trigger; then, unless two or more mornings are pending, the duties still due. A new cut carries again. The carried work keeps its order and every move, booked at the cut block's last at; the duties the continuation then books are those due by that at, right after the carried work and before any later cause (a due resignation waits for the first block without carried work) [review of E4x, 24 Oct 2026: this is the rule itself, not a claim that every at equals that of an uncut block]. A step books at least one entry (a duty that ends without an entry, such as a close whose closers in office fell below k, is no step), and every block books at least one step, so the work always ends. Where within that the node cuts is its own choice, as every block boundary is: a replay of a block with more stops after that block's last seq; a block without more is replayed with all of its work. A reader checks: every block at most 100,000 bytes; a block with more is followed by a block that starts at its last at and begins with a rule entry; a block with more may leave out duties due at its start, its successor books them; a restorer whose seal's h_to carries more continues that work first (§8.1). A Heart member's leave is never cut: its roles entry follows its entries in the same block [E-11]; when they would pass 100,000 bytes the leave is refused too_big and books nothing, and the member first declines the projects it receives (each decline's work is cut like any other). Said openly: about 100 small projects waiting behind a big one, or about 450 tiny projects whose votes end in the same second, take a few blocks of the same second; payments wait those few blocks.
  • Morning header: its tzdata is the version the circle pinned at founding [Decided 17 Oct 2026, C7 and (evening) 2A; the check: Proposal], and a witness computes the boundary with that version, never with a newer one of its own [Decided 17 Oct 2026 (evening), 2A]; a witness without that version signs no morning block and no seal (how it keeps the version is its own implementation) [Proposal]; how a verifier identifies, obtains and checks a release: §7.2.
  • Sum rule: the circle's sum of balances is 0 after every block (principle 4); every witness checks it.

Entry types ([seq, type, at, …]):

TypeBooksEmbeddedConsequences carried
genesisthe founding state; opening lines if an existing circle migrates (proposal: a migrating circle's Common Good balance opens as the reserve; there is no main line to carry [6a], since the live circle had no confirmed deposit at the check of 10 October, re-checked on a copy of the live database before migration)found act, rebuilt with ["c", ""] (its id is the circle id [Decided 17 Oct 2026, C5]); the mirror the found act gives (§3.7); circle_sig, the signature of the circle key the found act names over sha256("lb-found/3|" ‖ found id) (below the table)the circle key in office (from block 1), the circle parameters of the found act and its parent circle (when it names one [E-8]), as governance lines (below the table); the Heart, witness set, relays, rate source; then, in block 1, the rule entry start right after it (§3.9) [6c]: block 1 without it is invalid
paymember → member43910grow = min(amount, cap − wave), then settled = min(debt, max(0, balance)) read after the receipt and the grow move (today's createTransfer order), each moved receiver → reserve as one move, then drain() (§3.9) [Decided 16 Oct 2026, A8]; the amounts follow today's wave-growth and waiting-flow rules unchanged, only the destination changes (one step row per receipt, as today with Common Good renamed); a pay to a left or excluded line with a minus is a settlement: amount ≤ −balance (never above 0), no grow and no settled move (§3.11) [Decided 23 Oct 2026, E-9: anyone may settle a debt; the shape: Proposal]
givemember → the named receiving project up to amount − received, the rest → reserve; a give naming no project → reserve; then drain() (replaces cg)43910cover: the plus only, amount ≤ max(0, balance) (today's rule; Open 8g); a project wallet has no wave, so a give makes no wave growth; a named project that has ended is refused not_found [clarification, 19 Oct 2026 (D3 review)], an open one that is not receiving not_receiving [Proposal]
xout, xin, xdone, xundocross-circle legs through the world account43910 in xout and xin (across currencies with its 43919 quote id); the partner circle's genesis digest (g) on every leg; the partner's block as [height, digest] (src), or for the 7-day check the partner's consecutive seals as [day, digest] and the height range they cover (§4.5)hold, final, undo (a timeout alone never undoes; after 7 days the payer's circle reads the receiver circle's sealed ledger and books xdone or xundo by rule, naming that evidence [Decided 16 Oct 2026, 8j], §4.5); xin moves grow/settled to the reserve like pay, except a settlement to a left or excluded line with a minus (≤ −balance, no grow, no settled) [E-9]; xundo moves world → payer; an excluded or left key may book an xout of its plus, amount ≤ max(0, balance), never the wave [E-3; for a left key: Proposal]
actany act without a money effect (project proposal, motion, vote, request, invitation, parameter proposal, exclusion, readmission, account close, OWN opening and closing)43916recorded in order, so deadlines are deterministic
rulea transition a public rule makes due: start in block 1 only (origin → reserve, §3.9) [6c]; member admitted (member_join) or gone (member_leave); a booked rules act (member_rules, below the table) [proposal (D4 review, 17 Oct 2026)]; member_exclude, reference, reference_grant, reference_return and account_close (§3.11) [E-3, E-9]; project_open, reserve_move, project_full, project_pay [8a], project_lapse [8e], project_return [8e] (§3.9); the end of a vote (vote_pass or vote_fall, §3.9) [E-5]; request expired (request_expire); parameters effective (params_effective, at a param_propose's notice end, §3.1 rule 11) [E-1]; a step lowering (step_lower) [Proposal]. There is no rules_adopt any more [E-1]none: the rule and its input ids are namedthe bookings the rule makes
roleswitness, Heart, node, relay, rate-source and circle-key changes, resignations, and the loss of a Heart seat by an exclusion (§3.11) [E-3]; carries the new 30910 mirror (tags without g; mirror_of = this height; the circle id, the code and the founder never change, nor do the currency, tz, tzdata and the morning hour, which are written at founding [one currency per circle: Decided 16 Oct 2026; tz, tzdata and the morning hour: Decided 17 Oct 2026, C7; the check: Proposal]; the circle key changes only when the proposing act is circle_key_change, and then to exactly the key it names, in office from the next block (state line below the table) [Decided 17 Oct 2026, C5; in office from the next block: Proposal]); at most one roles entry per block [Proposal], so mirror_of names exactly one mirror per height and a second roles entry can never undo what the first put in office (for example a circle key change); block 1 books no roles entry: its genesis mirror is the mirror of height 1 [Proposal]none: acts is exactly [the id of the proposing act] (or of the resign act) [proposal (D4 review, round 3, 17 Oct 2026)]; for a change of k Heart members those who signed it, at least k distinct Heart members in office at the roles entry (the proposer counts), are in its o3|change line (§3.8), and it is booked after the change's notice (§3.4); a resignation's entry is booked at its notice end (a duty, §7.4)windows by height
gravone account's morning gravity (§7), computed from the cut-off statenoneavg, rule_micro, deduct, carry, debt; deduct moves to the reserve; booked right before the first entry after the boundary (in catch-up: after its morning opened) that touches the account (a visit), or else in a morning block, in HEX order and followed by drain() (§3.9, §7.4) [A8]; morning blocks hold only grav and rule entries; a payment block holds grav entries only as visits
reja refused note or act, with its reason (stale_prev, no_cover, not_member, not_allowed, expired, vote_ended, bad_template, stale_quote, bad_quote, not_receiving …; every reason and their order: below the table)the refused event's id, kind and author HEX only, never its tags or text [ruling of 16 Oct 2026, decisions 5 and 6]; src = the partner's xout block ([height, digest]) when a partner circle's note is refusednone; public; only refusals of members and applicants are booked [Decided 17 Oct 2026, C3] (and of a partner's note with src, which a verifier checks against the partner's ledger [Proposal: a ruling of the definitions, not part of C3]); refusals of any other key are answered, never booked [C3]; at most rej_per_author_per_day (a circle parameter: 20 by default [C3, E-1]) per author and morning day (below the table), above it the intake answers 429 and books nothing; an event with an invalid signature is never booked. Said openly: a refusal is the node's statement; a payer who disagrees publishes the note standalone and any verifier a 43924

There is no pout entry and no cg entry [Decided 16 Oct 2026, A6 and A8], no dep and no corr entry [6a], and no xrefund entry [8j].

Genesis, rule entry bodies and circle-key details [Decided 17 Oct 2026, C5; the parent: Decided 23 Oct 2026, E-8; the shapes: Proposal]:

  • genesis body: {"found": <compact found act>, "mirror": <the 30910 tags without g that the found act gives>, "circle_sig": <the signature of the circle key the found act names over sha256("lb-found/3|" ‖ found id)>} (there is no rules field any more [E-1]). Block 1 starts the state with g3|circle_key|<hex>|1, a g3|param:<name>|<integer> line for every parameter the found act names, g3|params_h|1, and g3|parent|<parent circle id>|<parent genesis digest> when the found act names a parent [E-8].
  • Rule entry bodies of round 5 [Proposal; the rules: E-1, E-3, E-5, E-6, E-9]: member_join {rule, in: [join id], party, ref?, src?, g?} (ref = the 43921 id of the reference the join names, src = [height, digest] of the old circle's block that books the reference entry, g = that circle's genesis digest; only for a key that comes from another circle, §3.11); member_leave {rule, in: [leave act id, or the proposing account_close id], party}; member_exclude {rule, in: [the proposing member_exclude id], party}; reference {rule, in: [leave act id], party, wave} (wave = the party's wave); reference_grant {rule, in: [43921 id], party, to, amount, to_amount, quote?, mv} and reference_return {rule, in: [43921 id], party, src, g, wave, mv} (§3.11) [E-9 (b)]; account_close {rule, in: [the proposing account_close id], party, mv?} (the moves close_cover and close_wave, each only when above 0); vote_pass and vote_fall {rule, in: [proposal id], project?} (project = the project's id when the proposal is a project); params_effective {rule, in: [param_propose id]}. There is no rules_adopt any more [E-1].
  • A roles entry whose proposing act is circle_key_change sets g3|circle_key|<new key>|<since_h>, since_h = the height of the roles entry + 1; no other roles entry changes the circle key. The mirror of the change's own height already names the new key: the 30910 with that mirror_of is signed by the new key, and a day seal whose h_to is that height names it (§3.6) [Proposal]; since a block books at most one roles entry, no later entry of the same block can undo the change [Proposal].

Duties, end-of-entry work, rule inputs and refusals [clarification, 17 Oct 2026 (D4 review), except where marked as a proposal]:

  • When a duty is booked. A duty whose due time is at or before a block's first at is booked at the start of that block (after its params_effective, when one is due; while two or more mornings are pending it waits, §7.4), with the block's first at; a due time inside a block's span (first at < due ≤ last at) belongs to the next block. Every due time is recorded when its deadline starts, with the parameters in force then, never retroactive [Consequence of E-1]: a vote's end (the at of its proposal's entry + its duration), the open lapse (open lapse at = published at + open_lapse_s), the receive lapse (receive lapse at = opened at + receive_lapse_s), the close return (close due = the k-th close + close_notice_s), the 8j check (check at = the xout's at + xcheck_s), a param_propose's notice end, and the roles entry of a resignation (at its o3|change notice end, §3.8 [proposal (D4 review, round 3, 17 Oct 2026)]); they fall due when the block's first at reaches them. A vote counts only at at < its proposal's vote end (else vote_ended) [E-5]. a3 and i3 lines, a request, an excluded key's application (o3|join … heart), an o3|invite line, an o3|exclude line and an o3|change line (while collecting, or a roles change of k Heart members never committed, §3.8) expire at the first block whose first at is later than their expires or until (request_expire's due time is expires + 1). The order of the entries inside a block: §7.4.
  • End-of-entry work = drain() (§3.9; the reserve_move, project_full, project_pay and project_return entries it books start no nested drain and no re-check), then the passed projects (status passed) re-checked in publication order: the first whose consent is given and, for a step raise, whose amount fits under built opens (project_open), drain() again, repeated until none opens; then the waiting account closes, in booking order; then the leaving lines (the references), in booking order; then the waiting list, while a place is free (§3.11) [E-3, E-6, E-9; the order: Proposal]. A reserve_move's in = [project id, seq of the entry whose end-of-entry work started this drain] (also after a restart within it).
  • The in of every rule entry [proposal (D4 review, 17 Oct 2026); the entries of round 5: Proposal (E-1, E-3, E-5, E-9)]: start [found act id]; member_join [join act id]; member_leave [leave act id, or the proposing account_close id]; member_rules [rules act id]; member_exclude [the proposing member_exclude id]; reference [leave act id]; reference_grant and reference_return [the 43921 id]; account_close [the proposing account_close id]; project_open [project id, the seq of the entry whose end-of-entry work opens it] [proposal (D4 review, round 3, 17 Oct 2026)]; reserve_move [project id, the triggering entry's seq] (above); project_full and project_pay [project id]; project_lapse [project id]; project_return [project id] after a receive lapse or inside drain(), [project id, the proposing project_close id] after a close (its Heart members are in the o3|change line) [proposal (D4 review, round 3, 17 Oct 2026)], [project id, the project_decline id], [project id, the leave act id], [project id, the proposing member_exclude id] at an exclusion [Proposal] or [project id, the project_withdraw id]; vote_pass and vote_fall [proposal id]; request_expire [pay_request id]; params_effective [param_propose id]; step_lower [step_propose id].
  • Applicants, admission and leaving [clarification, 17 Oct 2026 (D4 review, round 3); the waiting list, invitations and references: Decided 23 Oct 2026, E-6 and E-9; the mechanics: Proposal]. An applicant is a key with an o3|join line (§3.8): on the waiting list (waiting, no expiry) or an excluded key's application to the Heart (heart, until its join act expires); a join with a free place is admitted at once and leaves no line. How a join is judged and admitted: §3.11. member_join names a booked join act of that key that no member_join used; a key that is a member is not admitted again. A key that left and joins again keeps its line: status member, cap = the wave_cap in force, rules_v "", its balance, wave and history unchanged [clarification, 17 Oct 2026 (D4 review, round 3)]; a closed key that joins again starts at 0 (status member, cap = wave_cap) [E-3]. A member's booked leave act is followed at once by its member_leave (the next entry, as member_rules after a rules act), so no unused leave act stays in the state [clarification, 17 Oct 2026 (D4 review, round 3)], and it books an o3|leaving line (§3.11); an excluded key's leave books only the o3|leaving line (its status stays excluded); an applicant's own leave withdraws its o3|join (no member_leave) [E-6, E-9; Proposal]. The daily refusal limit counts per author and morning day, from one morning boundary to the next, not per local calendar date, so a restorer from a seal holds every refusal of the current day in the blocks it reads (§8.1 step 5) [clarification, 17 Oct 2026 (D4 review, round 3)].
  • Refusal reasons [proposal (D4 review, 17 Oct 2026); the names and their order follow the money machine of plan step D1; the cases each reason covers and the wait for an after height: clarification, 17 Oct 2026 (D4 review, round 3); the list of round 5: Proposal (E-1, E-3, E-5, E-6, E-7, E-9)]. When several apply, the reason booked is the first in this order: bad_template, bad_quote (the shape of the event and its quote; bad_template also: a note in another currency than the circle's, a note whose expires is beyond note_ttl_s of this circle's parameters (in a receiving circle: its own value, §4.5), a give whose p is not the named project's wallet (or the reserve), a circle_key_change naming the key in office, the founder's, a witness's or a Heart member's key, a found act or param_propose with a parameter outside its range, vote_min_s > vote_max_s or vote_max_s ≥ open_lapse_s; bad_quote also: a note whose expires is later than its quote's); not_found (what the event names is not open in the state: never booked, or ended; also an endorsement after its proposing act expired, or of another type, a request closed or for another receiver, a named invitation that is not open, a new circle's reference grant for a key whose reference no longer waits, §3.11); not_member, not_allowed, self_pay, refused_circle (the parties and their roles; not_member also: a project_propose whose recipient is not a member when it is booked (left, never joined, frozen or excluded) [clarification, 19 Oct 2026 (D3 review)], a member_exclude naming a key whose line is not member or frozen, a payment to a left or excluded line that is not a settlement (§3.11), and an excluded key's own payment or act other than its leave or an xout of its plus [Consequence: its line is not member]; not_allowed also: a note paying a request that names another payer, an accept by another key than the change names, the last Heart member's or witness's resignation, a duration outside vote_min_s … vote_max_s, a join by a key whose exclusion runs, a join without an invitation while invite_only = 1 (an excluded key's application excepted), a join naming another key's invitation, a join by a key whose newest member home names another circle without a valid reference from that circle [E-9], a join that brings a step while this key's reference from this circle still waits for its return [E-11], the leave of the last Heart member [E-11], a member_readmit when no place is free, an account_close of a Heart member in office or of a line that is not member, frozen, left or excluded, and the roles entry of a witness change while a Heart member in office has "against" as the newest vote [E-7]); wrong_status, not_receiving (the status of what it names: wrong_status = the project's o3|project line exists but its status does not allow the act; an ended project is not_found; not_receiving = a give naming an open project that is not receiving, while a give naming a project that has ended is not_found [clarification, 19 Oct 2026 (D3 review)]); expired, vote_ended, stale_quote (time windows; vote_ended = a vote booked at or after its proposal's vote end [E-5]); duplicate, repeated, stale_prev (the same event id again, and a join naming a reference this circle used already or one a waiting join carries [E-13]; the same author's act whose effect already holds, also a join act by a member or frozen key, a join of a key with an open o3|join, the same vote choice again, a further endorsement by a listed Heart member and a second param_propose while one is open; a second note on the same prev); no_cover, step_full (cover; no_cover also a reference grant whose to_amount is below the wave, §3.11). What an event names is judged by the open lines of the state (§3.8). An act booked below its after height is not refused: the node waits for that height (if the act expires first, it is refused expired). Removed with the objections and approvals [E-5]: objection_window, notice, no_consent, objection_stands and unanswered; new in round 5: vote_ended. The k-th exclusion act of a Heart member that finds the block's one roles entry taken waits for the next block (the intake answers roles_taken; nothing is booked). The machine's other names (bad_amount, bad_key, bad_day, bad_k, not_started, not_first, step_floor, too_early, grav_pending, out_of_order, above_room, reserve_short, replay_only) never appear in a rej: they are checks of the node's own entries or of today's app.

Line after the block (one per touched party): [index, balance, wave, cap, carry_micro, debt, aseq, last_h, note_n, note_head, last_gift_day, first_receipt_day, status, rules_v], where aseq is the account's own gap-free entry counter, last_h the previous block that touched it, and the two *_day fields are the quiet-day inputs gravity needs (all three exactly: §3.8); rules_v is the version of the circle's own rules text the member accepted (the rules act); it has nothing to do with the circle parameters. rules_v is "" until the member's first rules act (member_join sets ""); a booked rules act is followed at once by the rule entry member_rules {rule, in: [the rules act id], party} that sets rules_v to the act's version, copied as written (1 to 6 decimal digits) [clarification, 17 Oct 2026 (D4 review, round 3)] (an act entry has no party, so without it the line could not show the change) [proposal (D4 review, 17 Oct 2026)]. The found act no longer carries a rules tag [E-1], so ["rules", version, sha256] appears only in the rules act (the circle's own rules text) [clarification, 17 Oct 2026 (D4 review); E-1]. status is member, frozen, left, excluded or closed (the last two since 23 Oct 2026, E-3). Parties are HEX keys or keyless system addresses, never names [A5]. held_out is gone with payouts [A6]. paid_in is gone with deposits [6a]: it counted only money paid in less money paid out, so with neither it has nothing to count.

3.6 43917 v3 Day Seal, 43918 Snapshot Chunk, 30915 v3 Circle Head#

  • 43917 (once a day, right after the morning, also on days without payments or without any block) [Decided 16 Oct 2026: one seal a day after the 04:00 morning], tags in this order: ["c", <circle id>]; m = <scope16>:<date>; ["day", date, n]; ["boundary", unix] (the circle's morning hour of that day in its time zone, with the pinned tzdata); ["prev", previous seal digest, its day, its boundary, its covers] (["prev", ""] for the first seal, whose range always starts at height 1 and seq 1: a circle's seal chain starts at its block 1); ["covers", the last at of block h_to] (on a day without blocks: the previous seal's covers); ["range", h_from, h_to, seq_from, seq_to] (a day without blocks: h_from = h_to + 1, seq_from = seq_to + 1); ["head", digest of block h_to, h_to]; ["pay", RFC 6962 root over the canonical JSON bytes of the day's entries in seq order, count]; ["state", sparse Merkle root at h_to, line count]; ["snap", chunks root, chunk count, bytes]; ["gravity", date, moved, accounts] (always) [Consequence] (moved = the sum of the deducts of the morning's grav entries in the seal's range, accounts = the number of those grav entries [clarification, 17 Oct 2026 (D4 review)]); ["sum", "0"]; ["world", cur, used, step, built] (built, up to 20 digits: Σ (balance + wave) over every account line that is not a system account or a project wallet, of any status, members who left and excluded members included, since their money is still in the circle [clarification, 17 Oct 2026 (D1 review); the excluded: Consequence of E-3], a closed line holding 0; the formula: Proposal); ["quotes", RFC 6962 root over the distinct 43919 ids that the range's entries name, count] (each id once, as 32 raw bytes, sorted ascending; count = the number of distinct ids [clarification, 17 Oct 2026 (D4 review)]); ["reserve", balance] (the keyless reserve after h_to) [A8]; ["origin", balance] (the keyless origin: −start − granted + returned since block 1; it may go above 0, and the tag is signed) [6c, E-3, E-9 (b); the tag: Proposal]; ["signers", hash of the witness set of the office after h_to, q, n] (the hash covers the current witnesses of that office, until_h "", each as [hex, operator, since_h, ""], sorted by hex [clarification, 17 Oct 2026 (D4 review)]); ["circle_key", <the circle key of the newest mirror at or below h_to>] (read from the g3|circle_key line at h_to; at the height of a key change already the new key, which also signs the 30910 of that height; the 30915 head carries it to the root directory, so a reader picks the 30910 by it) [Proposal]; ["params", params_h] (the height of the newest genesis or params_effective at or below h_to, whose parameters are in force at h_to); there is no rules tag any more [Decided 23 Oct 2026, E-1]; qs × ≥ q of that office's witnesses over sha256("lb-seal/3|" ‖ digest); ["v","3"]. Size ~2 KB. The office of a seal [Proposal]: a seal is judged with the office after its last block h_to, the newest mirror at or below h_to (the genesis mirror or the newest roles entry's, read from the ledger): at least q of its witnesses sign the seal, and signers and circle_key name its witness set and circle key, as the state's g3 lines at h_to do. The seal chain [clarification, 17 Oct 2026 (D4 review)]: the first seal (n = 1, prev "") is the seal of the first day whose boundary is later than block 1's at; each later seal is for the next day: day = the previous seal's day + 1 and n = its n + 1, one seal per day without a gap (after an outage the missed days are sealed in order); validators check it. The day-chain checks apply to seals whose range lies on the chain a verifier replays; the synthetic seal at maximum lengths of the definitions is a standalone fixture and gets only the checks that need no chain [clarification, 17 Oct 2026 (D4 review, round 3)]. What a seal covers [Decided 17 Oct 2026, C2: payments never pause for the morning]: every block booked before the boundary and, when blocks carry the day's morning header (the morning blocks, and payment blocks with visits, §7.4), every block up to and including the last of them (payment blocks booked during the morning among them); no block spans the boundary. So every block after h_to books at or after the boundary, and every block before h_from books at or before the previous seal's covers; the 8j evidence (§4.5) rests on exactly this. The seal's state is the state at h_to, even when payments follow at once. Completeness [clarification, 17 Oct 2026 (D4 review)]: that no block before the seal's boundary was left out needs block h_to + 1 or the next seal with an empty range from h_to + 1; without either it is unverifiable.
  • 43918: c, m, i = <scope16>:<date>:<index>, ["chunk", i, n], ["range", first key, last key]; content = canonical state lines sorted by key (§3.8), ≤ 100,000 bytes (~450 account lines). Valid only against the seal's snap and state roots; a reader verifies a chunk before showing anything from it.
  • 30915: the newest 43917 mirrored for root: the same pubkey, created_at, content and tags (the qs tags included), then ["d", <circle id>] and ["seal", seal digest, seal day]; the seal tag recomputes as the digest of [0, pubkey, created_at, 43917, the seal tags without qs, content]. d is the circle id, so replacing the circle key never moves the head (its address is 30915:<node pubkey>:<circle id>: one head per node key). Like the seal it names the circle key of the newest mirror at or below the seal's h_to and the parameter height, under the witnesses' quorum, so a reader of the root directory picks the circle's 30910 by that key in one more query [Proposal]. Published at a per-circle offset spread over 24 hours: the first 4 bytes, big-endian, of sha256(the circle id as its 64 hex characters), mod 86,400, seconds after the seal (test_vectors.circle_id), not the hour after 04:00, so the heads of one time zone do not bunch into one hour (~560 writes/s at 10 M circles [E]).

3.7 30910 v3, 30916 v3, 43919 v3, 43924, 43921 Reference (43920 retired)#

  • 30910 v3 Circle Record (mirror) (Q10; mirror-only [Proposal, follows from A3 and A8, not confirmed]; addressed by the circle id [the circle id: Decided 17 Oct 2026, C5] and signed by the circle key its mirror names), tags in this order: ["d", <circle id>] (the id of the found act; never changes), code, name, currency (exactly one) [Decided 16 Oct 2026], tz, ["tzdata", "2026a"], morning (tz, tzdata and morning fixed at founding for 0.3.0 [Decided 17 Oct 2026, C7]), ["g", genesis digest, the founder's signature over sha256("lb-genesis/3|" + circle id + "|" + genesis digest)], ["mirror_of", <height of the genesis or roles entry it mirrors>], ["founder", <founder HEX>] (the author of the found act; the root directory checks decisions A9 and E-8 from it), ["parent", <parent circle id>, <parent genesis digest>] (only when the found act names a parent [Decided 23 Oct 2026, E-8; the tag: Proposal]), ["circle_key", <HEX of the circle key in office from the block after mirror_of (from block 1 for the genesis mirror)>] (the record's author must be this key; never the founder's, a witness's or a Heart member's key [Proposal]; changed only by circle_key_change [C5]), ["signer", hex, operator, since_h, until_h] × n (at most 100 tags; operators are names the circle declares itself, not a proof of independence), ["quorum", q, n], ["proposer", hex, since_h], ["steward", hex] × m (the Circle Heart; the tag keeps its technical name [Proposal, E-2]) + ["stewards_required", k] (live circle m = 4 [4a]; k for other acts: proposal, 3; k is never above m and never below 2 while m ≥ 2 [proposal (D4 review, round 3, 17 Oct 2026)]; a found act that breaks it is refused bad_template [proposal (D3 review, 19 Oct 2026)]), ["relay", wss, operator] × ≥ 4 of ≥ 3 operators [A2], ["archive", wss]…, optional ["bootstrap", "Q14"] (open question 14, not decided: while declared, two relay operators give a warning instead of a refusal), ["rate_source", <source id>, <public description>] (any source the circle chooses [A7]; start: the ECB daily reference rate [Decided 16 Oct 2026, start source]; how it is changed: proposal), ["api", https] (write intake), ["definitions", "0.3.0"], ["v","3"]. The record carries no circle parameter: the former quote_ttl and project_approvals tags are gone; the parameters live in the ledger (the found act, each param_propose that a params_effective names, and the state's g3|param:<name> lines, §3.1 rule 11) [Decided 23 Oct 2026, E-1]. No fund key [A8], no founder gate [A9], no rate panel [A7], no custodian tag [6a]. Canonical address 30910:<circle key in office>:<circle id>: it changes when the circle key is replaced, so readers query #d = the circle id and take the record the ledger confirms; every version is also carried in the ledger (genesis or roles entry). Authority rule: a 30910 counts only if it is signed by the circle key that the ledger's mirror at its mirror_of names (at the height of a key change already the new key; for blocks it is in office from the next height), its tags without g equal that mirror (the one the committed genesis or roles entry at mirror_of carries; a block books at most one roles entry, so a height names one mirror), and its g names the pinned genesis digest; readers take the valid record with the highest mirror_of; a record by an old circle key with a mirror_of at or above its replacement can never match; when they differ, readers follow the ledger. The genesis mirror is a function of the signed found act. Said openly: the circle key is no longer part of the record's address, so anyone can publish a 30910 that names a circle id; it counts only when the ledger's mirror at its mirror_of names its author. No key can re-point g: it carries the founder's signature over the circle id and the genesis digest; a reader keeps the genesis it pinned (from the circle link or QR, or the first g it saw for the circle id) and never follows another, and root relays keep the first-seen g and founder per circle id (relay/ledger-write-policy.py, mode root, which also checks the founder's signature in g, and pins them only when it holds the circle's found act and the record's founder is its author (or, for a circle configured on the relay, when its configured circle key signed the record) [Proposal], §9.2): a request in the letter to the Lana relay owner, now only extra safety [Decided 17 Oct 2026, C6]. The circle key can be replaced (§3.1 rule 8, §3.4).
  • 30916 v3 Member Home [Decided 16 Oct 2026: mandatory]: d=letsbalance, ["c", <circle id>], ["g", genesis digest], ["join", <height of the member_join rule entry>], ["attest", witness hex, since_day, sig] (by a witness current at the join height; the signature over sha256("lb-home/3|" + member + "|" + circle id + "|" + genesis digest + "|" + join + "|" + since_day)), n name words from KIND 0 (always [Consequence], formerly P9), w LANA address, ["v","3"]. Truth = the join entry; 30916 is a pointer. Before paying, the app checks the join (and absence of a leave) in the circle's ledger. Where a key is a member [Decided 23 Oct 2026, E-8 and E-9; the reading: Proposal]: the newest 30916 of a key (the newest counts) names the circle the key last joined; a new circle reads it on the root relays to see whether a joining key comes from another circle, and then needs that circle's reference (§3.11). A key with no member home anywhere was never a member and needs no reference [Proposal]. Root relays keep member homes (no deletion by KIND 5) [Proposal; at scale this meets Q16]. Said openly: a deleted home or a second key is not caught; that needs Lana's person check. Names [Decided 16 Oct 2026, A5]: the member can replace 30916 at any time; when KIND 0 changes, the app republishes 30916 with the new n words and the witness re-attests; relays keep only the newest version; no version is ever copied into the ledger.
  • 43919 v3 Rate Quote [Decided 16 Oct 2026, A7: the seller's circle quotes, the payer accepts by signing both amounts; the format below is the proposal for 0.3.0, the same word for word in every document]:
    • pubkey = the node (proposer) of the seller's (receiving) circle at created_at, checked against that circle's roles windows (the office at a time: §4.5); a quote signed in the very second of a node change is the new node's, although that block was still ordered by the old one [clarification, 17 Oct 2026 (D4 review, round 3)].
    • Tags: ["c", <seller circle id>], ["source", <source id = the circle's rate_source at created_at>, "<the source's own time for this rate, unix>"], ["base", "EUR"], ["rate", "<currency>", "<whole ppm: units of that currency per 1 EUR × 10^6>"] once for each currency the source gives (r_EUR = 1,000,000, implicit), ["expires", "<unix, ≤ created_at + quote_ttl_s>"] (quote_ttl_s: a parameter of the quoting circle, 600 s by default [E-1]; both circles judge a quote by the quoting circle's value: the quoting circle by its parameters in force at the booking, the payer's circle by the value it reads in the quoting circle's ledger, §4.5 [Proposal]; never NIP-40 expiration), ["prev", "<this circle's previous 43919 id, or \"\" on its first>"], ["v", "3"]; content "".
    • Conversion: to_amount = floor(amount × r_to / r_from) in BigInt, one rounding, no intermediate rounding. A price set in the receiver's currency: amount = ceil(price × r_from / r_to), which gives to_amount ≥ price; a payment request counts as paid when to_amount ≥ the requested amount. to_amount = 0 is refused.
    • Valid for a booking when: signed by that node; c is the seller circle; the source id equals its rate_source at created_at; source time ≤ created_at < expires ≤ created_at + quote_ttl_s (the quoting circle's value); the payer circle's xout at ≤ expires; to_amount equals the conversion exactly. Refusal reasons: stale_quote (expired), bad_quote (anything else).
    • Audit checks, not booking conditions (a quote enters a ledger only when a payment references it): the circle's prev chain has no gap, and for one source id the source time never goes back. A break is published as a 43924 fail.
    • Issuing: the node keeps at most one live quote and makes a new one only when asked and the live one has expired, has less than QUOTE_MARGIN_S left (a constant; proposal 120 s) or the source has given a newer rate; it publishes each quote to its circle's relays before handing it to any app. At most ≈ 180 a day per circle, none on a day without payments from other currencies. The payer's circle republishes to its own relays every quote its blocks reference, so each circle restores without the partner. the project owner's rate key is no longer needed; it may be one source a circle chooses.
    • Start source [Decided 16 Oct 2026, start source]: the ECB daily reference rate (EUR base, USD and GBP), read once a day by the node; the app shows the rate's date (the source time in source); a quote is valid 600 s (quote_ttl_s by default [E-1]). Proposal: RATE_STALE_ALERT_S = 432,000 s (120 h), a constant. Details and test vectors: docs/valute-in-tecaji.md.
  • 43924 Statement: c, ["about", "seal"|"range"|"block"|"signer"|"restore"], exactly one target (["target", digest, "h:<height>" | "d:<day>"] for a block or seal, ["e", id, "", "target"] for any other event), ["range", from, to] (the heights whose blocks the author checked for it: from the first block it replayed (1 when it replayed from genesis; h_from of the target seal when it started from the state of a seal it had verified before) to h_to for an ok, or to the last height it could check for missing or fail), ["result", "ok"|"fail"|"equivocation"|"missing"|"ignored"] (missing also means "could not be checked", with the missing event as evidence; never ok), ["state", root the author computed], ["votes", root, count] (Q23; the root: RFC 6962 over the 32 raw bytes of each block digest the author signed among the blocks of the statement's range (for a seal: the sealed day's blocks, the seal's range, also when the statement's range starts at block 1 [clarification, 17 Oct 2026 (D4 review, round 3)]; not the calendar day of signing), in height order), evidence the same way (["evidence", digest, "h:<height>" | "d:<day>"] or ["e", id, "", "evidence"]), short content [the range, missing and the votes root: clarification, 17 Oct 2026 (D4 review)]. Uses: each witness's daily ok with the root it computed and a root over every vote it signed for the sealed day (Q23); the daily restore drill result (§8.3); any verifier's challenge. A verifier checks a rej's reason only with the events that the reasons before it in the refusal order (§3.5) need (a bad_quote or stale_quote needs the quote and, across circles, the partner's xout time); without them the reason is unverifiable, never assumed [clarification, 17 Oct 2026 (D4 review, round 3)].
  • 43920 (retired) [Decided 23 Oct 2026, E-1]: the BSA Rules record of world-wide rule values was never published and is retired; its number stays reserved and is never reused (reserved_unused) [Consequence]. The time values and limits it held are circle parameters (§3.1 rule 11), set in the found act and changed by param_propose; there is no rules authority and no world signer, so decision 1A's signer question is gone.
  • 43921 Reference (new) [Decided 23 Oct 2026, E-9: a new kind, issued by itself after a member's "I want to leave" when the conditions hold, carrying the projects published and taken part in, the step built and the open OWN processes; the number, the tags and the verification: Proposal]:
    • Regular (40000+): every reference is its own event, kept for ever. pubkey = the node of the circle the person leaves, at the block that books the reference entry; the node signs it right after that block has its quorum and publishes it on the circle's relays (§3.11).
    • Tags in this order: ["c", <circle id>], ["p", <the person's HEX>], ["block", "<height>", <block digest>] (the block with the reference entry), ["g", <genesis digest>], ["currency", <code>], ["wave", "<minor>"] (the step the person built: the wave of the reference entry), ["own", "0"] (a reference is issued only while no OWN process about the person is open [E-9 (a)]), ["joined", "<unix>"] and ["left", "<unix>"] (the at of the newest member_join, and the at of the entry that booked the leave act, also for an excluded key) [Proposal], ["published", "<count>"] then up to 100 ["e", <project_propose id>, "", "published"] (newest first), ["took_part", "<count>"] then up to 100 ["e", <project id>, "", "took_part"] (the projects that paid the person, newest first [Proposal: the reading of »projekti, pri katerih je sodeloval«, "the projects they took part in"]), ["v", "3"]; content "".
    • The ledger entry is the authority (under the witnesses' quorum); the 43921 is the findable copy with the node's summary, which anyone checks against the circle's public blocks.
    • How the new circle checks it, and where it is kept: §3.11. Size ~0.7 KB; up to ~18 KB with 100 + 100 project ids [E].

3.8 System accounts and the decision state#

  • System accounts have no key [Decided 16 Oct 2026, A8 for project wallets and the reserve; 8i for world and world-step; 6c for origin, the name: Proposal]: every project wallet, reserve, world, world-step and origin are x-only points lift_x(sha256("lb-system/3|" + role + "|" + circle id + "|" + i)) for the first decimal i = 0, 1, 2 … that gives a valid point, where role is reserve, world, world-step, origin, or for a project wallet project| + the 64-hex id of its project_propose act (so the string is "lb-system/3|project|" + <project_propose id> + "|" + circle id + "|" + i). A project wallet is written project:<id> for display only; the point always comes from the string above. The test vectors (circle id, act id → x-only HEX) are test_vectors.system_addresses of the definitions. Nobody can sign for them; only entries that follow public rules move them. The single common-good account and the fund key on the server are gone. There is no main account: today it books only deposits, deposit corrections and payouts, and BSA has neither [A6, 6a] (the project owner also confirmed main as keyless under 8i before it went with 6a).
  • System accounts have no wave, no cap, no gravity and no debt (project wallets, reserve, world, world-step, origin): a receipt into one makes no wave growth and no counter-booking. The reserve and every project wallet never go below 0; a project wallet never exceeds its amount; world may be negative, as today; origin holds −start from block 1 and moves only by grant (origin → reserve, a newcomer's step) and close_wave (reserve → origin, a closed or moved account's wave), §3.11: origin = −start − granted + returned, and it may go above 0 [6c; E-3, E-9 (b); the shape: Proposal].
  • The decision state (everything the next booking depends on, committed by the state root; exact fields, value sets and lifetimes: state_lines of 43911 in the definitions): account lines s3|<hex>|balance|wave|cap|carry_micro|debt|aseq|last_h|note_n|note_head|last_gift_day|first_receipt_day|status|rules_v (status member, frozen, left, excluded or closed, the last two new [E-3]; no held_out [A6], no paid_in [6a]; keys only, never names [A5]); governance lines g3|<key>|<value> (code, name, currency, tz, tzdata, morning, founder, the circle key in office with its since_h (g3|circle_key|<hex>|<since_h>, changed only by a roles entry whose proposing act is circle_key_change [C5]), quorum, proposer, every signer with operator and window, the Heart (steward lines) and k, relays and archives, the bootstrap label while declared, rate source, api, every circle parameter (g3|param:<name>|<integer>, §3.1 rule 11) and their height (g3|params_h|<h>, the height of the genesis or of the newest params_effective) [E-1], the start, the parent circle (g3|parent|<parent circle id>|<parent genesis digest>, only when the found act names one) [E-8], the refusal list (by circle id), definitions version and g3|mirror_h|<h>, the height of the newest genesis or roles entry, whose mirror, in tag order, is the mirror in office [proposal (D4 review, round 3, 17 Oct 2026)]; there is no g3|rules line any more [E-1], and the fixed constants are not lines); open-item lines o3|<type>|<id>|… (the set of round 5 [Proposal; the rules: E-1, E-3, E-4, E-5, E-6, E-9]): projects o3|project|<id>|<status>|<amount>|<received>|<proposer>|<recipient>|<consent>|<published at>|<published seq>|<vote end>|<open lapse at>|<opened at>|<open seq>|<receive lapse at>|<close due>, 17 parts: status proposed (voting) / passed / receiving / full while open; published at = the at of the entry that booked the project_propose act [clarification, 17 Oct 2026 (D4 review)] and published seq = that entry's seq (the publication order of duties and re-checks); vote end = published at + its duration; open lapse at = published at + the open_lapse_s in force then; opened at = the at of project_open and open seq = its seq (the drain order), both "" before; receive lapse at = opened at + the receive_lapse_s in force then ("" before); close due; these due times replace the former rules-version fields, so a running deadline keeps its length [Consequence of E-1]; the line is removed in the entry that gives the project a final status: paid, declined, withdrawn, lapsed, closed or fell; there is no status rejected [Decided 17 Oct 2026, C4] and no status stopped [E-5]; motions o3|motion|<id>|voting|<proposer>|<published at>|<published seq>|<vote end> (8 parts) [E-5]; votes o3|vote|<proposal id>|<voter HEX>|<for or against>|<vote act id> (6 parts; the key is the first 4, so one member has one vote per proposal and a newer vote replaces it) [E-5]; cross-circle holds o3|hold|<note id>|held|<amount>|<payer>|<to circle id>|<to genesis digest>|<note expires>|<xout at>|<check at>|<party> (12 parts; a reference grant is held the same way, with the 43921 id as the note id, the reserve as payer, note expires "" and party = the newcomer whose wave it opened, "" for a leg [Decided 23 Oct 2026, E-11: the newcomer's step is revoked if the old circle refuses]; check at = xout at + the xcheck_s in force then, which replaces the rules version at the xout [Consequence of E-1]; an xdone names the note id, which commits to to_amount, its currency and the quote, so the hold's line suffices to judge it; that the xin moved exactly to_amount is the receiving circle's own booking rule [clarification, 17 Oct 2026 (D4 review, round 3)]); open requests; applicants o3|join|<join act id>|<key>|<waiting or heart>|<expires, "" while waiting>|<booked seq> (7 parts: the waiting list, admitted by rule in booked order, or an excluded key's application to the Heart, until its join act expires or the key's account_close [clarification, 25 Oct 2026, D4: a closed key joins as anyone does]; while it exists its key is an applicant) [E-6]; invitations o3|invite|<invite id>|<key>|<inviter>|<until> (6 parts; until = at + invite_ttl_s; one-time) [E-6]; exclusions o3|exclude|<hex>|<until>|<act id> (5 parts; until = the k-th act's at + exclusion_s) [E-3]; waiting account closes o3|close|<hex>|<act id>|<booked seq> (5 parts) [E-3]; leaving lines o3|leaving|<hex>|<leave act id>|<booked seq> (5 parts; booked seq = the seq of the member_leave the leave act books, or of the leave act's own entry for an excluded key [D4 N25]; until the reference, the key's member_join, or the act that reaches the threshold of its account_close [D4 N26], §3.11) [E-9]; references waiting for their return o3|reference|<hex>|<leave act id>|<wave> (5 parts; from the reference entry until reference_return, the key's member_join here or its account_close) [E-9 (b)]; a waiting join's grant o3|grant|<join act id>|<43921 id>|<old circle id>|<old genesis digest>|<src height>|<src digest>|<G>|<W>|<quote id or ""> (11 parts, beside its o3|join line, until the member_join and reference_grant that use it) [E-9 (b)]; open OWN processes o3|own|<own_open id>|<hex> (4 parts) [E-4, Proposal]; and changes of k Heart members being collected or under notice and resignations under notice (o3|change, below); there are no o3|objection, o3|param or o3|step lines any more [E-1, E-5]; booked acts and notes a3|<event id>|<expires> (every act and every note booked in this circle, so a duplicate is judged from the state [clarification, 17 Oct 2026 (D4 review, round 3), for the rule; proposal (D4 review, round 3, 17 Oct 2026), for the notes' lines]) and the idem window i3|<payer>|<idem>|<expires>, each removed at the start of the first block whose first at is later than its expires; and the used references u3|<old genesis>|<src height>|<newcomer hex>|<src digest>|<43921 id>|<member_join seq> (7 parts; the key is the first 4: a reference is the old circle's reference entry, named by its circle's genesis, the height of its block with the entry and the person, so two valid 43921 copies of one entry are one reference [review of E-13, 25 Oct 2026]; every reference a member_join of this circle carried, at the join or from the waiting list, whatever its step, also 0 [clarification]; never removed, so a restore from a seal keeps them and the circle never accepts that reference again, through any copy) [Decided 25 Oct 2026, E-13 (A)]. No value that enters a line contains |. No salt in any line [Consequence].
  • The o3|change line [clarification, 17 Oct 2026 (D4 review), for the fields and the k-th act; proposal (D4 review, 17 Oct 2026), for the lapse and the project field; proposal (D4 review, round 3, 17 Oct 2026), for consent, booked h, the new governance acts and the resignations]: o3|change|<proposing act id>|<collecting|notice>|<act type>|<stewards>|<expires>|<notice end or "">|<project or "">|<consent>|<booked h>, eleven fields (the field stewards keeps its technical name and lists the Heart members who signed; the types of round 5 add param_propose, member_exclude, member_readmit and account_close [E-1, E-3]; own_open has no o3|change line since E-10: any member books it alone, at once); project is the project_propose id a project_close closes and "" for a roles change (the next booking needs it, to refuse a second close of one project and to end the line when the project ends). stewards = the HEX keys of the proposing act's author and of every booked endorsement's author, sorted, joined by , (never a count). consent = waiting until the named key's accept act (signer_accept for signer_propose and signer_replace, steward_accept for steward_add) is booked, then yes; "" for every other type. booked h = the height of the block that booked the proposing (or resign) act: a restorer reads that block for what the change names (§8.1 step 5). One line for every change of k Heart members of an endorsable type, project_close included, and one for every resignation (steward_resign, signer_resign, signed by the person alone: the resign act id, stewards = the resigning key, in notice from its booking, notice end = its at + the change_notice_s in force then, 259,200 s by default [E-1]); the acts: docs/upravljanje-kroga.md. It is created by the entry that books the proposing act; an endorsement adds its author. It turns to notice at the act after which the listed keys that are Heart members in office reach k (in office for that block): notice end = that act's at + the type's notice (the change_notice_s then in force, 259,200 s by default, for signer_propose, signer_remove, signer_replace, steward_add, steward_remove, stewards_required_set, relay_change, circle_key_change and recovery [E-1]; max(change_notice_s, the old value of every changed parameter in seconds) for param_propose [Proposal, E-1]; 0 for proposer_swap, rate_source_set and refusal_list_set; the close_notice_s then in force for project_close); member_exclude, member_readmit, account_close and own_open take effect at that act, with no notice [E-3; own_open: Proposal]. expires: while collecting, the proposing act's own expires; in notice, notice end + the act_ttl_s in force at that act for a roles change (the commit window: proposal, so a change that is never committed does not stay for ever), and notice end for project_close, param_propose and a resignation (its return, its params_effective or the resignation's roles entry is a duty at notice end). The line ends with the entry that commits the change (the roles entry; for project_close the project_return; for param_propose the params_effective; for member_exclude, member_readmit, account_close and own_open the entry at the k-th act), or at the first block whose first at is later than expires (collecting, or a roles change of k Heart members never committed); a project_close line also ends with the entry that gives its project a final status (project_pay, project_return, project_lapse), or at its close due when fewer than k of its Heart members are in office then (the close is void, and the project's close due goes back to "" [clarification, 17 Oct 2026 (D4 review, round 3)]). A roles entry for a change of k Heart members is booked at an at with notice end ≤ at ≤ expires, with k of the line's Heart members in office at the roles entry and, where the type needs one, the consent yes; later endorsements may still be booked while the proposing act is valid (they never move the notice). A further endorsement by a listed Heart member is refused repeated. A second proposing project_close for a project whose close line exists is refused repeated (the Heart members endorse the open one). A param_propose in notice is void at its notice end when fewer than k of its signers are in office then (the line ends, no entry) [Proposal, E-1].
  • Lines, exactly [clarification, 17 Oct 2026 (D4 review), except where marked as a proposal]: state lines are sorted by their key (the key fields joined by |, not the whole line), compared as UTF-8 bytes. A member's cap is the wave_cap in force at its member_join; a later wave_cap change does not change existing caps [proposal (D4 review, 17 Oct 2026)]. last_gift_day = the circle's local calendar date (tz, pinned tzdata) of the at of the newest pay, give or xout the account booked as payer; first_receipt_day = the local date of its first receipt (pay or xin as receiver, project_pay to it), never changed afterwards; xundo, grav, grow and settled set neither. "Touch" has two meanings: for the p list, the lines and aseq an entry touches every account it names (its party and every move's from and to); for visit before touch only money moves count (§7.4). last_h in the state is the height of the newest block that touched the account ("" before any); a block's own line (the lines root leaf) shows the value from before that block, so it points back to the block that touched the account before (a chain a light client follows), and the next block's line comes from the state alone [clarification, 17 Oct 2026 (D4 review, round 3)]. A project wallet's account line appears with the first entry that names it and always carries the project's status. i3 lines are kept only by the payer's circle, for the notes it books as pay, give or xout; an xin keeps none.
  • Restore from a seal (§8.1 step 5) must equal full replay, checked by comparing this canonical state hash, never the SQLite file (which has UUIDs and rowids).

3.9 Projects and the reserve [Decided 16 Oct 2026, A8; details decided the same afternoon: 8a, 8b, 8e, 8f, 8j; the start decided later the same day: 6c; 8d follows from A8; no rejection by one Heart member (C4) decided 17 Oct 2026; the vote instead of approvals and objections (E-5, which replaces 8c) and the time values as circle parameters (E-1) decided 23 Oct 2026; Open 8g, 8h]#

the project owner: "money always goes to projects, which have no key … So it is always projects that are funded." The rules below are public, deterministic and recomputed by every witness; every move is between two lines of the same circle, so the sum stays 0 [A8, 8f]. This section is the one canonical text; docs/upravljanje-kroga.md, docs/prepoznavanje-goljufov.md, docs/nov-krog.md and docs/implementation-notes.md point here. The time values and the number of Heart "for" votes below are circle parameters [Decided 23 Oct 2026, E-1] (the defaults are shown; §3.1 rule 11): the number of votes is that of the parameters in force at the vote end [Proposal], and a running deadline is recorded as a due time when it starts and keeps its length, never retroactive [Consequence of E-1]. Said openly: a circle with fewer Heart members whose "for" counts than project_approvals opens no project; its start stays in the reserve.

StepRuleStatus
Publisha member's project_propose (title, description, amount, recipient, duration) is booked; status proposed (voting): its vote end = the entry's at + its duration (vote_min_s ≤ duration ≤ vote_max_s, else not_allowed); its keyless wallet exists with balance 0. A step raise is a project_propose whose recipient is the circle's world-step account[A8]; the duration set by the proposer at publication, never changed [Decided 23 Oct 2026, E-5, confirmed 23 Oct]; a step raise is a project [8j], world-step as its recipient [Proposal]; the recipient's consent as today [Proposal], implied when the proposer is the recipient [clarification, 19 Oct 2026 (D3 review)]; recipient a member when the act is booked (else not_member): Open 8h [clarification, 19 Oct 2026 (D3 review)]
Voteuntil the vote end every member may book a vote naming the project: "for", or "against" with its short public reason; one vote per member per project, the newest counts (o3|vote), changeable until the end; the same choice again is repeated; a vote at or after the vote end is refused vote_ended. There is no objection, no stop and no approval any more[Decided 23 Oct 2026, E-5]; replaces 8c and the approvals; the refusal's name: proposal
Decline, withdrawthe recipient's project_decline before it receives → declined (the recipient's leaving or exclusion does the same, below the table); the proposer's project_withdraw before it receives → withdrawn; a decline or withdrawal during the vote ends the project and its votes; the wallet is empty, nothing moves. No Heart member rejects a project alone: there is no project_reject and no status rejecteddecline: as today [Proposal]; during the vote: unchanged by E-5; no rejection by one Heart member [Decided 17 Oct 2026, C4]; at an exclusion: Proposal
End of the voteat the vote end (a duty: the first block whose first at reaches it) the newest votes are counted with the roles at that moment [Proposal]: the project passes only if no member (status member) has "against" as the newest vote and at least project_approvals Heart members in office have "for" (on a project the proposer's and the recipient's "for" do not count toward that number; on a motion the proposer's own "for" counts [Decided 23 Oct 2026, E-11]); rule vote_pass (status passed) or vote_fall (status fell, final; it may be proposed again, changed); its o3|vote lines go[Decided 23 Oct 2026, E-5: no "against" from anyone and at least 3 Heart "for" (E-1: project_approvals ≥ 3)]; the proposer never decides on their own proposal [Decided 10/15 Oct]; the roles at the vote end: proposal
Opena passed project opens at the end of the first entry after which its consent is booked (a step raise needs none: its recipient is keyless) and, for a step raise, its amount fits under built: a rule entry project_open sets status receiving, records the opening time and seq (o3|project, §3.8) and is followed at once by drain(); passed projects are re-checked in publication order at the end of every entry [clarification, 17 Oct 2026 (D1 review)]; a project that has not opened by its open lapse lapses (below)[E-5]; consent stays [Proposal]
Inflowevery inflow moves to reserve inside the entry that produces it, then drain() (below) moves it on to receiving projects[A8]; one move per receipt, as today with Common Good renamed
with several receiving projects, the oldest opening first; the part that would pass a project's amount goes on to the next; no project limits for now[8b]
with no receiving project the inflow stays in the reservefollows from decision 8 [A8] (8d, no longer open)
Full and paywhen received = amount, rule project_full (status full), then in the same block rule project_pay: the project's whole balance → the recipient (status paid); the recipient's grow and settled go to the reserve and on by drain(). For a step raise the recipient is world-step [Proposal], which has no wave, so nothing flows back: this project really uses up community money, and the circle's step rises by the amount[A8, 8a, 8j]
Lapse before openinga project that has not opened by its open lapse at (published at + open_lapse_s, 30 days by default, recorded at publication) lapses (rule project_lapse, status lapsed); its wallet is empty, so nothing moves; since vote_max_s < open_lapse_s, its vote has always ended by thenproposal carried over from orders; the due time: Consequence of E-1
Closing a receiving projectk Heart members book project_close; after close_notice_s (72 h by default; its close due recorded at the k-th project_close) of public notice a rule project_return moves the project's whole balance → reserve in one move (none when the wallet held 0 [proposal (D3 review, 19 Oct 2026)]) (status closed), then drain() moves it on to the next project; the close commits only if at least k distinct Heart members in office at the commit signed project_close, otherwise the collection is void [clarification, 17 Oct 2026 (D1 review)][8e]; k = 3 of 4: proposal
Lapse of a receiving projecta receiving project that is not full by its receive lapse at (opened at + receive_lapse_s, 90 days by default, recorded at its opening, so a project opened under 90 days keeps 90 even if the parameter later says 30 [clarification, 17 Oct 2026 (D1 review); Consequence of E-1]): rule project_lapse, then project_return → reserve (status lapsed), then drain()[8e]; counting from opening is a proposal (the project owner: "in 90 days")
Other returnsproject_return (status closed) also when the recipient books project_decline or leave while it receives, the recipient is excluded while it receives, the proposer books project_withdraw while it receives, or project_pay falls due but the recipient is no longer a memberproposal, not covered by 8e (the exclusion: Proposal, E-3)

Project statuses [E-5]: proposed (voting), passed, receiving, full, paid, declined, withdrawn, lapsed, closed, fell; final: paid, declined, withdrawn, lapsed, closed and fell.

Motions [Decided 23 Oct 2026, E-5: a Heart member may put any proposal to a vote, and a proposal without money is a public decision in the ledger; the shape: Proposal]: a Heart member's motion (title, duration, the proposal as text) is booked as o3|motion and voted on like a project, with the same rule (no "against" from any member and at least project_approvals Heart members "for") [Proposal], except that the proposer's own "for" counts toward them [Decided 23 Oct 2026, E-11]; at its vote end vote_pass or vote_fall is booked and its line goes: the entry is the public decision. A motion moves no money.

Inflows (each one move into reserve inside the entry that produces it): the grow and settled of every receipt (pay, xin, a project_pay to a member); every grav deduct; the part of a named give above the project's room, and a whole unnamed give (Open 8g); a step lowering (world-step → reserve, proposal); a project_return; once, in block 1, the start from origin [6c]. The reserve pays out only by reserve_move (to a project), by an account close or a reference return (close_cover to the closed line, close_wave to origin) and by a reference grant (reference_out to world), §3.11 [E-3, E-9 (b)]; a newcomer's grant comes in from origin and a returned step's reference_in from world.

drain(), run at the end of every entry [clarification, 17 Oct 2026 (D1 review)] as the first part of its end-of-entry work (§3.5), not only after an entry that moved money into the reserve or booked a project_open, since a give that exactly fills a named project moves nothing into the reserve and the full project must still be paid (a grav entry in a morning block included; the deducts of grav entries booked as visits are drained at the end of the entry they precede, §7.4), also in payment blocks during the morning; a member who leaves while the recipient of several receiving projects gives one project_return per project, each followed by its own drain(), as every inflow is [clarification, 17 Oct 2026 (D1 review)]: a member_leave (and likewise a member_exclude [Proposal, E-3]) first ends declined every project not yet receiving whose recipient is the leaver (the leaver's projects are those whose recipient is the leaver [clarification, 17 Oct 2026 (D4 review, round 3)]; no entry of its own; the member_leave entry carries the change), then returns each receiving project whose recipient is the leaver in drain order (project_open height, seq), each project_return followed by its end-of-entry work [proposal (D4 review, 17 Oct 2026)]; identically by every witness:

repeat
  for P in receiving projects, ordered by (height, seq) of their project_open entry      [8b]
    t = min(balance(reserve), amount(P) − received(P))
    if t > 0: rule reserve_move: reserve → P, t
    if received(P) = amount(P):
      rule project_full(P); rule project_pay(P): P → recipient(P), the whole amount   [8a]
        (if recipient(P) is no longer a member: rule project_return(P): P → reserve instead, below)
      if recipient(P) is a member: the recipient's grow, then settled (read after the
        receipt and the grow move), recipient → reserve; if the recipient's grav entry
        of an open morning is still pending, it is booked first, right before
        project_pay (visit before touch, §7.4)
      if recipient(P) is world-step: no wave, nothing flows back; the step
        (= balance(world-step)) has risen by amount(P)                                  [8j]
      restart the for-loop from the first project
until balance(reserve) = 0 or no receiving project has room
  • It ends: every pass either empties the reserve or pays a project, and a project pays at most once (paid never receives again).
  • A recipient who has left [clarification, 17 Oct 2026 (D4 review)]: inside drain(), a full project whose recipient's account is no longer a member (it left, or it is excluded or closed [Consequence of E-3]) books project_full, then project_return (status closed, the money to the reserve), and drain() goes on; a frozen recipient is still a member and is paid.
  • Invariant every witness checks: after the end-of-entry work of every entry except a grav entry booked as a visit (§3.5), balance(reserve) > 0 only if no receiving project has room.
  • Several project_open due in one block: a passed project opens at the end of the first entry after which its consent is given and, for a step raise, it fits under built, whether an act completed its last condition or not (a step raise that did not fit under built when its vote passed; a change of the parameters in force); passed projects are re-checked in publication order at the end of every entry, and projects that become openable at the end of the same entry open in publication order (project_propose seq) [clarification, 17 Oct 2026 (D1 review)]; those whose votes pass at the start of a block, by project_propose seq; each is followed at once by drain().
  • Size: a cascade that would pass 100,000 bytes closes the block after its last whole step; the next block, at the same at, starts with the remaining steps, exactly as they would have come (the block split, §3.5) [completed 24 Oct 2026, plan step E4x]. Invariant every witness checks: after the end-of-entry work of every entry except a grav entry booked as a visit, balance(reserve) > 0 only if no receiving project has room, or the block was cut (more) and the next block continues the drain.
  • The money fact [Decided 16 Oct 2026, 8f]: below the recipient's wave cap a project payment grows the recipient's wave by the whole amount, and the same amount goes on as inflow, so paying a project does not shrink project wallets plus reserve. The pool shrinks only by a step raise (its money goes into world-step, which has no wave) or a recipient at the cap, and grows back by a step lowering. The brake on projects is the vote (no "against" and at least project_approvals Heart "for"), not money [8f, E-5]; that the proposer's and the recipient's "for" do not count stays the guard.
  • No project limits for now [Decided 16 Oct 2026, 8b]: no maximum amount per project, no daily proposal limit, no limit on open proposals per member; today's order limits (SUPPORT_MAX_AMOUNT 100,000, one proposal a day, three open) are not carried over. Said openly: one large project holds back every project behind it until it is full or lapses after 90 days [8e].
  • The step outward [Decided 16 Oct 2026, 8j]: a raise is a project like any other; its recipient is world-step [Proposal]; when full, its project_pay moves the wallet into world-step and the step rises by that amount. Said openly: world-step has no wave, so a step-raise project really uses up community money. A lowering by s [Proposal]: step_propose with a negative amount, decided by a vote like a project [E-5], then rule world-step → reserve and drain(), only if step − s ≥ max(0, world_used); the builder does not book a lowering in 0.3.0 (no complete rule), and step_approve is gone. The step never exceeds what the members have built [Decided 15 Oct 2026]; built = Σ (balance + wave) over every account line that is not a system account or a project wallet, of any status, members who left included, since their money is still in the circle [clarification, 17 Oct 2026 (D1 review)]; the formula of built and the check step + s ≤ built at project_open and project_pay (docs/prepoznavanje-goljufov.md §5) are a proposal.
  • Every rule entry names the rule and its input ids (the acts and entries it follows from), so any reader can replay it.
  • Contributions (give) name a project in status receiving or no project; a contribution naming an open project in any other status is refused not_receiving [Proposal], and one naming a project that has ended (paid, declined, withdrawn, lapsed, closed or fell: its o3|project line is gone) not_found [clarification, 19 Oct 2026 (D3 review)].
  • The seal's snapshot carries every project's o3 line and the reserve's s3 line, and the seal carries ["reserve", balance], so the state of every project is public every day.
  • The start [Decided 16 Oct 2026, 6c: »6c, da«]: a circle's first money is one start of 1,000 in the circle's currency for the reserve at founding, and nothing else (no starting wave per member, no bridge from Lana). Block 1 books, right after its genesis entry, one rule entry start: origin → reserve, "100000" minor units (1,000.00; EUR, USD and GBP all have two decimals), then drain() (no project receives at genesis, so the start stays in the reserve). origin (SL »izvor«) is a keyless system account, derived like the others (§3.8, role origin); its line is −100000 from block 1 and moves only by grant and close_wave (§3.11) [E-3, E-9 (b)]; it is in every snapshot and every seal (["origin", balance], §3.6), and the sum stays 0. By 8f the start keeps coming back: a project payment to a member below the cap grows that member's wave by the whole amount, and the same amount flows on as inflow to the next receiving project or the reserve. The names start and origin and the exact shape of the entry are a proposal for definitions 0.3.0 (plan C1); that origin takes back a closed account's wave is decided [E-3, confirmed 23 Oct 2026]. The live circle gets the same start in its block 1 (plan E6; proposal: 1,000 EUR = "100000").

3.10 Size budget [E, from the measured 0.2.0 sizes]#

ItemBytes
Payment entry inside a block (compact note ~370, header ~40, two lines ~250, two p tags ~144)~800
Cross-circle payment, all legs in both circles (xout 800 + xdone 200 in A, xin 800 in B)~1,800
Block envelope without signatures (id, pubkey, sig, header tags, roots, the project or reserve line)~850
One qs tag~205
One-payment block: single witness / quorum 3 / FROST later~1.9 KB / ~2.3 KB / ~1.8 KB
Full block≤ 100 KB (~120 payments)
Morning gravity, per account (grav entry + line + p tag; while a project receives, also its reserve_move)~420; ~700 while a project receives (a morning block holds about 240 accounts, about 140 while a project receives; measured on the synthetic morning block of the definitions)
Snapshot line, full decision record~200 (≤ ~450 per chunk)
Seal + head~4.5 KB a day
A reference (43921)~0.7 KB; up to ~18 KB with 100 + 100 project ids [E]

3.11 Membership, exclusion, the reference and closing accounts [Decided 23 Oct 2026, E-3, E-4, E-6, E-8, E-9; the mechanics: Proposal]#

This section gathers the rules of round 5 that move people into and out of a circle. The parameters it names are circle parameters (§3.1 rule 11). Every rule here is deterministic and recomputed by every witness; the sum stays 0.

Joining [Decided 23 Oct 2026, E-6 and E-9; the order of the checks: Proposal]. A join act (optional ["e", <invite id>, "", "invite"], optional ["e", <43921 id>, "", "reference"]) is judged by these checks (when several apply, the reason booked is the first in refusal_order: so not_allowed before duplicate, and duplicate before repeated [clarification, 25 Oct 2026; D4 round 5 N4]): a key whose line is member or frozen: repeated; a key whose exclusion runs (an open o3|exclude): not_allowed; a key with an open o3|join: repeated; a named invitation that is not open: not_found, one of another key: not_allowed; invite_only = 1 and no invitation (except an excluded key's application): not_allowed; a key whose newest member home (30916; the node reads it on the root relays) names another circle, without a valid reference from that circle (below): not_allowed [E-9: a rule for every circle, not a setting]; a join that brings a step (a reference with a wave above 0) while this key's own reference from this circle still waits for the return of its wave (o3|reference): not_allowed [Decided 23 Oct 2026, E-11: no step while an earlier move out is not settled, A → B → A]; a join naming a reference this circle granted a step on already (its u3 line, whatever the step and whether the grant's hold has ended, through any 43921 copy of the same entry), or one that a waiting join already carries (its o3|grant line): duplicate, also for a member or an applicant whose join waits (not repeated) [Decided 25 Oct 2026, E-13 (A): a circle accepts a reference once]. Then:

  • an excluded key whose exclusion is over → o3|join|<id>|<key>|heart|<the join act's expires>|<seq>: it is never admitted by rule and never from the waiting list; member_readmit (the larger of k and 3 Heart members [E-10], no notice; tag ["e", <join act id>, "", "join"]) admits it at the k-th act (member_join, in [join act id]); refused not_allowed when no place is free; readmission gives membership only, never a Heart seat [E-3];
  • a free place (max_members = 0, or the members (status member or frozen) fewer than max_members) → member_join at once (in [join act id]; with a reference also ref, src and g);
  • otherwise the waiting list: o3|join|<id>|<key>|waiting||<seq> (no expiry; its later member_join names the join's reference when it has one).

An invite (["p", <HEX>], by a member) books o3|invite|<invite id>|<key>|<inviter>|<until>, until = at + invite_ttl_s; it is one-time: the line ends when a join uses it, or at the first block whose first at is later than until [E-6; one-time and 7 days: Proposal]. When a place frees (a leave, an exclusion, a close, a move, a parameter change), at the end of every entry (after drain(), the openings and the closes, §3.5) the first on the waiting list (the lowest seq) is admitted by rule, member_join (in [its join act]), while a place is free [Decided 23 Oct 2026, E-6]. An excluded key is never admitted from the list; only the Heart readmits it. An applicant's own leave act withdraws its o3|join (no member_leave).

Exclusion [Decided 23 Oct 2026, E-3; the shape: Proposal]. member_exclude is a Heart act in the endorsement form: the larger of k and 3 Heart members in office [Decided 23 Oct 2026, E-10], no notice, effective at the act that reaches them (the k-th act); ["p", <member HEX>], optional ["e", <OWN case event id>, "", "own"] [Proposal, E-4]; text required: a short public reason [Proposal]. The excluded key never counts toward its own exclusion. The named key must have a line with status member or frozen (else not_member). At the k-th act:

  • if the key is a Heart member: first a roles entry (acts = [the proposing act]; the mirror without its steward tag; stewards_required lowered to the number left when it is above it; at least one Heart member stays) [Decided E-3: "who first loses the Heart seat"]; if the block already holds a roles entry, the k-th act waits for the next block (the intake answers roles_taken);
  • then the rule entry member_exclude (in [the proposing act], party): status excluded; o3|exclude|<hex>|<until>|<act id> with until = at + exclusion_s; the key's projects end as at a leave (not yet receiving: declined; receiving: returned, in drain order) [Proposal, as for a leave].

The o3|exclude line ends at the first block whose first at is later than until; then the person may apply (a join, above).

An excluded line [Decided 23 Oct 2026, E-3]: frozen inside the circle (no payment, no give, no vote, no proposal; it receives nothing except a settlement, below); every morning still visits its plus (§7.2); it may send its plus to another circle (xout, amount ≤ max(0, balance), never the wave); the minus stays.

Leaving and the reference [Decided 23 Oct 2026, E-9: the reference is issued by itself after "I want to leave" when its conditions hold, otherwise not, and nobody moves to another circle without it; the mechanics: Proposal]. A leave act of a member (member_leave, status left) or of an excluded key (its status stays excluded) books o3|leaving|<hex>|<leave act id>|<seq>. At the end of every entry (after drain(), the openings and the closes, before the waiting list) each leaving line, in booking order, whose conditions hold gets the rule entry reference (in [leave act id], party, wave = its wave), and its leaving line goes. So the reference comes at the leave, or later, when a settlement brings the balance to 0 or the last OWN process closes. A leaving line also ends when its key joins again here or its account is closed (an account_close never gives a reference). The conditions [Decided 23 Oct 2026, E-9 and E-9 (a)]: no minus (balance ≥ 0) and no open OWN process about the key (o3|own), also without a debt: the process must close first (said openly: the Heart, which leads the processes, can hold a person back this way). The reference entry opens o3|reference|<hex>|<leave act id>|<wave> until the new circle's payment arrives (reference_return), the key joins here again or its account is closed [E-9 (b); Proposal].

Settlement [Decided 23 Oct 2026, E-9: a debt must be settled in any case, and anyone may settle it, by payments into the account, never above 0; during an exclusion too: Proposal (the supplement's proposal; the project owner: »če je bil izključen se rabi vrnit nazaj, poplačati predno se lahko seli«); the shape: Proposal]. A left or excluded line with a minus may receive payments that settle it: a pay from a member of the circle, or an xin from another circle, to that line, amount ≤ −balance (never above 0), with no grow and no settled move. Any other payment to it is refused not_member. A key that left (also to move) may send its plus to another circle like an excluded key (xout, ≤ max(0, balance)) [Proposal: so a person who moves takes the plus along].

43921 and the new circle's check [Proposal]. The node signs the 43921 (§3.7) right after the block that books the reference entry has its quorum, and publishes it on the circle's relays. A join that comes from another circle names it, ["e", <43921 id>, "", "reference"]; the new circle's node checks that its c is the circle the key's newest member home (30916) names (the last circle), that its p is the key, and that the named block of that circle carries the reference entry of the key with the same wave and a quorum of that circle's witnesses in office at that height (as for the 8j evidence, §4.5). The member_join entry then names it: {rule: "member_join", in: [join id], party, ref: <43921 id>, src: [height, digest], g: <that circle's genesis digest>}. The new circle republishes that 43921 and the named block to its own relays, so it restores without the old circle [Proposal]. A key with no member home anywhere was never a member and needs no reference [Proposal]. Said openly: a deleted home or a second key is not caught (that needs Lana's person check); root relays keep member homes (no deletion by KIND 5) [Proposal].

The step (wave) in the new circle [Decided 23 Oct 2026, E-9 (b), the project owner's own model: »… in se zadeva izniči«, "… and it cancels out"; the bookings, the rounding and the step brake: Proposal]. In the old circle the balance is 0; the new circle opens the same step (wave) the reference states and, as with every growth of a step, the same amount goes to its community, counter-booked from its own origin; the new circle sends that amount to the old circle's community; the old circle closes the account (its wave to 0) and returns exactly that amount to its origin. Both communities hold what they held before.

  • In the new circle: the member_join that names a reference with a wave W above 0 is followed in the same entry by the rule entry reference_grant (in [the 43921 id], party = the newcomer, to = the old circle id, amount = G in this circle's currency, to_amount = W in the old circle's, quote = the old circle's 43919 id, only across currencies, mv): the moves grant origin → reserve G and reference_out reserve → world G, in one entry (nothing drains between); the newcomer's wave grows by G (cap = wave_cap; a wave above it grows no more). G = W in one currency; across currencies G = ceil(W × r_new / r_old) under the old circle's 43919 valid at the join, so to_amount = floor(G × r_old / r_new) ≥ W. G is held like an xout (o3|hold, with the 43921 id as the note id and the reserve as payer) until xdone on the old circle's reference_return, or xundo on its refusal (reason refused), which gives G back to the reserve. A circle accepts a reference once [Decided 25 Oct 2026, E-13 (A); before it, plan step E4x refused it only while the grant's hold lasted]: the member_join that names a reference opens its u3 line, never removed (a restore from a seal keeps it), keyed by the reference's entry (the old circle's genesis, the block with the entry, the person), so any 43921 copy of that entry is the same reference [review of E-13, 25 Oct 2026]; a later join naming that reference, at the door or from the waiting list, after a readmission or after the person left and came back, is refused duplicate, and so is a join naming a reference that a waiting join carries already; the waiting list never admits a join with a used reference. A reference is valid once [Decided 23 Oct 2026, E-11]: right after that xundo the rule entry grant_revoke (in [the 43921 id], party = the newcomer, which the o3|hold line names; mv: close_wave reserve → origin r, none when r = 0) takes the unused part of the granted wave back to origin, r = min(G, wave − max(0, −balance)); the membership stays; a wave already used as cover stays (the circle bears it); nothing is taken from a closed line or from one whose step moved on with a reference of this circle that still waits for its return; the newcomer's grav entry of the open morning comes first, also when nothing is taken (r = 0: the touch is the xundo's) [clarification, 25 Oct 2026, D4 N19]. A grant has no expires, so the 8j evidence of not_booked (the partner's seals up to the note's expires) can never be complete and the old circle may book its reference_return later: a grant's hold is never undone as not_booked (not_allowed), and a silent old circle keeps it waiting, as any silent partner does [Decided 23 Oct 2026, E-11 (1A); D4 round 5 N6].
  • In the old circle: when it reads the new circle's block with the reference_grant, the rule entry reference_return (in [the 43921 id], party = the key, src = [height, digest] of that block, g = the new circle's genesis digest, wave = W, mv): reference_in world → reserve what arrives (to_amount), then close_wave reserve → origin exactly W, covered at once by what arrived (a rounding rest stays in the reserve); the line's wave, cap and debt become 0, and it is closed when its balance is 0 and none of its payments to other circles is still held (a plus left over, or a held payment, keeps the line left without a wave: gravity takes the plus, a refused payment comes back to it; then only an account_close closes it) [review of E4x, 24 Oct 2026]. Its grav entry of the open morning is booked first (visit before touch). It is refused, with src naming that block so that the new circle returns its hold by xundo, when no reference of the key waits for its wave (not_found: the key joined here again, its account was closed, or this reference was already returned or refused for another grant: every grant is answered on its own, E-11) or when what arrives is below W (no_cover). [review of E4x, 24 Oct 2026] The old circle returns only a grant that is right, else it refuses it the same way: the reference's wave is above 0 and the grant's party is the reference's person (not_allowed), and what the grant says arrives is exactly the wave in this circle's currency: W in one currency, across currencies floor(G × r_old / r_new) with G = ceil(W × r_new / r_old), in whole numbers (each division rounded once, as written; r_new and r_old are the rates of the new and the old circle's currencies in whole ppm per 1 EUR, r_EUR = 1,000,000, as the 43919 rate tags give them) under this circle's own 43919 that the grant names, signed by its node in office, naming this circle and valid at the grant's at (bad_quote). A node ends a hold only on an answer to its own block: the xin, reference_return or rej it reads names, as its src, this circle's block with the hold's xout or reference_grant (height and digest); an answer to another block ends nothing here; the booking decides: a rej of the note (or of the return) after its xin (or reference_return) naming the same block is a duplicate's refusal, no answer. A key whose reference of this circle another circle has granted comes back here only with that circle's reference.
  • Both sums stay 0 at every entry; in each circle origin = −start − granted + returned, which may go above 0.
  • [Decided 23 Oct 2026, E-10 (2A), safety] G counts against the new circle's step outward (world used + G ≤ step): a join whose grant does not fit waits on the waiting list until it fits, with its grant in o3|grant (§3.8) beside its o3|join line. Open question for the project owner: so a circle that cannot raise its step outward takes in no waves from other circles.

Closing an old account [Decided 23 Oct 2026, E-3; the accounting confirmed 23 Oct 2026 (»ostalo si pravilno razumel«); the circle covers a minus only when the member has died (E-3 Dopolnitev); the shape: Proposal]. account_close is a Heart act in the endorsement form: max(k, 3) Heart members [Decided 23 Oct 2026, E-10], no notice; ["p", <HEX>], text required: the public reason [Decided 23 Oct 2026, E-10 4A; D4 round 5 N9]. The line must be member, frozen, left or excluded and not a Heart member in office (else not_allowed). At the k-th act: a member or frozen line (a death) first gets member_leave (in [the proposing act]; never a reference); then o3|close|<hex>|<act id>|<seq> waits (seq: the member_leave it books first, else the k-th act's own entry; D4 round 5 N1). At the end of every entry (after drain() and the openings, before the references and the waiting list) each waiting close, in booking order, completes when its grav entry of the open morning is not pending, no leg of the account to another circle is held [D4 round 5 N2; with E-10], balance ≤ 0, and reserve ≥ −balance + wave. Then the rule entry account_close (in [the proposing act], party): close_cover reserve → line (−balance, when below 0), close_wave reserve → origin (the wave, when above 0); wave, cap, debt and carry become 0; status closed; its o3|close line goes. The new move reasons are close_cover (reserve → line), close_wave (reserve → origin), grant (origin → reserve), reference_out (reserve → world) and reference_in (world → reserve); origin moves only by start, grant and close_wave. A plus waits for gravity (or is sent away first). Never urgent; nothing breaks if an account stays. Invariants: origin = −start − granted + returned; Σ waves = grown + granted − returned. A closed key that joins again starts at 0 (status member, cap = wave_cap). Said openly: by E-3 Dopolnitev the circle covers a minus only when the member has died; the ledger cannot see a death, so this rests on the Heart's public act (k Heart members), and a line that left with a minus is otherwise not closed: its debt stays written, and anyone may settle it.

Gravity [Consequence of E-3]: every morning visits every line with status member, frozen, excluded or left (not closed) (§7.2); before, left lines were not visited, so leaving and coming back escaped gravity.

OWN processes [Decided 23 Oct 2026, E-4: the Heart leads and oversees them; they run in the existing OWN apps (encrypted), and only a decision reaches the ledger; the acts: Proposal, a consequence of E-9]. So that the rule can judge the reference's OWN condition, the ledger books that a process is open and that it is closed, with no content: own_open (any member, alone, at once [Decided 23 Oct 2026, E-10]; ["p", <HEX>], optional ["e", <OWN case id>, "", "own"]) books o3|own|<own_open id>|<hex> (about a key with an account line here, a closed one too; a key with no line is not_found [clarification, 25 Oct 2026, D4 N20]); own_close (one Heart member in office; ["e", <own_open id>, "", "open"]) ends it. Said openly: since an open process blocks the reference (E-9 (a)), any member can hold another's reference back until a Heart member closes the process. A member who does this on purpose to harm another can be excluded for it by the Heart (the usual exclusion, at least three Heart members) [Decided 23 Oct 2026, E-10]. An exclusion after an OWN process may name the OWN case event id, ["e", id, "", "own"] [Proposal].

Founding [Decided 23 Oct 2026, E-8: only a member of an existing circle founds a circle, every circle grows from the first one, one circle per founder key, ever, and a person is a member of one circle at a time; the shapes and mechanisms: Proposal]. The found act names its parent: ["parent", <parent circle id>, <parent genesis digest>] after start, required except for the root (the live circle); right after it the founder's reference from the parent, ["e", <43921 id>, "", "reference"] (required with parent [Proposal]; that the founder needs it: a consequence of E-8 and E-9). meta.root_circle names the root's circle id (empty while a draft; the examples use circle A as the TEST root, and circle B names A). The 30910 mirror carries ["parent", …] after founder when the found act names one. That the founder was a member of the parent when founding (its member home and the parent's member_join) is checked by the root directory and by readers [Proposal: details in phase G]. One circle per founder key, ever: the root relays keep the first found act per founder key (first-seen, like the genesis pin) and refuse a second circle record of the same founder [Proposal: the mechanism]; this replaces "at most three circles per founder". A person is a member of one circle at a time: joining (or founding) another means leaving the old one, and nobody moves without a reference, which is issued only after a leave; so a key cannot be a member of two circles (a second join finds the first new circle in the newest home). The founder's own join in the new circle may name the same reference. Said openly: one person with two keys is not prevented; that needs Lana's person check.

4. Payment write path#

4.1 Steps#

  1. Prepare (app). From the relays (or its cache) the app knows the circle's witness set and relays (from the ledger, cached ≤ 24 h), its own newest line (balance, wave, note_n, note_head) and that the receiver is a member. Across currencies it first asks the receiver circle's node for a 43919 quote, shows the converted price and the quote's validity, and continues only if the payer accepts [Decided 16 Oct 2026, A7]. It signs the canonical 43910 (n = note_n + 1, prev = note_head, expires = now + note_ttl_s (600 s by default; across circles, and during a parameter change's notice, the smaller of the two values [Proposal, E-1]), across currencies to_amount and the quote id) in the browser. 5–20 ms.
  2. Submit. HTTPS POST of the signed note to the node's api (write intake only; nothing is read from it that is not on the relays). 30–100 ms.
  3. Check and order (node). Signature and template round-trip; n/prev equal the payer's head (else stale_prev, a refusal, never "fraud"); not expired; payer and receiver are members (a payment to a left or excluded line with a minus is a settlement, §3.11); cover amount ≤ balance + wave at this exact seq (no held_out [A6]); receiver can receive; idem unused for (payer, prev). Assign seq, at (own clock, seconds, never below the previous at); compute grow and settled, their move to the reserve and the drain() that follows (§3.9), the lines and the state root. 2–10 ms.
  4. Close the block by the closing rule (§3.5).
  5. Witness round (quorum mode only) [Decided 16 Oct 2026, A3]. The node sends the unsigned block body to every witness over direct authenticated links. Each witness checks that the node is the node of this height in S(h), that h = its last + 1 and prev matches; re-runs every check and recomputes every line and root from its own state (built only from relay blocks); checks the sum is 0 and at is within ±5 s of its clock; writes its sign-guard (fsync); returns its signature over sha256("lb-block/3|" ‖ digest). q signatures (the node's included) = commit. 50–150 ms regional.
  6. Seal the event. The node adds the qs tags, signs the 43911, writes it to its write-ahead log (fsync) and sends the final event to the witnesses (they fsync it too).
  7. Publish (single publisher). The node sends the event on persistent sockets to every listed relay, pipelined in height order. Witnesses republish only what is still missing from a relay after 5 s (covers a node crash after step 6 without 4× message amplification).
  8. Final per §4.2. The node answers the POST with the block's height and digest and the relays that confirmed.
  9. The payer's app verifies by itself: one REQ {"kinds":[43911],"authors":S,"#h":["<scope16>:<h>"]} to 2 relays; exactly one block at that height on each, same digest (two events with one digest are the same block and may differ only in their witness signatures), signatures, embedded note, own line arithmetic (previous line ± moves = new line). Then "paid · block h · public on N of M relays · confirmed by q of n". This height-uniqueness read also closes single-witness equivocation across overlapping relay sets.
  10. The receiver's app keeps a live subscription {"kinds":[43911],"authors":S,"#p":[me],"limit":0} on 2 circle relays while open and shows "received" after the same checks.
  11. Repair. The circle's replication audit (§9.3) makes every block reach every listed relay.

4.2 When a payment counts [Decided 16 Oct 2026, A1]; operators (Q14); sending on (Q17)#

  • Final when the block carries ≥ q valid signatures of S(h) and ≥ 3 listed relays [A1]; of ≥ 3 operators (bootstrap ≥ 2) [Proposal Q14]; answered OK true for this exact id and every lower height is final. The app shows "paid · public on N of M relays" [A1].
  • Sending to every other listed relay continues; the app always shows the real "N of M" (Q17). This replaces the rule of 14 Sep 2026 that publishing waits for every relay's answer; the project owner decides.
  • The Lana relays count toward the three only after their owner applies the ledger write policy of §9.2 (Q18); the box relay ships with it.
  • [Open] (Q14, Q18): until the Lana relay owner applies the write policy, only the box relay counts, so under A1 no block could become final and the circle would depend on one outside owner. the project owner chooses: (a) the circle books nothing until then; (b) until then the Lana relays count as copies, publicly labelled "copies without protection against deletion"; (c) until then the circle finds two more relays with the same policy at other operators.
  • Durability before commit is each witness's local write-ahead log, not its relay; durability at commit is the final event on ≥ 3 relays.

4.3 Latency budget (payer sees "paid") [E]#

StepSingle witness, borrowed Lana relaysOwn regional relays, quorum 3 of 4p99 target
Sign in browser5–20 ms5–20 ms50 ms
POST to node30–100 ms30–100 ms300 ms
Checks, ordering, roots2–10 ms2–10 ms30 ms
Block closing (idle / busy)0–50 ms / ≤ W_max0–50 ms / ≤ W_max2 s
Witness round—50–150 ms400 ms
fsync guard + WAL1–10 ms1–10 ms30 ms
Third relay OK (EVENT→OK never measured; REQ→EOSE as proxy: third-fastest Lana relay ~390 ms [R])300–1,000 ms80–300 ms1.5 s
Answer to app30–100 ms30–100 ms300 ms
App's own read-back on 2 relays (warm)60–220 ms [M]60–220 ms [M]700 ms
Payer sees "paid"~0.5–1.5 s~0.3–0.9 s< 3 s

Today's same-machine v2 payment takes ~12 ms [R]. The first build step measures EVENT→OK; until then these are estimates.

4.4 Bootstrap: one witness [Decided 16 Oct 2026, A3]#

  • n = 1, q = 1: the circle's box is node and only witness, with full crash discipline (§4.6). Until there are enough circles to draw witnesses by lot (phase I), a circle has this one witness, its own computer, publicly labelled [Decided 23 Oct 2026, E-7].
  • The app shows "not yet decentralised" on every screen that shows money.
  • No money cap (the project owner: "no money cap"). There is no cap parameter in the found act.
  • An independent verifier replays the ledger daily and publishes 43924; the daily restore drill (§8.3) is public; any fail statement shows in every member's app. There are no payouts, so there is no payout circuit breaker [A6], and no deposits, so there is no deposit alarm [6a].
  • Known weakness, said openly: in single-witness mode a wrong entry can be booked before it is caught; a stolen node key can book alone (it cannot forge a member's note, but it can mis-book rule entries, for example moves between project wallets and the reserve). With no cap, what bounds the damage is how fast the public label, the daily verifier and the drill catch it, and then the move to four witnesses.

4.5 Spending twice is prevented#

  1. The member's chain: one successor per (n, prev); a second note on the same prev can never be booked; it is refused stale_prev (a stale read, not a crime).

  2. One block per height: each witness signs at most one digest per (circle, height) and persists that first; two blocks at one height would need two quorums, which overlap in ≥ f+1 witnesses, so at least one honest witness would have signed both, which it never does. A witness that signs two digests at one height leaves public proof (43924 equivocation) and is removed.

  3. Cover at a fixed point: the spendable check runs against the state after seq − 1, identical for every witness.

  4. Across circles: the payer's circle (A) books xout (a hold on world) before the receiver's circle (B) books anything. The step bounds the net outflow [clarification, 17 Oct 2026 (D4 review)]: world used = the balance of world = what the circle's members paid out to other circles less what came in (xout − xin − xundo); it may be negative. An xout counts only if used + amount ≤ step (the balance of world-step; else step_full): what members received from other circles they may spend in other circles even with step 0; the step bounds the net outflow. A timeout alone never undoes. xundo (world → payer) on B's signed refusal or "expired". A payment that hangs [Decided 16 Oct 2026, 8j]: nobody pays a refund. If A has booked neither xdone nor xundo by the hold's check at (the xout's at + A's xcheck_s then in force, 7 days by default [8j, E-1], recorded in its o3|hold line, so a later change never moves it [Consequence of E-1]), a duty falls due in A: every witness of A reads B's ledger from B's relays (B's witness set from B's log; quorum checked) and looks for the note in every B block whose at lies from A's xout at − 60 s to the note's expires (the margin is a proposal), found by height inside B's sealed ranges (heights are gap-free and at never goes back). B's office [Proposal]: A reads it from B's ledger, the office below the lowest block read and then each roles entry in the blocks read, in office from the next height, and judges each B seal with the office after its h_to (§3.6); a B block counts only with a valid quorum of B's witnesses in office at its height: a block without one (for example signed only by an old, retired or stolen key) is not B's and is ignored, and two blocks with valid quorums at one height are a fork, so the evidence is not used. A block or seal copy without a valid quorum of B's witnesses in office never counts and never hides a copy that has one, and what rests on an office that a missing block leaves unknown is unverifiable. So a hold whose evidence spans a key or witness change of B can still be settled, and noise signed by keys that are no quorum of the witnesses in office at that height cannot stall it; a key that was in office at a height (for example the single witness of a one-witness circle, later stolen) can still fork that height, and a fork stops the evidence. B can never book the note after its expires (§3.3; at most note_ttl_s after signing, 10 minutes by default; B judges the note by its own note_ttl_s), so once B's daily seals cover the whole time up to expires, B's answer is fixed:

    • B booked xin for this note id with exactly to_amount → A books xdone by rule, naming B's block as [height, digest];
    • B booked no xin for it (a rej, or nothing) → A books xundo by rule, world → payer, naming as its evidence B's consecutive seals as [day, digest] and the height range they cover [Proposal]: from the last seal whose predecessor covered only bookings before ws = A's xout at − 60 s (its prev covers < ws; the last such seal, so no named seal is superfluous [clarification, 17 Oct 2026 (D4 review)]) to the first seal whose boundary is later than the note's expires (strictly), so one or two seals; the xundo also names, as before = [day, digest], the real seal before the first one (omitted only when that is B's first seal), and every witness of A fetches it, checks B's quorum on it and that it chains to the first seal exactly as that seal's prev describes (digest, day, boundary, covers); without it the evidence cannot be verified and nothing is booked, because the first seal's own description of its predecessor is B's word alone. B's seals chain by digest and each names its predecessor's boundary and covers (§3.6), so every B block before that range books before the window and every B block after it at or after a boundary later than expires, when the note can no longer be booked. An idle B still seals every day (possibly with an empty range). Every witness checks the evidence against B's blocks, not only its seals: the seal before and every named seal must match B's blocks of their ranges (heights, digests, head, covers, entries, state root), and B's first seal always covers from its block 1. The evidence is closed by B's block right after the last seal (it follows that seal's head and books at or after its boundary) or, when B has booked no block since, by B's next daily seal, named as next (the seal of the day after, chained by prev, with B's quorum and an empty range from h_to + 1; a block at that height booked before its boundary refutes it); before relying on the next seal, a witness confirms on at least two of B's relays that no block exists at h_to + 1 (a runtime rule: a verifier without block h_to + 1 reports this check unverifiable [clarification, 17 Oct 2026 (D4 review)]). A block or seal that is not given leaves the evidence unverifiable, so nothing is booked; a B that stops sealing keeps the hold waiting. Every leg names B's genesis digest (g), so A reads only the B chain it pinned;
    • B's ledger cannot be read in full (B's relays silent, a missing height in the span, no B seal yet covering expires, a seal without B's quorum, two B seals for one day) → nothing is booked; never a guess. A witness that cannot read the span does not sign, so there is no quorum. The duty repeats [Proposal: every day after the morning] and the amount stays held.

    An unreadable partner never holds up A's own bookings: unlike the other duties (§7.4), this check becomes a due entry only once the node has read the evidence, and witnesses refuse an xdone or xundo they cannot verify themselves, never a block that leaves the check out. A node that keeps leaving out a check its witnesses can verify is replaced, as for censorship (§4.8). The payer gets the amount back at most once, and only on evidence; the refund by public decision (xrefund, reserve → payer) is gone [8j]. Across currencies (§3.7) [A7]:

    • the payer's circle checks the quote first, exactly as the receiver's circle will (signed by B's node of that time, B's source, not expired at this booking's at, to_amount exact; the office at a time t (a quote's node and rate source at its created_at) is that of the newest mirror booked at or before t (its genesis or roles entry's at ≤ t) [clarification, 17 Oct 2026 (D4 review)]), and refuses at intake with a public rej stale_quote or bad_quote, nothing held. In plain words: if the quote runs out before the payment is booked, the payment does not count and nothing is held; the app shows a new price and the payer signs again;
    • the receiver's circle books xin only if the quote is its own, to_amount = floor(amount × r_to / r_from) exactly, and the payer's circle booked xout (its at) no later than the quote's expires; else a public rej with bad_quote or stale_quote. A circle honours its own valid quote; there is no other tolerance;
    • back in the payer's circle, xdone is booked only if B's xin embeds the same note id and books exactly to_amount; anything else counts as a refusal (xundo).

    Different parameters in A and B [Decided 23 Oct 2026, E-1: each circle sets its own values; how they meet: Proposal]. Each circle applies its own values to what it books, and a mismatch can only end in a refusal and a return to the payer, so nothing is lost and both sums stay 0:

    • note_ttl_s: A judges the note at the xout by its own value, B at the xin by its own. If B's value is smaller, B refuses the note (rej with src, bad_template); A books xundo (refused) and the payer gets the held amount back. The app signs with the smaller of the two values.
    • quote_ttl_s: the quote belongs to the receiving (selling) circle B, and both circles judge it by B's own value: B by its parameters in force, A by the value it reads in B's ledger (as it reads B's node and rate source). If A read an older value, either A refuses (nothing moves), or B refuses at the xin (rej with src) and A returns the hold (xundo, refused).
    • xcheck_s: only A uses it, for its own holds (recorded at the xout as the hold's check at). A short wait can only find the evidence incomplete (B's seals do not yet pass the note's expires): nothing is booked and the check repeats; it never returns early.
  5. Relays do not refuse a second block at a height (a stateful "first block wins" rule could lock the honest chain out on a relay that saw a bad branch first); readers detect forks from the public evidence.

4.6 Crash discipline (every mode)#

  • Sign-guard for every witness, the node included: fsync {circle, key, last_h, last_digest} before releasing a signature; never sign a different digest at or below last_h.
  • Restart: read every listed relay, every archive and (in quorum mode) the other witnesses' write-ahead logs; adopt the highest valid chain seen anywhere; republish it until it is final; continue at tip + 1. Never sequence after reading only some relays (relays can lose an acknowledged event).
  • Guard lost: the key does not sign again. A new key epoch: a roles entry (node swap, decided by k of m Heart members and committed by the quorum; in single-witness mode by the Heart's acts alone, a known bootstrap weakness) names the new key and last_h = the highest height found anywhere.
  • Orphans versus forks: a block that never became final may be superseded at its height only by a block of a new key epoch whose roles entry names a last_h below it; any copy of the old block found anywhere must otherwise be adopted. Pipelined successors of an orphan are void by rule, not fraud. Fraud is only: two final blocks at one height, or one key signing two digests at one height.
  • Node crash after the witness round, before any relay has the block (quorum mode): witness locks are per (circle, node key, height). A committed proposer_swap naming last_h releases the old key's locks above it; if any copy of the old block exists, it is adopted instead.

4.7 Throughput and the size of one circle (Q13)#

  • Every relay of a circle holds all of it, so one circle's peak must fit one relay.
  • Blocks keep the event rate low: a 1M-member circle at 10 payments per member a day peaks at ~940 entries/s (5× peak, cross legs counted) but only ~7.5 blocks/s [E].
  • Binding limits: the node (today's v2 books 19–80 payments/s, an estimated 100–200 after known fixes [R]; Schnorr checks ~722/s per JS core, ~11,000/s native [R]) and serial blocks (one witness round + third OK per height → 2–9 blocks/s [E]). Pipelining: witnesses may sign h+1 once h has its quorum and is on ≥ 1 relay; publication and finality stay in height order.
  • Provisional cap: 100,000 members per circle at 10 payments a day (500,000 at 2 a day), raised only from measured numbers; a bigger community splits into circles.

4.8 Intake abuse and censorship#

  • Per-author rate limits at the intake and on the circle relays; refusals are booked publicly only up to a per-author daily limit (rej_per_author_per_day, a circle parameter, 20 by default [E-1]), and refusals of keys that are neither members nor applicants are answered, never booked [Decided 17 Oct 2026, C3].
  • The node returns a signed receipt (its signature over the note id) for every note it accepts into the queue. A receipted note that is neither booked nor refused within 60 s is public evidence (43924 ignored).
  • A member whose note gets no receipt within 10 s may publish it standalone to ≥ 3 circle relays (evidence, rate-limited). Witnesses forward such notes to the node and require a receipt. Evidence never halts the circle by itself; a node that keeps refusing receipts for notes forwarded by ≥ q witnesses is replaced (phase 1: proposer_swap; phase 2: view change).

5. Read path#

5.1 The reader contract (apps, witnesses, gateways, verifiers)#

  1. Discover from the circle link/QR (circle id, genesis digest, at least two relay hints) (Q10; the circle id [Decided 17 Oct 2026, C5]); read the root relays only at first install, and only those in the newest 38888 (relay tags only; never the retired alias host, see docs/releji-svetovna-mreza.md) [Decided 14 Sep 2026].
  2. Read the witness set and the circle key in office from the ledger (genesis + roles entries), and the circle parameters from the ledger's state (g3|param:<name>), not from the newest 30910; cache ≤ 24 h; refresh on any refusal. Pin authors to that set for blocks, seals and chunks (writes are open on today's relays [C]).
  3. Ask 2 relays in parallel; "not found" needs EOSE from ≥ 2; a relay that did not answer never means "nothing", and silence is never balance 0 (a silent [] once wiped a wallet list in 26 ms [R]). Always show the real "answered N of M".
  4. Raw WebSocket readers with timeouts above the reader's own budget; never the nostr-tools pool for ledger reads (it drops queued reads after a 4.4 s fake EOSE [R]).
  5. Fetch by height (#h, ≤ 500 values per filter, ≤ 200 filters per REQ; the 500 cap is per filter [M]); page by created_at only where no number exists, with until = oldest seen inclusive and de-duplication by id (until-1 lost 227 of 1,753 events [R]).
  6. Verify every event signature and every block's quorum before use; verify chunks against their seal.

5.2 Queries#

NeedQuery (on 2 relays)Checks
My balance nowone REQ, two filters: {"kinds":[43911],"authors":S,"#p":[me],"limit":1} and {"kinds":[43911],"authors":S,"#c":[<circle id>],"limit":1} (the tip)quorum, my line vs leaf, aseq continuity
Freshness at the tipif the tip is newer than my block: a sparse-Merkle proof of my line at the tip (from any witness API or gateway, ~1–2 KB), checked against the tip's quorum-signed state rootthe only full answer to withheld tips
My historywalk last_h back from my newest line, fetching heights in batches by #haseq runs 1…N with no gap
Is my note booked?#h from the POST answer, or {"kinds":[43911],"authors":S,"#p":[me],"since":…}embedded note id
A range of the circle#h values in batches of 500every height present, every prev links
Yesterday's state43917 by #m, then 43918 by #ichunk count, chunks root, state root, sum = 0
Any other accountas "my balance", with that account's HEXsame checks: everything is public [Consequence]
The circle in the root directory30915 by #d = [circle id] (where the root relay carries the head: open, §9.2), then 30910 by #d = [circle id] (both from root or circle relays)the head's seal tag recomputes and its qs carry the quorum; pick the 30910 whose author is the circle_key the head names; then author = the circle key that the ledger's mirror at mirror_of names (at the height of a key change already the new key), tags without g = that mirror, g = the pinned genesis; the valid record with the highest mirror_of
A reference43921 by #p = [the key] and #c = [the last circle id], from that circle's relays (or the new circle's, which republishes it)the node's signature; the named block carries the key's reference entry with the same wave, under a quorum of that circle's witnesses in office at its height (§3.11)
Where a key comes fromthe newest 30916 of the key (root relays; the newest counts)the circle it names; a key with none was never a member (§3.11)

Cost: one REQ to each of 2 relays, ~5–10 KB in small circles; 60–214 ms warm, 0.5–0.9 s including opening the socket [M]; ~4 signature checks (~5–10 ms on a phone).

5.3 Completeness, as named numbers#

QuestionProofA gap looks like
Every block?heights 1…H, each prev = the digest of h−1a missing height, a broken prev
Is H the newest?tip from ≥ 2 relays; tip state root + my proofrelays disagree → third relay or live feed
Every entry of a day?the seal's range, pay root and count; COUNT on the day's #m is exact for small sets [M]fewer entries, another root
A member's whole history?aseq 1…n, last_h pointersa missing aseq
The whole snapshot?n chunks, chunks root, state roota missing index, a root mismatch
Is a balance right?previous line + entries + rules = this line; quorum; sum 0a 43924 fail with the block as evidence

The 500-per-filter cap, partial lists and silent relays can delay a reader but never fool it: every gap is a named number.

5.4 Phones at scale (Q16)#

At small scale phones hold one live subscription on 2 circle relays while the app is open. At billions of users (0.2–1 billion concurrent sockets [E]; carrier-grade NAT against the 100-connections-per-address limit [C]) phones read through verified read gateways with push: anyone may run one; every byte is a signed event or a proof against a quorum-signed root, so a gateway can hide but never forge, and the app compares two sources. Circle relays size per-address limits for carrier-grade NAT and limit per author instead. Phones never hold sockets to root relays after first install.

6. Daily checkpoint (seal + public snapshot) [Decided 16 Oct 2026: one seal a day; Consequence: unsalted, always counts]#

  1. After the morning blocks (§7) the node builds the snapshot: every line of the decision state (§3.8, including every project and the reserve), sorted by key, cut into ≤ 100 KB chunks (43918), and the 43917 seal committing to the day's range, entries, chunks root, state root, counts, gravity totals, sum = 0, world numbers, the reserve balance, the rate quotes the day's entries referenced, the witness set and the circle key of the office after h_to [Proposal] and the parameter height (params). Witnesses recompute everything before signing the seal. The seal's range ends at the last block that carries the day's morning header (the morning blocks and payment blocks with visits, §7.4), or, on a day without such blocks, at the last block booked before the boundary; payments booked during the morning up to that block belong to it, later ones to the next day's seal [Decided 17 Oct 2026, C2: payments never pause for the morning]. The snapshot is the state at h_to.
  2. Chunks [E]: 1,000 members → 3 chunks (0.2 MB); 100,000 → ~220 chunks (20 MB); 1,000,000 → ~2,200 chunks (~200 MB). Fetched by #i values, ≤ 500 per filter.
  3. The seal is mirrored to root as 30915, spread over the day (§3.6).
  4. Restore from a seal (what it reads, and why seal + tail alone is not enough: §8.1 step 5) equals full replay, checked by the canonical state hash; this is part of the daily drill (§8.3).
  5. Independent attestations: every witness publishes a daily 43924 ok with the state root it computed (and the root over its votes, Q23); any verifier may add its own. A restorer that finds ≥ 2 independent ok statements (not all from the node) may start from that seal without replaying from genesis.
  6. One seal per day, after the 04:00 morning, every day, also without payments; a day without a seal is a public fact.

7. Gravity and other time-driven work#

7.1 Choice#

Gravity is a deterministic integer rule over public data and its per-account result is published in morning blocks (grav entries plus lines), so phones never recompute it and auditors can check it. One event per wallet per day is avoided (it would be 10 billion events a day at the target).

7.2 Determinism#

TodayRule
The room for deduction uses the balance at run timecut-off = the last seq booked before the morning opened (on time: the last seq with at < boundary; in catch-up: §7.4) [clarification, 17 Oct 2026 (D4 review)]; every input of an account's gravity (balance, wave, cap, carry, debt) is read at the cut-off, room = max(0, balance at the cut-off); visit before touch (§7.4) keeps the account untouched until its grav entry, so this is also its balance just before the entry; after an outage the missed mornings are booked in date order: a later missed morning reads its cut-off state with the grav results of every earlier missed morning applied, as if each had been booked on time, and an earlier morning's grav entry never counts as touching an account for a later morning [clarification, 17 Oct 2026]
Parameters read at run timethe parameter revision in force at the cut-off (params_h in the morning header)
Floating-point powers, a 30.4375-day month, double averagesparameters published as whole ppm (band_ppm_day, excess_ppm_day, transition_days, rest_after_days); BigInt averages at second resolution; the first window of a circle runs from the boundary before block 1 (an account's balance is 0 before its first entry), every later window from the previous boundary [clarification, 17 Oct 2026 (D4 review)]; one rounding rule in the spec
Server clock and time zoneat assigned by the node, bounded ±5 s by every witness; boundary instant published per day with the pinned tzdata (a verifier identifies a release by its IANA version string (the release's version file, the first line of its tzdata.zi, a +VERSION file, or the tz version a runtime reports, such as ICU's) and can obtain the pinned release from the IANA archive, which keeps every release (informative: data.iana.org/time-zones/releases/); it may compute with another release it holds only after checking, with the pinned release, that the circle's zone has identical UTC offsets and transitions over the dates it checks (from the boundary before the first date to the day after the last): identical transitions give identical boundaries and local dates; without the pinned release, or when the transitions differ, every result that depends on a boundary or a local date is unverifiable, never a guess [Decided 17 Oct 2026 (evening), 2A: the pinned version; clarification, 17 Oct 2026 (D4 review, round 3): how a verifier holds it]; the node makes the same check with its runtime's time-zone data before it signs a morning block or a seal, and otherwise waits [proposal (D3 review, 19 Oct 2026)]); tz, morning hour and tzdata are fixed in the found act for 0.3.0 [Decided 17 Oct 2026, C7] (no act or parameter changes them; a later definitions version may say how a circle follows new clock rules); a morning hour inside a clock change: a local hour that occurs twice counts at its first occurrence, a skipped local hour at the first instant after the gap
Database row order ≠ time orderone order: seq
Three separate enginesone written spec with test vectors; a second, independent implementation in the verifier
Who is visitedevery account line whose status at the cut-off is member, frozen, excluded or left (not closed, not a system account or project wallet) [Consequence of E-3: before, left lines were not visited, so leaving and coming back escaped gravity]; a grav entry is booked only if its deduct is above 0 or it changes carry or debt; 0.3.0 has no rules gate: rules_v never gates gravity (today's app has its gate off) [clarification, 17 Oct 2026 (D4 review)]
debt changes between morningssettled is an entry consequence, in order
Catch-up after an outageeach missed morning is booked as its own morning blocks, in date order, with its own boundary and cut-off. With two or more missed mornings the reading is chained: a later missed morning reads its cut-off state with the grav results of every earlier missed morning applied, exactly as if each had been booked on time (the result today's engine gives) [clarification, 17 Oct 2026], their drains included, and the whole catch-up comes before any other entry (§7.4) [clarification, 17 Oct 2026 (D4 review)]

Fairness at the boundary: the morning is cut by at, not by when the node decides to run it; the node can move a payment's at by at most the ±5 s the witnesses allow, and in single-witness mode that discretion is visible in public and flagged by the verifier.

7.3 The integer rule (today's morning computation, float inputs replaced)#

S       = Σ balance_i × seconds_i                    BigInt over the window of W_s seconds
                                                     (86,400; in the Ljubljana time zone 90,000 for the window
                                                     that contains 25 Oct 2026 and 82,800 for 28 Mar 2027)
avg     = floor((2·S + W_s) / (2·W_s))               half rounds up, as today's rounding of positive values; avg ≤ 0 → rule 0
rule_µ  = min(avg, wave)·band + max(0, avg − wave)·excess   (band and excess: the quiet-day switch below)
total_µ = rule_µ + carry_µ;  cents = total_µ div 10^6;  carry_µ' = total_µ mod 10^6
wanted  = cents + debt;  deduct = min(wanted, room);  debt' = min(wanted − deduct, wave)

The quiet-day switch, exactly [clarification, 17 Oct 2026 (D4 review): today's switch, with the transition per account (3A)]: with D the morning's local date and every day a local calendar date, quiet = 0 if the line has neither last_gift_day nor first_receipt_day, else max(0, D − the later of the two that are set); in_transition = first_receipt_day is set and D − first_receipt_day < transition_days; resting = rest_after_days > 0 and quiet ≥ rest_after_days; excess = band_ppm_day if in_transition, else excess_ppm_day; band = excess if resting, else band_ppm_day; rule_µ (rule_micro) = 0 if avg ≤ 0, else min(avg, wave) × band + max(0, avg − wave) × excess. All of it is read at the cut-off (visit before touch leaves the line untouched until the grav entry).

Whole seconds, and where a deduct counts [clarification, 17 Oct 2026]. at, every boundary and every window are whole unix seconds, and seconds_i is the whole number of seconds balance_i lasted inside the window (milliseconds exist only in today's app). In the window that ends at the next morning's boundary, a grav entry of morning D changes the balance from D's boundary (the window's start), not from the entry's at: visit before touch (§7.4) leaves the account untouched between the cut-off and its grav entry, so from the boundary on its balance is the cut-off balance minus the deduct, whatever the entry's at. Counting from at would make the next morning's S depend on the HEX order of the remaining entries and on when a visit happened. The same holds after an outage: the grav entries of a missed morning count from that morning's boundary, and the next missed morning reads its cut-off state with them applied (§7.2).

Rounding is checked against today's engine in shadow for 14 clean mornings before the switch.

7.4 Order of the morning and other duties#

  1. At the boundary the open block closes: no block spans a boundary. Payments keep flowing after it in their own blocks, with at ≥ boundary, interleaved with the morning blocks [Decided 17 Oct 2026, C2: payments never pause for the morning] (after an outage, once only the current morning is pending: catch-up, below). Visit before touch [the same decision, C2]: each account's gravity for day D is computed purely from the cut-off state (its balance, wave, cap, carry and debt at the cut-off, §7.2): deduct = min(wanted, max(0, balance)), debt' = min(wanted − deduct, wave) (§7.3). After the boundary (in catch-up: after the morning opened, below), before any entry touches an account (a move from or to it; only money entries touch: pay, give, xout, xin, xundo, grav, project_pay to a member, an entry that returns money; an act entry, which has no party and no move, and a rule entry that only names a party (member_join, a member_leave that moves nothing) touch none [clarification, 17 Oct 2026 (D1 review)]) whose grav entry for D is still pending, that grav entry is booked first, in the same block, right before the touching entry (several in HEX order). For a note, the visits of the accounts it would touch are booked before the note is judged, and it is judged on the state after them; a refused note leaves its visits booked (they are due anyway), and its rej follows them; a refusal that is only answered, never booked (a key that is neither a member nor an applicant [C3]; above rej_per_author_per_day), books nothing, its visits neither [proposal (D3 review, 19 Oct 2026)]. The account is therefore untouched between the cut-off and its grav entry, so the order in which the node books payments never changes anyone's gravity, and the order loses no debt: a debt the morning records (at most the wave, as the rule caps it) is settled by the next receipt. A block that books a grav entry carries the morning header. After an outage the missed mornings are booked in date order: a later missed morning reads its cut-off state with the grav results of every earlier missed morning applied, as if each had been booked on time, and an earlier morning's grav entry never counts as touching an account for a later morning [clarification, 17 Oct 2026]. Catch-up after an outage [clarification, 17 Oct 2026 (D4 review)]: the node books the missed mornings completely, in date order, in morning blocks, before any other entry. Mornings open at block starts, one at a time, in date order: a morning opens when its boundary is at or before the block's first at and every earlier morning is complete (on time: at the first block start at or after its boundary; a restorer from the seal of day D starts with morning D complete, since the seal is made right after it [clarification, 19 Oct 2026 (D3 review)]); its gravity is computed from the state at that moment, and its header's cut-off seq is the last seq booked before it opened (on time: the last seq with at < boundary; in catch-up: the last entry of the earlier morning), so a later missed morning reads the grav results of every earlier one and their drains, as if each had been booked on time. While two or more mornings are pending (one is open and a later boundary has passed too), a block holds only the open morning's grav entries (HEX order; visits only inside its drains) with their end-of-entry work (§3.5): no payment, act, roles entry, refusal or duty. A block carries one morning header, so the block that completes a morning ends there. [completed 24 Oct 2026, plan step E4x] A block that continues the carried work of a cut catch-up block (the block split, §3.5) holds that work first and opens no morning (when it books no grav entry it carries no header); a params_effective due during the catch-up waits until every missed morning whose boundary is at or before its notice end has opened, so it never applies to a morning before its notice end (§3.1 rule 11). Visit before touch for morning D covers the entries from D's opening on, so an earlier morning's catch-up entries are no touches for D, and it applies only to the newest, current morning. Payments, acts and duties resume as soon as only one morning is pending: this is C2, payments never wait for the current morning. In the next window's average every entry, including a catch-up's drain, counts by its at; only grav deducts count from their morning's boundary (§7.3). A new morning cannot open (no block carries morning D+1's header) while any grav entry of morning D is still pending; witnesses refuse such a block (grav_pending) [clarification, 17 Oct 2026 (D1 review)].
  2. Morning blocks book the remaining grav entries, in HEX order, of the accounts not yet visited (an account a drain's entry already needed is skipped) [clarification, 19 Oct 2026 (D3 review)]: header morning (boundary, cut-off, parameter revision, the tzdata pinned at founding, §3.5); grav entries and lines only for accounts where something changes, ≤ 100 KB each, counting the block's own entries only [clarification, 19 Oct 2026 (D3 review)] (about 240 accounts, about 140 while a project receives), with p tags of exactly the accounts they touch. Morning blocks hold only grav and rule entries (due rules and the drain() steps), booked at or after the boundary; a payment block holds grav entries only as visits (right before the entry that touches the account, or before the rej of a refused note [proposal (D3 review, 19 Oct 2026)]); a morning with nothing to book books no morning block.
  3. Witnesses recompute every grav line from the cut-off state; every grav deduct moves to the reserve, and drain() runs at the end of every entry, as at any other time (§3.9) [clarification, 17 Oct 2026 (D1 review)]: after each grav entry of a morning block, and at the end of the entry that a visit precedes. drain() fills projects oldest first and is defined per entry; a project that fills during the morning pays a recipient whose own grav entry, if still pending, is booked first (visit before touch), so it never sees the project payment. A mismatch means no quorum, so no morning: an alarm, never a guess (in single-witness mode the verifier and the drill catch it).
  4. The due rule entries open the block, earliest due time first (project_lapse (open_lapse_s, 30 days by default, before opening: proposal; receive_lapse_s, 90 days by default, after opening [8e]); project_return [8e]; the end of a vote (vote_pass or vote_fall) [E-5]; request expiry; the 7-day cross-circle checks (xcheck_s, §4.5) [8j], once their evidence is read; each followed by its end-of-entry work, drain() with its project_full and project_pay [8a]); they never wait for the morning blocks (the order inside a block: below) [clarification, 17 Oct 2026 (D4 review)]. A project that passed its vote is no duty when it opens: it opens in the end-of-entry work of the entry after which its consent is given and, for a step raise, it fits under built (§3.9). After the morning come the seal and chunks; the seal's range ends at the last block that carries the day's morning header.

Every time-driven change is such a duty: a block whose first at reaches a due time must start with all due entries in canonical order (when a duty is booked: §3.5), and witnesses refuse a block that omits one. The order inside a block [clarification, 17 Oct 2026 (D4 review), except where marked]: while two or more mornings are pending (catch-up, item 1) a block holds only the open morning's grav entries, with their end-of-entry work, nothing else; after a block the size rule closed, the carried work first and only it (the block split, §3.5: no morning opens and no params_effective in that block; then the duties still due) [completed 24 Oct 2026, plan step E4x]; otherwise first params_effective when a param_propose's notice end is due by the block's first at (after the morning header) [Proposal, E-1] and it does not wait (it waits while a missed morning at or before its notice end has not opened, or a duty due before its notice end is due: §3.1 rule 11) [completed 24 Oct 2026, plan step E4x], then the rule entries of item 4, every duty due by the block's first at, each followed by its end-of-entry work (§3.5), then the block's other entries (payments and acts with their visits, roles entries, refusals) or the open morning's remaining grav entries. Duties that fall due in the same second go in this order: the return after a closing notice (close_return), the lapse of a receiving project (receive_lapse), the lapse of a project that never opened (open_lapse), the end of a vote (vote_end) [Proposal, E-5], request_expire, a resignation; within a kind by publication (projects and motions: their published seq, which their o3 line holds) or by id (requests by request id) [clarification, 17 Oct 2026 (D1 review; D4 review and its round 3)], since the order changes who is paid. A due resignation is committed in a block of its own: its leading params_effective (when one is due), then the resignation's roles entry, nothing else; it comes before the morning block of an open morning (a morning block holds no roles entry), and the other duties due by then open the next block [proposal (D3 review, 19 Oct 2026)]. At the block start the void resignations are dropped first (§3.4); the earliest of the others, by notice end and then act id, takes the block [clarification, 19 Oct 2026 (D3 review)]. A due duty whose project already ended earlier in the same block (a receive lapse and a close return both overdue after an outage) is dropped [clarification, 17 Oct 2026 (D4 review, round 3)]. Due entries go earliest due time first; the kinds that item 4 lists are not an order among them, and project duties due in the same second follow the order just given [clarification, 17 Oct 2026]. A note's, quote's and act's TTL and the daily refusal limit are judged by the parameters in force at the booking, and the number of Heart votes by those in force at the vote end [Proposal, E-1]; a running deadline (a vote, a lapse, a closing notice, the 8j wait, an exclusion, an invitation, a change's notice) keeps the due time recorded in its open item when it started, never retroactive [Consequence of E-1] (§3.1 rule 11). The morning's grav entries are the exception: they follow item 1 (visit before touch) and item 2 (the rest in morning blocks), so payments never wait for the current morning (after an outage they wait only while the missed mornings are booked, item 1). Today's separate timers for support, gravity, seals and clean-up stop being independent.

Observation for volume: below the cap every receipt grows the wave and is counter-booked to the reserve and on to the receiving project [A8], so balances do not rise and gravity books almost nothing today.

8. Restore#

8.1 A circle whose server is gone, step by step#

Inputs: the circle link/QR (circle id, genesis digest, relay hints) or any member's 30916; plus, only to resume booking, the Heart's acts for a new node (live circle: the founder and three other Heart members [Decided 16 Oct 2026, A4 and 4a]; three of four must sign: proposal).

  1. Find the circle. From the link, or from root (newest 38888 → the circle's 30915 head by #d = the circle id (where the root relay carries the head: open, §9.2), then its 30910 by #d, signed by the circle key the head names). Switch to the circle's relays named there; trust nothing whose block 1 does not embed the found act whose id is the circle id, and nothing that does not chain to the genesis digest.
  2. Governance chain. Read genesis and every roles entry (by height; they are few); build the witness windows and the circle key in office by height. [proposal (D3 review, 19 Oct 2026)] For a restore from a seal the chain is mandatory: block 1 (its digest is the pinned genesis, its mirror the one its signed found act gives) and every block with a roles entry up to the height g3|mirror_h names, in height order, each signed by a quorum of the office the mirror before it puts in power; no block carries a pointer back to the previous roles block (none is added for it), so the restorer reads them from the circle's relays. The circle parameters and every change of them are in the circle's blocks (the found act and each param_propose that a params_effective names) and in the snapshot's g3|param:<name> lines, so a restore needs only the circle's relays [Consequence of E-1].
  3. Newest checkpoint. Newest 43917 from ≥ 2 relays with a valid quorum for its window; follow prev a few days; prefer a seal with ≥ 2 independent 43924 ok statements. Two valid seals for one day = fork alarm: stop and report.
  4. Snapshot. All chunks by #i; verify chunks root and state root; load every line.
  5. The day's blocks after the boundary, the named blocks and the tail [what a restore from the seal of day D reads, and why: clarification, 17 Oct 2026 (D4 review); the complete list: clarification, 17 Oct 2026 (D4 review, round 3); the lines it rests on (§3.8): proposal (D4 review, round 3, 17 Oct 2026)]. The decision state holds everything the next booking depends on, so a restorer from the seal of day D judges the tail exactly as a replay from block 1. For that it reads, besides the seal and its snapshot chunks (steps 3 and 4) and the governance chain of step 2 (mandatory: it shows that the seal's quorum is the office in power, from the pinned genesis on [proposal (D3 review, 19 Oct 2026)]), exactly: every block whose first at is at or after boundary(D), up to h_to (the window of the next morning's averages, and the refusals of the current morning day; none when the range ends before the boundary; after an outage also the catch-up blocks of earlier mornings in earlier seals' ranges, and each grav deduct counts from its own morning's boundary [clarification, 19 Oct 2026 (D3 review)]); the block right before the first of them, or the seal's head block when there is none, whose last at must be before boundary(D), so no block after the boundary is left out [proposal (D3 review, 19 Oct 2026)]; the block at the height the state's g3|mirror_h names (its genesis or roles entry carries the mirror in office, in tag order); the blocks at the booked heights of the open o3|change lines (what each change names: its relays, keys, witness, k, parameters (a param_propose), or the key it excludes, readmits or closes); every block after h_to (the tail, from h_to + 1 to the tip). The 43920 records are no longer read [E-1]. Nothing else. Blocks by #h, from every listed relay in parallel (union, de-duplicated); verify chain, quorum and every embedded signature; replay every tail entry with the pure state machine and compare every line and root. Why: the next morning's averages need each account's balance over [boundary(D), boundary(D+1)); its balance at boundary(D) is the snapshot balance less the moves of those blocks of the range other than grav deducts (which count from the boundary), and then every move in order. Seal + tail alone cannot give the next gravity. The restore proof of the definitions: §12.
  6. Gaps. A missing height: other circle relays, archives, partners' relays, witnesses' logs. If no copy exists anywhere: stop, report the height, never guess. A cut head [completed 24 Oct 2026, plan step E4x]: when the seal's h_to block carries more (the block split, §3.5), the state at h_to carries that work: the restorer reads it from that block's more tag, and the tail's first block continues it at the same at.
  7. Caches. Rebuild the SQLite projection from the replayed state.
  8. Resume. A new node key via proposer_swap (k Heart members + current quorum, or recovery if fewer than q witnesses survive (the larger of k and 3 Heart members and no Heart "against" [E-7, E-10]); recovery is void if any quorum-valid block above its named height appears during its notice); the new node starts at tip + 1. A lost or stolen circle key does not stop a restore: the Heart replaces it by circle_key_change (§3.4) [Decided 17 Oct 2026, C5].
  9. Compare. The canonical state hash of the restored state equals the seal's state root replayed forward; if an old database exists anywhere, its sums must match.

8.2 Costs (checkpoint + one day of tail, the worst moment) [E]#

Basis: reading 3 relays in parallel at the measured single-connection speeds (356–2,416 events/s, 0.55–3.7 MB/s per relay [M]), the slower of the event and byte rates; signature checks 11,000/s per native core, 722/s per JS core [R], 8 cores.

CircleSnapshotTail of one dayRead timeAll signatures (notes + quorum), native / JSQuorum only, JS
1,000 members, 2/day0.2 MB~3,100 blocks, 7 MB1–4 s15,000: 0.2 s / 3 s2 s
1,000 members, 10/day0.2 MB~12,700 blocks, 30 MB3–18 s64,000: 0.7 s / 11 s9 s
100,000 members, 10/day20 MB~56,000 blocks, 1.2 GB2–12 min1.5 M: 17 s / 4.4 min39 s
1,000,000 members, 10/day200 MB~133,000 blocks, 11.4 GB17 min – 1.9 h13.6 M: 2.6 min / 39 min1.5 min
  • Restore cost is bounded by the seal interval, not by the circle's age; hence the provisional cap of 100,000 members (§4.7, Q13).
  • Full replay from genesis (auditors, once, then they follow live): one circle-year of 1,000 members at 2 payments a day is ~1.1 M events, 2.6 GB; at 10 a day ~4.6 M events, 11 GB; linear in years and parallel by day (snapshot(d−1) + blocks(d) = snapshot(d)).
  • Several connections per relay at once and MB/s for large restores are unmeasured.

8.3 Restorable as a tested fact: the daily restore drill [Consequence]#

Every day, after the seal, the node (and any independent verifier) restores the circle from the relays alone into a scratch database, compares the canonical state hash with the seal and publishes the result as a 43924 statement (about = restore). A failed drill is an alarm on the admin page and in every member's app ("restore check failed on <day>"), not only for an administrator (a shared sync tool once ran "0 synced, 2000 errors" for days unnoticed [R]).

8.4 A new phone#

Scan the circle QR (or open the member's 30916), read the witness set from the circle relays, then §5.2: a balance in about a second. Nothing to back up on the phone except the BSA WIF.

9. Relays for the ledger#

9.1 Tiers#

TierRun byCarriesRules
Root (the relays in KIND 38888; four today) [Decided 14 Sep 2026; A2]the Lana relay owner(s)38888, 42893 definitions, every circle's found act (its id is the circle id) [Proposal] and the first found act of every founder key (one circle per founder key, ever [E-8]; the mechanism: Proposal), newest 30910 of every circle (by circle id), 30915 heads (spread over 24 h), KIND 0; while borrowed [Decided 16 Oct 2026; A2, A9: limited space]: small circles' ledgers under a quota (size: proposal, 1 GB or one year per circle, whichever comes first, Q18); optional 30917 offers. No rate records: quotes live on circle relays [A7]no payments at scale; no member homes beyond the borrowed phase (Q16), except that a new circle reads where a key comes from in its newest 30916 (E-8, E-9), so the root relays (or, at scale, the index relays) keep the newest 30916 of every key [Proposal]; phones only at first install
Circle relays [Decided 16 Oct 2026, A2]the circle's box relay + witnesses' relays + partners, cooperatives, hosting providers (+ Lana relays while borrowed)the circle's whole ledger: blocks, seals, chunks, acts, homes, the rate quotes it issued or relied on, and partner blocks; the references (43921) it issued, and those its member_join entries named [Proposal]≥ 4 relays, ≥ 3 operators [A2] (bootstrap ≥ 2, Q14); write policy §9.2
Archive relaysanyonefull histories, compressedno 10-year lower limit, no expiry, KIND 5 refused
Index relays (Q16)anyone30916 member homes sharded by key prefix; name searchat scale only
Gatewaysanyoneverified HTTP caches with pushcan hide, never forge

"Root relays only from KIND 38888" stays for root relays and Lana apps; circle relays are named by each circle in its own ledger [Decided 16 Oct 2026, A2: the project owner's yes to this new reading of the 14 Sep rule]. 38888 is the directory, but no circle's validity depends on it (Q10).

9.2 Write policy on every relay that stores ledger kinds#

The box relay ships with it; the Lana relays need their owner's change (Q18).

  • each served circle is configured by its id (the circle id) and circle_key (the key in office; after a circle_key_change the old key moves to retired); ledger kinds are recognised by their c tag; the found act is accepted when its id is a served circle id [the circle id: Decided 17 Oct 2026, C5; the configuration: Proposal]; a retired entry carries its role, {"key": <HEX>, "until": <unix>, "role": "signer" | "node" | "circle_key"}, and a retired key counts only in its own role, for events up to its until (a retired circle key can sign only an old 30910, never a block, seal, chunk, head or quote) [Proposal];
  • 43911, 43917, 43918 accepted only from keys in the circle's current witness set, read from its ledger;
  • 43916 and standalone 43910 only from members and applicants of that circle, rate-limited per author;
  • 43919 only from the circle's node of the time, as named by its ledger;
  • 43924 from the circle's witnesses, and from any other author rate-limited per author (a verifier's or auditor's challenge must always be publishable);
  • 43921 only from the circle's node of the time, as named by its ledger, and a partner's 43921 that this circle's member_join named (as for a partner's 43919) [Proposal]; 43920 is retired and no longer a ledger kind [E-1];
  • mode root (the Lana relays; a request in the letter to their owner, plan phase G): keep the first-seen g and founder per circle id, check the founder's signature over the circle id and the genesis digest, and accept a v3 30910 only from the circle_key it names; with the circle id this is only extra safety [the first-seen rule in the letter: Decided 17 Oct 2026, C6; the checks: Proposal]. How it keeps them [Proposal]: a root relay keeps every circle's found act (a 43916 whose first tag is ["c", ""] and that has no other c tag, from any author: its id is the circle id, so nobody can make a false one), and pins a circle id's genesis digest and founder only when it holds that found act and the record's founder is its author (or, for a circle configured on the relay, when its configured circle key signed the record); otherwise the relay stores the record unpinned (readers check it anyway), so nobody can claim a circle id first on a root relay; the plugin remembers at most seen_ids_max found acts, and beyond that a newer circle's records are kept unpinned, never falsely pinned; a pin is written only after every plugin of the relay (the chain) accepted the record; pins are not in LMDB and are not rebuilt from lookback, so a relay seeded from another relay's LMDB copy also copies the write policy's pins_file;
  • [Open] the policy must also admit 43916 from keys the log names as witness or guardian who are not members (docs/upravljanje-kroga.md);
  • [Open] whether a root relay accepts the 30915 head of a circle it is not configured for (checked against the witnesses of its pinned record); the prepared write policy accepts heads only of configured circles;
  • refuse KIND 5 and KIND 62 that target ledger kinds or are authored by any ledger key; refuse expiration and - on BSA kinds;
  • keep BSA kinds out of every purge and hard-delete filter;
  • no 10-year lower limit on circle and archive relays (rejectEventsOlderThanSeconds = 4000000000 (larger than the current unix time; measured 16 Oct 2026 on strfry 1.1.0: the value 0 refuses every event, even one made now));
  • per-address limits sized for carrier-grade NAT, per-author limits instead;
  • tested before the first publish, including whether strfry refuses to re-insert an id after a KIND 5 (unverified).

9.3 Sync and the replication audit#

  • The node publishes to every listed relay itself (§4.1 step 7). A replication audit runs daily and after outages (NIP-77 negentropy scoped by #c and day, cheap on small scoped sets [M]), republishes what is missing and publishes "copies N of M", which the app shows.
  • Never lana-relay-sync for any BSA kind until its four loss bugs are fixed (per-kind since loss above 500 events per 10 min, until-1, "complete" after a failed connection, a full-history diff every cycle); never the strfry router (a live stream with a fixed 45-kind list that has no BSA kind [C]).
  • Replica drift is real: up to 18 % within one kind today [M]. A reader always takes the union of signed events.

9.4 Switch-on and new relays [Consequence]#

  • Outbox held = "waiting for the project owner's yes on the definitions" (P7: one yes per kind). At switch-on the whole backlog goes out from genesis, oldest first, paged at a rate the relays accept.
  • A new or empty circle relay is back-filled with the full history (every block, seal, chunk and act), checked by height numbers and seal roots, before it is listed by a relay_change entry.
  • A new root relay gets the directory only (newest 30910, 30915 heads, every circle's found act, homes while borrowed, and the newest home of every key for E-8 and E-9 [Proposal]); seeded from another root relay's LMDB copy, it also gets that relay's pins_file (§9.2).

9.5 Today's four Lana relays#

  • Identical strfry 1.1.0 on 2-vCPU servers; free disk 11 / 90 / 23 / 51 GB; ingest 2,245–4,513 events a day [M/C]; the smallest is about 70 % full [C].
  • As the only replication they carry the whole public ledger of about 2 circle-years of one 1,000-member circle at 2 payments a day (11 GB free against ~5 GB a year per copy), half a circle-year at 10 a day [E]; the 1 October finding (the smallest relay full at ~8,500 payments a day [R]) says the same [Decided 16 Oct 2026: the four Lana relays will not carry 100 billion; the system must scale].
  • BSA kinds are not in the router's 45-kind list [C], so the relays would not copy each other; the circle publishes to each itself.
  • Operator independence is unclear (Q14): until shown otherwise the four count as one operator for the ≥ 3-operator rule.
  • Role [Decided 16 Oct 2026, A2]: the root directory for ever, and a borrowed home for small circles with limited space, counted as copies only after the owner applies §9.2 (Q18).

10. Sizes and capacity#

10.1 Model constants [E]#

Per payment ~1.1 KB of entries (cross legs included: 1.62 entries per payment at the 10 October simulation's ~31 % cross share [R], ~45 % more bytes); block envelope ~0.85 KB + 0.205 KB per signature (3 signatures, or one FROST signature ~0.15 KB); payments per block = (entries/s while awake) × W_max + 1, at most ~120; morning lines ~0.25 KB for half the accounts; snapshot ~0.2 KB per account; disk factor 2× [M]; 16 waking hours; peak 5× per circle, 3× for the world; relay planning budget 300 events/s (1/6 of an external ~1,856/s benchmark [R], never measured on our relays).

10.2 One circle [E]#

CirclePayments/dayEntries/dayEvents/day (blocks + morning + chunks)Peak entries/s → blocks/sRaw per day, one copyDisk/year, one copyDisk/year, 3 copiesBytes per payment, all-in
1,000 × 22,0003,240~3,1000.2 → 0.27 MB5 GB15 GB3.5 KB
1,000 × 1010,00016,200~12,7000.9 → 0.730 MB22 GB66 GB3.0 KB
5,000 × 10 (W = 2 s, FROST)50,00081,000~21,0004.7 → 1.278 MB57 GB172 GB1.6 KB
100,000 × 101 M1.6 M~56,00094 → 3.21.2 GB0.9 TB2.7 TB1.2 KB
1,000,000 × 1010 M16.2 M~133,000940 → 7.511.6 GB8.5 TB25 TB1.2 KB

Small circles pay mostly for envelopes (one payment per block); that is the price of sub-second publication, and the absolute cost is tiny (a 1,000-member circle's box needs ~20–90 GB a year for 4 copies). The 5,000-member row assumes W_max = 2 s, while w_max_s is 1 s at founding (§3.5; proposal: a circle above about 10,000 members raises it to 2 s by param_propose); re-run it with the parameter chosen.

10.3 One million circles, one billion users [E]#

2 payments/day10 payments/day
Payments2 B/day (23,000/s)10 B/day (116,000/s)
Events/s average / 3× peak36,000 / 107,000146,000 / 439,000
Raw per day, one copy7 TB30 TB
Disk per year, 3 copies / 4 copies15 PB / 21 PB66 PB / 87 PB
Relay-equivalents for 4 copies at 3× peak: 300 ev/s / 1,856 ev/s1,400 / 2305,900 / 950
Root: 30910 + 30915~9 GB on disk, 12 head writes/ssame

10.4 The principle-6 target: 10 billion users, 100 billion payments a day, ≥ 3 copies [E]#

100 billion a day = 1.157 million payments a second on average.

Profile2 M circles × 5,000, W = 2 s, one FROST signature10 M circles × 1,000, W = 1 s, 3 signatures
Payments per block (average while awake)3.81.3
Bytes per payment, all-in1.6 KB3.0 KB
Events/s average / 3× world peak0.49 M / 1.48 M1.46 M / 4.39 M
Raw per day, one copy157 TB300 TB
Raw per year, one copy57 PB109 PB
Disk per year, 3 copies (4 copies)343 PB (458 PB)656 PB (875 PB)
Over 10 years if volume grows linearly to the target, 3 copies, uncompressed~1.7 EB~3.3 EB
Relay-equivalents for 4 copies at 3× peak, 300 ev/s / 1,856 ev/s19,700 / 3,20058,600 / 9,500
Circle-box model instead2 M box relays, ~57 GB a year each per copy, ~1–5 events/s at peak10 M box relays, ~22 GB a year each
Root30910 + 30915 ≈ 18 GB on disk; 23 head writes/s≈ 90 GB; 116 head writes/s (the smallest root relay's disk must grow or root gains relays)
  • Per user: ~34–66 MB a year on disk across 3 copies; at ~$15 per TB-year of disk plus servers and power (~3×) about $0.002–0.004 per user a year. Bytes are cheap; running tens of thousands of reliable relays is the cost (Q15).
  • The floor is the payments' own payload (signatures, keys, amounts, balances after): ~65 TB a day per copy even with no envelope [R]; binary encoding would halve JSON-hex but would leave Nostr.
  • Nostr has never run anything like this: the largest public relays ingest 2–6 events/s [R]; 1.16 M/s is the sum of millions of light cells, not one system. No component sees the world total.
  • KIND 0 and member homes of 10 B members on every root relay would be ~10 TB and ~15 TB per relay; the smallest root relay fits ~11 M profiles, ~7 M homes [E] (Q16).

10.5 Storage over ten years without breaking principle 2 (Q19, Q15)#

  1. Shard by circle: each circle's growth sits on its own relays and partners (a 5,000-member circle at 10 a day: ~57 GB a year per copy).
  2. Checkpoints are read compaction, not deletion.
  3. Circle boxes keep everything (it is small). Shared relay groups at scale: hot relays keep 30–90 days; older blocks move to ≥ 3 archive relays of different operators, are verified there by negentropy and against the seal roots, and only then may leave the hot relay (the only place an operator removes a ledger event, Q19).
  4. Archives compress (strfry zstd dictionaries, unverified on our build; JSON-hex compresses 2–3× [E]).
  5. No 10-year lower limit on circle and archive relays, or history older than 10 years can never be copied to a new relay [C].
  6. Who pays (Q15): each circle pays its relay operators through a project (Common Good no longer exists [A8]); partners by reciprocity; archives by the circles that use them.

10.6 Not measured, not certain#

strfry EVENT→OK latency and sustained ingest at 2 KB and 100 KB events; whether OK means fsync'd (power-cut test); the cost of a duplicate EVENT; concurrent sockets and subscriptions per relay; MB/s served for a restore; negentropy on 1–2 M scoped events; whether strfry refuses re-insertion after KIND 5; zstd ratio; witness round times on real networks; all event sizes until the 0.3.0 examples are signed. The first build step measures them on a separate strfry with the production configuration, never on the Lana relays.

11. Failure modes (ledger)#

FailureDefenceWhat still breaks
Relay silent, [], 429, timeoutEOSE from ≥ 2; named numbers expose gaps; raw readers; "answered N of M"nothing, if 2 relays answer
Partial results (500 cap, 4.4 s pool drop)reads by height ≤ 500 per filter; inclusive until + dedupe; no nostr-tools pool—
Replica driftunion of signed events; daily scoped negentropy audit; "copies N of M" public—
Operator hard-delete≥ 4 relays of ≥ 3 operators; a gap is visible at once; any holder republishes the identical signed eventan operator can always delete their own copy
KIND 5 / expiration (NIP-09 and NIP-40 on all four [M])ledger keys never sign KIND 5; §9.2 policy; tested before the first publisha relay without the policy can lose copies; archives are the backstop
A relay censors the circlereplace it by relay_change; 3 of ≥ 4 suffice—
Node censors a notereceipts; standalone evidence to ≥ 3 relays; witnesses forward; proposer_swap / view changea delay of seconds to minutes
Node or witness crashsign-guard, WAL, restart reads all relays, adopt the highest chain, lock release rules (§4.6)non-final blocks; apps resend
Up to f witnesses faultyquorum q = 2f+1 of 3f+1—
More than f witnesses downliveness lost, safety kept: reads work, payments waituntil replaced by governance
More than f witnesses colludeverifiers replay and publish fail with evidence; apps check their own lines; partners stop accepting; cross-circle exposure bounded by the step outwardsafety lost until people choose the honest branch (the limit of any BFT system)
Single-witness mode lies or its key is stolen [Decided 16 Oct 2026, A3]public label, daily verifier and drill, height-uniqueness check by appsa wrong entry can be booked before it is caught; no money cap bounds it (A3)
A bug shared by every witnesssecond independent implementation; test vectors; planted-bug tests; upgrades effective at a named height with shadow runsuntil found, a shared bug passes the quorum
A wrong move between project wallets and the reservekeyless wallets [A8]; only rule entries naming their inputs; one canonical drain(); every witness recomputes them and checks the reserve invariant; verifiers replayin single-witness mode, until caught
Money stuck in a receiving project (recipient gone, project found bad, never fills)the Circle Heart closes it with public notice (close_notice_s, 72 h by default), or it lapses 90 days (by default) after opening; project_return moves its balance to the reserve, then drain() [Decided 16 Oct 2026, 8e]the money waits in the keyless wallet until the notice or the 90 days have passed
The seller circle quotes a bad ratethe payer sees the converted price and does not pay [A7]; the quote is public and signed by that circle's nodea payer who does not look
Stale chain head on a member's devicerefused stale_prev; the app re-reads and re-signs—
Clock skew, tz database changeat checked ±5 s; note expires; published boundary; tzdata pinned in the found act and unchanged in 0.3.0 [Decided 17 Oct 2026, C7]a government that changes its clock rules: how a circle follows is left to a later definitions version
Oversized event≤ 100 KB by bytes, tested at maximum lengths—
Spam, open writes, disk fillingauthors pinned; circle-relay policy; per-author limits; borrowed quota; disk alarm at 70 %root relays keep open writes (owner's choice)
10-year windowno lower limit on circle and archive relaysthe four Lana relays refuse events older than 10 years [C]
Circle key lost or stolenit only stamps the 30910 mirror (and once the binding of the found act in block 1) [Proposal]; readers follow the ledger; k Heart members replace it by circle_key_change with the new key's proof of possession and public notice (change_notice_s, 72 h by default [E-1]), the witnesses book it, and from the height of the change only the new key's records count (it signs the 30910 of that height; for blocks it is in office from the next one); every seal and head names the circle key of the office after its last block [Decided 17 Oct 2026, C5; the proof of possession, when the new key counts and the key in the seal: Proposal]; the circle id never changesuntil the change is booked, a thief can only publish records that equal the ledger's mirror (anything else does not count); a lost key leaves new mirrors unsigned until the change (the ledger goes on; readers follow the ledger)
A false circle under the same namethe name is the circle id, the id of the founder's found act: another found act has another id, so it is another circle [Decided 17 Oct 2026, C5]; readers pin the circle id and the genesis digest from the link or QR; root relays with the first-seen rule keep the first g and founder per circle id (extra safety [C6])a reader who has neither the link nor the QR must compare the circle id itself
A Heart member's key is stolenevery Heart change needs k Heart members, so one key cannot exclude, close an account, change parameters or change witnesses alone; a parameter change waits at least the time it replaces, so a stolen key cannot skip the warning [Proposal, E-1]; a witness change also fails on one Heart "against" [E-7]; every act is publick stolen keys act as k Heart members; every member sees it in public, and whoever disagrees can leave with a reference and join or found another circle
Circles with different parameterseach circle applies its own values to what it books; a mismatch in note_ttl_s or quote_ttl_s ends in a refusal and xundo, and a short xcheck_s only repeats the check (§4.5) [Proposal, E-1]nothing is lost; a payer may have to sign again
A member leaves in minusno reference while in minus [E-9]; the debt stays written in the old circle, and anyone may settle it, never above 0 [E-9]; the circle covers it only when the member has died (an account close) [E-3 Dopolnitev]the debt can stay open for ever; no other circle admits the person from that circle without a reference
One person with two keysone key, one circle, through the member home and the reference (E-8, E-9)not prevented: that needs Lana's person check (said openly)
Member key lost or stolen (Q11)optional guardians, freeze, key_movewithout guardians the balance stays frozen and public
Cross-circle partner silenta timeout alone never undoes; after 7 days every witness of the payer's circle reads the partner's sealed ledger up to the note's expires: not booked → xundo naming the partner's seals and the real seal before them (§4.5); booked → xdone [Decided 16 Oct 2026, 8j]; a partner block counts only with a valid quorum of the partner's witnesses in office at its height, so noise signed by keys that are no quorum of the witnesses in office at that height (for example an old or stolen key) cannot stall the check [Proposal]while the partner's ledger cannot be read (relays gone, a missing height, no seal covering expires), the amount stays held: never a guess; a key that was in office at a height (for example the single witness of a one-witness circle, later stolen) can still fork that height, and a fork stops the check
A person wants their name gone [Decided 16 Oct 2026, A5]the ledger carries keys only; the name lives only in KIND 0 and 30916, which the person replaces; relays keep only the newest versionold copies of a profile someone saved, and names someone wrote into free text despite the field warning; a payment's existence and amount stay, by principle

12. Tests (when built)#

  • Replay equals restore: a restore from a seal (what it reads: §8.1 step 5) and full replay from genesis give the same canonical state hash, for every day of a generated year.
  • Block arithmetic: every line = previous line ± entries; the sum is 0 after every block; a changed line, a dropped entry or a line moved to another party fails the digest or the witness check; a block whose at span is above w_max_s (10 s without the parameter lines) is refused.
  • Sign-guard: a witness never signs a second digest at a height, across a kill at every step of §4.1; restart adopts the highest chain found on any relay or archive.
  • Double spend: two notes on one prev → one booked, one rej stale_prev; an expired note is never booked; two blocks at one height are detected by the app's height-uniqueness read.
  • Byte budget: every example and every generated block ≤ 100,000 bytes and ≤ 1,000 tags at maximum field lengths; morning blocks cut by bytes.
  • Template round-trip: a note that does not round-trip the v3 template is refused, never repaired.
  • Readers: a silent relay, an empty [], a 429 or a timeout never produce "not found" or balance 0; a missing height is reported by number; paging with inclusive until loses nothing on a 1,753-event fixture.
  • Gravity: the integer rule matches today's engine for 14 clean shadow mornings; clock-change windows use 90,000 and 82,800 s; a morning hour inside a clock change gives the first occurrence of a repeated hour and the first instant after a skipped one (Ljubljana and New York, both changes); a missed morning is booked as its own morning, and with two missed mornings the later reads its cut-off state with the earlier one's grav results applied; a grav deduct counts from its morning's boundary, not from the entry's at [clarification, 17 Oct 2026]; a morning header whose tzdata is not the one pinned at founding is refused; the morning cut by at is independent of when the node runs it; a payment booked before or after an account's grav entry gives the same lines (visit before touch); the order loses no debt: a debt the morning records (capped at the wave by the rule) is settled by the next receipt; an entry that touches an account after the boundary (in catch-up: after the morning opened) before its grav entry is refused; an act entry, or a rule entry that only names a party, touches no account and needs no visit [clarification, 17 Oct 2026 (D1 review)]; a block that carries morning D+1's header while a grav entry of morning D is pending is refused (grav_pending) [clarification, 17 Oct 2026 (D1 review)].
  • Snapshot: every chunk verifies against the seal; a missing or altered chunk is reported, never shown.
  • Relay policy (test relay only): KIND 5 against a block refused; an expiration block refused; a block by an unknown key refused; whether an id deleted by KIND 5 can be re-inserted.
  • Drill: a deliberately broken relay copy makes the daily drill fail and every member's app shows it.
  • Projects and reserve: a project passes only with no "against" from any member and at least project_approvals Heart "for" votes, the proposer's and the recipient's "for" not counted; one "against" as the newest vote makes it fall; the newest vote counts, and a repeated choice is repeated; a vote at or after the vote end is refused vote_ended; a duration outside vote_min_s … vote_max_s is refused not_allowed; a passed project opens at the end of the entry after which its consent is given (a step raise: once it fits under built), and lapses at its open lapse if it has not opened; a decline or withdrawal during the vote ends the project and its votes; the reserve moves to a newly opened project up to its amount in the same block; inflow stops at the amount and the surplus goes on (to the next project or the reserve); after every entry except a grav entry booked as a visit the reserve is above 0 only if no receiving project has room; one receipt makes exactly one step move (into the reserve); a full project is paid once and its recipient's grow/settled cascade ends; drain() runs at the end of every entry, every morning grav entry and every entry with visits included, and a give that exactly fills a named project gets it paid [clarification, 17 Oct 2026 (D1 review)]; a contribution from the wave (above the plus) and a contribution to a project that is not receiving are refused; project_return moves a receiving project's balance to the reserve after a project_close and close_notice_s, and for a receiving project not full by its receive lapse [8e]; a full step-raise project moves its wallet into world-step, raises the step by its amount and books no wave growth [8j]; the sum is 0 after every move; nobody can sign for a project wallet, the reserve, world or world-step; the project wallet address matches the test vector (role project|<id> before the circle id); and [clarification, 17 Oct 2026 (D1 review)] a step raise that did not fit under built when its vote passed opens at the end of the first entry after which it fits, and projects that become openable at the end of one entry open in publication order; duties due in the same second go in the order close return, receive lapse, open lapse, vote end, request expiry, resignation; built counts every account line that is not a system account or a project wallet, members who left included; a project_close without k distinct Heart members still in office at the commit commits nothing; a recipient of several receiving projects who leaves or is excluded gives one project_return per project, each followed by its own drain().
  • Cross-circle check after 7 days [8j]: a note B never booked up to its expires, with B's seals covering that time, returns the hold to the payer by xundo naming B's consecutive seals as [day, digest] and the height range they cover: from the last seal whose predecessor covered only bookings before A's xout at − 60 s to the first seal whose boundary is later than the note's expires (strictly), one or two seals (an idle B still seals every day), each checked against B's blocks, and closed by B's block right after the last seal or, for a B that booked no block since, by B's next daily seal (a next seal that hides a block is refused; a missing one leaves the hold waiting), plus the real seal before them (before), checked against B's chain; an evidence that skips the seal holding the booking is refused, so is a first seal whose prev misdescribes the seal before it, and an evidence without the seal before is unverifiable; a note B booked gives xdone; with B's relays silent, a missing height in the span or no B seal covering expires, nothing is booked and A's other bookings continue; a B block without a valid quorum of B's witnesses in office at its height (for example signed only by an old, retired or stolen key) is ignored and does not stall the check, a key or witness change of B inside the span does not stop it, and two quorum-valid B blocks at one height make the evidence unusable; a later answer from B never moves the amount a second time.
  • Rate quotes: a note whose to_amount differs from the quote's conversion, a quote not signed by the seller circle's node of that time, or an xout booked after the quote's expires is refused publicly (bad_quote, stale_quote); the payer's circle refuses an expired quote at intake and holds nothing; xdone is booked only for a xin with the same note id and exactly to_amount; a valid quote is honoured exactly; the conversion test vectors of docs/valute-in-tecaji.md (EUR→USD, USD→EUR, USD→GBP, a price in the receiver's currency, to_amount = 0) give the same cents in the node, the witness and the verifier.
  • Circle id and circle key [C5]: the circle id equals the found act's id, rebuilt with ["c", ""] (test_vectors.circle_id: scope16 and the head offset); the system addresses match test_vectors.system_addresses; a 30910 by any key other than the circle key that the ledger's mirror at its mirror_of names (at the height of a key change already the new key), or by the old key at or above a circle_key_change, never counts; a circle_key_change whose pop does not verify is refused (bad_template), also when the pop was made for an older act (another created_at); a roles entry that changes the circle key without circle_key_change, or to another key than the one it names, is refused, and so is a second roles entry in one block; the seal whose h_to is the height of a key change names the new key.
  • Circle parameters [E-1]: a found act or param_propose with a value outside its range, vote_min_s > vote_max_s or vote_max_s ≥ open_lapse_s is bad_template; a second param_propose while one is open is repeated; the notice end is the k-th act's at + max(change_notice_s, the old value of every changed parameter in seconds); params_effective comes at the notice end, first in its block, and the block is under the new parameters from it; a change with fewer than k of its signers in office at its notice end is void; a running deadline keeps the due time recorded when it started (a project opened under a 90-day receive lapse keeps 90 days when the parameter later says 30); TTL checks use the parameters in force at the booking; a restore from the circle's relays alone gives the same parameters (the found act, the param_propose acts and the g3|param:<name> lines); across circles a mismatch in note_ttl_s or quote_ttl_s ends only in a refusal and xundo, and a short xcheck_s never returns early; no 43920 is read or accepted.
  • Round 5: membership, the reference and the Heart [Decided 23 Oct 2026, E-2 … E-9; the tests: Proposal]: an exclusion takes effect at the act that reaches max(k, 3) Heart members [E-10], never counts the excluded key, first takes a Heart seat (a roles entry, or a wait for the next block when the block's roles entry is taken) and ends the key's projects as at a leave; an excluded line pays, gives, votes and proposes nothing, receives only a settlement, is visited by every morning and may xout only its plus; an excluded key's join before the end is not_allowed, after it goes to the Heart, never to the waiting list, and member_readmit admits it only with a free place; a member's leave books member_leave and its leaving line; the reference comes when its conditions hold, at the leave or later (a settlement to 0, the last OWN process closed), and never while in minus, nor with an open OWN process and a minus; an open OWN process blocks the reference also without a debt [E-9 (a)]; the step transfer (reference_grant with grant and reference_out, reference_return with reference_in and close_wave) keeps both sums 0, rounds G up across currencies so that to_amount ≥ W, returns G to the reserve by xundo when the old circle refuses it, never as not_booked, and grant_revoke then takes the unused part of the granted wave back to origin [E-11], a join with a step waits until an earlier move out of the circle is settled [E-11], a Heart member who leaves loses the seat [E-11], and a grant that does not fit under the step waits on the waiting list; a settlement never takes a line above 0 and moves no grow or settled; a join from another circle without a valid reference is not_allowed, and with one its member_join names ref, src and g; a key with no member home needs none; an account close waits for a pending grav entry, a held leg, a plus and a short reserve, then moves close_cover and close_wave, sets wave, cap, debt and carry to 0, and keeps origin = −start − granted + returned and Σ waves = grown + granted − returned; a closed key that joins again starts at 0; own_open needs one member and own_close one Heart member [E-10]; the morning visits every line that is not closed, also through the block builder [review of round 5]; invitations are one-time and expire after invite_ttl_s; invite_only refuses a join without an invitation; the waiting list admits in booking order while a place is free; a motion passes and falls like a project and moves no money; a witness change is refused while a Heart member in office has "against"; the examples rebuild byte for byte; at least 15 planted bugs in the new rules (scripts/plant-def5-bugs.ts) are each caught; the random workloads (test:long) include votes, motions, exclusions, readmissions, closes, settlements, references, OWN processes, invitations, the waiting list and parameter changes.
  • Checks from the D4 review [clarification, 17 Oct 2026 (D4 review); the commit window, the project field and the mirror: proposal (D4 review, 17 Oct 2026)]: catch-up after an outage (the missed mornings booked complete, in date order, before any other entry, one morning open at a time, each morning's cut-off seq the last seq booked before it opened, a later missed morning reading the earlier ones' grav results and drains, no payment, act, roles entry, refusal or duty while two or more mornings are pending, and payments again as soon as only one is; §7.4); the o3|change line (its eleven fields, the turn to notice at the act with which k Heart members in office are reached, the commit window and the lapse, repeated for a further endorsement by a listed Heart member and for a second close of one project, a close line ended by its project's final status; §3.8); the seal day chain (the first seal is that of the first day whose boundary is later than block 1's at, then day + 1 and n + 1 without a gap; §3.6); a block's at span checked exactly against w_max_s when the validator has the parameter lines (Block arithmetic, above); and the mirror a change of k Heart members gives (the mirror in office with exactly that change and nothing else; docs/upravljanje-kroga.md).
  • Checks from the D4 review, round 3 [clarification, 17 Oct 2026 (D4 review, round 3); the new lines, fields and acts and the resignation duty: proposal (D4 review, round 3, 17 Oct 2026)]: the restore proof (circle B and circle A each restored from a seal of the examples; since round 5, A's seal of 16 Oct covers its blocks 1–4, each reading exactly what §8.1 step 5 lists, rebuild the tail byte for byte and reach the same judgement as a replay from block 1); the new governance acts (steward_add, steward_remove, stewards_required_set, signer_remove and signer_replace, with the accept acts that set a change's consent; docs/upravljanje-kroga.md); the resignation duty (the roles entry of a steward_resign or signer_resign falls due change_notice_s (72 h by default) after its booking, due resignations go one per block, the earliest notice end first, and a block that leaves a due one out is refused).
  • The D3 review [clarification, 19 Oct 2026 (D3 review); the new rules: proposal (D3 review, 19 Oct 2026)]: the block library and the independent verifier agreed on about 1.3 million generated entries except two points these rules settle: a give or any act naming a project that has ended is not_found, and a project_propose whose recipient is not a member when it is booked is not_member. Further: a proposer who is the recipient has consented; a project_return from an empty wallet books no move; a note's visits are booked before it is judged and stay booked when it is refused; the restorer's list (§8.1 steps 2 and 5: the mandatory governance chain, the block before the first block after the boundary, the catch-up blocks after an outage, and the 43920 records of everything still running, which are no longer read since E-1); a block's first at is its first entry's; a morning block skips accounts already visited; a due resignation in a block of its own, void ones dropped first; a found act that breaks the bound on k is bad_template; a second resignation of one role by the same key is repeated; signer_replace keeps the quorum; a steward_accept naming a nomination had no effect (nominations are gone since 23 Oct 2026, E-2); a node checks its time-zone data before it signs.
  • No payouts, no deposits: no act, entry, line or setting for payouts or deposits exists; held_out and paid_in are absent from every line and from the state hash; there is no main account and no custodian.
  • No secret leaves: no event, log line or statement contains a private key, a WIF, a session token or an account number; no ledger event contains a name (only HEX keys); HEX only, never npub.

13. Decided and open points that touch this specification#

Decided 16 Oct 2026 (the project owner's answers): A1 finality (quorum and three relays) · A2 circle relays and the new reading of "only from 38888" · A3 witnesses, at most one per operator, single-witness bootstrap without a money cap · A4 stewards (names; now the Circle Heart, E-2) · A5 keys only in the ledger, names only in KIND 0 and 30916, no legal-review gate, no 43925 · A6 no bank data, no payouts (no payout acts, pout, held_out, reserve statement or payout breaker) · A7 rate quotes by the seller circle (43919), the payer signs both amounts · A8 keyless project wallets and keyless reserve instead of Common Good · A9 founding without personal approval (P3 dropped). Kept from 10/15 Oct: 72 h notice (now the default shortest vote, E-1 and E-5), every objection answered before approval (gone with the objections, E-5), the proposer never decides.

Decided 16 Oct 2026, afternoon (the project owner's answers to the open points; same source file, section "Odgovori na odprte točke"): 4a four stewards (now Heart members, E-2) in the live circle, the founder and three other Heart members; a project needs three of four · 6a no money deposits in BSA ("a different system altogether"): no deposit acts, no dep or corr, no custodian, no paid_in, no main account, no question 12, no deposit alarm, no 6b; the wave grows only with what a member receives · 8a a project pays its recipient once the whole amount is collected · 8b inflow to projects in order, oldest first; no project limits for now · 8c an objection within 72 h of publication; the project stays stopped until the objector withdraws; no effect once receiving (replaced on 23 Oct 2026 by E-5) · 8e the Heart closes a receiving project with 72 h notice (a default since E-1), the money goes to the reserve; a project that does not fill in 90 days lapses · 8f a project payment does not use up community money; the brake is the Heart's approval (since E-5, the vote); sum 0 · 8i world and world-step keyless (main also confirmed, then gone with 6a) · start source: the ECB daily rate, its date shown, quotes valid 10 minutes · 8j a hanging cross-circle payment: no refund payer; after 7 days the payer's circle reads the receiver circle's sealed ledger: not booked → xundo naming the receiver's seals, booked → xdone, unreadable → wait; the 7-day refund by public decision and xrefund are dropped; a step raise is a project, and the step rises by its amount when it is full · 8d follows from A8: with no receiving project the inflow stays in the reserve.

Decided 16 Oct 2026, later the same day (the project owner's answer to the new open point 6c, »6c, da«; same source file, section "Odgovor na 6c"): 6c the first money in a new circle is one start of 1,000 in the circle's currency for the reserve at founding, booked in block 1 as the rule entry start from the keyless origin (−100000 from then on; that it never moves again is a proposal), sum 0; by 8f it keeps coming back; no starting wave per member, no bridge from Lana; the names start and origin and the entry shape are a proposal for 0.3.0 (plan step C1); the live circle gets the same start at its genesis (E6; proposal: 1,000 EUR) (§3.9).

Decided 17 Oct 2026 (the project owner's answers to phase C, »1. DA - parametre shrani v posebni KIND … · 2. DA · 3. DA · 4. DA · … · 6. DA«, and after the explanation of points 5 and 1, »7 Da, Lahko narediš vse skupaj v fazi D …«; same source file, sections "Odgovori na fazo C" and "Odgovor na pojasnilo točk 5 in 1"): C1 the time values and the number of project approvals are world rule values in one world-wide record, 43920 BSA Rules, signed by the key that publishes the definitions on lananostr.site; a change counts from its effective, at least 7 days after publication, never retroactively; every block and seal names the version it used; several signatures later (for example 3 of 5) (replaced on 23 Oct 2026 by E-1: §3.1 rule 11) · C2 payments never pause for the morning; visit before touch (§7.4) · C3 refusals of keys that are neither members nor applicants are answered, never booked; an act is valid 7 days (ACT_TTL_S); at most 20 refusals of one key a day are booked (REJ_PER_AUTHOR_PER_DAY) (§3.5; both are circle parameters since E-1: act_ttl_s, rej_per_author_per_day) · C4 no Heart member rejects a project alone: no project_reject and no status rejected; an objection stopped a project (gone since E-5) (§3.9) · C5 the circle's name is its circle id, the id of the found act the founder signs; the circle key can be replaced by k Heart members (three of four in the live circle) with 72 h of public notice (a default since E-1), booked by the witnesses (§3.1 rule 8, §3.4) · C6 the first-seen rule ("the first ledger stands") goes into the letter to the Lana relay owner (phase G); with C5 it is only extra safety (§9.2) · C7 tz, morning hour and tzdata are written at founding and do not change in 0.3.0 (§7.2).

Decided 17 Oct 2026, evening (the project owner's answers to three questions after phase D, »vsi da« to the proposal »1A, 2A, 3A«; same source file, section "Odgovori na tri vprašanja po fazi D"): 1A for now only the rules authority's one key (the key that publishes the definitions) signs 43920; several signatures (for example 3 of 5) come before the first circle the project owner does not run joins (for example the first circle from another ecosystem); who the signers are stays open; the tension with principle 3 is thereby limited in time and said openly (dropped on 23 Oct 2026 with E-1) · 2A the tzdata part of C7: the version is pinned at founding with tz and the morning hour, and every witness computes the boundaries with it, never with a newer one of its own; in 0.3.0 it never changes, not even by the Circle Heart; how the Heart could later move a circle to a newer version is for a later definitions version (§3.5, §7.2) · 3A the transition (transition_days, 60 days) runs per account from its own first receipt (first_receipt_day), as the definitions say; today's app counts from the circle's start (the live circle has no payments), and the switch to the 0.3.0 gravity applies the per-account rule (§7.3).

Decided 23 Oct 2026 (the project owner's answers before phase E; same source file, section "Odgovori pred fazo E" with its subsections "Dopolnitev" and "Referenca"): E-1 the time values and limits are circle parameters, which the Circle Heart changes within the bounds of the definitions; 43920 and the rules authority are retired (the number reserved), which replaces C1 and drops 1A; fixed for every circle: a project needs at least 3 Heart "for" votes and no "against", and the money and gravity computation; 72 h is fixed nowhere (C5's fixed notice becomes change_notice_s) (§3.1 rule 11) · E-2 the stewards are the Circle Heart (one person: a Heart member); members never vote on the Heart (steward_nominate and steward_vote are gone); the Heart adds and removes Heart members (§2, §3.4) · E-3 the Heart excludes any member by three votes (E-10: the larger of k and 3), at once, with a public reason; an exclusion lasts 3 months; the Heart readmits, membership only; an excluded line is frozen, gravity visits its plus, and it may take its plus to another circle; the Heart closes old accounts: a minus is covered by the reserve only when the member has died, a plus waits for gravity, and at 0 the wave goes to 0 and the reserve returns the same amount to origin (confirmed in the supplement) (§3.11) · E-4 the Heart leads and oversees OWN processes; only a decision reaches the ledger (§3.11) · E-5 consensus votes ("all for, or it falls"): no "against" from any member and at least 3 Heart "for"; the proposer sets the duration at publication, at least 72 h by default (confirmed); an "against" carries a short public reason, the newest vote counts; a proposal without money is a public decision; replaces 8c and the approvals (§3.9) · E-6 joining: open, by invitation only, or a maximum with a waiting list; the first on the list is admitted by rule; the Heart decides about an excluded person (§3.11) · E-7 witnesses are computers drawn by lot among the circles' computers (the direction for phase I); until then one witness, the circle's own computer, labelled; the Heart's vote (three "for", none "against") only for exceptions (§2, §3.4) · E-8 only a member of an existing circle founds a circle; every circle grows from the first; one circle per founder; one circle at a time, per key through the member home; replaces "at most three circles per founder" (§3.11) · E-9 the reference (43921): issued by itself after "I want to leave" when not in minus; a debt must be settled, and anyone may settle it, up to 0; an open OWN process with a minus: no reference; no move without a reference: a new circle admits a person from another circle only with one (a rule for every circle) (§3.7, §3.11) · D8 the acts for Heart and witness changes are accepted, with E-7 for witnesses and E-1 for the notice · E-9 (a) an open OWN process blocks the reference also without a debt · E-9 (b) the step moves with the person: the new circle opens the same wave from its origin and pays the same amount to the old circle's community, which closes the account and returns the wave to its origin; "it cancels out" (§3.11) · E-11 (»1a,2a in 3c«) a grant's hold ends only by the old circle's word, a silent old circle means waiting; on a motion the proposer's own "for" counts, on a project the recipient never counts for itself; gravity never stronger than today's and tightened only with at least 30 days of notice; a Heart member who leaves loses the seat; no join with a step while an earlier move out is unsettled; a reference is valid once (grant_revoke) (§3.4, §3.9, §3.11, §7) · E-10 (answers 1B, 2A, 3A, 4A) an exclusion, a readmission, an account close and the Heart's witness exceptions always need at least three Heart members (the larger of k and 3; a Heart of fewer than three cannot do them), the Heart's other changes and the parameters k; any member opens an OWN process, one Heart member closes it; the wave a reference brings counts against the new circle's step outward; the longest vote 14 days by default; the Heart may close anyone's account with a public reason and cover its minus (§3.4, §3.9, §3.11).

Still open (proposals in §3.1, §3.4, §3.5, §3.7, §3.9, §3.11, §4.5 and §2): Open 3a (seven witnesses above about 10,000 members; may one owner then hold two) · Open 8g (contributions only from the plus; unnamed to the reserve) · Open 8h (the recipient is a member). Proposals that come with the afternoon answers and were not confirmed: k = 3 of 4 for other Heart acts and for closing a project · world-step as the recipient of a step-raise project · the recipient's consent as today · more ways to return a receiving project's money (recipient declines or leaves, proposer withdraws, recipient no longer a member at payment) · the 90 days counted from opening · the 30-day lapse before opening · the step lowering, and the formula and check of the built limit · the daily retry and the 60 s margin of the 7-day check · rate_source_set and rate_stale_alert 120 h · the circle key signs only the 30910 mirror and, once, the binding of the found act in block 1. Proposals that come with C5 (17 Oct 2026): the circle key of the newest mirror at or below the seal's last block in every seal and 30915 head · at most one roles entry per block · the proof of possession of a new circle key, bound to the act's created_at, and that the circle key is never the founder's, a witness's or a Heart member's key, nor the key already in office · the new circle key in office from the next block · the tag shapes (c tags, circle_key_change). Proposals that come with C6, C7 and 8j (17 Oct 2026): root relays keep every circle's found act and pin a circle id only with it (or, for a circle configured on the relay, when its configured circle key signed the record), after every plugin accepted the record, and a retired key counts only in its own role (§9.2) · the 8j evidence counts a partner block only with a valid quorum of the partner's witnesses in office at its height (§4.5) · a block's at span is at most w_max_s, and the morning header's tzdata is the one pinned at founding (§3.5). Proposal that comes with 2A: a witness without the pinned tzdata signs no morning block and no seal; how it keeps that version is its own implementation (§3.5). The notice of Heart changes (witnesses, relays, Heart members, recovery, the circle key) was a fixed 72 h [Decided 17 Oct 2026, C5]; since 23 Oct 2026 it is the circle parameter change_notice_s, 72 h by default [Decided 23 Oct 2026, E-1]. Open question: whether a root relay accepts the 30915 head of a circle it is not configured for (checked against the witnesses of its pinned record); the prepared write policy accepts heads only of configured circles (§9.2). Dropped with E-1 (23 Oct 2026): the proposals that came with C1 (the bounds of the rule values and the shape of 43920, rules_adopt, a witness's first-seen time of a 43920) and the open question of who signs the world rules. Proposals of round 5 (23 Oct 2026): the bounds of the circle parameters, and vote_max_s (14 days) (§3.1 rule 11) · the notice of a parameter change, max(change_notice_s, the old value of every changed time), one change open at a time, void without k signers in office at its end · TTL checks with the parameters in force at the booking; the stricter value during a notice and the smaller one across circles · each circle applies its own values across circles (§4.5) · the vote: the roles at the vote end, the same rule for a motion, consent kept, vote_ended, the place of vote_end among the duties (§3.9, §7.4) · the exclusion: a required public reason, exclusion_s 90 days, the projects ended as at a leave, an optional OWN case id · the reference: its mechanics (o3|leaving, a later issue), the 43921 tags (joined, left, "took part" = the projects that paid the person), the new circle's check and republication, no reference for a key that was never a member, root relays keeping member homes (§3.7, §3.11) · the settlement's shape (no grow, no settled), settling during an exclusion, a left key's xout of its plus · own_open (any member, E-10) and own_close (one Heart member) · the parent and founder-reference tags, the root relays' first found act per founder, the founder's membership check (phase G) · invitations valid 7 days and once, the applicant's withdrawal, max_members 0 = no limit · the technical names steward_* and the English names "Circle Heart" and "Heart member". Proposals of E-9 (b): the bookings of the step transfer (reference_grant, reference_return, the moves grant, reference_out, reference_in), the rounding across currencies, an account close waiting while a leg is held. Round 5's open questions were answered by E-10 (23 Oct 2026: at least three Heart members; the step brake kept; the longest vote 14 days; any account may be closed).

Still open questions: Q10 (the trust anchor, the circle id with the genesis digest: decided, C5 and C6; what the link and QR carry: proposal), 38888 as directory only · Q11 guardians · Q13 circle size cap · Q14 operators per circle, the four Lana relays as one operator, the bootstrap tension (no finality until the Lana relays apply §9.2); decision 2 says ≥ 3 operators, so the bootstrap ≥ 2 is a temporary departure the project owner must approve (proposal: three operators at the latest when the circle has four witnesses) · Q15 who pays relays (now through a project) · Q16 KIND 0 and homes at scale · Q17 sending on after three relays (changes the 14 Sep "wait for all" rule) · Q18 the new letter to the Lana relay owner (replaces P6; carries the borrowed-space size and the first-seen rule [C6]) · Q19 removal from hot relays · Q20 definitions version pinned per circle · Q21 votes (formerly objections) signed by key and public, purpose public for ever · Q23 witness votes · Q24 project images off the relays · P2 where the circle key lives · P7 one yes per definitions version and per kind. Q12 (a deposit limit per signature) is moot: there are no deposits [6a].

Clarifications of 17 Oct 2026 (D1 review) [no decision needed: each follows from existing text or decisions]: they need no decision from the project owner; two of them make "never retroactive" (C1, now E-1) concrete: a project opens without an act once its last condition holds (§3.9), and a running deadline keeps the length in force when it started (§3.1 rule 11, §3.8). The others: drain() at the end of every entry, and after each project_return (§3.9); the order of project duties due in the same second (§7.4); built over every account line that is not a system account or a project wallet, members who left included (§3.6, §3.9); an approval was refused unless booked after the notice, with no standing objection, every objection answered and the recipient's consent given (approvals and objections are gone since E-5) (§3.9); no block carries morning D+1's header while a grav entry of morning D is pending (§7.4); only money entries touch an account for visit before touch (§7.4); a project_close commits only with k Heart members in office at the commit (§3.9).