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

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=1 stays 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 tzdata version 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.md and 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 types steward_*, the tags ["steward", hex] and stewards_required, the signer role value steward, 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) = a vote act, "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, written project:<id>; reserve (rezerva) = the keyless reserve; rate quote (ponudba tečaja) = 43919 v3; reference (referenca) = the reference rule entry and its findable copy, a 43921; circle id (rojstna številka kroga) = the event id of the circle's signed found act (found act = ustanovna listina), the circle's name for ever; parent circle (matični krog) = the circle a found act names in parent; 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 by circle_key_change; circle parameters (nastavitve kroga) = the integer values of "Circle parameters" below, changed by param_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_pay to a member).

Roles#

RoleCountSignsBounded byStatus
Memberany (at most max_members when set; the others wait on the list)43910 notes, 43916 acts (vote included), own 30916own acts only; a member of one circle at a timekey 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 43924at most f of n faulty; at most one per operatorn = 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 referencesevery other witness recomputes every numberrotation 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 nowtheir 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 membersnames, 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 / auditoranyone43924 statementsnothing: a statement carries its evidence[Proposal]
Guardians of a memberchosen by the member (e.g. 2 of 3 members)freeze, key_moveonly if the member named them in advance[Proposal Q11]
Circle keyone 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 idholder [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-stepone per project; one reserve, one world, one world-step per circle and currencynothing (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 roles entry; each signer carries since_h and until_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 the roles entry). At most one signer per operator [Decided 16 Oct, Q3], written into the log as a rule the witnesses check on every roles entry. 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, and at within ±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 below last_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 by params_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].
  • 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_remove or signer_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 fail with 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 true for 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 at is 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_s of 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 pubkey or a p tag (HEX).
  • An act has effect only once booked, as an act entry (no money effect) or as the cause of a rule or roles entry. It is judged by its author's role at the booking height.
  • Every act carries expires, at most act_ttl_s after 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 at created_at − AT_TOLERANCE_S (5 s, a fixed constant) ≤ at ≤ expires, its expires judged by the act_ttl_s in 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 as a3 lines until they expire, so an old act can never be booked again.
  • After expires an act is refused (rej entry with reason expired). 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 most rej_per_author_per_day refusals 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 booked xout brought is refused with src naming that block, so the payer's circle can undo its hold.
  • Acts are embedded in blocks; a standalone copy is optional. No expiration and no NIP-70 - tag; ledger keys never sign KIND 5 or 62.
  • Due duties: every time-driven change is a rule entry: params_effective at the notice end of a param_propose (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; 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_pass or vote_fall at a proposal's vote end [Decided 23 Oct 2026, E-5; the entries: Proposal]; project_lapse after open_lapse_s (30 days by default) for a project that never opened; project_open followed by drain(); reserve_move; project_full and project_pay [Decided 16 Oct, 8a]; project_return after the close_notice_s notice of a project_close or after receive_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 first at is later than their end, with no entry. At the end of every entry the rule also books, in this order after drain() 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's roles entry is a duty too, due change_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 an xdone or xundo they 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_adopt is 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 status stopped and no rejected [Decided 23 Oct 2026, E-5; Decided 17 Oct, C4 for rejected]. A block whose at passes 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 same at, 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's grav entries 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.
GroupAct typesSigned by
Foundingfound (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
Membershipinvite (["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), rulesmembers / applicant
Exclusion and accountsmember_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
OWNown_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 innone: 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 outnone: 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—
Projectsproject_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_rejectproposer / recipient / Heart members
Votesmotion (["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 outwarda 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
Parametersparam_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
Rolessteward_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" belowHeart members / the new Heart member or witness (its accept) / the resigning Heart member or witness
Recoveryrecovery (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" belowthe larger of k and 3 Heart members (3 of 4 in the live circle)
Member safetyguardians_set, freeze, key_movemember / 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):

NameMinMaxDefaultUnitStatus
band_ppm_day0330330ppm/daya circle parameter as before; never stronger than today's, a raise waits at least 30 days [Decided 23 Oct 2026, E-11]
excess_ppm_day022,84022,840ppm/daynever stronger than today's (half in 30 days), a raise waits at least 30 days [Decided 23 Oct 2026, E-11]
transition_days603,65060daysnever shorter than today's, a shortening waits at least 30 days [Decided 23 Oct 2026, E-11]
rest_after_days03,650183days0 = 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_cap1999,999,999,999,999100,000,000minor unitsas before
w_max_s1101sas before
vote_min_s86,4002,592,000259,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_s86,4002,592,0001,209,600 (14 days)s[Decided 23 Oct 2026, E-10 (3A)]
project_approvals393Heart members[Decided 23 Oct 2026, E-1: at least 3, a circle may require more]
close_notice_s86,4002,592,000259,200 (72 h)s[Decided 16 Oct, 8e]; a circle parameter [E-1]
receive_lapse_s604,80031,536,0007,776,000 (90 days)s[Decided 16 Oct, 8e]; counted from project_open [Proposal]; a circle parameter [E-1]
open_lapse_s604,80031,536,0002,592,000 (30 days)s[Proposal] (today's 30-day rule for orders); a circle parameter [E-1]
change_notice_s86,4002,592,000259,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_s86,4002,592,000604,800 (7 days)s[Decided 16 Oct, 8j]; a circle parameter [E-1]
quote_ttl_s3003,600600 (10 min)s[Decided 16 Oct, start rate source]; a circle parameter [E-1]
note_ttl_s603,600600 (10 min)s[Decided] (the note rule); a circle parameter [E-1]
act_ttl_s86,4002,592,000604,800 (7 days)s[Decided 17 Oct, C3]; a circle parameter [E-1]
rej_per_author_per_day11,00020refusals[Decided 17 Oct, C3]; a circle parameter [E-1]
exclusion_s86,40031,536,0007,776,000 (90 days)s[Decided 23 Oct 2026, E-3: 3 months]; 90 days, and that it is a parameter [Proposal]
invite_ttl_s3,6002,592,000604,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_only0100/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_members0999,999,9990 (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 the xout, the receiving circle at the xin. If the receiving circle's value is smaller, it refuses the note (rej with src: bad_template); the payer's circle books xundo (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 the xin (rej with src) 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 the xout). A short wait can only find the evidence incomplete (the receiving circle's seals do not yet pass the note's expires): 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)#

ChangeRuleStatus
Project: the voteproject_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 retroactivethe 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]
Motionmotion 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 decisionthe 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: receivingevery 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 routingevery 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: paymentreceived = 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 lapserule 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 outwardraise 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 hangsB 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]
Parametersparam_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 noticethe 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 sourcerate_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 onlynames, 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, relaysWho 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 rootsone 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 keycircle_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 wayk 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 swapwithin 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 listrefusal_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]
Recoveryfewer 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 versionpinned 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]
Joiningjoin 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 itopen / 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 readmissionmember_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 seatthe 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]
Referencea 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]
Settlementa 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_memberanyone 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 plusa 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 accountaccount_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 processown_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 ledgerthe Heart leads and oversees OWN; only decisions reach the ledger [Decided 23 Oct 2026, E-4]; the record [Consequence of E-9; Proposal]
Foundingthe 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 readersonly 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 reserve inside the entry that produces it (one step row per receipt, as today with Common Good renamed): the grow and settled of every receipt (pay, xin, project_pay to a member); every grav deduct; the part of a named give above the project's room, and a whole unnamed give [Open 8g]; a step lowering. Each is a move between two accounts, so the circle's sum stays 0 after every block [Decided 16 Oct, Q8, 8f]. There is no dep [Decided 16 Oct, 6a] and no late xundo after 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 a project_open, since a give that exactly fills a named project moves nothing into the reserve and the full project must still be paid (a grav entry in a morning block included; the deducts of grav entries booked as visits are drained at the end of the entry they precede), also in payment blocks during the morning; a member who leaves while the recipient of several receiving projects gives one project_return per project, each followed by its own drain(), as every inflow is [clarification, 17 Oct 2026 (D1 review)]; 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 grav entry booked as a visit, balance(reserve) > 0 only 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 grav entry is still pending, that grav entry 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_pay to 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. Every grav deduct moves to the reserve and drain() runs as after any inflow, so the order the node books payments in never changes anyone's gravity.
  • Several project_open due 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 under built or a change of the circle parameters) open in publication order (project_propose seq) [clarification, 17 Oct 2026 (D1 review)]; each followed at once by drain(). A cascade that would pass 100,000 bytes closes the block after its last whole step; the next block, at the same at, starts with the remaining steps exactly as they would have come (the block split, 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 than project_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 genesis entry, one rule entry start: origin → reserve, "100000" minor units (1,000.00; EUR, USD and GBP all have two decimals), then drain() (no project receives at genesis, so the start stays in the reserve). origin (SL »izvor«) is a keyless system account, derived like the others (role origin, below under "System accounts: no key"); its line is −100000 from block 1 and moves again only by close_wave when 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 names start and origin, the rule that origin moves only by start and close_wave and 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 of docs/knjiga-na-relejih.md.
  • A project's image: ["img", sha256, url] in project_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 give entry (it replaces cg) with ["e", <project_propose id>, "", "project"] naming a project in status receiving, or naming none; cover: the plus only, amount ≤ max(0, balance) (today's rule) [Open 8g]; the project is credited at most amount − received, the rest goes to the reserve; an unnamed contribution goes to the reserve; then drain() [Open 8g]. [Proposal] a contribution naming an open project in any other status is refused with rej reason not_receiving; one naming a project that has ended (its o3|project line is gone) is refused not_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_propose whose recipient is not a member when it is booked (left, never joined or frozen) is refused not_member [clarification, 19 Oct 2026 (D3 review)].
  • Votes [Decided 23 Oct 2026, E-5; replaces Proposal Q21 on objections]: a vote is 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_out is 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); status adds excluded and closed [Decided 23 Oct 2026, E-3]; every morning visits every line with status member, frozen, excluded or left, never closed [Consequence of E-3];
  • governance lines g3|<key>|<value>: the circle parameters (g3|param:<name> for every parameter of "Circle parameters" above, and g3|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 a roles entry whose proposing act is circle_key_change, from the next block [Decided 17 Oct, C5; the shape and in office from the next block: Proposal]; the world rules line g3|rules is 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; status proposed (voting), passed, receiving or full; every running deadline recorded as a due time when it starts, never retroactive); motions o3|motion|id|voting|proposer|published_at|published_seq|vote_end (8); votes o3|vote|<proposal id>|<voter>|<for or against>|<vote act id> (6; the key is the first 4); open requests; cross-circle holds o3|hold|note|held|amount|payer|to circle|to genesis|note expires|xout at|check at|party (12; the check time recorded at the xout; party: a reference grant's newcomer, "" for a leg [E-11]; a grant ends only by xdone or a refused xundo, which grant_revoke follows [Decided 23 Oct 2026, E-11]); applications o3|join|<join id>|<key>|<waiting or heart>|<expires, "" while waiting>|<booked seq> (7); invitations o3|invite|<invite id>|<key>|<inviter>|<until> (6); exclusions o3|exclude|<hex>|<until>|<act id> (5); waiting closes o3|close|<hex>|<act id>|<booked seq> (5); waiting references o3|leaving|<hex>|<leave act id>|<booked seq> (5); OWN processes o3|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|param and o3|step [Decided 23 Oct 2026, E-1, E-5]. No open deposits [Decided 16 Oct, 6a].
  • the o3|change line [clarification, 17 Oct 2026 (D4 review), for the fields and the k-th act; proposal (D4 review, 17 Oct 2026), for the lapse and the project field; proposal (D4 review, round 3, 17 Oct 2026), for consent, booked h and 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 = the project_propose id a project_close closes, "" 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 = waiting for signer_propose, signer_replace and steward_add until the named key's accept act is booked, then yes, 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_readmit and account_close included [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 to notice at the k-th act ("Heart changes" above): notice end = that act's at + the type's notice. A resignation's line (type steward_resign or signer_resign) is in notice from its booking, with notice end = its at + change_notice_s (72 h by default) and expires = that notice end, and stays until its roles entry (a duty). expires: while collecting, the proposing act's own expires; in notice, for a roles change other than a resignation the end of its commit window ("Heart changes" above), for project_close and param_propose the notice end (the return, or params_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 to notice. The line ends with the entry that commits the change (the roles entry; for project_close the project_return), or at the first block whose first at is later than expires (a change still collecting, or a roles change never committed); a project_close line also ends with the entry that gives its project a final status (project_pay, project_return, project_lapse), or at its close due when fewer than k of its Heart members are in office then (the close is void); a param_propose line 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, origin and one wallet per project are x-only points lift_x(sha256("lb-system/3|" + role + "|" + circle id + "|" + i)) for the first decimal i that 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 is world, world-step, reserve, origin or project| + the 64-hex id of the project_propose act (the wallet is written project:<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 main account. 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-good no longer exists. [Open] migration of the live circle: proposal, today's Common Good balance opens as the reserve line 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, by drain()); project_pay (project → recipient, or → world-step for a raise) [Decided 16 Oct, 8a, 8j]; project_return (project → reserve) [Decided 16 Oct, 8e]; world-step → reserve on a lowering [Proposal]; xout (payer → world), xin (world → member) and xundo (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) and close_wave (reserve → origin, the closed line's wave) [Decided 23 Oct 2026, E-3, confirmed; the names: Proposal]. There is no xrefund, no dep and no corr. 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. world may be negative, as before. origin is −start from block 1 and moves only by close_wave: origin = −start + Σ close_wave (the state's returned), and Σ waves = grown − returned [Decided 23 Oct 2026, E-3; the invariants: Proposal]. origin also 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 of docs/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 found act (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 an a tag. scope16 = the first 16 hex characters of the circle id (h, m and i keep <scope16>:…); the keyless system accounts come from the circle id (above); the 30910 and the 30915 carry it as d, 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)]; a found act that breaks it is refused bad_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 the circle_key it names. quote_ttl and project_approvals are not in the mirror: they are circle parameters, carried in the ledger's state (g3|param:*) [Decided 23 Oct 2026, E-1]. The rate_panel and rate_rule tags are removed [Decided 16 Oct, Q7]; the custodian tag 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 or roles entry).
  • Authority rule: a 30910 counts only if it is signed by the circle key that the ledger's mirror at its mirror_of names (the mirror carried by the committed genesis or roles entry 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 without g equal that mirror, and its g is the pinned genesis; readers take the valid record with the highest mirror_of. When they differ, readers follow the log. The genesis mirror is a function of the signed found act. Said openly: anyone can publish a 30910 that names a circle id; it counts only when the ledger's mirror at its mirror_of names its author. The circle key cannot re-point g, which carries the founder's signature over the circle id and the genesis digest. Root relays keep the first-seen g and founder per circle id (relay/ledger-write-policy.py, mode root, which also checks the founder's signature over the circle id) [Proposal: they keep every circle's found act (a 43916 whose first tag is ["c", ""] and that has no other c tag, from any author: its id is the circle id, so nobody can make a false one; the plugin remembers at most seen_ids_max found acts, and beyond it a newer circle's records are kept unpinned, never falsely pinned) and pin a circle id's g and founder only when they hold that found act and the record's founder is its author (or, for a circle configured on the relay, when its configured circle key signed the record), otherwise 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 signs circle_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's created_at in 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 within act_ttl_s of its created_at, so an old pop can never be used again [Proposal]. Further Heart members endorse it ("Heart changes" above); once change_notice_s (72 h by default) has passed since the k-th act, a roles entry 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>). A roles entry changes the circle key only when its proposing act is circle_key_change, and then to exactly the key it names; a block books at most one roles entry [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 whose mirror_of is the change's own height; a 30910 by the old key with a mirror_of at or above the change never counts. A relay that serves the circle moves the old key to retired with the role circle_key and an until: a retired circle key counts only for an old 30910 up to its until, never for a block, seal, chunk, head or quote [Proposal]. The circle id never changes, and with it scope16, every keyless account and the genesis stay. A stolen key and a lost key are replaced the same way. A pop that 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 and roles) and in found and circle_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 below h_to (the genesis mirror or the newest roles entry's). Its witnesses sign the seal, and the seal names their set (signers) and that mirror's circle key (["circle_key", <hex>], after signers in the seal's tag order), as the state's g3 lines at h_to do; 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 qs tags, 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 first g it saw for the circle id), and never follows another g for the circle id.
  • Founding [Decided 16 Oct, Q9; the circle id and the first circle key: Decided 17 Oct, C5; tz, morning hour and tzdata fixed 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 signs found in 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_circle names the root's circle id (empty while a draft; the examples use circle A as the TEST root, and circle B names A) [Proposal]. It becomes block 1, and the ledger is public from it. Block 1's genesis entry embeds the found act (rebuilt with ["c", ""]), the mirror it gives and the first circle key's signature over sha256("lb-found/3|" + found id) (circle_sig), which binds the founding to that key; the rule entry start follows. 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's member_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 reference entry 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: the at of the newest member_join and of the member_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]: the join names the reference, ["e", <43921 id>, "", "reference"]; the new circle's node checks that its c is the circle the key's newest member home (30916) names (the last circle), its p is the key, and the named block of that circle carries the reference entry of the key with the same wave and a quorum of that circle's witnesses in office at that height (as for the 8j evidence); the member_join entry then names it: {rule: "member_join", in: [join id], party, ref: <43921 id>, src: [height, digest], g: <that circle's genesis>}. 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 of docs/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 the member_join the new circle opens the reference's wave W from its own origin into its reserve (the grant) and pays it to the old circle's community as a cross-circle hold (reference_out in the new circle, reference_in in the old one); the old circle returns exactly W to its origin (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 relay tags 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_s of notice (72 h by default [Decided 23 Oct 2026, E-1]), booked by the witnesses in a roles entry 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, scope16 and every keyless account stay; only the key that signs the 30910 is new, from the change's own mirror (mirror_of = the height of its roles entry; 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 roles entry (proposer swap, k Heart members + current quorum; in single-signer mode the Heart's acts alone) naming the new key and last_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 roles entry names a last_h below 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_swap naming last_h releases 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_s notice, 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, recovery does 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 and custodian_name, the dep and corr entries, 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, xin and a project_pay to a member. Reference codes D2A-XXXXXX are no longer needed.
  • No payouts [Decided 16 Oct, Q6]: payout_request, payout_cancel, payout_sent, payout_reject, the pout entry, the held_out line field and the member cover term − held_out are removed; cover is amount ≤ balance + wave.
  • No monthly reserve statement act (the bank statement) and no statement hash [Decided 16 Oct, Q6]. The name reserve now 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 fail statement 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_set by the member names guardian keys and the threshold k (e.g. 2 of 3 members). freeze and key_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)#

