Running a circle: witnesses and the Circle Heart: 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.
Scope and status#
- New document for definitions 0.3.0 (0.2.0 was never published). Nothing is built and nothing is published.
RELAY_PUBLISH_OFF=1stays until definitions 0.3.0 are published (KIND 42893 by the Lana authority) and the project owner says yes (proposal P7: one yes per definitions version and one per kind switched on). - Sources: the recommended architecture of 16 October 2026 (roles §2, acts §3.4, write path §4.3–4.6, governance §8, tensions §13), amended by the project owner's answers to questions 1–9 and to the open points, both of 16 October 2026, by his answers C1–C7 of 17 October 2026 and by his answers 1A–3A of that evening, which override the architecture wherever they differ (no money cap, no payouts, no deposits, no bank data, names never in the ledger, rate quotes by the seller's circle, projects instead of Common Good, four people who decide (since 23 Oct the Circle Heart), a cross-circle hold settled by the receiving circle's ledger instead of a refund, world-wide rule values in 43920 (retired on 23 Oct), no rejection by one person (replaced by the vote on 23 Oct), a circle named by its circle id with a replaceable circle key). Amended again by the project owner's answers before phase E of 23 October 2026 (E-1 … E-8, the addition "Dopolnitev" and E-9 "Referenca"), which override everything earlier where they differ: no world rules record (43920 retired, its number reserved), the time values and limits are circle parameters the Circle Heart changes within bounds, the Circle Heart (formerly the stewards) is never elected by members, exclusion and readmission by the Heart, closing old accounts with the wave returned to
origin, consensus votes instead of approval after notice and objections, joining settings (open, invite only, a maximum with a waiting list), witnesses by lot as the direction for phase I, founding only by a member of an existing circle (one circle per founder key, one circle per person at a time) and the reference (43921). Labels: [M] measured on 16 Oct, [C] relay config read on 16 Oct, [R] earlier report or memory, [E] estimate. - Status labels: [Decided <date>]; [Decided 16 Oct, Qn] for the project owner's answers to questions 1–9; [Decided 16 Oct, 4a], [Decided 16 Oct, 6a], [Decided 16 Oct, 8a], 8b, 8c, 8e, 8f, 8i, 8j, [Decided 16 Oct, start rate source] and, later the same day, [Decided 16 Oct, 6c] for his answers to the open points; [Decided 17 Oct, C1] … [Decided 17 Oct, C7] for his answers C1–C7 of 17 October 2026; [Decided 17 Oct (evening), 1A], 2A, 3A for his answers of that evening to three questions after phase D (»vsi da«; source section "Odgovori na tri vprašanja po fazi D": 1A for now only the key that publishes the definitions signs 43920, several signatures before the first circle the project owner does not run joins, who: open (void since 23 Oct 2026, E-1); 2A the
tzdataversion pinned at founding, part of C7; 3A the transition runs per account from its first receipt); [Open 3a], [Open 8g], [Open 8h] for points still open, each with the proposal stated (8d is not open: it follows from Q8); [Proposal Qn] for questions 10–24; [Proposal] for details never put to the project owner or not covered by his answers; [Open] for points the design itself has not settled; [Decided 23 Oct 2026, E-n] for the project owner's answers before phase E (source section "Odgovori pred fazo E" with its "Dopolnitev" and "Referenca", E-9; where_reports/2026-10-23-faza-E/D-def5-zasnova.mdand that section differ, the section wins); [Consequence] for what follows from a decision without a new one; [Decided 23 Oct 2026, E-9 (a)] and (b) for his answers of the same day to the two questions on the reference (source section "Odgovora na vprašanji o referenci": an open OWN process blocks a reference also without a debt; the built step moves by his method, which cancels out between the two circles). Where an older label names a decision that E-1 … E-9 replaced, the text says so. - Glossary (as in
docs/knjiga-na-relejih.md): witness = signer; node = the witness that proposes and orders blocks (proposer); Circle Heart (SL »Srce kroga«; formerly "the stewards") = the people who decide by k of m, and a Heart member (SL »član Srca«) is one of them [Decided 23 Oct 2026, E-2]; the technical names stay: act typessteward_*, the tags["steward", hex]andstewards_required, the signer role valuesteward,o3|change[Proposal]; k =stewards_required; act = 43916; block = 43911 v3; project (projekt) = a public plan with an amount (project_propose), decided by a consensus vote; vote (glas) = avoteact, "for" or "against" (an "against" with a short public reason); motion (drug predlog) = any other proposal a Heart member puts to a vote (motion); project wallet (denarnica projekta) = its keyless account, writtenproject:<id>; reserve (rezerva) = the keylessreserve; rate quote (ponudba tečaja) = 43919 v3; reference (referenca) = thereferencerule entry and its findable copy, a 43921; circle id (rojstna številka kroga) = the event id of the circle's signedfoundact (found act = ustanovna listina), the circle's name for ever; parent circle (matični krog) = the circle a found act names inparent; root circle = the live circle, which names no parent; genesis digest (prstni odtis prvega bloka) = the digest of block 1; circle key (ključ kroga) = the key that signs the 30910 mirror, replaceable bycircle_key_change; circle parameters (nastavitve kroga) = the integer values of "Circle parameters" below, changed byparam_propose[Decided 23 Oct 2026, E-1]. There is no world rules record and no rules authority any more: KIND 43920 is retired and its number stays reserved [Decided 23 Oct 2026, E-1]. There is no custodian role [Decided 16 Oct, 6a]. - Members, witnesses and Heart members are shown and stored by Nostr HEX key, never npub. The ledger (blocks, acts, entries, seals, snapshots) never carries a person's name [Decided 16 Oct, Q5]; a name exists only in KIND 0 and in the 30916 member home (
n), both replaceable, and a relay keeps only the newest version. No private key, WIF, server address or bank data of any kind appears in any event, setting or log [Decided 16 Oct, Q6]. - [Consequence of the 16 Oct principles] (principles 1 and 2): settings, project decisions and membership each get a signed public record; nothing local that cannot be rebuilt from the relays. Payouts and deposits do not exist [Decided 16 Oct, Q6 and 6a]: a wave grows only with receipts (
pay,xin,project_payto a member).
Roles#
| Role | Count | Signs | Bounded by | Status |
|---|---|---|---|---|
| Member | any (at most max_members when set; the others wait on the list) | 43910 notes, 43916 acts (vote included), own 30916 | own acts only; a member of one circle at a time | key rules [Decided 16 Oct]; joining [Decided 23 Oct 2026, E-6]; one circle at a time [Decided 23 Oct 2026, E-8] |
| Witness (signer) | n = 3f+1: 4 (f = 1, q = 3); bootstrap n = 1, q = 1; 7 (f = 2, q = 5) above about 10,000 members [E] | block digests (qs tags), daily 43924 | at most f of n faulty; at most one per operator | n = 4, q = 3, bootstrap 1, one per operator [Decided 16 Oct, Q3]; n = 7 [Proposal, Open 3a]; chosen by lot among the circles' computers (the direction for phase I), until then one witness, the circle's own computer [Decided 23 Oct 2026, E-7] |
| Node (proposer) | one witness per height; phase 1 fixed (the circle's box), phase 2 rotating (same format) | the 43911 event itself; the circle's 43919 rate quotes; the circle's 43921 references | every other witness recomputes every number | rotation later [Proposal, from the text of Q3]; quotes [Decided 16 Oct, Q7]; swap procedure [Proposal]; references: a new kind [Decided 23 Oct 2026, E-9], signed by the node [Proposal] |
| Heart member (technical name: steward) | live circle: the founder and three other Heart members (m = 4); HEX keys enter the log at plan step I1, not now | their own vote; with k Heart members: param_propose, project_close, circle_key_change and the other Heart changes; with the larger of k and 3: member_exclude, member_readmit, account_close and the witness exceptions [Decided 23 Oct 2026, E-10]; alone: motion, own_close, steward_resign (and own_open, as any member may [E-10]) | public rules, notice periods; a Heart member's "for" never counts on a project they proposed or that pays them; never elected by members | names, m = 4 [Decided 16 Oct, Q4, 4a]; the name Circle Heart, no election, the Heart adds and removes Heart members [Decided 23 Oct 2026, E-2]; k = 3 [Proposal, stays]; at least project_approvals (≥ 3) Heart "for" and no "against" for a project [Decided 23 Oct 2026, E-1, E-5]; k for the circle key [Decided 17 Oct, C5] |
| Verifier / auditor | anyone | 43924 statements | nothing: a statement carries its evidence | [Proposal] |
| Guardians of a member | chosen by the member (e.g. 2 of 3 members) | freeze, key_move | only if the member named them in advance | [Proposal Q11] |
| Circle key | one in office per circle; replaced by circle_key_change (k Heart members, change_notice_s notice, 72 h by default, booked by the witnesses; in office from the next block [Proposal]); never the founder's, a witness's or a Heart member's key [Proposal] | the 30910 mirror and, once, the found act's binding in block 1 (circle_sig) | alone nothing (readers follow the log; 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), its tags without g equal that mirror, and its g names the pinned genesis digest); it never names the circle, which is named by its circle id | holder [Decided 16 Oct]; role [Proposal, follows from Q3 and Q8]; replaceable [Decided 17 Oct, C5]; the notice a circle parameter [Decided 23 Oct 2026, E-1] |
Project wallet, reserve, world, world-step | one per project; one reserve, one world, one world-step per circle and currency | nothing (keyless x-only points) | moved only by entries the witnesses recompute | [Decided 16 Oct, Q8, 8i] |
The custodian role and its acts are removed with deposits [Decided 16 Oct, 6a]. The rate-publisher panel and the project owner's hourly rate key are removed [Decided 16 Oct, Q7].
Witness set#
- Size and quorum. n = 3f+1, q = 2f+1. n = 4, q = 3 [Decided 16 Oct, Q3]; n = 7, q = 5 above about 10,000 members [E, Proposal, Open 3a]. The signer set S(h) is defined by height: genesis plus every committed
rolesentry; each signer carriessince_handuntil_h. Who the witnesses are: chosen by lot among the circles' computers, the direction for phase I (docs only, no code in 0.3.0;docs/releji-svetovna-mreza.md); 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 Heart's vote is only for exceptions ("Signer set, relays" below) [Decided 23 Oct 2026, E-7]. - Operators. Every signer is named in public with its operator (
["signer", hex, operator, since_h, until_h]in the 30910 mirror and in therolesentry). At most one signer per operator [Decided 16 Oct, Q3], written into the log as a rule the witnesses check on everyrolesentry. The double-spend argument (two quorums overlap in ≥ f+1 signers, at least one honest) assumes at most f faulty signers; one per operator satisfies it at n = 4. [Open 3a] at n = 7 safety would still hold with two per operator (f = 2); the decided rule says one, and the n = 7 case was not confirmed in the answers. Until the project owner answers: one per operator. - Duties of every witness.
- Recompute every line and root from its own state, built only from relay blocks; check signatures and the template round-trip of every embedded note and act; check
prev,h= its last + 1, the circle sum = 0 after the block, the reserve and every project wallet ≥ 0, every project wallet ≤ its amount, andatwithin ±5 s of its own clock. - Sign-guard: fsync
{circle, key, last_h, last_digest}before releasing a signature; never sign a different digest at or belowlast_h. Tens of bytes; the only local state besides the key and the write-ahead log. - Keep a relay with the circle's full history; republish only what is still missing from a listed relay after 5 s.
- Publish a daily 43924
["result","ok"]with the state root it computed and a root over every vote it signed that day ([Proposal Q23], option A: daily summary public, a single vote on request or as evidence). - Read the signer set from the log, cached ≤ 24 h, refreshed on any refusal; never from the newest 30910.
- Read the circle parameters in force for a block from its own state (
g3|param:*, changed only byparams_effective), never from any world-wide record: there is none, KIND 43920 is retired [Decided 23 Oct 2026, E-1]; judge every check of a block by the parameters in force for it, except a running deadline, which keeps the due time recorded when it started ("Circle parameters" below) [Decided 17 Oct, C1, and 23 Oct 2026, E-1: never retroactive; the per-block judging: Proposal].
- Recompute every line and root from its own state, built only from relay blocks; check signatures and the template round-trip of every embedded note and act; check
- Equivocation. A signer that signs two digests at one (circle, height) leaves public proof: a 43924
["result","equivocation"]with both signatures as evidence. It is removed through the signer-change rule (signer_removeorsigner_replace: the larger of k and 3 Heart members "for" [E-10] and no Heart member "against", "Rules" below) [Decided 23 Oct 2026, E-7]. - Faults. ≤ f witnesses down: nothing changes. > f down: liveness lost, safety kept (reads work, payments wait) until replaced by governance. > f collude: verifiers replay and publish
failwith evidence; apps check their own lines; partner circles stop accepting; cross-circle exposure is bounded by the step outward. - Finality [Decided 16 Oct, Q1]: a block counts when it carries ≥ q valid signatures of S(h) and ≥ 3 listed relays [Q1]; of ≥ 3 operators (bootstrap ≥ 2) [Proposal Q14]; answered
OK truefor this exact id and every lower height is final (the four Lana relays count as one operator: [Proposal Q14]). The app shows "Paid · block h · public on N of M relays · confirmed by q of n". Whether sending to the remaining relays continues without waiting is [Proposal Q17].
Censorship by the node [Proposal]#
- The node returns a signed receipt (its signature over the note id) for every note it accepts into its queue.
- A receipted note neither booked nor refused within 60 s is public evidence: 43924
["result","ignored"]. - No receipt within 10 s: the member may publish the note standalone to ≥ 3 circle relays (evidence, rate-limited). Signers forward such notes to the node and require a receipt.
- A node that keeps refusing receipts for notes forwarded by ≥ q signers is replaced (phase 1
proposer_swap; phase 2 view change). Evidence never halts the circle by itself.
Bootstrap: one witness [Decided 16 Oct, Q3; relays Q2; Proposal Q14]#
- n = 1, q = 1: the circle's box is the only witness and the node.
- App label, always visible: "one witness · not yet decentralised" [Decided 16 Oct, Q3].
- No money cap [Decided 16 Oct, Q3: "ni meje denarja"]: no cap parameter in
found, no cap label, no cap check. This supersedes the architecture's bootstrap money cap and its open question about what the cap measures. - Relays [Decided 16 Oct, Q2]: the circle's own box relay from day one; in total at least four relays of at least three operators; the Lana relays (from 38888) are a borrowed home for small circles with a per-circle quota. [Proposal Q14]: the four Lana relays count as one operator until shown otherwise (NIP-11 lists four contacts [M]; the relay-owner letter is addressed to one owner [R]); they count as copies only after their owner applies the write policy for ledger kinds. The architecture's trigger "≥ 3 operators before the cap" is void (there is no cap). [Open] (Q14, Q18): until the Lana relay owner applies the write policy, only the box relay counts, so under Q1 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.
- Compensating controls: public label; daily replay and restore drill by the proposer and any verifier, published as 43924; every app's height-uniqueness read on 2 relays after each payment; the node's ±5 s discretion over
atis visible and flagged by the verifier. - Known weakness (F12 below): a wrong entry can be booked before it is caught, and with no cap its size is not bounded by any parameter; a lost sign-guard or key is replaced by the Heart's acts alone.
- Leaving bootstrap: witnesses will be drawn by lot among the circles' computers, the direction for phase I; until there are enough circles to draw from, a circle keeps its one witness, publicly labelled [Decided 23 Oct 2026, E-7].
signer_propose+signer_accept(the larger of k and 3 Heart members "for" [E-10], no Heart member "against",change_notice_sof notice) stay for the Heart's exceptions ("Rules" below).
Acts (KIND 43916)#
kind 43916, pubkey = the actor (member, applicant, invitee, Heart member, signer, founder, guardian)
tags: ["c", <circle id>] first; the found act carries ["c", ""], since its own id is the circle id
["t", <act type>] second
the type's tags, in the order its act type lists ("e" references, "p" subjects, typed values …);
an endorsement carries only ["e", <proposing act id>, "", "proposal"]
["after", "<height>"] (optional)
["expires", "<unix: after created_at, at most created_at + act_ttl_s>"] (always) validity window
["idem", <32 lowercase hex>] (optional) ["v", "3"] (last)
content: human text where the type has one, ≤ 500 characters, PUBLIC FOREVER
- Free text stays inside the act. There is no 43925 Public Text and no text "beside the chain"; the legal review is not a gate [Decided 16 Oct, Q5]. Every free-text field in the app (payment purpose, the reason of an "against", the reason of an exclusion, project and motion title and description) shows: "public for ever; do not write names, personal or bank data" [Decided 16 Oct, Q5]. No act type has a name field; a person is the act's
pubkeyor aptag (HEX). - An act has effect only once booked, as an
actentry (no money effect) or as the cause of aruleorrolesentry. It is judged by its author's role at the booking height. - Every act carries
expires, at mostact_ttl_safter it was signed (a circle parameter, 604,800 s = 7 days by default) [Decided 17 Oct, C3; a circle parameter: Decided 23 Oct 2026, E-1]; it is booked only atcreated_at−AT_TOLERANCE_S(5 s, a fixed constant) ≤at≤expires, itsexpiresjudged by theact_ttl_sin force at its booking (during a parameter change's notice apps sign with the stricter of the two values) [Proposal], and the same act id at most once (duplicate); booked act ids stay in the state asa3lines until they expire, so an old act can never be booked again. - After
expiresan act is refused (rejentry with reasonexpired). Only refusals of members and applicants are booked; a refusal of a key that is neither is answered and never booked [Decided 17 Oct, C3]. At mostrej_per_author_per_dayrefusals of one author are booked per morning day (from one morning boundary to the next; D4 review, round 3) (20 by default; a circle parameter [Decided 23 Oct 2026, E-1]) [Decided 17 Oct, C3]; above it the intake answers 429 and books nothing. A booked refusal carries only the refused event's id, kind and author HEX and the reason code, never its tags or text. Exception [Ruling; not part of C3]: a note that a partner circle's bookedxoutbrought is refused withsrcnaming that block, so the payer's circle can undo its hold. - Acts are embedded in blocks; a standalone copy is optional. No
expirationand no NIP-70-tag; ledger keys never sign KIND 5 or 62. - Due duties: every time-driven change is a
ruleentry:params_effectiveat the notice end of aparam_propose(the first block whose firstatreaches it starts with it, after the morning header; from that entry on the block is under the new parameters; it waits for every missed morning at or before its notice end and every duty due before it, never retroactive [completed 24 Oct 2026, plan step E4x]) [Decided 23 Oct 2026, E-1; the entry: Proposal];vote_passorvote_fallat a proposal's vote end [Decided 23 Oct 2026, E-5; the entries: Proposal];project_lapseafteropen_lapse_s(30 days by default) for a project that never opened;project_openfollowed bydrain();reserve_move;project_fullandproject_pay[Decided 16 Oct, 8a];project_returnafter theclose_notice_snotice of aproject_closeor afterreceive_lapse_s(90 days by default) receiving without filling [Decided 16 Oct, 8e]; request expiry (request_expire). An exclusion, an invitation and a change's commit window end with their lines, at the first block whose firstatis later than their end, with no entry. At the end of every entry the rule also books, in this order afterdrain()and the openings: the waiting closes (account_close), the waiting references (reference) and the waiting list (member_join) ("Rules" below) [Decided 23 Oct 2026, E-3, E-6, E-9; the order: Proposal]. A resignation'srolesentry is a duty too, duechange_notice_s(72 h by default) after its resign act, one per block ("Heart changes" below) [proposal (D4 review, round 3, 17 Oct 2026); the notice a parameter: Decided 23 Oct 2026, E-1], in a block of its own before that morning's morning block [proposal (D3 review, 19 Oct 2026)]. The 7-day check of a cross-circle hold (xcheck_s, Rules table below) is not time-driven alone: it becomes a due entry only once the node has read the partner circle's ledger, and witnesses refuse anxdoneorxundothey cannot verify themselves [Decided 16 Oct, 8j]. Rule names:start,member_join,member_leave,member_rules,member_exclude,reference,account_close,project_open,reserve_move,project_full,project_pay,project_lapse,project_return,vote_pass,vote_fall,request_expire,params_effective,step_lower;rules_adoptis gone with 43920 [Decided 23 Oct 2026, E-1]. Project statuses:proposed(voting),passed,receiving,full,paid,declined,withdrawn,lapsed,closed,fell; final:paid,declined,withdrawn,lapsed,closed,fell; there is no statusstoppedand norejected[Decided 23 Oct 2026, E-5; Decided 17 Oct, C4 forrejected]. A block whoseatpasses a due time must start with all due entries in canonical order; signers refuse a block that omits one, except a block the size rule closed (more): its work goes on in the next block, at the sameat, first and in the same order (the block split, ledger document §3.5) [completed 24 Oct 2026, plan step E4x]. Duties that fall due in the same second go in this order: the return after a closing notice, the lapse of a receiving project, the lapse of a project that never opened, a vote end, a request expiry, a resignation; within a kind by publication (projects, motions) or by id [clarification, 17 Oct 2026 (D1 review); the vote end in this order: Proposal]. The morning'sgraventries are the exception: visit before touch (ledger document §7.4), so payments never wait for them. - Relay write policy for 43916: accepted only from members and applicants of that circle, rate-limited per author. [Open] witnesses and guardians who are not members also sign acts; the policy must admit the keys the log names in those roles.
| Group | Act types | Signed by |
|---|---|---|
| Founding | found (name, code, the first circle key, currency, tz, tzdata, morning hour, first signer set with quorum and node, the first Circle Heart (steward tags) and k, relays and archives, an optional ["bootstrap", "Q14"] label (open question 14, not decided), the rate source, the write intake (api), every circle parameter as ["param", name, "<integer>"] in the order of "Circle parameters" below, the start, the parent circle ["parent", <parent circle id>, <parent genesis digest>] and the founder's reference ["e", <43921 id>, "", "reference"] (both required except for the root circle), definitions version); its first tag is ["c", ""] and its event id is the circle id [Decided 17 Oct, C5]; signed by the founder and bound to the first circle key by that key's signature over it in block 1 (circle_sig); tz, morning hour and tzdata are fixed at founding [Decided 17 Oct, C7]; it carries every circle parameter and names no world rules version [Decided 23 Oct 2026, E-1]; only a member of an existing circle founds, one circle per founder key [Decided 23 Oct 2026, E-8; the tags: Proposal]; no money cap [Decided 16 Oct, Q3] | founder |
| Membership | invite (["p", <HEX>]; one-time, valid invite_ttl_s) [Decided 23 Oct 2026, E-6; the shape: Proposal], vouch, join (optional ["e", <invite id>, "", "invite"], optional ["e", <43921 id>, "", "reference"] [Decided 23 Oct 2026, E-6, E-9; the tags: Proposal]), leave ("I want to leave"; for an applicant it withdraws the application), rules | members / applicant |
| Exclusion and accounts | member_exclude (["p", <member HEX>], optional ["e", <OWN case event id>, "", "own"]; text required: a short public reason), member_readmit (["e", <join act id>, "", "join"]) and account_close (["p", <HEX>]; text required: a short public reason, since the ledger cannot see a death [Decided 23 Oct 2026, E-10 4A]): each by the larger of k and 3 Heart members in the endorsement form, no notice, effective at the act that reaches them in office [Decided 23 Oct 2026, E-3 and E-10; the reason and the shapes: Proposal] | Heart members |
| OWN | own_open (["p", <HEX>], optional ["e", <OWN case id>, "", "own"]; any member, alone, at once [Decided 23 Oct 2026, E-10]) and own_close (["e", <own_open id>, "", "open"]; one Heart member in office); never any content of the process [Decided 23 Oct 2026, E-4; the record: Consequence of E-9, Proposal] | Heart members |
| Money in | none: deposit_declare, deposit_cancel, deposit_attest, deposit_reject, deposit_correct and custodian_name are removed [Decided 16 Oct, 6a]; question 12 (a one-signature limit) is dropped with them | — |
| Money out | none: payout_request, payout_cancel, payout_sent, payout_reject and the monthly reserve statement act are removed [Decided 16 Oct, Q6]; the name reserve now denotes only the keyless reserve wallet | — |
| Projects | project_propose (amount, recipient, ["duration", "<seconds>"] after p, title; content = description; vote_min_s ≤ duration ≤ vote_max_s of the parameters in force at its booking, else not_allowed) [the duration: Decided 23 Oct 2026, E-5, confirmed], project_consent (not needed when the proposer is the recipient: the project_propose is the consent, and a project_consent is refused repeated [clarification, 19 Oct 2026 (D3 review)]), project_decline, project_withdraw (a decline or a withdrawal during the vote ends the project and its votes), project_close (Heart members, after close_notice_s, 72 h by default, of public notice [Decided 16 Oct, 8e]; k = 3 [Proposal]); project_approve, project_object, project_object_withdraw and project_answer are removed: a project is decided by a vote [Decided 23 Oct 2026, E-5]; there is no project_reject | proposer / recipient / Heart members |
| Votes | motion (["title", <≤ 100 characters>], ["duration", "<s>"]; text required: the proposal) by one Heart member in office [Decided 23 Oct 2026, E-5; one member: Proposal]; vote (["e", <project_propose, motion or witness change id>, "", "proposal"], ["vote", "for" or "against"]; an "against" requires its short public reason as text, a "for" carries none) by any member, on a witness change by a Heart member [Decided 23 Oct 2026, E-5, E-7; the shapes: Proposal] | a Heart member / members |
| Step outward | a raise is a project, with every project act and rule [Decided 16 Oct, 8j]: a project_propose whose recipient is world-step [Proposal]; a lowering: step_propose (negative amount), decided by a vote like a project; the builder does not book it in 0.3.0 (no complete rule); step_approve is removed [Decided 23 Oct 2026, E-5; the lowering: Proposal] | member |
| Parameters | param_propose (the full new set of every circle parameter) by k Heart members in the endorsement form, with notice; param_approve and param_object are removed [Decided 23 Oct 2026, E-1; the shape: Proposal] | Heart members |
| Roles | steward_accept (signed by the new Heart member; its e tag names the steward_add it consents to), steward_resign, signer_propose, signer_accept (signed by the new witness; ["e", <id>, "", "proposal"] names a signer_propose or a signer_replace), signer_resign, proposer_swap, relay_change, rate_source_set, refusal_list_set, circle_key_change (["key", <new key HEX>], ["pop", <the new key's proof of possession>], exact form under "The circle key and the 30910 mirror"; k Heart members by the endorsement form, change_notice_s notice from the k-th act, text optional [Decided 17 Oct, C5; the notice a parameter: Decided 23 Oct 2026, E-1; the shape and the pop: Proposal]); [proposal (D4 review, round 3, 17 Oct 2026)] steward_add (["p", <new Heart member HEX>]), steward_remove (["p", <Heart member HEX>]), stewards_required_set (["k", "<k>"]), signer_remove (["p", <witness HEX>]) and signer_replace (["p", <old witness HEX>], ["signer", <new witness HEX>, <operator>]): k Heart members by the endorsement form, text optional [the Heart adds and removes Heart members: Decided 23 Oct 2026, E-2]; signer_propose, signer_replace and signer_remove also need the larger of k and 3 Heart members [Decided 23 Oct 2026, E-10] and no Heart "against" [Decided 23 Oct 2026, E-7]; steward_resign and signer_resign have no tags of their own and are signed by the resigning Heart member or witness alone; steward_nominate and steward_vote are removed: members never vote on the Heart [Decided 23 Oct 2026, E-2]; the mirror each of these acts gives, if any: "The mirror a roles entry carries" under "Rules" below | Heart members / the new Heart member or witness (its accept) / the resigning Heart member or witness |
| Recovery | recovery (new signer set, last height found anywhere); the larger of k and 3 Heart members "for" [Decided 23 Oct 2026, E-10] and no Heart member "against" [Decided 23 Oct 2026, E-7]; the mirror its roles entry carries: "The mirror a roles entry carries" under "Rules" below | the larger of k and 3 Heart members (3 of 4 in the live circle) |
| Member safety | guardians_set, freeze, key_move | member / k of the guardians the member named [Proposal Q11] |
Circle parameters (KIND 43920 retired) [Decided 23 Oct 2026, E-1]#
What they are. Every time value and limit is a circle parameter with a default, changed by the circle's Heart within the bounds of the definitions [Decided 23 Oct 2026, E-1: »72 ur ne more biti fiksno to je lahko default nastavitev, ki jo lahko spremeinijo«]. There is no world rules record, no rules authority and no world signer: KIND 43920 (BSA Rules) is retired and its number stays reserved, never reused; meta.rules_authority, meta.rule_values, the constant RULES_NOTICE_S, the rules tag of the found act, of the seal and of the head, the state line g3|rules, the rule entry rules_adopt, the restore of 43920 records and the validators of 43920 are gone, and so is decision 1A's signer question [Decided 23 Oct 2026, E-1]. Said openly: this removes the one key with world-wide reach that 1A had to limit in time (principle 3); inside a circle that power now lies with its Heart.
Fixed for every circle (definitions, not parameters): a project needs at least 3 Heart "for" votes and no "against" (project_approvals ≥ 3); the money and gravity computation [Decided 23 Oct 2026, E-1]; the constants XCHECK_MARGIN_S = 60 s, AT_TOLERANCE_S = 5 s, QUOTE_MARGIN_S = 120 s and RATE_STALE_ALERT_S = 432,000 s (120 h) [Proposal]. The constants are clock margins and the node's own timing, not rules a community lives by.
The parameters, in this order (the found act and param_propose carry all of them, each ["param", name, "<integer>"]; a value outside its range, or vote_min_s > vote_max_s, or vote_max_s ≥ open_lapse_s, is bad_template):
| Name | Min | Max | Default | Unit | Status |
|---|---|---|---|---|---|
band_ppm_day | 0 | 330 | 330 | ppm/day | a circle parameter as before; never stronger than today's, a raise waits at least 30 days [Decided 23 Oct 2026, E-11] |
excess_ppm_day | 0 | 22,840 | 22,840 | ppm/day | never stronger than today's (half in 30 days), a raise waits at least 30 days [Decided 23 Oct 2026, E-11] |
transition_days | 60 | 3,650 | 60 | days | never shorter than today's, a shortening waits at least 30 days [Decided 23 Oct 2026, E-11] |
rest_after_days | 0 | 3,650 | 183 | days | 0 = off, otherwise at least 183 (1 to 182 is invalid); a rest that comes sooner waits at least 30 days [Decided 23 Oct 2026, E-11] |
wave_cap | 1 | 999,999,999,999,999 | 100,000,000 | minor units | as before |
w_max_s | 1 | 10 | 1 | s | as before |
vote_min_s | 86,400 | 2,592,000 | 259,200 (72 h) | s | [Decided 23 Oct 2026, E-5, addition: the shortest vote 72 h by default, a circle setting]; bounds [Proposal] |
vote_max_s | 86,400 | 2,592,000 | 1,209,600 (14 days) | s | [Decided 23 Oct 2026, E-10 (3A)] |
project_approvals | 3 | 9 | 3 | Heart members | [Decided 23 Oct 2026, E-1: at least 3, a circle may require more] |
close_notice_s | 86,400 | 2,592,000 | 259,200 (72 h) | s | [Decided 16 Oct, 8e]; a circle parameter [E-1] |
receive_lapse_s | 604,800 | 31,536,000 | 7,776,000 (90 days) | s | [Decided 16 Oct, 8e]; counted from project_open [Proposal]; a circle parameter [E-1] |
open_lapse_s | 604,800 | 31,536,000 | 2,592,000 (30 days) | s | [Proposal] (today's 30-day rule for orders); a circle parameter [E-1] |
change_notice_s | 86,400 | 2,592,000 | 259,200 (72 h) | s | [Decided 23 Oct 2026, E-1: 72 h is a default, not fixed]; the notice of a change of the circle key, the witnesses, the Heart members, k, the relays and the parameters, and of a resignation |
xcheck_s | 86,400 | 2,592,000 | 604,800 (7 days) | s | [Decided 16 Oct, 8j]; a circle parameter [E-1] |
quote_ttl_s | 300 | 3,600 | 600 (10 min) | s | [Decided 16 Oct, start rate source]; a circle parameter [E-1] |
note_ttl_s | 60 | 3,600 | 600 (10 min) | s | [Decided] (the note rule); a circle parameter [E-1] |
act_ttl_s | 86,400 | 2,592,000 | 604,800 (7 days) | s | [Decided 17 Oct, C3]; a circle parameter [E-1] |
rej_per_author_per_day | 1 | 1,000 | 20 | refusals | [Decided 17 Oct, C3]; a circle parameter [E-1] |
exclusion_s | 86,400 | 31,536,000 | 7,776,000 (90 days) | s | [Decided 23 Oct 2026, E-3: 3 months]; 90 days, and that it is a parameter [Proposal] |
invite_ttl_s | 3,600 | 2,592,000 | 604,800 (7 days) | s | [Decided 23 Oct 2026, E-6: invitations]; 7 days and one-time [Proposal: the decision itself marks them as a proposal] |
invite_only | 0 | 1 | 0 | 0/1 | [Decided 23 Oct 2026, E-6]; 0 in the found act (a found act with 1 is bad_template: no member exists yet to invite the first one) [Clarification, review of round 5, 23 Oct 2026] |
max_members | 0 | 999,999,999 | 0 (no limit) | members | [Decided 23 Oct 2026, E-6]; 0 = no limit [Proposal] |
The bounds and the order are [Proposal]. A circle with fewer Heart members who may vote "for" on a project than project_approvals passes no project; its start stays in the reserve (said openly).
Changing parameters [Decided 23 Oct 2026, E-1: the Heart changes them within the bounds; the shape: Proposal]: param_propose is a Heart act in the endorsement form (k Heart members in office; the first act carries the full new set, endorsements name it). At most one is open at a time (a second proposing act: 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; g3|param:* 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]: it waits while a missed morning whose boundary is at or before the notice end has not opened yet (catch-up after an outage) and while a duty due before the notice end is due at the block; those mornings and duties come first, under the old parameters (ledger document §3.1 rule 11, §7.4). Said openly: after an outage a change can take 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 [Decided 17 Oct, C1, and 23 Oct 2026, E-1: never retroactive; recording the due time: Proposal]: each is recorded as a due time when it starts: 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. A member's cap stays when wave_cap changes. Example: a project opened under a 90-day receive lapse keeps 90 days even if the Heart later sets 30.
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 [Proposal; checked value by value; the canonical text is the ledger document]:
note_ttl_s: the payer's circle at thexout, the receiving circle at thexin. If the receiving circle's value is smaller, it refuses the note (rejwithsrc:bad_template); the payer's circle booksxundo(refused) and the payer gets the held amount back. Sum 0 in both circles. The app signs with the smaller of the two values.quote_ttl_s: the quote belongs to the receiving (selling) circle; both circles judge it by that circle's own value: the receiving circle by its parameters in force, the payer's circle by the value it reads in the receiving circle's ledger (as it reads its node and rate source). If the payer's circle read an older value: either it refuses (nothing moves) or the receiving circle refuses at thexin(rejwithsrc) and the payer's circle returns the hold (xundo, refused).xcheck_s: only the payer's circle uses it, for its own holds (recorded at thexout). A short wait can only find the evidence incomplete (the receiving circle's seals do not yet pass the note'sexpires): nothing is booked and the check repeats; it never returns early.- So a mismatch can only end in a refusal and a return to the payer; nothing is lost and both sums stay 0.
The notice of Heart changes is change_notice_s (72 h by default), no longer fixed at 259,200 s [Decided 23 Oct 2026, E-1; this changes C5's "fixed 72 h"]. A shortening of change_notice_s itself takes effect only after the old notice (above), so a stolen key can never skip the warning in force; said openly, a Heart that lowers change_notice_s to its minimum (one day, a proposed bound) also shortens its own protection against a stolen key from then on.
Rules (checked by every witness)#
| Change | Rule | Status |
|---|---|---|
| Project: the vote | project_propose (any member; duration with vote_min_s ≤ duration ≤ vote_max_s of the parameters in force at its booking, else not_allowed) booked → vote end = the at of its entry + duration, recorded and never changed → the recipient's project_consent (today's rule; implied when the proposer is the recipient [clarification, 19 Oct 2026 (D3 review)]) → any member books vote "for" or "against" (an "against" with its short public reason) at at < vote end (else vote_ended); one vote per member per proposal, the newest counts, changeable until the end, the same choice again is repeated (line o3|vote|<proposal id>|<voter>|<for or against>|<vote act id>) → at the vote end, a duty: the newest votes are counted with the roles at that moment: the project passes only if no member (status member) has "against" as the newest vote and at least project_approvals (3 by default) Heart members in office have "for", the proposer's and the recipient's "for" not counted toward that number → rule vote_pass (status passed) or vote_fall (status fell, final; it may be proposed again, changed), its vote lines go → a project that passed opens (project_open, status receiving, followed at once by drain()) at the end of the entry after which its consent is given and, for a step raise, the step fits under built; projects that passed are re-checked in publication order at the end of every entry [clarification, 17 Oct 2026 (D1 review)]; not opened within open_lapse_s (30 days by default) → rule project_lapse; project_withdraw by the proposer before it opens, or the recipient's project_decline, ends it and its votes (withdrawn, declined); there is no project_reject, no objection and no status stopped; no maximum amount, no daily proposal limit and no limit on open proposals; project_approvals is that in force at the vote end, while the vote end and the open lapse are recorded when the project is booked, never retroactive | the vote "all for, or it falls", at least 3 Heart "for" and no "against", the duration set by the proposer at publication and never changed, at least 72 h by default [Decided 23 Oct 2026, E-5, confirmed; E-1]; nobody decides on their own project [Decided 16 Oct, Q4, Q8, 4a]; no limits for now [Decided 16 Oct, 8b]; the vote replaces approval after notice, the objection window and its stop (8c) and C4 [Decided 23 Oct 2026, E-5]; consent and recipient never decides (today's rule) [Proposal]; the 30-day lapse (today's rule) [Proposal]; counting with the roles at the vote end [Proposal] |
| Motion | motion by one Heart member in office (title, duration in the same bounds, text); voted like a project; at the vote end vote_pass or vote_fall by the same count (no member "against", at least project_approvals Heart "for"); its line goes, and the entry is the public decision | the Heart puts any proposal to a vote, and it falls if anyone is against [Decided 23 Oct 2026, E-5]; one Heart member, and the Heart "for" count for a motion [Proposal] |
| Project: receiving | every inflow moves to reserve, and drain() (below, and §3.9 of the ledger document) moves it on: rule reserve_move min(balance(reserve), amount − received) into each receiving project in order, until received = amount; a project wallet never exceeds its amount | [Decided 16 Oct, Q8] |
| Inflow routing | every inflow → reserve, then drain(); receiving projects in the order of their project_open entries, the oldest first | [Decided 16 Oct, Q8]; order [Decided 16 Oct, 8b]; no project → stays in the reserve [follows from Q8] |
| Project: payment | received = amount → rule project_full (status full), then in the same block rule project_pay: project wallet → recipient, the whole amount (status paid); the recipient's grow and settled move to the reserve and on by drain() (none when the recipient is world-step, which has no wave) | [Decided 16 Oct, 8a]; that this uses up no community money (below the recipient's cap) [Decided 16 Oct, 8f] |
| Project: closing and lapse | rule project_return: the project wallet's whole balance → reserve in one move (none when the wallet held 0 [proposal (D3 review, 19 Oct 2026)]), then drain(); (a) on the Heart's project_close after close_notice_s (72 h by default, recorded at the k-th close as the close due [clarification, 17 Oct 2026 (D1 review)]) of public notice (status closed); 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)]; (b) when receive_lapse_s (90 days by default, by block at, recorded at the opening [clarification, 17 Oct 2026 (D1 review)]) have passed since its project_open entry and received < amount: rule project_lapse, then the return (status lapsed). (c) also (status closed) when the recipient books project_decline or leave, or is excluded, while it receives (a recipient of several receiving projects who leaves gives one project_return per project, each followed by its own drain() [clarification, 17 Oct 2026 (D1 review)]), the proposer books project_withdraw while it receives, or project_pay falls due but the recipient is no longer a member | (a), (b) [Decided 16 Oct, 8e]; the periods circle parameters [Decided 23 Oct 2026, E-1]; counting the 90 days from project_open [Proposal; the project owner: "in 90 days"]; k = 3 for project_close [Proposal]; (c) [Proposal, not covered by 8e; an exclusion: Proposal] |
| Step outward | raise s: a project whose recipient is world-step, with every project rule above (the vote included) except the recipient's consent (world-step has no key) [Proposal]; at project_pay the wallet moves into world-step with no wave growth and no counter-booking (so this project really uses up community money); checked step + s ≤ built at project_open and at project_pay, where built = Σ (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 (a closed line holds 0) [clarification, 17 Oct 2026 (D1 review)]; lower s: step_propose (negative amount) → decided by a vote like a project (the builder does not book it in 0.3.0: no complete rule) → rule step_lower: world-step → reserve, then drain(), only if step − s ≥ max(0, world_used) | public decision like a project, never above what was built [Decided 15 Oct]; a raise is a project [Decided 16 Oct, 8j]; decided by the vote [Decided 23 Oct 2026, E-5]; the formula and check of built [Proposal]; the lowering, never below what is used, and its acts [Proposal]; step_approve is gone; [Open] what happens if step + s > built when the raise project is full; [Open] an account_close lowers built (its close_wave leaves the circle), so the step may then stand above built |
| Cross-circle payment that hangs | B may book the note only in a block whose at ≤ the note's expires (at most note_ttl_s, 10 minutes by default, after signing; each circle applies its own note_ttl_s to its side, "Circle parameters" above; ledger document §3.3). xcheck_s (7 days by default, A's parameter, recorded at A's xout) after A's xout, with neither B's xin nor B's signed refusal or "expired" seen, every signer of A reads B's log from B's relays (B's signer set from B's log, cached ≤ 24 h): (a) no B block in the range of B's consecutive seals as [day, digest] and the height range they cover: from the 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) books or refuses that note id → xundo by rule: world → payer, the held amount, naming those seals and the range as evidence, plus the real seal before them (before, checked against B's chain: B's quorum, and it chains to the first seal exactly as that seal's prev describes; without it nothing is booked) [the evidence rule: Proposal]; 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. B's office is taken from B's ledger (the office below the lowest block read, then each roles entry in the blocks read, in office from the next height), and each seal is judged with the office after its h_to (the newest mirror at or below it); a block counts only with a valid quorum of B's witnesses in office at its height: a block or seal copy without one (for example one signed only by old, retired or stolen keys that are no quorum of the witnesses in office at that height) is not B's, never counts and never hides a copy that has one, and two blocks with valid quorums at one height are a fork, so the evidence is not used; 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, but 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 [Proposal]. 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 block or seal that is not given leaves the evidence unverifiable, so nothing is booked; a B that stops sealing keeps the hold waiting. (b) a B block books it with exactly to_amount → xdone by rule, naming B's block as [height, digest]; every leg names B's genesis digest (g); (c) B's log cannot be read in full, or its seals do not yet cover that time → nothing is booked, the amount stays held and the check repeats; never a guess, and A's other bookings go on. The check becomes a due entry only once the node has read the evidence; a witness refuses an xdone or xundo it cannot verify itself, and a node that keeps leaving out a check its witnesses can verify is replaced. A reversal, never a receipt: no wave change, no counter-booking. Nobody pays anything: there is no xrefund and no source account | [Decided 16 Oct, 8j], replaces the 7-day refund by public decision [Decided 10/15 Oct]; the check repeating every day after the morning [Proposal]; the 7 days and the 10 minutes are circle parameters (xcheck_s, note_ttl_s), each circle applying its own to its side [Decided 23 Oct 2026, E-1; across circles: Proposal]; the 60 s margin is the fixed constant XCHECK_MARGIN_S [Proposal] |
| Parameters | param_propose (the full new set of every circle parameter, each in its range; vote_min_s ≤ vote_max_s < open_lapse_s) by k Heart members in the endorsement form; at most one open; notice end = the k-th act's at + max(change_notice_s, the old value of every changed parameter in seconds); at the notice end the duty params_effective (the first block whose first at reaches it starts with it, after the morning header; from that entry on the block is under the new parameters; g3|param:* and g3|params_h change); void when fewer than k of its signers are in office then ("Circle parameters" above). The time values, the daily refusal limit and the number of Heart "for" votes a project needs are circle parameters, no longer world rule values [Decided 23 Oct 2026, E-1]; the time zone, the morning hour and tzdata are fixed at founding and do not change in 0.3.0 (no act or parameter changes them; a later definitions version may say how a circle follows new clock rules) [Decided 17 Oct, C7; the tzdata part confirmed: Decided 17 Oct (evening), 2A]; the morning header's tzdata is the version the circle pinned at founding [the check: Proposal], and a witness computes the boundary with that version, never with a newer one of its own [Decided 17 Oct (evening), 2A]; a witness without that version signs no morning block and no seal [Proposal]. w_max_s bounds every block: a block closes at the latest w_max_s after its first entry, so its at span is at most w_max_s (a check without the parameter lines uses 10 s, the top of the parameter's range) [consequence of the closing rule; the check: Proposal], so no block can hold a whole vote or notice | the Heart changes every parameter within its bounds [Decided 23 Oct 2026, E-1]; k = 3 of 4 [Proposal]; the notice end, the duty and the shape [Proposal]; param_approve, param_object and the objection threshold are gone |
| Rate source | rate_source_set (any source id with a public description), a proposing act and endorsements of it, together from at least k distinct current Heart members (the proposer counts), committed by the current quorum in a roles entry like every Heart change, with no notice ("Heart changes" below); its mirror replaces rate_source with the act's, and a quote takes the source of the newest mirror booked at or before its created_at (docs/knjiga-na-relejih.md §4.5) [clarification, 17 Oct 2026 (D4 review)]; the quote validity is the receiving circle's parameter quote_ttl_s (600 s by default) [Decided 23 Oct 2026, E-1]; quotes and their checks as in "Currencies and exchange rates" | the circle chooses its source itself; no definitions gate a source [Decided 16 Oct, Q7]; start source the ECB daily reference rate, its date shown in the app, quote validity 600 s [Decided 16 Oct, start rate source]; changed by k Heart members at any time, rate_stale_alert 120 h [Proposal] |
Circle Heart (steward) | live circle: the founder and three other Heart members, entered at I1; the founder seats the first Heart in the found act (steward tags); members never vote on the Heart: steward_nominate and steward_vote are removed; the Heart changes only by Heart changes and a Heart member's own resignation: steward_add (the new Heart member's steward_accept gives the consent), steward_remove and stewards_required_set (k, within its 30910 bound), each by k Heart members with change_notice_s (72 h by default) of notice and a roles entry, and steward_resign, by the Heart member alone at any time, committed change_notice_s later as a duty ("Heart changes" below; the mirrors: "The mirror a roles entry carries" below); an excluded Heart member first loses the seat by a roles entry ("Exclusion and readmission" below); a readmitted former Heart member is a member only | names, m = 4 [Decided 16 Oct, Q4, 4a]; the name Circle Heart, no election, the Heart adds and removes Heart members [Decided 23 Oct 2026, E-2]; k = 3 [Proposal, stays]; at least project_approvals (≥ 3) Heart "for" on a project [Decided 23 Oct 2026, E-1, E-5]; k for the circle key: three of four [Decided 17 Oct, C5]; the seat lost first, and readmission as a member only [Decided 23 Oct 2026, E-3]; the founder seats the first Heart [Proposal]; adding and removing, setting k and the resignation as a duty [proposal (D4 review, round 3, 17 Oct 2026)] |
| Signer set, relays | Who the witnesses are: by lot among the circles' computers, the direction for phase I (no code in 0.3.0); until enough circles exist, one witness, the circle's own computer, publicly labelled; the Heart's vote only for exceptions [Decided 23 Oct 2026, E-7]. The exceptions: signer_propose (a proposing act and endorsements of it, together from at least k distinct current Heart members (the proposer counts), see "Heart changes" below) + the new signer's signer_accept → change_notice_s (72 h by default) public notice from the k-th act → committed by the current quorum in a roles entry within its commit window ("Heart changes" below), carrying the mirror described under "The mirror a roles entry carries" below (a new witness is in office from the next height), and no Heart "against": any Heart member in office may book a vote naming the change, and its roles entry is refused (answered not_allowed) while a Heart member in office has "against" as the newest vote; refused if it gives one operator two signers. The same way, while the other witnesses can still book: signer_remove retires a current witness (a box that is gone, a witness that signed two blocks at one height; at least one witness stays), and signer_replace retires one and adds a new one in one change, the number of witnesses staying (it needs the new witness's signer_accept); a witness may also resign alone (signer_resign, a duty change_notice_s later, "Heart changes" below). relay_change goes by k Heart members the same way, without the "against" rule; a new relay is listed only after back-fill of the whole history, verified by heights and seal roots | one per operator [Decided 16 Oct, Q3]; by lot, one witness until then, the Heart's vote only for exceptions with "for" and no Heart "against" [Decided 23 Oct 2026, E-7], by at least three Heart members, the larger of k and 3 [Decided 23 Oct 2026, E-10]; the notice a parameter [Decided 23 Oct 2026, E-1]; procedure [Proposal]; signer_remove, signer_replace and the resignation as a duty [proposal (D4 review, round 3, 17 Oct 2026)] |
| Circle key | circle_key_change: a proposing act naming the new key (key) with the new key's proof of possession (pop, bound to the act's created_at; exact form under "The circle key and the 30910 mirror" below) and endorsements of it, together from at least k distinct current Heart members (the proposer counts; see "Heart changes" below) → change_notice_s (72 h by default) public notice from the k-th act → committed by the current quorum, within the commit window ("Heart changes" below), in a roles entry whose mirror carries the new key (a block books at most one roles entry [Proposal]); the new key is in office from the next block (the circle_key governance line, with its since_h); a roles entry changes the circle key only when its proposing act is circle_key_change, and then to exactly the key it names; refused when the pop does not verify (bad_template) or the key is the one in office; afterwards only the new key signs the 30910, already the one whose mirror_of is the change's own height (that mirror names the new key), and a 30910 by the old key with a mirror_of at or above the change never counts; the circle id never changes; a stolen and a lost key are replaced the same way | k Heart members (three of four in the live circle), public notice, booked by the witnesses [Decided 17 Oct, C5]; the notice a circle parameter, 72 h by default [Decided 23 Oct 2026, E-1]; the proof of possession, the act shape, in office from the next block, and the rule that the circle key is never the founder's, a witness's or a Heart member's key and never the key already in office [Proposal] |
| Proposer swap | within the signer set: k Heart members + current quorum; no notice (who validates does not change) | [Proposal]; later rotation [Proposal, from the text of Q3] |
| Refusal list | refusal_list_set by k Heart members, committed by the current quorum in a roles entry like every Heart change, with no notice ("Heart changes" below); its mirror changes only mirror_of, and the state's g3|refuse:<circle id> lines become exactly its list [clarification, 17 Oct 2026 (D4 review)] | [Proposal]; notice: none in the definitions, whether it needs one [Open] |
| Recovery | fewer than q signers survive: the recovery of the larger of k and 3 Heart members [E-10] + change_notice_s (72 h by default) notice, with no Heart "against" (as for a witness change); void if any quorum-valid block above the named height appears during the notice; restart at the highest height found on any relay or archive; while q survive, the witnesses change by signer_remove, signer_replace and signer_propose instead ("Signer set, relays" above) [proposal (D4 review, round 3, 17 Oct 2026)] | [Proposal]; k "for" and no Heart "against" [Decided 23 Oct 2026, E-7]; the notice a parameter [Decided 23 Oct 2026, E-1] |
| Definitions version | pinned in found and in the governance lines; no act and no parameter changes it in 0.3.0 (param_propose carries only the circle parameters; how a circle moves to a later definitions version is not defined yet) | [Proposal Q20] |
| Joining | join judged in the reasons' order: a member or frozen key: repeated; a key whose exclusion runs: not_allowed; an open o3|join of the key: repeated; a named invite that is not open: not_found, of another key: not_allowed; invite_only = 1 and no invite (not an excluded key's application): not_allowed; a key whose newest member home (30916, read on the root relays) names another circle without a valid reference from that circle: not_allowed; a join that brings a step while this key's own reference from this circle still waits for the return of its wave: not_allowed [Decided 23 Oct 2026, E-11: A → B → A]. Then: an excluded key (period over) → o3|join|<id>|<key>|heart|<act expires>|<seq> (only member_readmit admits it); a free place (max_members = 0, or members with status member or frozen < max_members) → member_join at once (with a reference also ref, src, g); otherwise the waiting list o3|join|<id>|<key>|waiting||<seq> (no expiry). When a place frees (a leave, an exclusion, a close, a parameter change), at the end of every entry (after drain(), the openings and the closes) the first on the list (lowest seq) is admitted by rule (member_join, in: [its join act]) while a place is free. An applicant's own leave withdraws its o3|join (no member_leave). invite books o3|invite|<invite id>|<key>|<inviter>|<until>, until = at + invite_ttl_s; a join that uses it ends it | open / invite only / a maximum with a waiting list, the first on the list by rule, an excluded key never from the list [Decided 23 Oct 2026, E-6]; from another circle only with the last circle's reference [Decided 23 Oct 2026, E-9]; the order of checks, the lines and the one-time invitation [Proposal] |
| Exclusion and readmission | member_exclude by the larger of k and 3 Heart members in office [E-10], no notice (the excluded key never counts toward its own exclusion; the named key must have 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 above it; at least one Heart member stays; if the block already holds a roles entry, the k-th act waits for the next block, answered 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). An excluded line is frozen inside the circle (no pay, no give, no vote, no proposal; it receives nothing but a settlement); every morning still visits its plus; it may send its plus to another circle (xout, amount ≤ max(0, balance), never the wave); the minus stays. After until (the line ends at the first block whose first at is later) its join goes to o3|join … heart; member_readmit (["e", <join act id>, "", "join"]) by the larger of k and 3 Heart members [E-10] admits it (member_join, in: [join act id]), refused not_allowed when no place is free; membership only, never a Heart seat | the Heart excludes any member, a Heart member too, at once, for 3 months, then the Heart decides on readmission, as a member only; the money rules [Decided 23 Oct 2026, E-3]; never from the waiting list [Decided 23 Oct 2026, E-6]; the reason, the order inside the block and the projects' end [Proposal]; the threshold of an exclusion and a readmission, the larger of k and 3 [Decided 23 Oct 2026, E-10] |
| Reference | a leave of a member (member_leave, status left) or of an excluded key (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, own = its open OWN processes) and its line goes; the conditions: balance ≥ 0, and never an open OWN process together with a minus; and no open OWN process at all [Decided 23 Oct 2026, E-9 (a); so the design's isolated rule REFERENCE_OWN_BLOCKS is always true]. A leaving line also ends when its key joins again here or its account is closed (an account_close never gives a reference). The node signs the 43921 right after the block with the entry has its quorum ("The reference, KIND 43921" below) | issued by itself after "I want to leave" when the conditions hold, else not; no minus; an open OWN process with a minus blocks it; nobody moves without it [Decided 23 Oct 2026, E-9]; an open OWN process blocks it also without a minus [Decided 23 Oct 2026, E-9 (a)]; issued later when the conditions come to hold, and the mechanics [Proposal] |
| Settlement | 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 | anyone may settle a debt, payments into the account, never above 0, also while excluded [Decided 23 Oct 2026, E-9]; the shape [Proposal] |
| Leaving with a plus | a key that left (also to move) may send its plus to another circle like an excluded key (xout, ≤ max(0, balance), never the wave) | [Proposal: so a person who moves takes the plus along] |
| Closing an old account | account_close by max(k, 3) Heart members [E-10], no notice (["p", <HEX>]; text required: a short public reason, since the ledger cannot see a death; it waits while a leg of the account to another circle is held) [Proposal]; the line must have status member, frozen, left or excluded and not be a Heart member in office (not_allowed); at the k-th act a member or frozen line first gets member_leave (in: [the proposing act]; never a reference); then o3|close|<hex>|<act id>|<seq> waits; at the end of every entry (after drain() and the openings, before the waiting list) each waiting close, in booking order, completes when its grav entry of the open morning is not pending, balance ≤ 0 and reserve ≥ −balance + wave: 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 line goes. A plus waits for gravity (or is sent away first). Never urgent; nothing breaks if an account stays. Invariants: origin = −start + Σ close_wave (the state's returned); Σ waves = grown − returned. A closed key that joins again starts at 0 (status member, cap = wave_cap) | the Heart closes old accounts; a plus waits for gravity; at 0 the wave returns to origin; never urgent [Decided 23 Oct 2026, E-3, confirmed]; a minus is covered only when the member has died [Decided 23 Oct 2026, the E-3 addition]: the ledger cannot see a death, so covering a minus is the Heart's public responsibility when it signs a close of a line below 0 [Consequence]; k and the mechanics [Proposal] |
| OWN process | own_open by any member, alone and at once [Decided 23 Oct 2026, E-10], books o3|own|<own_open id>|<hex>; own_close by one Heart member in office ends it; nothing of the process's content enters the ledger | the Heart leads and oversees OWN; only decisions reach the ledger [Decided 23 Oct 2026, E-4]; the record [Consequence of E-9; Proposal] |
| Founding | the found act names ["parent", <parent circle id>, <parent genesis digest>] after start and the founder's reference ["e", <43921 id>, "", "reference"] right after it, both required except for the root (the live circle; meta.root_circle); the 30910 mirror carries ["parent", …] after founder; 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; whether 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 | only a member of an existing circle founds; every circle grows from the first one; one circle per founder key, ever; one circle per person at a time; this replaces "at most three circles per founder" [Decided 23 Oct 2026, E-8]; the founder's reference [Consequence of E-8 and E-9]; the tags, the root and the relay mechanism [Proposal; details phase G] |
Heart changes (changes by k Heart members; formerly called "k-steward changes") [Proposal; k distinct Heart members: ruling of 16 Oct 2026; the circle key by k Heart members with notice: Decided 17 Oct, C5; the notice a circle parameter, 72 h by default: Decided 23 Oct 2026, E-1]: 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, member_exclude, member_readmit, account_close and own_open are one Heart member's proposing act plus endorsements (signer_remove, signer_replace, steward_add, steward_remove and stewards_required_set: proposal (D4 review, round 3, 17 Oct 2026); param_propose: Decided 23 Oct 2026, E-1, the shape a proposal; member_exclude, member_readmit and account_close: Decided 23 Oct 2026, E-3, the shape a proposal; own_open: a proposal after E-4 and E-9): 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's o3|change line ("Decision state for governance" below) lists the Heart members who signed it; the change commits only with at least k distinct Heart members among them ("Who is in office at a height" below), and only after the notice of its type (change_notice_s, 72 h by default, for signer_propose, signer_remove, signer_replace, steward_add, steward_remove, stewards_required_set, relay_change, recovery and circle_key_change [Decided 23 Oct 2026, E-1; formerly fixed at 259,200 s by C5]; for param_propose max(change_notice_s, the old value of every changed parameter in seconds), so a stolen key cannot skip the warning in force [Proposal]; none for proposer_swap, rate_source_set and refusal_list_set, and none for member_exclude, member_readmit, account_close and own_open, which take effect at the k-th act [Decided 23 Oct 2026, E-3; own_open: Proposal]; close_notice_s for project_close) from the k-th act: the act with which k of the listed Heart members in office (for that block) were reached, from its at, never from the last listed act; endorsements booked later never move the notice [clarification, 17 Oct 2026 (D4 review)]; each act is used once. A witness change (signer_propose, signer_replace, signer_remove) and a recovery also need no "against": any Heart member in office may book a vote naming the change, and its roles entry is refused (answered not_allowed) while a Heart member in office has "against" as the newest vote [Decided 23 Oct 2026, E-7; the shape: Proposal]. The roles entry that commits a change names exactly [the proposing act id] as its acts (for a resignation, [the resign act id]); the Heart members who signed are in the o3|change line, not in the entry; a project_close is committed by its project_return, with in = [project id, the proposing project_close id] [proposal (D4 review, round 3, 17 Oct 2026)]; a param_propose by its params_effective, a member_exclude by its member_exclude entry (after a roles entry when the key holds a Heart seat), a member_readmit by its member_join, an account_close by the entry that books its waiting close (and, for a member or frozen line, its member_leave), and an own_open at its k-th act by its o3|own line [Proposal]. A further endorsement by a Heart member the change already lists is refused repeated, and so is a second proposing project_close for a project that already has an open o3|change line (the Heart members endorse the open one) [clarification, 17 Oct 2026 (D4 review)] and a second proposing param_propose while one is open [Proposal]. Consent [proposal (D4 review, round 3, 17 Oct 2026)]: signer_propose and signer_replace need the new witness's signer_accept, and steward_add the new Heart member's steward_accept, naming the proposing act (Acts above); the accept sets the line's consent from waiting to yes, and the change commits only with yes; an accept by another key is refused not_allowed, a second one repeated. A Heart member who leaves the circle [Decided 23 Oct 2026, E-11]: right after the entries of its leave act (member_leave and what follows it) a roles entry with acts = [the leave act] takes the seat (the mirror without its steward tag, k lowered to the number left when above it); the last Heart member cannot leave (not_allowed); in a block that holds a roles entry already the leave is answered (roles_taken). Resignations [proposal (D4 review, round 3, 17 Oct 2026); the notice a circle parameter: Decided 23 Oct 2026, E-1]: a Heart member's steward_resign or a witness's signer_resign, signed by that person alone (no endorsement, no k), is a change of its own: its o3|change line is in notice from its booking, and change_notice_s (72 h by default) later its roles entry is due, a duty that witnesses refuse a block to leave out: it is booked in the first block whose first at reaches the notice end; due resignations go one per block, the earliest notice end first, then by act id, before any other roles entry (in one second after the other duties: ledger document §7.4); the last Heart member or witness cannot resign (refused not_allowed); a due resignation that can no longer take effect (the person was removed meanwhile, or it would leave no Heart member or witness, as when the last two resign together) is void: its line goes at that block without an entry, so a resignation never halts the circle; void resignations are dropped first, 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 (ledger document §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)]. Commit window [proposal (D4 review, 17 Oct 2026)]: the roles entry of a roles change other than a resignation is booked at an at from the notice end to the notice end + act_ttl_s in force at the k-th act; a change not committed by then lapses (its o3|change line ends, "Decision state for governance" below) and must be proposed again, so no change waits for ever. A block books at most one roles entry [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, so a height names one mirror at height 1 too [Proposal]. A roles mirror never changes the code, the circle id, the founder, the parent, the currency, the time zone (tz), the tzdata or the morning hour: they are written at founding [Proposal; follows from C7, E-8 and the one currency per circle]. 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 members (the steward tags) 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 is signed by a quorum of the witnesses in office at its height; a Heart member's act counts only if its author was a Heart member 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; a resignation's needs none). A reader that checks only part of the ledger takes the office from the mirror of the newest genesis or roles entry below its first height, read from the ledger, never from a circle record (a record can be older or newer than the part it checks); without that mirror the office is unverifiable, never assumed. It takes the circle parameters in force below the part the same way (the g3|param:* lines below it); without them the checks that depend on them are unverifiable, and so is what began before the part (an endorsement whose proposing act, a roles entry whose acts, an xdone or xundo whose hold, a project_open whose project, a vote_pass whose votes, or a refusal whose key's membership lies before it): never refused and never passed; a witness checks those against its own state below the part and never signs what it cannot verify. The part is judged block by block with the parameters in force for each block (a params_effective entry changes them from that entry on); each TTL is judged by the parameters in force at its booking [Proposal], and every running deadline by the due time recorded when it started [clarification, 17 Oct 2026 (D1 review); Decided 23 Oct 2026, E-1: never retroactive].
The mirror a roles entry carries [proposal (D4 review, 17 Oct 2026)]: the mirror in office with mirror_of = the roles entry's height h and exactly the change its proposing act names, nothing else. circle_key_change: circle_key = the act's key. relay_change: each relay or archive tag of the act, in act order: "add" appends ["relay", url, operator] after the last relay tag (["archive", url] after the last archive tag, or after the last relay tag when there is none); "remove" removes the tag with that URL; an add of a listed URL or a remove of an unlisted one makes the change impossible (it cannot commit and lapses). rate_source_set and refusal_list_set: as in their rows above. proposer_swap: proposer = [the act's key, h + 1]; the key must be a current witness. signer_propose: needs the named witness's signer_accept (its consent, "Heart changes" above) booked before the roles entry; appends ["signer", hex, operator, h + 1, ""] after the last signer tag; quorum = [floor(2n/3) + 1, n] for the n current witnesses after it. recovery: every current witness the act does not name gets until_h = h + 1; every named key that is not current is appended [hex, operator, h + 1, ""]; quorum = the act's [q, n], which must match (n = the number of current witnesses after the change); if the proposer in office is not named, the first named witness becomes proposer from h + 1. [proposal (D4 review, round 3, 17 Oct 2026)] signer_remove and signer_resign: the witness (the act's p, or the resigning author) gets until_h = h + 1, quorum is recomputed ([floor(2n/3) + 1, n] for the n witnesses left; at least one stays), and if it is the proposer, proposer = [the first witness left in mirror order, h + 1]. signer_replace (with its consent): the old witness (p) gets until_h = h + 1, the new one is appended ["signer", hex, operator, h + 1, ""] after the last signer tag, quorum stays as it is (n is unchanged) [proposal (D3 review, 19 Oct 2026)], and if the old one was the proposer, proposer = [the new one, h + 1]. steward_add (with its consent): ["steward", hex] after the last steward tag (after the proposer tag when there is none); k stays. steward_remove and steward_resign: the steward tag goes (at least one Heart member stays), and stewards_required becomes the number of Heart members left when it is above it; the same when a member_exclude first removes the seat of a Heart member [Decided 23 Oct 2026, E-3; the mirror: Proposal]. stewards_required_set: stewards_required = the act's k. There are no election acts: steward_nominate and steward_vote are removed [Decided 23 Oct 2026, E-2]; an accept act (signer_accept, steward_accept) only gives its change the consent. A resulting mirror that breaks a 30910 rule (relays, operators, quorum, the bound on k: "The circle key and the 30910 mirror" below) cannot commit.
Inflow and drain() (the canonical text is §3.9 of docs/knjiga-na-relejih.md; the rule below must stay identical to it):
- Inflows, each one move into
reserveinside the entry that produces it (onesteprow per receipt, as today with Common Good renamed): thegrowandsettledof every receipt (pay,xin,project_payto a member); everygravdeduct; the part of a namedgiveabove the project's room, and a whole unnamedgive[Open 8g]; a step lowering. Each is a move between two accounts, so the circle's sum stays 0 after every block [Decided 16 Oct, Q8, 8f]. There is nodep[Decided 16 Oct, 6a] and no latexundoafter a refund, since there is no refund [Decided 16 Oct, 8j]. drain(), at the end of every entry [clarification, 17 Oct 2026 (D1 review)]: not only after an entry that moved money into the reserve or booked aproject_open, since agivethat exactly fills a named project moves nothing into the reserve and the full project must still be paid (agraventry in a morning block included; the deducts ofgraventries booked as visits are drained at the end of the entry they precede), also in payment blocks during the morning; a member who leaves while the recipient of several receiving projects gives oneproject_returnper project, each followed by its owndrain(), as every inflow is [clarification, 17 Oct 2026 (D1 review)]; identically by every signer:
repeat
for P in receiving projects, ordered by (height, seq) of their project_open entry [Decided 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 [Decided 8a]
the recipient's grow, then settled (read after the receipt and the grow move), recipient → reserve
(nothing when recipient(P) = world-step); a pending grav entry of the recipient is booked
first, right before project_pay (visit before touch)
restart the for-loop from the first project
until balance(reserve) = 0 or no receiving project has room
- It ends: each pass empties the reserve or pays a project, and a project pays at most once. Invariant checked by every signer: after every entry except a
graventry booked as a visit,balance(reserve) > 0only if no receiving project has room. So the reserve holds money only while no project can receive. - Morning (visit before touch [Decided 17 Oct, C2; the canonical text is §7.4 of the ledger document]): payments never pause for the morning. Each account's gravity is computed from the cut-off state (after the last entry before the boundary); after the boundary, before any entry touches an account whose
graventry is still pending, thatgraventry is booked first, right before the touching entry; only money entries touch an account (a move from or to it:pay,give,xout,xin,xundo,grav,project_payto a member, an entry that returns money), while an act entry, which has no party and no move, and a rule entry that only names a party touch none [clarification, 17 Oct 2026 (D1 review)]; morning blocks book the rest in HEX order. Everygravdeduct moves to the reserve anddrain()runs as after any inflow, so the order the node books payments in never changes anyone's gravity. - Several
project_opendue in one block: projects that passed are re-checked in publication order at the end of every entry; projects that become openable at the end of the same entry (by an act, at a vote end, or without an act, for example a step raise that now fits underbuiltor a change of the circle parameters) open in publication order (project_proposeseq) [clarification, 17 Oct 2026 (D1 review)]; each followed at once bydrain(). A cascade that would pass 100,000 bytes closes the block after its last whole step; the next block, at the sameat, starts with the remaining steps exactly as they would have come (the block split, ledger document §3.5) [completed 24 Oct 2026, plan step E4x]. - No project limits [Decided 16 Oct, 8b: "no limits for now"]: no maximum amount per project, no daily proposal limit and no limit on open proposals per member; today's
SUPPORT_MAX_AMOUNT(100,000) and the order limits do not carry over. The per-author spam limits on acts and refusals (F18) are not project limits and stay. - Heart members who are the proposer or the recipient of a project do not count toward its Heart "for" votes. With m = 4 and
project_approvals= 3 such a project can still pass with the other three [Decided 16 Oct, 4a; the vote: Decided 23 Oct 2026, E-5]. In a circle with fewer eligible Heart members thanproject_approvals(a circle parameter, never below 3 [Decided 23 Oct 2026, E-1]) no project can pass, so every inflow and the start stay in the reserve (said openly). [Open] how many signatures count for other Heart acts while m < k. - The start [Decided 16 Oct, 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
genesisentry, oneruleentrystart:origin→reserve,"100000"minor units (1,000.00; EUR, USD and GBP all have two decimals), thendrain()(no project receives at genesis, so the start stays in the reserve).origin(SL »izvor«) is a keyless system account, derived like the others (roleorigin, below under "System accounts: no key"); its line is −100000 from block 1 and moves again only byclose_wavewhen the Heart closes an old account [Decided 23 Oct 2026, E-3]; it is in every snapshot and every seal (["origin", balance]), 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 namesstartandorigin, the rule thatoriginmoves only bystartandclose_waveand the exact shape of the entry are a proposal for definitions 0.3.0 (plan C1). The live circle gets the same start in its block 1 (plan E6; proposal: 1,000 EUR ="100000"). The canonical text is §3.9 ofdocs/knjiga-na-relejih.md. - A project's image:
["img", sha256, url]inproject_propose; the file on three independent file servers, never in the event ([Proposal Q24]; relay event limit 131,072 bytes [C]). - A contribution is a member's 43910 booked as a
giveentry (it replacescg) with["e", <project_propose id>, "", "project"]naming a project in statusreceiving, or naming none; cover: the plus only,amount ≤ max(0, balance)(today's rule) [Open 8g]; the project is credited at mostamount − received, the rest goes to the reserve; an unnamed contribution goes to the reserve; thendrain()[Open 8g]. [Proposal] a contribution naming an open project in any other status is refused withrejreasonnot_receiving; one naming a project that has ended (itso3|projectline is gone) is refusednot_found[clarification, 19 Oct 2026 (D3 review)]. A project wallet has no wave, so a contribution makes no wave growth. - The recipient of a project is a member of the circle [Open 8h, proposal]; a relay operator who is not a member joins first. A
project_proposewhose recipient is not a member when it is booked (left, never joined or frozen) is refusednot_member[clarification, 19 Oct 2026 (D3 review)]. - Votes [Decided 23 Oct 2026, E-5; replaces Proposal Q21 on objections]: a
voteis signed by the voter and public with their HEX key; an "against" carries a short public reason; the app shows the name from KIND 0; the ledger never carries the name [Decided 16 Oct, Q5].
Decision state for governance#
Committed by the state root of every block and by each daily snapshot:
- 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:held_outis removed [Decided 16 Oct, Q6];paid_in(money paid in) is removed with deposits [Decided 16 Oct, 6a] (the line format in the ledger document must match);statusaddsexcludedandclosed[Decided 23 Oct 2026, E-3]; every morning visits every line with statusmember,frozen,excludedorleft, neverclosed[Consequence of E-3]; - governance lines
g3|<key>|<value>: the circle parameters (g3|param:<name>for every parameter of "Circle parameters" above, andg3|params_h, the height from which they apply) [Decided 23 Oct 2026, E-1; the shape: Proposal], signer set with operators, proposer, Heart members (steward) and k, relays, rate source, refusal list, definitions version, the parent circle (parent: circle id and genesis, only when the found act names one) [Decided 23 Oct 2026, E-8; the shape: Proposal] (no custodians and no L_att [Decided 16 Oct, 6a]); the circle key in office,g3|circle_key|<hex>|<since_h>, changed only by arolesentry whose proposing act iscircle_key_change, from the next block [Decided 17 Oct, C5; the shape and in office from the next block: Proposal]; the world rules lineg3|rulesis removed with 43920 [Decided 23 Oct 2026, E-1]; - open-item lines [what they track: Decided 23 Oct 2026, E-3, E-4, E-5, E-6, E-9; the shapes: Proposal; the canonical lines: knjiga-na-relejih.md §3.8]: 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 fields; statusproposed(voting),passed,receivingorfull; every running deadline recorded as a due time when it starts, never retroactive); motionso3|motion|id|voting|proposer|published_at|published_seq|vote_end(8); voteso3|vote|<proposal id>|<voter>|<for or against>|<vote act id>(6; the key is the first 4); open requests; cross-circle holdso3|hold|note|held|amount|payer|to circle|to genesis|note expires|xout at|check at|party(12; the check time recorded at thexout; party: a reference grant's newcomer, "" for a leg [E-11]; a grant ends only byxdoneor a refusedxundo, whichgrant_revokefollows [Decided 23 Oct 2026, E-11]); applicationso3|join|<join id>|<key>|<waiting or heart>|<expires, "" while waiting>|<booked seq>(7); invitationso3|invite|<invite id>|<key>|<inviter>|<until>(6); exclusionso3|exclude|<hex>|<until>|<act id>(5); waiting closeso3|close|<hex>|<act id>|<booked seq>(5); waiting referenceso3|leaving|<hex>|<leave act id>|<booked seq>(5); OWN processeso3|own|<own_open id>|<hex>(4); Heart changes being collected or under notice, and resignations under notice (o3|change, next item). Removed:o3|objection,o3|paramando3|step[Decided 23 Oct 2026, E-1, E-5]. No open deposits [Decided 16 Oct, 6a]. - the
o3|changeline [clarification, 17 Oct 2026 (D4 review), for the fields and the k-th act; proposal (D4 review, 17 Oct 2026), for the lapse and theprojectfield; proposal (D4 review, round 3, 17 Oct 2026), forconsent,booked hand the resignations]:o3|change|<proposing act id>|<collecting|notice>|<act type>|<stewards>|<expires>|<notice end or "">|<project or "">|<consent>|<booked h>, 11 fields. The proposing act id is, for a resignation, the resign act's id;stewards= the HEX keys of the proposing act's author and of every booked endorsement's author, sorted, joined by,(never a count; for a resignation the resigning key);project= theproject_proposeid aproject_closecloses,""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);consent=waitingforsigner_propose,signer_replaceandsteward_adduntil the named key's accept act is booked, thenyes, and""for every other type;booked h= the height of the block that booked the proposing (or resign) act, which a restorer reads for what the change names. One line for every Heart change ("Heart changes" above),project_close,param_propose,member_exclude,member_readmitandaccount_closeincluded [Decided 23 Oct 2026, E-1, E-3: the acts; the line: Proposal], created by the entry that books the proposing act; a booked endorsement adds its author. It turns tonoticeat the k-th act ("Heart changes" above): notice end = that act'sat+ the type's notice. A resignation's line (typesteward_resignorsigner_resign) is innoticefrom its booking, with notice end = itsat+change_notice_s(72 h by default) andexpires= that notice end, and stays until itsrolesentry (a duty).expires: while collecting, the proposing act's ownexpires; in notice, for a roles change other than a resignation the end of its commit window ("Heart changes" above), forproject_closeandparam_proposethe notice end (the return, orparams_effective, is a duty at the notice end); a change without notice (member_exclude,member_readmit,account_close) is committed at its k-th act and never turns tonotice. The line ends with the entry that commits the change (therolesentry; forproject_closetheproject_return), or at the first block whose firstatis later thanexpires(a change still collecting, or a roles change never committed); aproject_closeline 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); aparam_proposeline likewise ends void at its notice end when fewer than k of its signers are in office.
Restore from seal + tail must equal full replay, compared by the canonical state hash.
System accounts: no key [Decided 16 Oct, Q8 for project wallets and the reserve; 8i for world and world-step; 6c for origin]#
world,world-step,reserve,originand one wallet per project are x-only pointslift_x(sha256("lb-system/3|" + role + "|" + circle id + "|" + i))for the first decimalithat gives a valid point (from the circle id, never from a key, so they survive a change of the circle key [Decided 17 Oct, C5]), where role isworld,world-step,reserve,originorproject|+ the 64-hex id of theproject_proposeact (the wallet is writtenproject:<id>for display only; the test vector is fixed in plan C1). Nobody can sign for them. They have no wave, no cap, no gravity and no debt.- There is no
mainaccount. It stood only for money paid in (it booked deposits, their corrections and payouts; removed by plan step D0, 17 Oct 2026), and BSA has none of these [Decided 16 Oct, Q6, 6a]; so it is no longer needed. the project owner also confirmed it as keyless under 8i. common-goodno longer exists. [Open] migration of the live circle: proposal, today's Common Good balance opens as thereserveline in genesis and today's open orders are published again as projects.- They move only by entries the witnesses recompute:
start(origin→reserve, once, in block 1) [Decided 16 Oct, 6c; the name: Proposal]; inflows into the reserve;reserve_move(reserve→ project, bydrain());project_pay(project → recipient, or →world-stepfor a raise) [Decided 16 Oct, 8a, 8j];project_return(project →reserve) [Decided 16 Oct, 8e];world-step→reserveon a lowering [Proposal];xout(payer →world),xin(world→ member) andxundo(world→ payer, on B's refusal, "expired" or the 8j check) [Decided 16 Oct, 8j];account_close:close_cover(reserve→ the closed line, up to its minus) andclose_wave(reserve→origin, the closed line's wave) [Decided 23 Oct 2026, E-3, confirmed; the names: Proposal]. There is noxrefund, nodepand nocorr. A block that moves a system account any other way is refused by every witness. - The reserve and project wallets never go below 0 (as Common Good never did); a project wallet never exceeds its amount.
worldmay be negative, as before.originis −start from block 1 and moves only byclose_wave:origin= −start + Σclose_wave(the state'sreturned), and Σ waves = grown − returned [Decided 23 Oct 2026, E-3; the invariants: Proposal].originalso moves by the E-9 (b) grant:origin→reserve, the newcomer's wave [Decided 23 Oct 2026, E-9 (b); the entry: Proposal, §3.11 ofdocs/knjiga-na-relejih.md("Membership, exclusion, the reference and closing accounts")]. - Today's fund key loses its spending role; a 43910 authored by it is refused once the log is on. Circle relays are paid by a project [Proposal Q15].
The circle key and the 30910 mirror#
- [Decided 16 Oct] the circle key is kept by the app and the creator. [Proposal, follows from Q3 and Q8, not confirmed by the project owner] it signs only the 30910 v3 mirror and, once, the found act's binding in block 1 (
circle_sig) (supersedes the part of P2 in which it signed node and relay changes; P2's custody part, the founder's browser plus a paper copy, stays a proposal). [Decided 17 Oct, C5] it never names the circle, and k Heart members can replace it (below). - The circle id [Decided 17 Oct, C5; the tag shapes: Proposal]: a circle is named by its circle id, the NIP-01 event id of its signed
foundact (43916,t=found). 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 (the thief's found act has another id). The found act cannot carry its own id, so its first tag is["c", ""]; every other BSA event except the 30910 names its circle by["c", <circle id>](a payment note by["c", <payer circle id>, "", "from"]and, across circles,["c", <receiver circle id>, "", "to"]), and relays query#c; no BSA kind uses anatag.scope16= the first 16 hex characters of the circle id (h,mandikeep<scope16>:…); the keyless system accounts come from the circle id (above); the 30910 and the 30915 carry it asd, and the 30915 head is published at the offset (the first 4 bytes, big-endian, of sha256(the circle id as 64 hex characters)) mod 86,400 s after its seal. - 30910 v3 tags, in this order:
["d", <circle id>],code,name,currency,tz,["tzdata","2026a"],morning,["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>],["founder", <founder HEX>],["parent", <parent circle id>, <parent genesis digest>](only when the found act names one [Decided 23 Oct 2026, E-8; the shape: Proposal]),["circle_key", <HEX of the circle key the mirror puts in office>],["signer", hex, operator, since_h, until_h]× n (operators are names the circle declares itself),["quorum", q, n],["proposer", hex, since_h],["steward", hex]× m (the Heart members),["stewards_required", k](k is never above the number of Heart members and never below 2 while there are at least 2 [proposal (D4 review, round 3, 17 Oct 2026)]; afoundact that breaks it is refusedbad_template[proposal (D3 review, 19 Oct 2026)]),["relay", wss, operator]× ≥ 4 of ≥ 3 operators,["archive", wss]…, optional["bootstrap", "Q14"](open question 14, not decided),["rate_source", <source id>, <public description>],["api", https],["definitions","0.3.0"],["v","3"]. The record's author must be thecircle_keyit names.quote_ttlandproject_approvalsare not in the mirror: they are circle parameters, carried in the ledger's state (g3|param:*) [Decided 23 Oct 2026, E-1]. Therate_panelandrate_ruletags are removed [Decided 16 Oct, Q7]; thecustodiantag is removed [Decided 16 Oct, 6a]. No key for any system account. Canonical address:30910:<circle key in office>:<circle id>; it changes when the 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 orrolesentry). - Authority rule: a 30910 counts only if it is signed by the circle key that the ledger's mirror at its
mirror_ofnames (the mirror carried by the committed genesis orrolesentry at that height; at the height of a key change already the new key, which is in office for blocks only from the next height), its tags withoutgequal that mirror, and itsgis the pinned genesis; readers take the valid record with the highestmirror_of. When they differ, readers follow the log. The genesis mirror is a function of the signedfoundact. Said openly: anyone can publish a 30910 that names a circle id; it counts only when the ledger's mirror at itsmirror_ofnames its author. The circle key cannot re-pointg, which carries the founder's signature over the circle id and the genesis digest. Root relays keep the first-seengand founder per circle id (relay/ledger-write-policy.py, moderoot, which also checks the founder's signature over the circle id) [Proposal: they keep every circle'sfoundact (a 43916 whose first tag is["c", ""]and that has no otherctag, from any author: its id is the circle id, so nobody can make a false one; the plugin remembers at mostseen_ids_maxfound acts, and beyond it a newer circle's records are kept unpinned, never falsely pinned) and pin a circle id'sgand founder only when they hold that found act and the record'sfounderis its author (or, for a circle configured on the relay, when its configured circle key signed the record), otherwise they store the record unpinned (readers check it anyway), so nobody can claim a circle id first on a root relay; a pin is written only after every plugin of the relay accepted the record]; this first-seen rule is a request in the letter to the Lana relay owner (plan phase G) and, with the circle id, only extra safety [Decided 17 Oct, C6]. The root relays also keep the first found act per founder key and refuse a second circle record of the same founder: one circle per founder key, ever [Decided 23 Oct 2026, E-8; the mechanism: Proposal]. - Changing the circle key [Decided 17 Oct, C5: k Heart members (three of four in the live circle), public notice, booked by the witnesses; the notice
change_notice_s, 72 h by default: Decided 23 Oct 2026, E-1; the proof of possession, the act shape, in office from the next block and the rule that the circle key is never the founder's, a witness's or a Heart member's key: Proposal]: a current Heart member signscircle_key_change(group Roles, text optional) with["key", <new key HEX>]and["pop", <the new key's BIP-340 signature over sha256("lb-circle-key/3|" + circle id + "|" + new key HEX + "|" + created_at)>](the act'screated_atin decimal), a proof of possession, so nobody can name a key someone else holds; it binds the act's time, so a pop is good for its own act only: an act is booked only withinact_ttl_sof itscreated_at, so an old pop can never be used again [Proposal]. Further Heart members endorse it ("Heart changes" above); oncechange_notice_s(72 h by default) has passed since the k-th act, arolesentry booked by the current quorum within the commit window ("Heart changes" above) carries the new mirror (mirror_of= its height, naming the new key), and the new key is in office from the next block (g3|circle_key|<hex>|<since_h>). Arolesentry changes the circle key only when its proposing act iscircle_key_change, and then to exactly the key it names; a block books at most onerolesentry [Proposal], so a second one in the same block can never undo the change. From then on only the new key signs the 30910, already the one whosemirror_ofis the change's own height; a 30910 by the old key with amirror_ofat or above the change never counts. A relay that serves the circle moves the old key toretiredwith the rolecircle_keyand anuntil: a retired circle key counts only for an old 30910 up to itsuntil, never for a block, seal, chunk, head or quote [Proposal]. The circle id never changes, and with itscope16, every keyless account and the genesis stay. A stolen key and a lost key are replaced the same way. Apopthat does not verify is refused (bad_template). [Proposal] The new key is not the key in office, and the circle key is never the founder's, a witness's or a Heart member's key, checked in every mirror (genesis androles) and infoundandcircle_key_change. - The circle key in every seal [Proposal]: a day seal is judged with the office after its last block
h_to: the newest mirror at or belowh_to(the genesis mirror or the newestrolesentry's). Its witnesses sign the seal, and the seal names their set (signers) and that mirror's circle key (["circle_key", <hex>], aftersignersin the seal's tag order), as the state'sg3lines ath_todo; at the height of a key change that is already the new key, which also signs the 30910 of that height. The 30915 head copies it, so a reader of the root directory picks the right 30910 by that key in one more query. - Trust anchor [Decided 17 Oct, C5 and C6; the details: Proposal]: the circle id together with the genesis digest (the digest of block 1: the NIP-01 hash of the block without its
qstags, which does not change with the witnesses' signatures). The circle's link and QR carry the circle id, at least two relay hints and the genesis digest as an extra pin; every block carries the genesis digest. 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 firstgit saw for the circle id), and never follows anothergfor the circle id. - Founding [Decided 16 Oct, Q9; the circle id and the first circle key: Decided 17 Oct, C5;
tz, morning hour andtzdatafixed at founding: Decided 17 Oct, C7; every circle parameter in the found act: Decided 23 Oct 2026, E-1; the parent circle and one circle per founder key: Decided 23 Oct 2026, E-8; the founder's reference: Consequence of E-8 and E-9; the tag shapes: Proposal]: the founder signsfoundin the browser; its event id is the circle id. After["c", ""]and["t", "found"]its tags are, in this order:name,code,["circle_key", <hex>](the first circle key),currency,tz,tzdata,morning,signer…,quorum,proposer,steward… (the first Circle Heart),stewards_required,relay…,archive…,bootstrap?,rate_source,api,param… (every circle parameter, in the order of "Circle parameters" above),start,["parent", <parent circle id>, <parent genesis digest>]and right after it["e", <43921 id>, "", "reference"](the founder's reference from the parent; both required, except for the root circle, the live circle, which names neither),definitions; then the act's closing tags (after?,expires,idem?,v). The found act names no world rules version any more (43920 is retired) [Decided 23 Oct 2026, E-1].meta.root_circlenames the root's circle id (empty while a draft; the examples use circle A as the TEST root, and circle B names A) [Proposal]. It becomes block 1, and the ledger is public from it. Block 1'sgenesisentry embeds the found act (rebuilt with["c", ""]), the mirror it gives and the first circle key's signature oversha256("lb-found/3|" + found id)(circle_sig), which binds the founding to that key; the rule entrystartfollows. The 30910 names the founder (and the parent) and carries the founder's signature over the circle id and the genesis, so the directory can check A9. The creator's BSA ID from the circle's settings (ADMIN_PUBKEYS, see the new-circle document) is used once, to recognise the founder; afterwards it is not a live authority. The root directory lists a circle by an objective rule the relay policy checks: the founder in the 30889 list (kept by the Lana registrar, one body), the found act names a parent circle, and the root relays hold no earlier found act of the same founder (one circle per founder key, ever; this replaces "at most 3 circles per founder") [Decided 23 Oct 2026, E-8; the check: Proposal, details phase G], with a quota on borrowed relays; P3 is dropped. Whether the founder was a member of the parent when founding (the parent'smember_join, the founder's member home and the reference) is checked by the root directory and by readers [Proposal: details phase G]. An unlisted circle keeps working through its link and QR [Proposal Q10]. Said openly: one person with two keys is not prevented (that needs Lana's person check) [Decided 23 Oct 2026, E-8]. - The reference, KIND 43921 [a new kind: Decided 23 Oct 2026, E-9; the number 43921 (free in the BSA family) and the shape: Proposal]: a regular event; the node signs it right after the block that books the
referenceentry has its quorum, and publishes it on the circle's relays. Tags:["c", <circle id>],["p", <person HEX>],["block", "<height>", <block digest>](the block with the reference entry),["g", <genesis digest>],["currency", <code>],["wave", "<minor>"](the step the person built),["own", "<open OWN processes>"](always "0", since an open OWN process blocks the reference [Consequence of E-9 (a)]),["joined", "<unix>"]and["left", "<unix>"](the membership: theatof the newestmember_joinand of themember_leave),["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"](projects paid to the person, newest first),["v", "3"]; content: empty. 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. Verification by the new circle [Proposal]: thejoinnames the reference,["e", <43921 id>, "", "reference"]; the new circle's node checks that itscis the circle the key's newest member home (30916) names (the last circle), itspis the key, and the named block of that circle carries thereferenceentry 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); themember_joinentry then names it:{rule: "member_join", in: [join id], party, ref: <43921 id>, src: [height, digest], g: <that circle's genesis>}. A key with no member home anywhere was never a member and needs no reference [Proposal]; said openly, a deleted member 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 in the new circle [Decided 23 Oct 2026, E-9: »da dobi istega tam«; how: E-9 (b), the project owner's method; the entries: Proposal, §3.11 ofdocs/knjiga-na-relejih.md("Membership, exclusion, the reference and closing accounts")]: in the old circle the balance is 0 (a condition of the reference); at themember_jointhe new circle opens the reference's wave W from its ownorigininto itsreserve(the grant) and pays it to the old circle's community as a cross-circle hold (reference_outin the new circle,reference_inin the old one); the old circle returns exactly W to itsorigin(close_wave) and closes the account (a plus left over stays, without a wave). Across currencies the amount paid is G = ceil(W × r_new / r_old) under the old circle's 43919 quote. Each circle stays at sum 0, and both communities end as they were. [Proposal, safety] The grant counts against the new circle's step outward (world_used + G ≤ step); a join whose grant does not fit waits on the waiting list [open question for the project owner: a circle that cannot raise its step takes in no waves]. The founder's own join in the new circle uses the same reference, with the same transfer. - 38888 [Proposal Q10]: only the
relaytags are read, for root relays only [Decided; reading for circles' ledgers Decided 16 Oct, Q2]; no circle's validity depends on it, because the link carries the circle id, the genesis digest and relay hints. This keeps the earlier decision but changes how much a circle relies on it, and is stated as such.
Recovery and key epochs [Proposal]#
- The circle key is not a key epoch [Decided 17 Oct, C5]: a lost or stolen circle key is replaced by
circle_key_change(k Heart members,change_notice_sof notice (72 h by default [Decided 23 Oct 2026, E-1]), booked by the witnesses in arolesentry of the current quorum [C5]; the new key's proof of possession [Proposal]; "The circle key and the 30910 mirror" above). The circle key signs no block, so nothing in the chain changes: no height is skipped and no lock moves, and the circle id, the genesis,scope16and every keyless account stay; only the key that signs the 30910 is new, from the change's own mirror (mirror_of= the height of itsrolesentry; in office for blocks from the next height). The epochs below are about witness and node keys. - Guard lost: the key does not sign again. A new key epoch is a
rolesentry (proposer swap, k Heart members + current quorum; in single-signer mode the Heart's acts alone) naming the new key andlast_h= the highest height found anywhere. - Restart of any witness: read every listed relay, every archive and, in quorum mode, the other signers' write-ahead logs; adopt the highest valid chain; republish it until final; continue at tip + 1.
- 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
rolesentry names alast_hbelow it; any copy of the old block found anywhere must otherwise be adopted. Fraud is only two final blocks at one height, or one key signing two digests at one height. - Locks: signer locks are per (circle, proposer key, height); a committed
proposer_swapnaminglast_hreleases the old key's locks above it. - [Open] in single-signer mode a lost only witness is both a "guard lost" case (the Heart's acts, no notice) and a "fewer than q survive" case (
recovery,change_notice_snotice, no Heart member "against"); the architecture does not say which applies. - [Open] if more than f current witnesses refuse (rather than fail) to commit their own replacement,
recoverydoes not apply (it needs fewer than q survivors); the architecture names no path besides people choosing the honest branch (F11).
No deposits and no payouts [Decided 16 Oct, Q6 and 6a]#
- No deposits [Decided 16 Oct, 6a: "a completely different system"]:
deposit_declare,deposit_cancel,deposit_attest,deposit_reject,deposit_correct, the custodian role andcustodian_name, thedepandcorrentries, the per-attestation limit L_att (question 12), the deposit alarm and the downward deposit correction (formerly 6b) are removed. A wave grows only with receipts:pay,xinand aproject_payto a member. Reference codesD2A-XXXXXXare no longer needed. - No payouts [Decided 16 Oct, Q6]:
payout_request,payout_cancel,payout_sent,payout_reject, thepoutentry, theheld_outline field and the member cover term− held_outare removed; cover isamount ≤ balance + wave. - No monthly
reservestatement act (the bank statement) and no statement hash [Decided 16 Oct, Q6]. The namereservenow denotes only the keyless reserve wallet. - No bank data of any kind in any event, setting, log or the 30910 [Decided 16 Oct, Q6]: no account numbers, IBANs, statement files or their hashes.
- Today's code: the deposit and payout routes are gone (plan step D0, 17 Oct 2026). A copy of the live database showed no deposit and no payout row first; the start-up step that drops their tables refuses to start on a ledger that has any.
- With no deposit alarm, a 43924
failstatement is public evidence and pauses nothing by itself; the circle's defences against a wrong entry are those of F11 and F12. - Custodian certificates of 0.1.0 are removed from the code (plan step D0).
Member guardians [Proposal Q11]#
guardians_setby the member names guardian keys and the threshold k (e.g. 2 of 3 members).freezeandkey_move(to a new key) need k guardian signatures and are public acts.- They act on the member's BSA account in this circle's ledger only; LANA coins on the Lana chain are not covered.
- Without guardians the account of a lost key stays frozen and public (F21).
- [Open] a notice period for
key_move.
Statements (KIND 43924)#
["c", <circle id>], ["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], ["result", "ok"|"fail"|"equivocation"|"missing"|"ignored"], ["state", root computed], ["votes", root, count], evidence the same way (["evidence", …] or ["e", id, "", "evidence"]), short content (~0.7 KB + evidence ids [E]). Governance uses: each witness's daily ok; the daily restore drill; any verifier's challenge (a fail is evidence; there is no deposit alarm to trigger [Decided 16 Oct, 6a]); equivocation proof; censorship evidence. A restorer that finds ≥ 2 independent ok statements for a seal (not all from the proposer) may start from that seal.
Failure modes (governance)#
| # | Failure | Defence | What still breaks |
|---|---|---|---|
| F7 | Node censors a note | receipts; standalone evidence to ≥ 3 relays; signers forward; proposer_swap / view change | a delay of seconds to minutes |
| F8 | Node or witness crash | sign-guard, write-ahead log, restart reads all relays, adopt the highest chain, lock release rules | non-final blocks; apps resend the same note |
| F9 | Up to f witnesses faulty | quorum q = 2f+1 of 3f+1 | — |
| F10 | More than f witnesses down | liveness lost, safety kept | until replaced by governance |
| F11 | More than f witnesses collude | verifiers publish fail with evidence; apps check their own lines; partners stop accepting; step outward bounds exposure | safety lost until people choose the honest branch |
| F12 | Single witness lies or is stolen | label, daily verifier and drill, height-uniqueness reads; no money cap [Decided 16 Oct, Q3] | a wrong entry can be booked before it is caught, and its size is not bounded |
| F18 | Spam acts | per-author limits at intake and on circle relays; refusals of keys that are neither members nor applicants are answered and never booked; at most rej_per_author_per_day (20 by default) refusals of one author booked per morning day (from one morning boundary to the next; D4 review, round 3), above it the intake answers 429; an act is valid at most act_ttl_s (7 days by default) [Decided 17 Oct, C3; circle parameters: Decided 23 Oct 2026, E-1] | — |
| F20 | Circle key lost or stolen | it signs only the mirror; readers follow the log, and 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), its tags without g equal that mirror, and its g names the pinned genesis digest; the circle is named by its circle id, so no false circle can take its name; k Heart members replace the key by circle_key_change with change_notice_s of notice (72 h by default), booked by the witnesses, and a record by the old key with a mirror_of at or above the change never counts [Decided 17 Oct, C5]; the first-seen rule of the root relays is extra safety [Decided 17 Oct, C6] | until the change is booked (at least change_notice_s after the k-th act; the Heart can shorten that notice, but a shortening applies only after the old notice [Proposal]) a thief can sign 30910 records with the key in office: a false one never counts, but on a relay that keeps only the newest record of that key it can push the honest one aside, so a new reader without the circle link finds no valid record there until the new key's record is out; a lost key means no new mirror until the change |
| F21 | Member key lost or stolen | optional guardians, freeze, key_move | without guardians the account stays frozen and public |
| F22 | Partner circle silent | a timeout alone never undoes; after 7 days A reads B's public log: not booked and sealed past the note's expires → xundo returns the held amount to the payer, naming B's seals and the real seal before them; booked → xdone; unreadable → wait, while A's other bookings go on [Decided 16 Oct, 8j] | while B's log cannot be read, the amount stays held |
| F23 | Fake or wasteful project | a vote of at least 72 h by default; a single "against" of any member makes it fall; at least three Heart "for", never the proposer or the recipient; keyless wallet; every key and every vote is public [Decided 23 Oct 2026, E-5] | a project nobody votes against and three Heart members vote for |
| F24 | Money stuck in a receiving project (recipient gone, project found bad, never fills) | the Heart's project_close after close_notice_s (72 h by default), or receive_lapse_s (90 days by default) without filling: project_return moves the balance to the reserve and on by drain() [Decided 16 Oct, 8e] | up to the closing notice, or up to receive_lapse_s |
| F25 | Heart members misuse their power (an exclusion or an account close, by at least three of them; the parameters, by k), or a member opens OWN processes to hold references back (any member may, E-10) | every act public and signed, with a reason where one is required; k signatures, at least three for an exclusion or a close (E-10); a Heart member closes an OWN process, and opening one to harm another is a reason for exclusion (E-10); parameters only within their bounds and after a notice at least as long as the time they replace [Proposal]; gravity never stronger than today's, and a change that makes it take more only after at least 30 days of notice [Decided 23 Oct 2026, E-11]; a Heart member who leaves the circle loses the seat [Decided 23 Oct 2026, E-11]; the money and gravity computation and the floor of 3 Heart "for" are fixed; any member's "against" makes a project fall; a settled member leaves with a reference and founds their own circle [Decided 23 Oct 2026, E-2] | an exclusion takes effect at once; a member in minus, or one with an open OWN process, gets no reference and cannot move [Decided 23 Oct 2026, E-9 and E-9 (a)]; a minus covered at a close is not checked against a death (the Heart's public responsibility) |
| F26 | One person, two keys | the member home (30916, the newest counts) and the reference stop one key from being in two circles at once or founding two; the root relays keep member homes | one person with two keys can be in two circles and found two circles; a deleted member home is not caught (both need Lana's person check) [Decided 23 Oct 2026, E-8] |
Tests (when built)#
- A project does not start receiving unless its vote passed: at the vote end no member has "against" as the newest vote and at least
project_approvalsHeart members in office have "for", the proposer's and the recipient's "for" not counted; a vote at or after the vote end is refusedvote_ended; a newer vote replaces the older, the same choice again isrepeated; an "against" without a reason is refused; aproject_proposewhose duration is outsidevote_min_s…vote_max_sis refusednot_allowed; a project that passed opens only with the recipient's consent and lapses afteropen_lapse_s[Decided E-5, E-1]. - A motion passes or falls by the same count, and its
vote_passis a public decision with no money effect [Decided E-5; the count for a motion: Proposal]. - With four Heart members, a project proposed by or paying one of them passes with the "for" of the other three; that member's "for" never counts [Decided 4a].
- There is no
project_approve,project_object,project_object_withdraw,project_answer,project_reject,steward_nominate,steward_vote,param_approve,param_objectorstep_approveact type, no project statusstoppedorrejected, noo3|objectionline and no 43920 record orrules_adoptentry [Decided E-1, E-2, E-5; C4]. - At
project_openthedrain()moves min(reserve, amount − received) to the project; a project wallet never exceeds its amount; surplus goes to the next receiving project in receiving order, the oldest first [Decided 8b], then stays in the reserve; with no receiving project every inflow stays in the reserve [follows from Q8]; after every entry except agraventry booked as a visit the reserve is above 0 only if no receiving project has room; one receipt makes exactly one move into the reserve;drain()runs at the end of every entry, agraventry in a morning block included, and agivethat exactly fills a named project gets it paid although it moves nothing into the reserve [clarification, 17 Oct 2026 (D1 review)]; no amount, daily or open-proposal limit refuses a project [Decided 8b]. - Gravity deducts and wave-growth counter-bookings (from payments, sales outside and project payments to members) land on the receiving project or the reserve, never on any other account; the circle sum is 0 after every block.
- A full project pays its recipient once and only when received = amount [Decided 8a], and the recipient's counter-booking goes to the reserve and on by
drain()(below the recipient's cap, project wallets plus reserve are unchanged by the payment [Decided 8f]); the cascade ends;project_returnmoves a receiving project's balance to the reserve after aproject_closewithclose_notice_sof notice and afterreceive_lapse_swithout filling [Decided 8e; circle parameters: E-1]; a recipient'sproject_decline,leaveor exclusion, or the proposer'sproject_withdraw, while the project receives returns its balance to the reserve [Proposal]; a contribution above the giver's plus is refused [Open 8g]. - No key can sign for a project wallet, the reserve,
worldorworld-step, and nomainaccount exists; a block that moves one without a rule entry is refused;common-gooddoes not exist. - A step raise is a project whose
project_paymoves intoworld-stepwith no wave growth and no counter-booking; a raise project that would bring the step abovebuiltdoes not open; a lowering belowworld_usedis refused. - A cross-circle hold: after 7 days, if B's quorum-signed seals cover the time up to the note's
expiresand no B block books the note, A booksxundoby rule (world→ payer, no wave change, B's consecutive seals as[day, digest]and the height range they cover: from the seal whose predecessor covered only bookings before A'sxoutat− 60 s to the first seal whose boundary is later than the note'sexpires(strictly), one or two seals (an idle B still seals every day) as evidence, plus the real seal before them (before), checked against B's chain; an evidence that skips the seal holding the booking, or whose first seal misdescribes the seal before it, is refused; each seal is checked against B's blocks, and the evidence is closed by B's block right after the last seal or, if B booked none since, by B's next daily seal (after a witness confirms on at least two of B's relays that no such block exists); else nothing is booked); if a B block books it, A booksxdone; if B's log cannot be read or the seals stop beforeexpires, nothing is booked; a signer that cannot verify B's seals refuses a block with thexundo; a B block without a valid quorum of B's witnesses in office at its height is ignored, and two B blocks with valid quorums at one height are a fork, so the evidence is not used [Proposal]; noxrefundentry exists [Decided 8j]. - No deposit or payout act type, no
dep,corrorpoutentry, no custodian role and noheld_outorpaid_infield exist; a schema test proves no act, entry, setting or 30910 can carry bank data or a person's name. - A signer change without the new signer's accept, before
change_notice_s, while a Heart member in office has "against" as the newest vote on it, or giving one operator two signers is refused [E-7]; arecoveryis void when a quorum-valid block above its height appears during the notice; a proposer swap takes effect at once. - An act after
expires(at mostact_ttl_safter signing), or by a key without the role at the booking height, is refused with a publicrejwhen its author is a member or an applicant; a refusal of any other key is answered and never booked; refusals of one author aboverej_per_author_per_dayin a morning day are not booked (429) [Decided C3; parameters: E-1]. - A block that omits a due
ruleentry is refused by every witness. - A 30910 whose tags without
gdiffer from the mirror atmirror_of, whosegis not the pinned genesis digest, or whose author is not the circle key that mirror names (at the height of a key change already the new key), is ignored by readers; among valid records readers take the one with the highestmirror_of. - A
circle_key_changewhosepopdoes not verify, or verifies only over anothercreated_at(an old pop used again), is refused (bad_template); the change is committed only by arolesentry with k distinct current Heart members, booked at leastchange_notice_safter the k-th act, and the new key is in office from the next block; a block with tworolesentries is refused; arolesentry whose proposing act is notcircle_key_changenever changes the circle key; after the change a 30910 by the old key with amirror_ofat or above it never counts, and the 30910 of the change's own height counts only by the new key; the circle id,scope16, every keyless account and the genesis never change; every seal names the circle key of the newest mirror at or below itsh_to[Decided C5; the pop, in office from the next block, onerolesentry per block and the seal tag: Proposal]. - A found act or
param_proposewith a missing, extra or out-of-range parameter, withvote_min_s>vote_max_sor withvote_max_s≥open_lapse_sis refusedbad_template; aparam_proposetakes effect only byparams_effectiveat the first block whose firstatreaches its notice end (the k-th act'sat+ max(change_notice_s, the old value of every changed parameter in seconds)), never earlier, and is void when fewer than k of its signers are in office then; a second openparam_proposeisrepeated; every check in a block uses the parameters in force for it, except a running deadline, which keeps the due time recorded when it started (a project opened under a 90-day receive lapse keeps 90 days when the Heart later sets 30); a cross-circle mismatch ofnote_ttl_s,quote_ttl_sorxcheck_sends only in a refusal and a return to the payer, with both sums 0; a restore from the relays gives the same parameters [Decided E-1; the details: Proposal]. - A witness signing two digests at one height yields a 43924
equivocationthat any reader can verify. - A single-witness circle shows the label; no money-cap parameter or check exists.
- A cross-currency payment carries both amounts and the id of a 43919 rate quote signed by the seller circle's node and still valid at booking; the app shows the ECB rate's date [Decided start rate source].
- Restore from seal + tail equals full replay, including every
g3ando3line and every project wallet and reserve line. - Exclusion:
member_excludetakes effect at the k-th act of Heart members in office (the excluded key never counts), first removing a Heart seat by arolesentry; the excluded line pays, gives, votes and proposes nothing, is still visited by every morning, may send at most its plus to another circle and receives only a settlement; itsjoinbeforeuntilis refusednot_allowed, after it goes to the Heart, never to the waiting list, andmember_readmitgives membership only [Decided E-3, E-6]. - Reference: a
leavewith balance ≥ 0 (and no open OWN process) gets itsreferenceentry at the end of that entry; aleavein minus gets none until a settlement brings it to 0, and never while an OWN process is open together with a minus; a settlement above 0 or any other payment to a left or excluded line is refused; an open OWN process without a minus blocks it [Decided E-9 (a)]; a 43921 matches its block; ajoinof a key whose newest member home names another circle is refused without that circle's valid reference [Decided E-9]; the step transfer of E-9 (b): its tests follow its entries [Open]. - Closing an account:
account_closecompletes only when the balance is ≤ 0, its morning is not pending and the reserve covers −balance + wave; it movesclose_coverandclose_wave, sets wave, cap, debt and carry to 0 and the statusclosed;origin= −start + Σclose_wave; a Heart member in office cannot be closed; a close never gives a reference [Decided E-3; the mechanics: Proposal]. - Joining: with
invite_only= 1 ajoinwithout an open invite of that key is refused; an invite is used once and ends afterinvite_ttl_s; withmax_membersreached ajoinwaits, and when a place frees the lowest seq on the list is admitted by rule; an excluded key never comes from the list [Decided E-6]. - Founding: a found act without
parentand the founder's reference (except the root) is invalid; the root relays refuse a second circle record of the same founder; a 30910 carriesparentwhen the found act names one [Decided E-8; the mechanism: Proposal]. - OWN:
own_openby any member, alone, at once [Decided 23 Oct 2026, E-10],own_closeone Heart member; while ano3|ownline of a key is open, its reference waits [Decided E-4, E-9 (a), E-10].