#FailureDefenceWhat still breaks
F7Node censors a notereceipts; standalone evidence to ≥ 3 relays; signers forward; proposer_swap / view changea delay of seconds to minutes
F8Node or witness crashsign-guard, write-ahead log, restart reads all relays, adopt the highest chain, lock release rulesnon-final blocks; apps resend the same note
F9Up to f witnesses faultyquorum q = 2f+1 of 3f+1—
F10More than f witnesses downliveness lost, safety keptuntil replaced by governance
F11More than f witnesses colludeverifiers publish fail with evidence; apps check their own lines; partners stop accepting; step outward bounds exposuresafety lost until people choose the honest branch
F12Single witness lies or is stolenlabel, 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
F18Spam actsper-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]—
F20Circle key lost or stolenit 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
F21Member key lost or stolenoptional guardians, freeze, key_movewithout guardians the account stays frozen and public
F22Partner circle silenta 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
F23Fake or wasteful projecta 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
F24Money 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
F25Heart 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)
F26One person, two keysthe 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 homesone 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_approvals Heart members in office have "for", the proposer's and the recipient's "for" not counted; a vote at or after the vote end is refused vote_ended; a newer vote replaces the older, the same choice again is repeated; an "against" without a reason is refused; a project_propose whose duration is outside vote_min_s…vote_max_s is refused not_allowed; a project that passed opens only with the recipient's consent and lapses after open_lapse_s [Decided E-5, E-1].
  • A motion passes or falls by the same count, and its vote_pass is 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_object or step_approve act type, no project status stopped or rejected, no o3|objection line and no 43920 record or rules_adopt entry [Decided E-1, E-2, E-5; C4].
  • At project_open the drain() 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 a grav entry 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, a grav entry in a morning block included, and a give that 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_return moves a receiving project's balance to the reserve after a project_close with close_notice_s of notice and after receive_lapse_s without filling [Decided 8e; circle parameters: E-1]; a recipient's project_decline, leave or exclusion, or the proposer's project_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, world or world-step, and no main account exists; a block that moves one without a rule entry is refused; common-good does not exist.
  • A step raise is a project whose project_pay moves into world-step with no wave growth and no counter-booking; a raise project that would bring the step above built does not open; a lowering below world_used is refused.
  • A cross-circle hold: after 7 days, if B's quorum-signed seals cover the time up to the note's expires and no B block books the note, A books xundo by 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'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) 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 books xdone; if B's log cannot be read or the seals stop before expires, nothing is booked; a signer that cannot verify B's seals refuses a block with the xundo; 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]; no xrefund entry exists [Decided 8j].
  • No deposit or payout act type, no dep, corr or pout entry, no custodian role and no held_out or paid_in field 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]; a recovery is 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 most act_ttl_s after signing), or by a key without the role at the booking height, is refused with a public rej when its author is a member or an applicant; a refusal of any other key is answered and never booked; refusals of one author above rej_per_author_per_day in a morning day are not booked (429) [Decided C3; parameters: E-1].
  • A block that omits a due rule entry is refused by every witness.
  • A 30910 whose tags without g differ from the mirror at mirror_of, whose g is 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 highest mirror_of.
  • A circle_key_change whose pop does not verify, or verifies only over another created_at (an old pop used again), is refused (bad_template); the change is committed only by a roles entry with k distinct current Heart members, booked at least change_notice_s after the k-th act, and the new key is in office from the next block; a block with two roles entries is refused; a roles entry whose proposing act is not circle_key_change never changes the circle key; after the change a 30910 by the old key with a mirror_of at 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 its h_to [Decided C5; the pop, in office from the next block, one roles entry per block and the seal tag: Proposal].
  • A found act or param_propose with a missing, extra or out-of-range parameter, with vote_min_s > vote_max_s or with vote_max_s ≥ open_lapse_s is refused bad_template; a param_propose takes effect only by params_effective at the first block whose first at reaches its notice end (the k-th act's at + 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 open param_propose is repeated; 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 of note_ttl_s, quote_ttl_s or xcheck_s ends 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 equivocation that 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 g3 and o3 line and every project wallet and reserve line.
  • Exclusion: member_exclude takes effect at the k-th act of Heart members in office (the excluded key never counts), first removing a Heart seat by a roles entry; 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; its join before until is refused not_allowed, after it goes to the Heart, never to the waiting list, and member_readmit gives membership only [Decided E-3, E-6].
  • Reference: a leave with balance ≥ 0 (and no open OWN process) gets its reference entry at the end of that entry; a leave in 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; a join of 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_close completes only when the balance is ≤ 0, its morning is not pending and the reserve covers −balance + wave; it moves close_cover and close_wave, sets wave, cap, debt and carry to 0 and the status closed; 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 a join without an open invite of that key is refused; an invite is used once and ends after invite_ttl_s; with max_members reached a join waits, 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 parent and the founder's reference (except the root) is invalid; the root relays refuse a second circle record of the same founder; a 30910 carries parent when the found act names one [Decided E-8; the mechanism: Proposal].
  • OWN: own_open by any member, alone, at once [Decided 23 Oct 2026, E-10], own_close one Heart member; while an o3|own line of a key is open, its reference waits [Decided E-4, E-9 (a), E-10].