Change history
A running log of documentation-affecting changes, newest first. Each entry links to the section that changed (or that describes the change) so you can jump straight to it instead of re-reading the whole page.
Versioning. Sections are tagged with a date and a protocol version
(MAJOR.MINOR.PATCH):
- MAJOR — a breaking change to the SithBit public ABI (removing or
reordering an instruction variant, changing an account layout that clients
read, or repurposing an error code). Instruction enums and error codes stay
append-only and the protocol is pre-launch, so MAJOR remains
0for now. - MINOR — an additive public-ABI change (a new instruction, error, or field), a significant change to the economic model that changes how end users use the system (fees, pricing, prepayment rules), or — widened at v0.10.0 — a significant additive capability or default-behavior change that affects deployments (a new enforcement default, a new storage/config backend kind). Earlier entries tagged such changes PATCH.
- PATCH — documentation-only or otherwise non-behavioral changes.
A run of documentation-only edits between behavioral changes keeps the same version across several dated sections: the version tags the protocol state, the date tags when the docs moved.
2026-07-27 — v0.41.0 (money-path hardening: sender stamp reclaim, purchase slippage guard, admin-close value guard)
-
Senders can now withdraw unspent prepaid postage. A new
ReclaimFromboxStampsinstruction (discriminant 52) returns the balance above rent to a sender who prepaid against their own wallet address, zeroing the stamp count and leaving the frombox alive on its rent so the recipient keeps the price it set. The frombox derives from the hash of the signer’s address bytes, so reproducing that derivation is the authorization — no stranger can reach someone else’s frombox, and a frombox keyed on an email string stays recipient-managed by design. Documented at Reclaiming unspent stamps, with the concept-level story under Prepaying with stamps. This corrects the threat model, which previously stated that prepaid stamps had no refund path at all. New instruction: MINOR. -
Stamp purchases carry a slippage ceiling.
CreateFromboxandAddStampsgained an additivemax_price_lamportsfield; the recipient controls the per-stamp price and can raise it between the moment a buyer is quoted and the moment their transaction lands, so a purchase above the ceiling now reverts with custom error 107 rather than silently overpaying.frombox stamppins the ceiling to the price it just quoted by default, with--max-priceto pre-authorize a rise and--no-max-priceto opt out. Additive ABI field affecting how end users buy postage: MINOR. -
The admin reclaim tool can no longer reach accounts holding value.
AdminCloseAccount, in all three programs, now refuses any target whose balance sits above its rent-exempt minimum (custom error 106), sopostmaster reclaimreaps only rent-empty leftover state — never a sender’s escrowed postage, a reply bounty, or a live auction bid. New error code: MINOR. -
A permissionless crank can no longer capture the requester’s deposit.
PendingReclaimrecords the wallet that funded the request, anddomain reclaim --finalizepins the pending account’s rent refund to it. Finalize stays permissionless to crank; only the refund target changed. The new field is noted in the privacy reference. Additive account field: MINOR. -
Error codes 105
PinLeaseAccountInfo, 106AdminCloseEscrowPresentand 107PriceExceedsMaxare now listed in the program reference; 105 predates this entry and had simply never been written down.
2026-07-27 — v0.40.7 (timelock docs gate widened to all four constants)
- The “7 days” figure is now fenced for every timelock, not just
mailbox close.
check_timelock.pyguarded exactly one ofmail_model’s four same-valued timelock constants, so the prose describing domain deactivation, reclaim-by-proof and reply bounties could drift from its constant unnoticed — the three constants are deliberately independent literals, so retuning any one of them would have silently falsified those pages. The checker is now table-driven with one row per constant (19 fenced mentions in total, up from 9) and each row is drift-proved independently. Rows own file-exclusive allowlists, enforced at startup, because the context filters really do overlap inside a shared page. Scope stays.md-only: the three diagrams that also say “7 days” are excluded, since the screenshot gate already hashes them. The checker also gained a--self-testproving its exit-code contract against fixture trees, joining the link and anchor checkers. Known gap: a handful of close-family figures remain unfenced —closing-accounts.md,economics.md,threat-model.mdandproving-behavior.mdeach mix figures from two or more constants in one file, which the file-exclusive model cannot express; fencing them needs per-section scoping. Tooling and gate only, no documented behavior changed: PATCH.
2026-07-23 — v0.40.6 (first-run screenshot re-baseline)
- Webmail first-run screenshot re-baselined. The
committed
webmail-first-run.pngwas the last frame still shot on the old capture rig: its standalone capture path had no CDP session, so the frame rendered in the capture host’s own color scheme and could not be reproduced on a box whose desktop theme differed. The shot now rides the same capture driver — and the same dark-theme/timezone pin — as every other committed screenshot, so the full set is byte-reproducible on any box (run-to-run AE=0 across all four driver-captured frames). Same subject, same dark theme; only capture tooling and pixels moved. Documentation only: PATCH.
2026-07-23 — v0.40.5 (API-mode on-chain reply reveal + mailbox-credentials reference)
- Webmail: “Reply on-chain” now works in API mode. The on-chain compose card was CSS-hidden for the whole page lifetime whenever an account API was configured, so a trustless-viewer Reply click seeded the draft into an invisible card — a silent no-op. The card now reveals itself when the pane opens (it stays hidden until then, so nothing changes in the always-rendered UI), floating in the corner like the server compose pane. This narrows the v0.40.4 entry’s “it was never silent” note: that held for trustless mode only. The webmail screenshot set was proven pixel-neutral (same-rig A/B, AE=0 on all three shots) and re-pinned hash-only. Client-shell UX only, no protocol change: PATCH.
- CLI reference: new
Mailbox credentials
page documents
sithbit mailbox credentials— the offline, no-RPC derivation of the deterministic mail login (username = the wallet public key, password = the base58 wallet signature over the fixed auth challenge) — and wires it into the Mailboxes command tree beside the client-certificate alternative; the client walk-through pages already showed the invocation and are now cross-linked from the reference. Documentation only: PATCH.
2026-07-23 — v0.40.4 (lease-open acknowledgement + reference and screenshot upkeep)
- Lease-open acknowledgement — the trustless viewer’s “Lease this
message” button now switches the two view-routed shells to the settings
view with the lease form prefilled: webmail routes
via the
#/settingshash (so the browser’s Back button returns to the mail view), while the Outlook taskpane switches its plain view state (no history entry). No reply listener was added — the on-chain Reply compose card already opens in place in the mail view, so it was never silent. The webmail screenshot set was proven pixel-neutral (same-rig A/B, AE=0 on all three shots) and re-pinned hash-only. Client-shell UX only, no protocol change: PATCH. - Docs screenshots:
webmail-inbox.pngandmarketplace-listings.pngre-baselined on the current capture rig. The webmail capture driver now pins the topbar wallet line to a fixed display base58 (the public key of the checked-inmail-key1test keypair — the same wallet the marketplace capture signs in with) before the inbox shot; previously a fresh keypair minted per run made that line the frame’s one nondeterministic element. Both shots are re-shot on the chrome-headless-shell 151 rig and proven run-to-run byte-identical (AE=0 across consecutive full captures), so committed-vs-fresh comparisons are directly meaningful again. Capture tooling and images only: PATCH. - CLI reference: new
Create a client certificate
page documents
sithbit mailbox create-cert— the offline SASL EXTERNAL certificate mint (<prefix>.crt/.keyPEMs plus the deterministic password-less.p12, including--out’s extension-replacement behavior) — and wires it into the Mailboxes command tree; installation stays on the client walk-through pages, now cross-linked. Documentation only: PATCH.
2026-07-23 — v0.40.3 (the gRPC RPC rosters now gate-fenced against the proto)
-
Docs-tooling: the two hand-maintained
SolanaMailRPC rosters are now gate-fenced. A new docs-gate leg,mail_docs/check_rpc_rosters.py, diffsmail_api/README.md‘s flat RPC list and the gateway topology appendix’s three role buckets against the service definition inmail_api/protos/sithbit.proto: name-set equality both ways, the buckets’ union covering the proto set with no RPC claimed by two roles, and — where a bucket is introduced by an English number word (“Five RPCs”, “Thirteen RPCs”) — that word matching the bucket’s own list length. Both rosters had silently gone stale twice before (most recently the chain-read bucket omitting v0.40.0’sGetPinLease, caught only by hand at v0.40.1) — that drift class now fails the gate instead of waiting for a manual sweep. Docs tooling only, no protocol or server change: PATCH. -
Docs-tooling: the committed capture tooling now reproduces the webmail settings screenshot on its own.
capture-populated.mjs’s webmail pass now scrolls the settings page to the Pinning-leases pane — the shot’s subject, which sits below the fold — before shootingwebmail-settings.png; previously the committed image was reproducible only with an uncommitted modification to the capture driver. The upstreamed step’s output was verified byte-identical to the committed PNG, so no screenshot changed. Docs tooling only, no protocol or server change: PATCH. -
The trustless viewer now hands the open message to the Pinning-leases pane in all four GUI shells (webmail, Thunderbird, Outlook, Chrome): a Lease this message button beside Reply — shown only once a body has rendered, since a local-only message has no CID to lease — dispatches a
sithbit-lease-open {cid, messageId}event that prefills the pane’s create fields with the message’s on-chain CID and id. In webmail and Outlook the prefill waits in the settings view where the pane lives; in Chrome and Thunderbird the pane sits above the viewer on the same page. Prefill only — the user still reviews the deposit and submits — and manual CID entry is unchanged. No committed screenshot changes appearance (the new button is unreachable in every committed capture). Client-side UI only, no protocol or on-chain ABI change: PATCH.
2026-07-23 — v0.40.2 (pinning leases reach the web clients)
- A Pinning leases pane in all four GUI shells (webmail, Thunderbird, Outlook, Chrome): the v0.40.0 pinning-lease surface — until now CLI-only — is now a shared dashboard pane. Create a lease by a message’s CID and id (the recipient defaults to your own mailbox, the deposit prefills to the protocol minimum straight from the on-chain constant, and the one-time creation fee splits to the recipient’s operator exactly as the CLI resolves it), check whether your wallet holds a lease on a CID, and close a lease anytime to reclaim the deposit — including after the message itself has settled, since the lease is addressed by the CID. The transactions are built and signed in the shared wasm module, byte-parity-fenced against the CLI’s own builders, and the pane is documented on each client page. Client-side UI only, no protocol or server change: PATCH.
2026-07-22 — v0.40.1 (the sender-reputation figures reach the gRPC gateway)
- New
GetSenderReputationRPC on theSolanaMailservice: wallet in, the recorded cumulative postage spend and the effective first-contact rate in bps out — the same two figures as the CLI’ssithbit postoffice reputation, computed through the same fenced on-chain rule (tuned floor included), so MX operators and other servers can weigh a sender’s on-chain track record without shelling out to the CLI. Absent reputation account = the ordinary zero-spend/full-price answer; a failed chain read surfaces asUNAVAILABLErather than masquerading as zero spend. The gateway topology appendix’s chain-read role now counts all thirteen read RPCs (it had also omitted v0.40.0’sGetPinLease). Additive gRPC surface, no on-chain ABI change: PATCH. - The settings pane’s wallet-derived mail password is now real markup in all four shells (webmail, Thunderbird, Outlook, Chrome — the pane logic existed but no shell rendered it): a Derive mail password button, gated on the wallet being unlocked, with the same one-time reveal pattern as the encryption-key pane — username and derived password computed entirely client-side (see The mail password). A reactivity fix rides along: unlocking the wallet now re-renders the derive gate immediately (it previously stayed on the “unlock your wallet” hint until a reload). The webmail settings screenshot was re-shot to show the new section. Client-side UI only, no protocol or server change: PATCH.
sithbit mailbox create-certand the extensions’ Certificate sign-in now emit a combined.p12: the CLI writes<name>.p12— a password-less PKCS#12 bundle (certificate + unencrypted key, deterministic per wallet) — beside the PEM pair whenever--outis given, the wasm module derives the byte-identical bundle client-side, and both the Thunderbird and Outlook extensions’ Download client certificate button now saves<pubkey>.p12first, ahead of the PEM pair. The client pages’ certificate-login walkthroughs drop the manualopenssl pkcs12 -exportconversion step — the bundle imports in one step (leave the password prompt blank) — and note that the.p12, like the.key, embeds the wallet secret. Client surface only (CLI output + extension download), no protocol or server change: PATCH.
2026-07-22 — v0.40.0 (pinning leases: paid extended retention for mail bodies)
- New: pinning leases —
a per-(CID, holder) mail-program account
(
sithbit mail lease create/show/close) escrowing a reclaimable deposit (minimum 0.01 SOL, returned in full at close) that asks operators to keep a message body pinned past the default retention. Deliberately no expiry and no renewal fee; the only spend is a one-time creation fee (default 0.001 SOL, cap 10×, tunable viaSetPinLeaseFee/ read-onlypostoffice fee pin-lease) split with the recipient’s domain authority at the operator share. New instructionsCreatePinLease(49) /ClosePinLease(50) /SetPinLeaseFee(51), errors 103–105, Postoffice 192→200; see the economics rationale and the program reference. - The auto-settle sweeper
enforces leases with no new configuration: before releasing a pin it
asks the gateway’s new
GetPinLeaseRPC whether the CID is leased — a leased copy still settles (the stamp reclaim is unaffected) but keeps its pin; an unanswerable lookup fails closed and the copy retries next sweep. - The privacy reference on-chain account table gains the PinLease row (a lease publicly binds its holder wallet to a message CID), and the compute-units table the three new fences.
2026-07-22 — v0.39.2 (small-item cleanup: cheaper first-contact purchases, fee visibility, reference completeness)
- CreateFrombox on the default reputation tail costs ~27% less compute: the pricing pass’s postoffice and reputation reads now thread through to the fee-collection leg instead of being re-derived (the second postoffice PDA grind was the bulk of the cost). Measured CU dropped 48,625 → 35,256 and the fenced ceiling 72,000 → 58,000 — see Compute-unit budgets. No account-list, fee, or pricing change: PATCH.
sithbit postoffice fee attestationjoins the public read-only fee getters: it prints the effective one-time verified-sender attestation fee and its cap without a signature, in every CLI build. The read-surface list also now names thefee settlementgetter it had omitted.- Reference de-staling: the
mail-grpc topology appendix’s
chain-read role now counts all eleven read RPCs (it omitted
ListParticipantsandGetSenderAttestation), and the privacy field reference’s on-chain account table grew from nine rows to the full eighteen account types — adding the marketplace escrow/bid accounts, the participant beacon, the sender attestation/reputation records, and the three pending-timelock markers.
2026-07-22 — v0.39.1 (the verified-sender trust mark reaches the web clients)
- The readers now show a “✓ Verified” trust mark beside the From line when the sender holds an on-chain verified-sender attestation from its domain — the deferred client half of the v0.38.0 trust-mark decision, across all four shells (webmail, Thunderbird, Outlook, Chrome). The api-backed reader resolves the From address to a wallet on-chain and checks that wallet’s attestation; the trustless viewer binds the program-verified envelope signer instead. Absence renders nothing — no negative indicator. See Using it (the inbox screenshot now shows the mark).
- The web compose/prepay paths now pass the payer’s attestation to the first-contact frombox purchase when it exists on-chain (one existence check, the CLI’s default since v0.39.0) — so an attested org’s webmail first contact prices at the floor without any CLI step. Top-ups are unchanged (attestation affects first-contact pricing only). No ABI or fee-rule change: PATCH.
2026-07-22 — v0.39.0 (reputation-scaled sender friction: proven senders pay less at first contact)
- The default price a stranger pays at first contact now scales with the
sender wallet’s on-chain track record. New
Reputation-scaled first-contact pricing
section: a per-wallet
SenderReputationaccount (new mail-sidesender_reputationPDA seed — see the PDA seeds table) records the wallet’s cumulative distinct-recipient postage spend atCreateFromboxtime, and that spend steps the default first-contact rate: 10,000 bps (full default postage) below 0.1 SOL of spend, 7,500 from 0.1 SOL, 5,000 from 1 SOL, 2,500 from 10 SOL. A verified-sender attestation prices first contact at the floor immediately. Recipient-set prices are never touched — only the default a stranger inherits — and a nonzero price never rounds to zero: first contact is never free. Owner (self) purchases stay on the legacy path, unaffected. - The discount floor is delegate-tunable: new mail-side
SetReputationFloorinstruction (discriminant 48,sithbit postmaster fee reputation-floor <BPS>) tunesreputation_floor_bps(defaultDEFAULT_REPUTATION_FLOOR_BPS= 1,000 bps = 10% of the recipient’s default postage, capped atMAX_REPUTATION_FLOOR_BPS= 10,000; over-cap refuses with new custom error 102ReputationFloorAboveCap, and a zero rate stores the “unset” sentinel and resolves to the default). The postoffice account grew 184→192 bytes (versioned reads default older accounts; the setter upgrades in place). See the tunable-constants table and the error-codes tail. - Third-party stamp purchases now carry a reputation tail by default:
CreateFromboxaccepts 6/8/9/10-account forms — the CLI and wasm builders emit the 9-account form (operator pair + the payer’s sender-reputation PDA, lazily created rent-exempt) on every third-party create, and append the payer’s attestation as a tenth account when one exists on-chain. A present-but-invalid attestation fails the purchase (error 19 / error 17) instead of silently repricing. See Reputation-scaled first contact on the stamps page, which also documents the new read-onlysithbit postoffice reputation <WALLET>lookup (cumulative spend + effective first-contact rate in bps, floor included) and the floor setter. - The wasm frombox builders (
create_frombox_tx/create_frombox_unsigned) gained a trailing optionalattestationparameter and emit the 9-account reputation tail on third-party creates; existing JS callers are unaffected. - The compute-unit table’s
CreateFromboxrow now measures the 9-account default-tail path — 48,625 CU measured / 72,000 fenced (the old 12,251 / 35,000 row measured the owner-legacy list) — andSetReputationFloorlands at 6,756 / 30,000.
2026-07-22 — v0.38.0 (verified-sender attestation: a domain vouches for its sending wallet)
- A domain can now attest its sending wallets on-chain. New
Verified-sender attestation
concept page and
Attest a verified sender
CLI reference: a sending organization proves control of its domain’s
DNS — the same staged DNSSEC proof
domain authorizerides — and mints aSenderAttestationrecord binding the domain to a wallet, the protocol’s trust mark for organizational senders. Attesting requires noMailDomainaccount and confers no serving rights; a domain may attest any number of wallets, one revocable record per (domain, wallet) pair. - Two new domain-program instructions:
AttestSender(discriminant 17, permissionless — the attested wallet rides the payload) andRevokeSenderAttestation(18, holder-signed close with rent refund; the PDA re-derives from the signer, so no other key reaches the record), plus the newsender_attestationPDA seed — see the program reference and the new blake3 table row. - The attestation fee is delegate-tunable: new mail-side
SetSenderAttestationFeeinstruction (discriminant 47,sithbit postmaster fee attestation <LAMPORTS>) tunes the one-time feeAttestSenderpays the postoffice (defaultDEFAULT_SENDER_ATTESTATION_FEE_LAMPORTS= 0.01 SOL, capped atMAX_SENDER_ATTESTATION_FEE_LAMPORTS= 0.1 SOL; over-cap refuses with new custom error 101SenderAttestationFeeAboveCap, and a zero fee stores the “unset” sentinel and resolves to the default). The postoffice account grew 176→184 bytes (versioned reads default older accounts; the setter upgrades in place). See the tunable-constants table. - Both query surfaces ship: the read-only
sithbit domain attestation <MAIL_DOMAIN> <WALLET>lookup (every build), and the gRPC gateway’s newGetSenderAttestationcall —{domain, wallet}→{attested, attested_at}, where a clean absence answersattested = falseand a failed chain read isUNAVAILABLE, never afalse. A client badge over these reads is planned but not yet shipped. See Looking up an attestation. - The compute-unit table’s three attestation
rows (landed with the measurement suite) are part of this release:
AttestSender322,474 CU measured / 345,000 fenced,RevokeSenderAttestation11,224 / 34,000,SetSenderAttestationFee6,546 / 30,000.
2026-07-22 — v0.37.0 (client-certificate download from the extensions)
- The Thunderbird
and Outlook
client pages’ certificate-login sections now document the extension
path: each extension’s settings surface gained a “Certificate
sign-in” section whose Download client certificate button derives the
<pubkey>.crt/<pubkey>.keypair in-extension — byte-identical tosithbit mailbox create-cert’s output, and deterministic per wallet (re-downloading anywhere yields the identical certificate). Import into the mail client or OS store stays manual; locked and external (Phantom/Ledger) wallets cannot derive and the CLI path remains the canonical route.
2026-07-22 — v0.37.0 (privacy concept diagrams)
- The What’s public and private page gained two concept diagrams: one under What your operator holds showing where a password-less account’s mail sits and what at-rest sealing does and does not protect against, and one under What you control laying out the five account-holder privacy settings and their defaults.
2026-07-22 — v0.37.0 (do-not-disturb vs. autoresponder diagram)
- The Do not disturb
concept page gained a side-by-side diagram contrasting the classic
accept-and-autoreply flow (mail piles up with postage to settle; the
“I’m away” reply may never reach the sender) with SithBit’s
refuse-at-the-door
450(the sender’s own mail server queues and retries; nothing piles up and no stamp is burned).
2026-07-21 — v0.37.0 (stamp-fee operator split + honest gRPC fee fields)
- The per-stamp protocol fee now splits with the recipient’s MX
operator.
CreateFrombox/AddStampsaccept an optional trailing “operator tail” — the recipient’s mailbox, its named domain, and the domain authority. When present (the CLI, wasm builders, and web prepay all build it automatically), the authority receivesoperator_share_bps(default 10%) of the hybrid fee and the postoffice the remainder; the buyer’s total is unchanged. Lapse and filler rules mirror the settlement share, and legacy account lists keep the whole fee with the postoffice — the tail is optional, so no client breaks and no instruction payload changed. The owner waiver still precedes the split. See The per-stamp protocol fee. FromboxResponsecan now say “fee unknown”. Newbool stamp_fee_known(field 6) on the gRPC response:falsemeans the gateway’s postoffice read failed and the two fee arms are 0 — unknown, not free — which no value convention could express since a stored flat fee of 0 legitimately charges nothing. The failed read stays non-fatal and uncached.- The wasm frombox builders (
create_frombox_tx/add_stamps_txand their unsigned twins) gained trailing optionaloperator_domain/operator_authorityparameters (both-or-neither); existing callers are unaffected.
2026-07-21 — v0.36.0 (Core Concepts go GUI-first, with concept graphics)
- Every Core Concepts page now points at the GUI clients first. The
Addresses, Mailboxes,
Fromboxes, Aliases,
Domains, Email,
and marketplace pages describe each
user action via the getting-started wizard, the client
panes, and the marketplace web page; the
sithbitCLI equivalents moved into footnotes (or stay inline only where no GUI exists — domain registration, auctions, escrowed transfers, and the advertiser campaign flow). - Four new concept diagrams: Mailboxes gained the address–mailbox–aliases relationship, Fromboxes the sender–recipient–postage triangle, The Marketplace a three-stall market-square map of names, domains, and attention, and Privacy’s one-line summary a public-envelope vs sealed-letter split view. (Campaigns already carries its lifecycle diagram.)
2026-07-21 — v0.36.0 (glossary: sans-io)
- The glossary gained a sans-io entry, and the term’s mentions on Standards and RFC coverage now link to it (hover for the definition tooltip).
2026-07-21 — v0.36.0 (settlement basis-point rates: hybrid stamp fee + tunable operator share)
- The per-stamp protocol fee is now a hybrid: third-party stamp
purchases at
AddStamps/CreateFromboxpay the greater of the flat per-stamp fee and a bps share of the escrowed postage (stamp_fee_bps, defaultDEFAULT_STAMP_FEE_BPS= 100 = 1%, capped atMAX_STAMP_FEE_BPS= 1 000). At the defaults the arms cross at 0.01 SOL of postage per stamp — cheap friend-tier stamps still pay the flat fee, while a default-priced 1-SOL stranger stamp now pays 0.01 SOL instead of 0.0001. The recipient-self-funding waiver covers the whole hybrid unchanged (“friends mail you free” is untouched), and the refundable signature surcharge is never in the bps base. See The per-stamp protocol fee. - The operator share is now delegate-tunable: the 10%
OPERATOR_SHARE_BPSsplit atDeleteMailsettlements, reply-bounty claims, escrowed alias transfers, marketplace sales, and auction settlements now reads the postoffice’soperator_share_bpsfield (default 1 000 = today’s behavior, capped atMAX_OPERATOR_SHARE_BPS= 2 000). Behavior at the default is byte-identical; an unreadable postoffice charges the protocol defaults (the rate read never blocks a settlement). - New
SetSettlementBpsinstruction (discriminant 46, delegate-only) sets both rates in one instruction; over-cap rates refuse with new custom errors 99OperatorShareBpsAboveCap/ 100StampFeeBpsAboveCap. A zero rate stores the “unset” sentinel and resolves to its protocol default — the bps rates cannot be tuned to literal zero. The postoffice account grew 160→176 bytes (versioned reads default older accounts; writers upgrade in place). See the program reference and the tunable-constants table. - Every quote surface knows the hybrid:
sithbit postoffice fee stampprints both arms, the newsithbit postoffice fee settlement/sithbit postmaster fee settlement <OPERATOR_SHARE_BPS> <STAMP_FEE_BPS>read and tune the rates (Postmaster administration), the CLI stamp-purchase preview quotes the hybrid against the actual postage, the gRPCFromboxResponsegainedstamp_fee_bps, and the webmail prepay card and onboarding funding page price quotes through a new wasmstamp_purchase_feeexport. - New section: Modeling the postoffice’s revenue base — the honest segmentation (waived owner purchases, flat-dominant friend tiers, priced-out strangers) that motivates the settlement rates as the scalable, capped levers.
2026-07-21 — v0.35.0 (length-tiered premium pricing for short alias names)
- Registering a 1–4 character alias now pays a per-length premium claim
fee instead of the flat fee; names of 5 or more characters are
unchanged. Defaults: 10 SOL (1 char), 1 SOL (2), 0.1 SOL (3), 0.05 SOL
(4) — short names are scarce assets (36 one-character combinations) and
are priced accordingly, on the registrant’s side per the positioning
principle. The schedule lives on the postoffice
(
ALIAS_TIER_FEES_LAMPORTS, account grown 128→160 bytes, versioned reads default older accounts) and is delegate-tunable via the newSetAliasTierFeesinstruction (discriminant 45), each slot capped at 10× its default (MAX_ALIAS_TIER_FEES_LAMPORTS; over-cap refuses with new custom error 98AliasTierFeeAboveCap). See Economics — Alias holders and the tunable-constants table. - Delegate reservations stay fee-free at every length — the postmaster reserves premium short names for rent alone and resells them on the marketplace at seller-set prices; see Reserve aliases in bulk.
- The price always shows before you pay.
sithbit alias createprints a fee preview (per premium name + run total, or the delegate waiver notice),sithbit postoffice fee aliasprints the effective per-length schedule with its caps, and the newsithbit postmaster fee alias-tiers <1> <2> <3> <4>tunes it — see Create an alias and Postmaster administration. The webmail aliases pane quotes “Registration fee: N SOL” live as you type (from the fetched postoffice account, protocol defaults when unreadable), and the onboarding wizard’s funding check prices a premium handle by its length.
2026-07-21 — v0.34.0 (IMAP SPECIAL-USE mailbox attributes, Tier 1)
- The IMAP server now advertises
SPECIAL-USE(RFC 6154) and marks the well-known top-level mailbox names —Sent,Trash,Drafts,Junk(alsoSpam),Archive— with their\Sent-style attributes in LIST responses, case-insensitively, so clients file sent/deleted/draft mail into the same folders everywhere. INBOX and nested names carry no role; theLIST (SPECIAL-USE)selection filter andCREATE-SPECIAL-USEare not supported. See the Standards support IMAP table.
2026-07-21 — v0.33.0 (IMAP advertises SASL-IR)
- The IMAP server now advertises
SASL-IR(RFC 4959) in the greeting and CAPABILITY responses, wherever theAUTH=mechanisms are offered. The initial-response form of AUTHENTICATE was already accepted; the advertisement lets clients discover it instead of probing. See the Standards support IMAP table.
2026-07-21 — v0.32.0 (docs: setup and earnings join the SithBit CLI; onboarding leads with the web wizard)
Documentation-only: the version tags the unchanged protocol state.
- The two CLI walkthroughs move into the SithBit CLI reference tree:
First-run setup (
sithbit setup, now the tree’s first subtopic) and Revenue snapshot (sithbit earnings, between Campaigns and Closing accounts). Cross-links follow (Fromboxes’ USD-annotation pointer, the CLI Quickstart’s walkthrough link, and Solana clusters’ faucet note). - “Setup and earnings” becomes Getting started — the page now opens with the browser wizard the four web clients share (the audience most users belong to), keeps the standalone get-started and refused-sender pages, and points terminal-comfortable readers at the two relocated CLI topics. The page’s URL and section anchors are unchanged.
2026-07-21 — v0.32.0 (docs: tables wrap in place instead of scrolling)
Documentation-only: the version tags the unchanged protocol state.
- Prose tables no longer cut off their last column behind mdBook’s
horizontal scrollbar — felt hardest in the Configuration
reference’s key/default/meaning tables.
Book-wide CSS (
css/brand.css) now spans tables across the text column, slims the cell padding, left-aligns headers, and lets long tokens in every column but the first break at the overflow point (config keys never break mid-token; a width floor keeps “Default” readable beside a long “Meaning”).
2026-07-21 — v0.32.0 (docs: deploy-page service table and provider links)
Documentation-only: the version tags the unchanged protocol state.
- Running a mail server’s service table now lists
the optionally-embedded IPFS node among
sithbitd’s roles, with its “needed when” column noting that role applies only under[ipfs] kind = "embedded"— a fleet delegates tosithbit-ipfsdor a pinning service instead. - Choosing a commodity provider — each provider name now links to that provider’s developer sign-up page (or product home page where sign-up URLs are region-specific).
2026-07-21 — v0.32.0 (docs: Icon legend joins the Glossary)
Documentation-only: the version tags the unchanged protocol state.
- The Icon legend now sits in the Glossary
sidebar section, right after Terms and
definitions, instead of under Appendix: Reference —
the two term-lookup pages now live side by side. The source file (and its
deployed URL) is unchanged; only the
SUMMARY.mdplacement moved.
2026-07-21 — v0.32.0 (docs: landing-page hero leads with earned postage)
Documentation-only: the version tags the unchanged protocol state.
- Welcome landing tweaks — the hero paragraph now says the sender-paid postage is earned by you, not just that it prices out spam, and the “No gatekeeper, no single company” card drops its featured accent border to sit as a regular card; the spam-pricing card is the page’s only featured one.
2026-07-21 — v0.32.0 (sithbitd installs as a systemd or Windows service)
MINOR — an additive deployment capability.
- Running as an OS service —
the new
sithbitd service install/sithbitd service uninstallsubcommands install the daemon under systemd (a generated unit file with restart-on-failure, network ordering, and commented unprivileged-user/low-port-capability lines;--printrenders it without writing) or the Windows service control manager (an auto-start registration whose internalservice runverb re-anchors the recorded working directory and config before the daemon boots). Neither install activates anything behind the operator’s back — thesystemctl/Start-Servicestep is printed, not run.
2026-07-21 — v0.31.0 (Closing accounts joins the SithBit CLI reference)
PATCH — documentation-only.
- The closing-accounts reference now lives in the SithBit CLI tree as
its Closing accounts
subtopic, right after Campaigns — retitled from “Closing accounts and
reclaiming rent”, following the campaign reference out of the appendix.
All cross-links follow, and the old deployed URL
(
appendix/closing-accounts.html) redirects to the new page so external bookmarks keep working.
2026-07-21 — v0.31.0 (Campaign CLI reference moved under the SithBit CLI)
PATCH — documentation-only.
- The
sithbit campaignreference now lives in the SithBit CLI tree as its Campaigns subtopic, beside the other command references, instead of in the appendix. All cross-links follow, and the old deployed URL (appendix/campaign-cli.html) redirects to the new page so external bookmarks keep working.
2026-07-21 — v0.31.0 (Sponsored mailbox creation: a domain authority provisions for its users)
MINOR — additive public-ABI change (a tail field on CreateMailbox and
on the Mailbox account, plus three appended error codes).
- A domain’s on-chain authority can now create a mailbox for a different
owner. Sponsored mailboxes
explains the concept and its three guards: only the named domain’s
authority may pay, the default postage is forced to the 1-SOL spam floor,
and no self-alias is bundled. The CLI surface is
mailbox create --for <address>(requires--domain). - The mailbox account records its funder, and closing refunds the funder.
The
Mailboxaccount gains a tailfunderfield (shown bymailbox getand the wasm account decoder);mailbox close --finalizenow routes the mailbox’s rent to the recorded funder — the owner itself on a self-created mailbox (unchanged), the sponsor on a sponsored one — with the CLI passing the funder account automatically. The pending-close account’s rent still refunds to the owner who funded the request. - Program & PDA reference
gains error codes 95–97 (
SponsoredMailboxRequiresDomain,UnauthorizedDomainSponsor,FunderAccountInfo) and updates theCreateMailbox/FinalizeCloseMailboxrows. This retires the lastTODOin the workspace’s Rust tree (the payer/owner split in the mail program’s create processor).
2026-07-21 — v0.30.1 (Navigation reorder: standards up front, clients first under Using SithBit)
PATCH — documentation-only.
- Standards and RFC coverage moved to the front matter, directly after the Introduction — the wire-compatibility story now greets a reader before the concept chapters instead of trailing them.
- “Using SithBit” reordered around the reader’s journey: GUI clients leads the section, followed by Setup and earnings (moved here from Core Concepts), with Economics after them.
- “RFC” is now a glossary term. The glossary’s Mail protocols section defines it, so RFC references linked to it get the standard hover tooltip; the standards page links its first prose mention.
2026-07-21 — v0.30.1 (Full sithbit-console tutorial and reference in the appendix)
PATCH — documentation-only.
- The
sithbit-consoleadmin TUI now has a full appendix page. The sithbit-console admin TUI documents the operator console end-to-end: prerequisites (a reachable account API and theadmin_walletsallowlist), running and configuring it, the wallet-challenge login, a tutorial through both tabs (Accounts → Mailboxes → Messages with chain states, the on-chain balances pane, queue depths and the confirmed dead-letter requeue/discard workflow with the cloud-store claim window), a complete key reference, the console’s deliberate scope limits (API-only, no store access, no chain writes), and a troubleshooting table. The job-queues section and the configuration reference now link to it; previously the console was documented only in fragments across those two pages.
2026-07-21 — v0.30.1 (Client pages note on-chain domain ownership for wallet submission)
PATCH — documentation-only.
- The Outlook and Thunderbird client pages now carry the on-chain-ownership
half of the wallet-submission envelope rule. Both
Outlook and
Thunderbird previously phrased
the sender rule as “your own wallet address at a domain the server serves /
is authoritative for”, which omitted the v0.29.0 enforcement: on a
chain-connected submission server the wallet must also own that domain
on-chain (its recorded
GetMailDomainauthority), not merely have the server serve it. The pages now state that nuance at end-user altitude and add the matching553 5.7.1refusal case; the full rule (including the chain-less-dev-stack fallback to server-served domains only) still lives in the configuration reference.
2026-07-21 — v0.30.0 (Onboarding wizard warns on an unfunded wallet before the mailbox create)
MINOR — a new client capability and default onboarding behavior.
- The web onboarding wizard now checks the wallet balance before it claims a mailbox. On the Review and Finish steps, a wallet that can’t cover the create cost (the account rents, plus the flat alias fee when a handle is claimed — about 0.0013 SOL bare, 0.0124 SOL with a handle) gets a plain-language warning naming the wallet, its balance, and how much more to transfer. The warning does not block the flow — you can fund the wallet out of band and continue.
- A funded-then-failed create no longer shows the raw chain error. If the create is attempted with too little SOL, the node’s “Attempt to debit an account but found no record of a prior credit” preflight rejection is rewritten into the same funding guidance, across the create, import, and connect-wallet paths.
- Single source of truth for the figure. The required-funding amount the
wizard quotes is computed by the same core routine the CLI
sithbit setupwizard uses, so the web and CLI figures can never drift.
2026-07-20 — v0.29.0 (Wallet submission envelope now checks on-chain domain ownership)
MINOR — a new enforcement default that affects deployments.
- A gateway-backed submission listener now requires the authenticated
wallet to own the envelope domain on-chain. For a wallet-literal
Wallet submission envelope,
a listener with a chain gateway (
[grpc]configured) no longer accepts<wallet>@<domain>merely because the domain is inlocal_domains; the domain must also be one the wallet is the recorded on-chain authority for, checked via the gateway’sGetMailDomainlookup (exact base58 match).local_domainsstill scopes which domains the listener serves; the authority check scopes which of those the authenticated wallet may send as. - Chain-disabled listeners are unchanged. A listener with no chain
gateway (an empty
[grpc]/ dev MX) has no per-wallet lookup available and falls back tolocal_domainsalone, so empty-config dev stacks keep sending.
2026-07-20 — v0.28.0 (Chrome extension gains trustless compose/reply parity)
MINOR — a new client capability and a new shipped default that affect deployments.
- The Chrome extension can now send trustlessly, at parity with webmail,
Thunderbird, and Outlook. The
Trustless viewer’s header
gains a Reply on-chain button, and the popup mounts the same floating
on-chain compose card the other GUI clients carry — a Compose on-chain
button opens it blank, Reply seeds it with the decrypted sender and the
parent message’s account address, and the seal → pin →
SendMaillifecycle is signed in the extension’s wasm module with no mail server in the path. - The extension ships a default IPFS pin origin. Connection settings
gains
ipfsPinUrl(defaulthttp://127.0.0.1:8182— an unauthenticated loopback sithbit-ipfsd) and its optionalipfsPinToken(default empty), where outbound sealed bodies are pinned; saving a non-loopback pin origin prompts for that host’s permission.
2026-07-20 — v0.27.1 (Second CID pointer linked on the mailbox page)
PATCH — documentation-only, no protocol change.
- The “Opting out of IPFS storage” section now links “CID”. The Opting out of IPFS storage prose said the on-chain message carries a “fetchable CID” as bare text; it now points to What is a CID?, matching the same page’s No-IPFS bullet, which already linked the term.
2026-07-20 — v0.27.0 (All nine dashboard panes documented on every GUI client; CID explained for non-technical readers)
PATCH — documentation and docs-tooling only, no protocol change.
- The Domains, Reply bounties, and Mailbox panes are now documented on all four GUI client pages. The Thunderbird, Outlook, Chrome and webmail pages previously described only six of the nine shared dashboard panes; the domain-marketplace pane (list or buy a domain), the reply-bounty settlement pane (claim a bounty on a message you replied to, or refund an expired one you placed), and the mailbox-config pane (claim the mailbox and set its handle, sending domain, default stamp price, and opt-out-of-IPFS flag) are now described on each, in that page’s own form.
- “CID” is now explained for non-technical readers. The
IPFS storage: benefits page opens
with a new “What is a CID?” section that explains a content identifier as a
fingerprint computed from a message’s exact bytes — the same content always
yields the same CID (so it is the address you fetch by) and any change yields
a different one (so it doubles as a tamper check) — with a two-row
illustration and a note that SithBit produces CIDv1 byte-for-byte identically
to Kubo. The glossary’s terse
CIDentry now links to it. - Docs-tooling: the mailbox-close timelock figure is now fenced. A new
mail_docs/check_timelock.pygate leg parsesMAILBOX_CLOSE_TIMELOCK_SECSfrommail_model/src/constants.rsand asserts, both ways, that the “7 days” quoted in the mailbox-close docs matches it — so retuning the constant or drifting the prose fails the docs gate. It is scoped by an explicit allowlist plus a mailbox-close context filter, so the identical “7 days” literal used for the domain-deactivation, reclaim, and bounty-window constants is not swept in. - The dashboard chain panes now load over a direct RPC connection, not only the account API. Balances, the encryption key, mailbox settings and the mailbox-close request now populate for a wallet-unlocked client with no account API configured — previously they re-rendered but stayed empty until an API token existed. The Aliases pane still needs the API, since there is no on-chain alias index to read directly. (The web-client screenshots were re-pinned to the updated source: this change is confined to the API-less load path, which the documentation screenshots — captured in API-backed mode — do not exercise, verified by re-capturing the inbox, settings and marketplace shots.)
- Docs-tooling:
check_anchors.pygains a--self-testleg. A checked-in, build-free fixture tree undermail_docs/tests/anchor_fixtures/(aclean/root that must exit 0 and abroken/root that must exit 1) proves the checker’s exit-code contract, mirroringcheck_links.py --self-test. Unlike the link fixtures, each anchor-fixture root ships both asrc/and a hand-authoredbook/HTML tree, because the checker validates#fragmentlinks against built-book anchors. It is a standalone dev command, not wired into the docs-gate chain; the defaultcheck_anchors.pyrun is unchanged.
See The Chrome extension, The webmail app and IPFS storage: benefits.
2026-07-20 — v0.27.0 (External wallets can buy stamps and claim a mailbox; Glossary promoted)
PATCH — client and docs only, no protocol change.
- External wallets (Phantom/Ledger) can now buy stamps and claim a mailbox. The dashboard gated those buttons on holding an unlocked in-app wallet key, even though the unsigned-transaction paths behind them were already wired and working for external wallets. Setting a stamp price, publishing an encryption key and settling reply bounties still require the in-app key — those have no unsigned equivalent — and the panes now say so specifically instead of telling every user to “unlock your wallet”.
- The mailbox-close pane is documented on the Thunderbird, Chrome, Outlook and webmail client pages, including the 7-day wait, that it is cancellable throughout, and that the encryption-key close stays instant. Outlook gained a full pane list, which it previously lacked entirely.
- The account-closing figure no longer shows
CloseMailboxas an instant one-step close; the mailbox and key legs now carry their own timings. local_domainson the submission listener is shown as a real configuration example rather than described in prose. Each SMTP role carries its own list — the MX section’s copy does not carry over — which is the domain half of the wallet-envelope rule.- The Glossary is now a top-level section in the navigation, immediately before Appendix: Reference. Its page keeps its existing address, so every existing link to it still works.
- The web-client screenshots were regenerated, which replaced a marketplace listings image that had been shipping as a blank page.
- The Core Concepts pages no longer assume you can read the source. References to internal file, function and type names, and to configuration keys and their file sections, have been rewritten as plain statements of what the system does — the concepts pages now explain the protocol without requiring a copy of the code beside them. Every fact those references carried is retained; only the way of stating it changed.
See GUI clients, Close a mailbox, Configuration and Terms and definitions.
2026-07-20 — v0.26.0 (Closing a mailbox is timelocked; the one-step close is disabled)
MINOR — BREAKING for clients that emit CloseMailbox. Closing a mailbox is
now a two-step, 7-day flow. RequestCloseMailbox (42) starts the clock and
refunds nothing — the mailbox stays open and keeps receiving mail;
FinalizeCloseMailbox (44), legal only after MAILBOX_CLOSE_TIMELOCK_SECS
(604,800 s), closes it and refunds the mailbox’s rent and the transient
pending record’s together; CancelCloseMailbox (43) aborts the request
meanwhile. The CLI spells these mailbox close, mailbox close --finalize
and mailbox close --cancel, and the flow is reachable in webmail, Outlook,
Thunderbird and Chrome, including trustless mode.
- The one-step
CloseMailbox(discriminant 16) is refused with error 94,InstantCloseDisabled. The discriminant still decodes, so indexers replaying history resolve old transactions — the same shape item 30 used forTransferAlias/UnilateralTransferDisabled(85). MAJOR stays0: the protocol is pre-launch. - New errors 91–94:
MailboxCloseAlreadyPending,NoPendingMailboxClose,MailboxCloseTimelockNotElapsed,InstantCloseDisabled. New PDA seedPENDING_MAILBOX_CLOSE_SEED(pending_mailbox_close) — the prefix is load-bearing twice over: the Mailbox PDA is bare-seeded on the address, andPendingMailboxClose,PendingDeactivationandPendingReclaimall serialize to the same eight bytes, so only the derivation distinguishes them. - Why a delay and not a fee. Instant rent reclamation made a burned sending identity free to discard. The owner of a mailbox is a recipient, and the positioning principle puts the cost burden on senders — so the lever is time, not money: the rent still comes back in full. Spammers get capital stuck for a week per burned identity and operators get a flagging window; honest owners see a delay on an action they take approximately never.
CloseKeydeliberately stays instant. It revokes a compromised delegated encryption key; a seven-day window there would leave MX servers sealing to a key the attacker holds, protecting the attacker rather than the owner.- Compute units: three new fenced rows — RequestCloseMailbox 13,334 / 36,000, CancelCloseMailbox 12,156 / 35,000, FinalizeCloseMailbox 12,858 / 36,000.
See Close a mailbox, Closing accounts, the threat model and Economics.
2026-07-20 — v0.25.0 (Wallet submission envelopes are pinned to the wallet’s own address)
MINOR — a new enforcement default on the submission path; no protocol
change. A wallet-authenticated submission session may now present exactly one
envelope sender: its own wallet base58, at a domain the listener is
authoritative for (local_domains). Another wallet’s address, its own address
at a domain the server does not serve, and the null sender MAIL FROM:<> are
all refused 553 5.7.1.
- The case-sensitivity fix is the security-relevant part. The previous rule
compared the envelope local part case-insensitively, which for base58 is
wrong:
Aliceandalicedecode to different keys, so a wallet session could send as a neighbouring valid wallet. The comparison is now exact. - Scope, stated honestly. The domain leg checks the domains this server serves, not the domains this wallet’s mailbox holds on-chain — the per-wallet reverse lookup is not reachable from the SMTP driver without new gateway surface. On a multi-domain instance a wallet may still send as itself at any domain that instance serves.
- Alias and password submission are byte-for-byte unchanged; the new rule is consulted only for wallet-literal identities.
- Dev-stack trap. With
local_domainsempty the check falls back tohostname, which the empty-config dev stack leaves aslocalhost, and the chain-disabled dev stack never discovers domains — so sending as<wallet>@sithbit.netthere now returns553where it previously worked. The refusal text names the sender, not the domain, so both the symptom and the one-line fix are written down. Note each SMTP role reads its ownlocal_domains: setting it under[smtp]does not affect the[submission]listener.
See Wallet submission envelopes, Thunderbird and Outlook.
2026-07-19 — v0.24.0 (Onboarding: passphrase confirmation, reachable connection settings)
PATCH — client/docs only, no protocol change. Four fixes found smoke-testing the Chrome extension loaded unpacked, all in shared client code, so every client gets them.
- Passphrase reveal and confirmation. The wallet passphrase set during onboarding could not be seen and was typed only once — and a typo there is unrecoverable: the wallet seals fine and only fails later, at unlock, with no way back. Every passphrase field now has a reveal (“eyeball”) toggle, and every field that sets a passphrase (the onboarding wizard’s step 1, the wallet manager’s import, the marketplace sign-in) now requires a matching confirmation before it will seal anything. See Web onboarding: the browser wizard.
- Connection settings are reachable during onboarding. In the Chrome extension they had been gated behind the signed-in view, which requires a registered on-chain mailbox — which in turn requires a reachable account API, the very thing those settings configure. With no API running, a new user was pinned in the onboarding wizard with no way to correct the URL or switch to trustless mode. They now sit in a collapsed disclosure at the foot of every view. See The Chrome extension.
- A meaningful message when the account API is unreachable. A refused
connection surfaced the browser’s bare
Failed to fetch. Clients now name the endpoint and the remedy, in language matched to the reader: a loopback URL means the reader runs the stack themselves, any other host means they are somebody’s mail customer. - A degraded popup no longer reads as broken. An unreachable account API is reported as a warning with the fix, and onboarding continues, instead of dumping a raw error and blocking.
2026-07-19 — v0.24.0 (Chrome extension: in-popup mail reader + side panel)
PATCH — client/docs only, no protocol change. The Chrome extension gains
a real in-popup mail reader, at parity with webmail: the shared three-pane
reader (folder rail, message list, message view, compose, and search) over the
account API’s /v1/mail surface when an account API
is reachable, and a trustless on-chain inbox (the mailbox’s messages listed
straight from Solana, bodies unsealed in wasm, no server) as the server-down
fallback and the only reader when the API url is left blank. The same surface
now also opens in Chrome’s persistent side panel via an Open in side
panel button (the toolbar-icon click still opens the transient popup). See
The Chrome extension.
2026-07-19 — v0.24.0 (Core Concepts section rename)
PATCH — docs only. The first documentation part, previously titled
Basic Concepts, is now Core Concepts in the navigation. Only the
displayed part title changed; the page URLs under basic-concepts/ are
unchanged, so existing links and bookmarks still resolve. (Earlier
change-history entries that name the old title are left as-is — they record
what the section was called at the time.)
2026-07-19 — v0.24.0 (Cloudflare backend: true multi-daemon writes)
MINOR — deployment-affecting default-behavior change. The cloudflare
store’s single-writer delivery caveat is removed: IMAP-uid allocation is now
a server-side atomic UPDATE … RETURNING on D1, and keyed leases moved from
Workers KV (best-effort, no CAS) to the same strict single-statement CAS the
SQLite/Turso stores run, on D1’s leases table — so any role may run
N-wide on Cloudflare, exactly as on postgres/aws/azure (see Scaling
out’s checklist and Which stores support
which split). The DMARC
drain also became one atomic DELETE … RETURNING, so concurrent daemons
partition report rows instead of double-reporting. The
[store.cloudflare]
kv_namespace_id key is retired: still accepted so existing TOMLs keep
parsing, but ignored, and no longer a required id — the KV namespace itself
is no longer a provisioning prerequisite. The Durable-Object route the
glossary recorded for this work was
superseded by these plain atomic D1 statements (no Worker-side code).
2026-07-18 — v0.23.0 (Addresses/Fromboxes/Email/Marketplace move into Basic Concepts + Technical Reference)
PATCH — docs only. Wave 1 of the docs audience reorg (item 42): Addresses, Fromboxes, Email, and Marketplace now split cleanly between a new Basic Concepts section (pure conceptual/explanatory prose, no CLI examples) and the CLI reference under Technical Reference → SithBit CLI. Every command-reference page now opens with a short referral link back to its concept page. Mailboxes, Aliases, Domains, and the GUI-clients pages are untouched this wave — the deferred remainder of the reorg. See Basic Concepts → Fromboxes and Basic Concepts → Email for the split’s shape.
2026-07-18 — v0.23.0 (CLI Quickstart relocated ahead of the docs audience reorg)
PATCH — docs only. The developer quickstart page moved from
getting-started.md to CLI Quickstart
under a new Technical Reference section, retitled to avoid colliding
with a future end-user “Getting Started” tutorial section (item 42’s
audience reorg, in progress). Operating a SithBit Server re-nested
under Technical Reference alongside it; no operator pages moved, only
the SUMMARY.md heading structure changed. Every inbound link across the
book was repointed to the new path.
2026-07-18 — v0.23.0 (DNS rows for the autoconfig/autodiscover hostnames)
PATCH — docs only. The DNS guide’s client-access
section now
spells out the two hostname records the native-wizard fallback path
needs — autoconfig.<domain> and autodiscover.<domain> pointed at the
domain-sithbit host — with the TLS-certificate SAN caveat. The routes
themselves were already documented on the
domain-sithbit page;
the zone-side half was missing.
2026-07-18 — v0.23.0 (compute-unit table now gate-fenced against the suite)
PATCH — docs tooling. A new docs-gate leg, mail_docs/check_cu_rows.py,
diffs the compute-unit table’s
measured/ceiling values against the integration suite’s fenced constants
(mail_client/tests/api/cu.rs), both ways, and checks the methodology
prose still quotes the suite’s grind allowance. The rounded-auction-rows
drift the previous entry corrects had sat silent since the auction wave —
this class of drift now fails the gate instead of waiting for a manual
sweep.
2026-07-18 — v0.23.0 (auction rows now quote exact measured CU)
PATCH — docs only. In the compute-unit table, the three auction rows had rounded “Measured CU” values while every other row quotes the integration suite’s exact fenced measurement. Aligned to the suite’s constants: SellAlias (open auction) 26,800 → 26,798, BidAlias 19,700 → 19,715, SettleAuction 26,700 → 26,674. Ceilings unchanged; all 25 rows now match the suite exactly.
2026-07-18 — v0.23.0 (cancel-instruction CU ceilings documented)
PATCH — docs only. The compute-unit table
now covers the three marketplace cancel flows fenced by the integration
suite: CancelTransferAlias (alias transfer cancel, 24,828 measured /
48,000 ceiling), CancelAliasListing (alias sell --cancel, 19,183 /
42,000), and CancelDomainListing (domain sell --cancel, 16,001 /
39,000). The methodology’s bump-grind variance note gains
alias transfer cancel as the widest swing recorded (9,816–24,828 CU).
2026-07-18 — v0.23.0 (threat-model lockbox metadata retitle)
PATCH — docs only. In the threat model, the lockbox scope bullet formerly led “Body only, in v1.” — stale now that the v2 sealed-envelope engine has landed. Retitled “Metadata stays visible.”: the SMTP envelope and headers travel unsealed regardless of lockbox version; the bullet’s substance is unchanged.
2026-07-18 — v0.23.0 (opt-in wallet-literal recipients on a chain-less MX)
MINOR — new configuration setting (default preserves existing behavior everywhere):
[smtp] accept_wallet_literals(defaultfalse). A chain-less MX (no[grpc]configured) refuses every recipient today; with this switch on, it accepts syntactically valid 32-byte base58 wallet-literal local parts — mirroring the account API’s chain-less compose route, where a literal wallet resolves to itself. No postage check applies on that path (no chain to consult), which is why the default stays off: leaving it unset keeps the postage gate intact and behavior byte-identical. Inert when[grpc]is configured. Applies tosithbitdand the standalonesmtp-serveralike. See Configuration.
2026-07-18 — v0.22.0 (marketplace guards: no deactivation while listed, no sale of an inactive domain)
MINOR — additive on-chain behavior change (new refusals using existing error codes; one instruction gains a required account):
RequestDeactivateDomainrefuses while a listing is open. The instruction now takes the domain-listing PDA as a required read-only account and refuses withDomainHasPendingListing(code 64) when a marketplace listing stands — a deactivation can no longer be staged under a live listing. Thesithbit domain deactivatebuilder passes the new account. See Program reference → Marketplace.BuyDomainrefuses an inactive domain. Settlement now re-checksis_activeat purchase time and refuses withInactiveDomain(code 25) — a deactivation finalized after listing can no longer sell a dead name. Inactive domains stay listable by design; the sale completes once the domain is reactivated. (An in-flight pending deactivation was already refused at buy time, code 29.)- Reference corrections riding the change:
DeactivationAlreadyPendingis code 29 (the page said 28), andBuyDomain’s account list is 9 slots (the row predated the pending-reclaim slot).
2026-07-18 — v0.21.1 (devnet keypair locations reconciled)
PATCH — repository layout and documentation only (no code behavior, on-chain ABI, instruction, error-code, or configuration change):
- Keypair homes reconciled.
keypair/again holds the mainnet-track vanity keypairs for all three programs; the live devnet mail/alias program keypairs moved beside the domain one atmail_client/tests/*-dev-keypair.json(the retired first-generation devnet pair is now git-history-only). The devnet vanity-ID appendix’s keypair-location prose and bothcpstaging workflows now reflect the layout, and the per-program README deploy snippets are correct as written again.
2026-07-18 — v0.21.0 (lockbox envelope: rich HTML + attachments in the engine)
MINOR — additive capability in the shared lockbox engine (no on-chain ABI, instruction, error-code, or configuration change; the shipped plugins’ user-facing behavior is unchanged today):
- The sealed payload is now a structured envelope. The shared compose/read engine seals a JSON envelope carrying the text body plus, when the sending client supplies them, rich HTML and attachments — as one sealed unit, with no wasm or on-chain change. Messages sealed by earlier versions remain readable (bare-body fallback). A 12 MiB pre-seal ceiling refuses oversized payloads with a clear error (sized so the double-base64 result clears the SMTP server’s default 25 MiB message-size limit). The Thunderbird and Outlook plugins still hand the engine only the plaintext body — host-side compose glue for HTML/attachments is a planned addition. See How it works and What v1 does — and does not — do.
2026-07-18 — v0.20.7 (smoke script rebuilds images)
PATCH — tooling and documentation only (no code behavior, on-chain ABI, instruction, error-code, or economic change; no configuration key, value, or default moves):
docker/smoke.shrebuilds before probing — the script now brings the compose stack up withdocker compose up -d --build, so a standalone smoke run rebuilds the images instead of silently probing stale local ones (the already-exportedchainprofile covers themail-grpcbuild too). Documented in The compose dev stack.
2026-07-18 — v0.20.6 (web-client terminology sweep)
PATCH — code comments only (no rendered UI, logic, or configuration change):
- “knob” retired from the web clients — the eight remaining
occurrences in
webclients/source comments (the shared panes and onboarding-wizard modules, and the fund/DND standalone pages’ operator-endpoint headers) now read “setting”, completing the v0.20.1/v0.20.4/v0.20.5 terminology sweeps. The screenshot manifest was re-pinned hash-only — no pixel changed, so the recorded captures remain valid.
2026-07-18 — v0.20.5 (build-features heading & terminology polish)
PATCH — documentation and comments only (no code behavior, on-chain ABI, instruction, error-code, or economic change; no configuration key, value, or default moves):
- Deploy’s build-features section renamed — the heading is now
Slim-build features
(formerly “Storage-backend build features”), reflecting everything
the section grew to cover: the storage backends and the key-source
(
akv/asm/gsm) and app-config (awsconf/azconf) cloud features. Inbound links in Deploy, Scaling out, and this page’s earlier entries follow the new anchor (URL only — the old entries keep their wording). - Configuration-reference cross-links — the key-sources and cloud-app-config passages in the configuration reference each point at Slim-build features for the per-binary slim build commands.
- Terminology residuals — the retired “knob” leaves its last
holdouts (the
ipfs_daemonandipfs_gatewaycrate READMEs and acheck_config_keys.pycomment; now “setting”), completing the v0.20.1/v0.20.4 sweeps.
2026-07-17 — v0.20.4 (terminology sweep completed in source)
PATCH — source comments and example-config prose only (no code behavior, on-chain ABI, instruction, error-code, or economic change; no configuration key, value, or default moves):
- Terminology sweep, source side — the informal “knob” is now retired
from the Rust source comments and test names (
mail_spooler,smtp_server,account_api,mail_store,mail_client,mail_grpc,ipfs_swarm,pop3_proto,app_config,key_source) and from the prose comments of the two canonical example configs (sithbitd.example.toml,sithbit_ipfsd.example.toml), completing the v0.20.1 book sweep. Same standing rule, same replacements: “switch” for boolean enable/disable entries, “setting”/“option” for tunable values, and case-appropriate rewrites (e.g. “deliberately not configurable”) elsewhere. Meaning is unchanged everywhere; earlier entries on this page keep their wording as the record of the retired term.
2026-07-17 — v0.20.3 (slim per-binary builds)
PATCH — build features and documentation only (no on-chain ABI, instruction, error-code, or economic change; a default build compiles the exact same feature set as before):
- Slim per-binary builds are now real — every binary crate forwards
its dependencies’ cloud features under the same names, so
--no-default-features --features <what you need>works at the binary you actually build. Forwarded alongside the storage backends:akv/asm/gsm(the credential-sealing key source’s cloud secret managers) andawsconf/azconf(the cloud app-config sources). See the build-features section for concrete slim build commands. Defaults still compile every cloud; a config naming a compiled-out cloud parses in every build and fails at load with a purposefulNotCompilederror naming the cargo feature to rebuild with. mail_store’s key-source edge is feature-forwarded — its formerly unconditional dependency on all ofkey-source’s clouds now follows the same per-cloud features, so store-consuming binaries can strip clouds too.
2026-07-17 — v0.20.2 (compose smoke runs mail-grpc live)
PATCH — dev/CI tooling and documentation only (no on-chain ABI, instruction, error-code, or economic change; nothing a deployment configures moves):
docker/smoke.shnow boots thechainprofile live — it exportsCOMPOSE_PROFILES=chainfor every compose call it makes (teardown included), somail-grpcstarts with the rest of the compose dev stack and must pass the healthy-wait. No validator is required: the gateway’s readiness gates on its own gRPC listener, never on chain connectivity. The previous smoke only statically parsed the profile (docker compose --profile chain config -q), which let a stale broken image sit undetected on a dev host — the live boot caught exactly such an image on landing.- CI’s smoke job lifts the profile too
(
.github/workflows/docker-publish.yml): the job-levelCOMPOSE_PROFILESbuilds the mail-grpc image alongside the other five before the smoke runs, so the gRPC gateway is exercised live on every push and pull request, not merely compiled.
2026-07-17 — v0.20.1 (terminology sweep: “knob”)
PATCH — documentation only (no code change):
- Terminology sweep across the book, per style direction: the informal “knob” gives way to industry-standard terms — “switch” for boolean enable/disable entries, “setting”/“option” for tunable values, and “settings” for collections. Meaning is unchanged everywhere, including in earlier entries on this page, which keep their versions, dates, and facts.
2026-07-17 — v0.20.0 (smarthost implicit-TLS dial)
MINOR — an additive capability affecting deployments (no on-chain ABI, instruction, error-code, or economic change):
- New
[spooler.smarthost] implicit_tlsswitch — defaultfalse; when set, the relay dials the smarthost with TLS from the first byte (the port-465 “SMTPS” style, named after the inbound listeners’ switch) instead of the default in-band STARTTLS, so STARTTLS never happens on the wire. The port is not auto-switched to 465 — it stays whatever the operator set — the handshake keeps the smarthost path’s strict webpki verification, and the direct-to-MX path is unchanged. This is the first consumer of the SMTP client machine’s implicit-TLS dial mode (SendMachine::new_tls) — see the[spooler]reference.
2026-07-17 — v0.19.0 (truthful TLS-RPT rows; report retention setting)
MINOR — a default-behavior change and a new deployment setting (no on-chain ABI, instruction, error-code, or economic change):
- TLS-RPT success rows are now flag-truthful — a §4.1 success row is recorded only when the completed conversation actually ended on TLS (the send outcome carries the negotiated flag), so a success row can no longer describe a plaintext session; a completed plaintext opportunistic delivery — including a declined STARTTLS offer that continued in the clear — records no row at all (neither a TLS session nor a failed attempt). This closes v0.18.0’s recorded gap; the honest limit that remains (“never offered” vs “offered but declined” — both unrecorded) is in the rewritten RFC 8460 conformance section.
- Pre-dial policy exclusions now record TLS-RPT rows — hosts a policy
excludes before dialing land never-dialed failure rows instead of
vanishing (the other v0.18.0 gap): a DANE-unusable host records
dnssec-invalidwith a baretlsapolicy block, an MX target outside an enforce-mode MTA-STS policy recordssts-policy-invalidrendering the enforce policy body, with the planner’s diagnostic infailure-reason-code. Unreachable/timed-out hosts and STS testing-mode mismatches still record nothing — see the configuration reference. - New
[spooler] report_retention_dayssetting — default0= keep forever; when set, an hourly worker prunes ingested DMARC aggregate reports (dmarc_rua/) and pending TLS-RPT rows (tlsrpt/pending/) older than the window. Off by default deliberately:dmarc_rua/is the dataGET /v1/admin/dmarc-reportsserves, and retention removes reports from that surface — see the[spooler]table.
2026-07-17 — v0.18.2 (Outlook + Thunderbird gain the trustless reply/compose card)
PATCH — additive client UI over existing chain capability (no on-chain
ABI, instruction, error-code, or economic change; the compose threads
SendMail’s existing bounty/expiry/reply parameters through the already
parity-fenced builders — the same call as item 39’s webmail card, v0.8.8):
- Outlook: Trustless reply and compose —
the taskpane’s trustless reader gains webmail’s Reply on-chain
action, and the mail view mounts the floating on-chain compose card
(reply-chip threading, bounty SOL + claim-window-days fields, inline
stamp prepay). Replies are on-chain sends — never a host SMTP
compose. The connection-settings pane gains the IPFS pin service
URL/token (
config.ipfsPinUrl/config.ipfsPinToken, default the loopback sithbit-ipfsd, unauthenticated). - Thunderbird: Trustless reply and compose — the same seam on the extension’s dashboard; the options page surfaces the pin URL/token, and a non-loopback pin origin joins the Save-click host-permission grant automatically.
2026-07-17 — v0.18.1 (postmaster page cross-link)
PATCH — documentation only (no code change):
- Initializing the postoffice —
the “held by anyone else” recovery path’s mention of the holder closing
the alias (
sithbit alias close) now links to Closing accounts, matching the transfer link beside it.
2026-07-17 — v0.18.0 (TLS-RPT reporting; DANE for MX-less domains)
MINOR — an additive capability and a default-behavior change affecting deployments (no on-chain ABI change):
- DANE now covers MX-less domains — the outbound relay’s default-on
daneenforcement previously skipped domains with no MX record (the documented RFC 7672 §2.2.1 subset). A DNSSEC-proven MX denial (Secure proof on the negative answer’s SOA) now marks the implicit-A fallback secure, so TLSA at_25._tcp.<domain>is consulted and enforced for signed MX-less recipients — see the rewritten DANE conformance caveat and the dns.md publishing note. The narrower remaining subset: denials without a validatable SOA stay insecure. Unsigned zones behave exactly as before. - TLS-RPT (RFC 8460) sending — new default-off
[spooler.tlsrpt]switch: dialed relay attempts record per-host TLS results, and a drain worker folds them into per-domain aggregate reports delivered to recipients publishing_smtp._tls.<domain>rua targets — over bothmailto:(DKIM-signed via the outbound relay) andhttps:(application/tlsrpt+gzipPOST). The new RFC 8460 conformance section carries the honest gaps (certificate-* taxonomy collapses into validation-failure with detail preserved; pre-dial exclusions record nothing; duplicate-on-crash tolerated via deterministic report ids). This closes the “no TLS-RPT” limitation recorded by the MTA-STS and DANE landings.
2026-07-17 — v0.17.0 (DMARC aggregate-report ingestion; postmaster alias claim)
MINOR — additive capabilities affecting deployments (all off by default or init-time only; no on-chain ABI change):
- DMARC RUA ingestion — SithBit deployments can now receive the
aggregate reports other operators send about their domains. Three pieces,
documented across dns.md, the
configuration reference, and a new
RFC 7489 §7.2 conformance section:
[smtp] postmaster_wallet(RFC 5321 §4.5.1 — bare/domained postmaster bypasses alias resolution and the frombox/postage gate so external reporters can deliver at all; unset keeps refusals byte-identical),[spooler.dmarc_rua_ingest](matched delivered recipients get their reports parsed with the vendored RFC 7489 parser and stored as JSON under the fixeddmarc_rua/blob prefix — additive to delivery, never a diversion), and the account API’sGET /v1/admin/dmarc-reports[/{id}]admin reader. Scope is deliberately ingest + store + surface only: auto-disabling accounts from RUA data is rejected on record (aggregate rows carry no join key to a local wallet; failing rows are almost always third-party spoofers). Norufingestion, no blob pruning yet. postmaster initclaims thepostmasteralias — the init transaction now atomically registers the globalpostmasteralias to the delegate, fee-waived by construction (the alias program’s delegate waiver reads the postoffice state written one instruction earlier; rent-only). A squatted name refuses loudly with nothing submitted — the postoffice is deliberately never created without its name; the alias program still has no reserved words, so the squat window is narrowed to deploy→init, not closed.
2026-07-17 — v0.16.1 (config-key docs gate; example-config drift fixes)
PATCH — documentation/tooling only (no behavioral change):
- New docs-gate leg —
mail_docs/check_config_keys.pydiffs the six canonical example configs’ keys (commented-out entries included) against the configuration reference in both directions, killing the drift class where a key ships in an example TOML but never reaches the docs (or vice versa). - Drift repaired by the new gate —
sithbitd.example.tomlgained the documented-but-missing[store.cloudflare]backend block,client_cert_authon the three authenticated listeners,[smtp.server]limits.*, and the[swarm]service-record freshness settings (the last also added tosithbit_ipfsd.example.toml); both IPFS binaries’ examples gainedobservability.otlp.metrics_interval_seconds; the reference gainedstore.aws.sqs_wait_time_secondsand the gateway’spublic_host, and the[store.blobs]s3/azure key lists are now machine-checkable code spans. - Example-value fix —
domain_sithbit.example.toml’s[mail_hosts.smtp]showed the retired 587/STARTTLS pair while claiming to show defaults; the in-code default (and the documented RFC 8314 posture) is 465/SSL. - RefundBounty CU fence — the expiry-gated sender reclaim was the one bounty-family instruction never CU-measured; the compute-units table gains its row (7,579 max measured, 31,000 ceiling — the cheapest fenced instruction: no reply-linkage check and no operator share on the refund path).
2026-07-17 — v0.16.0 (chain-account proxy read; accepting_at on the DND check)
MINOR — additive public-API changes (a new route and a new response field; no on-chain ABI or economic-model change):
- New authenticated chain read —
GET /v1/chain/account/{address}on the account API returns any raw account verbatim (ownerbase58,database64; 404 when absent), the generic escape hatch API-mode web shells use to decode accounts client-side — e.g. the bounty-claim resolver’s domain-account read, so a domained claim pays the domain authority instead of falling back to the filler pair. accepting_aton the anonymous DND check —GET /v1/dnd/{wallet}now carries the RFC 3339 UTC instant the wallet accepts mail again, gated three ways: currently excluded, owner opted in viaexpose_dnd_schedule, and the schedule ever reopens (a full-week recurring schedule omits it). The schedule page localizes it to the sender’s own clock (“accepting mail again at …”); the not-opted-in default stays yes/no only.
2026-07-17 — v0.15.2 (docs: introduction reordered around the no-token pitch)
Documentation-only: the introduction’s “Priced in SOL — No New Token to Trust” subtopic moved up to lead the protocol sections (ahead of “Decentralized Email”), and the former “Only on Solana” subtopic became a note box directly beneath it.
2026-07-17 — v0.15.2 (docs: privacy cross-links for the DND-exposure opt-in)
Documentation-only: What you control and the
privacy reference now name the
expose_dnd_schedule opt-in — anonymous schedule checks return only the
yes/no “away right now” answer unless the owner opts in — linking to
What the refused sender sees
for the semantics. The deploy guide’s GCP mail-tier
bullet now points at the PROXY-protocol container recipe as the exception
to “VMs, not serverless”.
2026-07-17 — v0.15.2 (ChainSender: pin service lazily required by send)
PATCH — web-client behavior change, no public-ABI change: ChainSender
no longer demands an IPFS pin URL at construction — only send() pins, so
the pin service is lazily required at pin time (a send without one refuses
at the pin stage before anything is pinned or submitted; prepay() never
pins). The onboarding fund page drops its dummy-pinUrl workaround.
2026-07-17 — v0.15.1 (mail-migrate replays the DND-exposure opt-in)
PATCH — behavioral defect fix, no public-ABI change: sithbit-migrate
now replays each account’s expose_dnd_schedule opt-in onto the target
store; previously a migration silently reset the flag to hidden
(fail-safe, but lossy for owners who had opted in). The
migration guide’s field list updated to match.
2026-07-17 — v0.15.0 (docs: diagrams catch up to the three-leg bounty split)
Documentation-only (the settlement change itself shipped at v0.14.0): the reply-bounty flow and campaign lifecycle diagrams — titles, box labels, and the campaigns page’s alt text and “paid twice” bullet — still described the retired 90/10 recipient-to-postoffice split. All now state the three legs: 90% to the claimant, 10% to the claimant’s active domain authority, with the postoffice collecting the share only when no active domain resolves.
2026-07-17 — v0.15.0 (self-service refusal links; DND schedule privacy)
MINOR — new default-off capability plus a public-API default-behavior
change (no on-chain ABI or economic-model change; the widened-at-v0.10.0
rule): a single new [smtp]/[submission] setting, self_service_base_url
(default unset = every refusal stays byte-identical to the legacy text),
makes the RCPT-time refusals link self-service pages — the postage
refusals (450 4.7.0 out of stamps, 550 5.7.0 no frombox) append
{base}/fund.html?to=…&from=…, and sithbitd’s do-not-disturb refusal
(450 4.2.1) appends {base}/dnd.html?to=… (the standalone
smtp-server carries only the funding link — it has no DND gate). The
two pages ship in the onboarding web bundle: fund.html quotes the
stamp price trustlessly off the chain (postage + settlement surcharge +
live protocol fee) and takes a Phantom/Ledger prepay; dnd.html shows
the recipient’s away state. Alongside them, the anonymous
GET /v1/dnd/{wallet} route’s default behavior changed —
privacy-tightening: it used to return the full exclusion list to any
caller, and now always answers excluded_now but includes the
exclusions array only when the owner opted in via the new
expose_dnd_schedule account flag (PATCH /v1/account, default
false; a wallet with no account answers excluded_now: false).
- New Do not disturb page: the case for reject-at-RCPT DND over accept-and-autoreply (the sender’s MTA queues and retries; no unread pile-up; the sender learns at send time; a refusal burns no stamp), what a refused sender finds on each linked page, and the schedule-sharing opt-in.
- Configuration reference:
the
self_service_base_urlrow in the[smtp]/[submission]table and a new one-setting-two-pages subsection, including the standalone-smtp-serverscope note. - account-api: the DND schedule surface —
the authenticated
GET/PUT /v1/account/dndroutes, theexpose_dnd_scheduleflag onGET/PATCH /v1/account, and the changed publicGET /v1/dnd/{wallet}contract, called out as a behavior change. - Self-service pages for refused
senders: the
two pages in the onboarding bundle and their
<meta>endpoint settings (sithbit-rpc-url/sithbit-api-url, localStorage fallbacks, same-origin default under the account API’s[static]root).
2026-07-16 — v0.14.0 (ClaimBounty operator share to the domain authority)
MINOR — economic-model change (no wire-ABI change: the instruction’s
discriminant and payload are untouched): ClaimBounty’s 10% operator
share (OPERATOR_SHARE_BPS) now pays the claimant’s domain authority
when their mailbox names an active domain — the DeleteMail settlement’s
domain-resolution rules, filler-account guards included — and falls to
the postoffice when the chain legitimately doesn’t resolve (no mailbox,
no domain named, domain closed or inactive; the prior behavior, preserved
for domainless claimants). The claimant keeps the remainder including the
rounding dust, exactly as before, and RefundBounty is unchanged. The
instruction grew from 4 to 7 accounts (mailbox, domain, and authority
appended; the mailbox PDA stands in as a filler when no domain is named).
Re-measured: 24 847 CU (was 21 624), fenced at 48 000 (was 45 000).
- Reply bounties: the claim-split
bullet is rewritten for the three destinations — claimant, domain
authority when active, postoffice fallback — and ties the operator leg
to the
DeleteMailsettlement’s resolution rules. - Claiming the bounty: the user-facing payout callout now names the domain authority as the operator leg’s destination, with the postoffice fallback.
- Compute-unit consumption: the ClaimBounty row carries the new measurement and ceiling, noting it is measured on the domained 7-account path.
2026-07-16 — v0.13.0 (domain-sithbit mail_hosts table correction)
Documentation defect fix (no version bump — docs-only): the
domain-sithbit [mail_hosts]
table still claimed
the advertised SMTP default was 587/STARTTLS; the code default has
been 465/SSL since the RFC 8314 cutover (v0.9.0, fenced in
domain_sithbit/src/config.rs tests), and configuration.md already said
so. Same drift class as the v0.11.6 sithbitd port corrections.
2026-07-16 — v0.13.0 (MTA-STS policy publication)
MINOR — new default-off capability (no on-chain ABI or economic-model
change; the widened-at-v0.10.0 significant-additive-capability rule):
domain-sithbit now publishes a domain’s MTA-STS policy (RFC 8461) at
GET /.well-known/mta-sts.txt, rendered from a new optional [mta_sts]
config section (mode default "testing", mx patterns, max_age
default one week). The section is validated fail-fast at boot — an
unknown mode, an enforce/testing policy without an mx pattern, or a
max_age above the RFC’s one-year ceiling (31557600, fenced equal to
the value the sending relay clamps fetched policies to) refuses to start —
and with no section the endpoint replies 404, so existing deployments are
untouched. TLS stays the fronting proxy’s job (a certificate for
mta-sts.<domain>), and the _mta-sts.<domain> discovery TXT record
stays operator-managed DNS.
- New domain-sithbit: publishing the MTA-STS
policy
subsection: the route, the opt-in 404 contract, the startup failure
modes, and the
mta-sts.<domain>A/CNAME + TLS-proxy fronting. - New
[mta_sts]— MTA-STS policy publication reference section: the key/default table and the boot-time failure modes. - RFC 8461 conformance section: the “sending side only” scope bullet is replaced by a publish-side bullet — what is implemented (§3.2 serializer, well-known route, startup validation, the shared one-year ceiling) and what is not (no per-domain policy map, no TLSRPT, TXT record stays operator DNS).
- Sending mail: SPF, DKIM, DMARC,
PTR: the MTA-STS
inbound guidance now points at the built-in endpoint instead of “host
the policy file yourself”, and ties the TXT
idbump to editing the[mta_sts]section.
2026-07-16 — v0.12.0 (DANE outbound enforcement)
MINOR — additive behavioral change (no on-chain ABI or economic-model
change; the widened-at-v0.10.0 new-enforcement-default rule): the outbound
relay now looks up and enforces recipient MX hosts’ DNSSEC-validated DANE
TLSA records (RFC 7672) by default on direct-to-MX delivery — a validated
usable TLSA set pins the STARTTLS handshake to the published certificate
data (preferred over MTA-STS wherever both apply), and any failure defers
rather than downgrading — behind a new [spooler] dane switch (default on).
Send-side only: publishing TLSA records stays operator DNS work. Only
tightens delivery to domains that sign their zones and publish TLSA;
everything else keeps the MTA-STS/opportunistic posture.
- New RFC 7672 conformance section: TLSA discovery over a DNSSEC-validating resolver and the per-host outcome matrix, DANE-EE/DANE-TA verifier semantics (EE skips name/expiry/chain; TA path-validates anchored at the matched chain cert), the DANE-over-MTA-STS composition rules, the documented CNAME and implicit-A subsets, and the send-side-only scope.
[spooler]— outbound workers: thedanekey and a paragraph on the pinned handshake, the stricter-of-both rule under an MTA-STS enforce policy, never-dialed bogus hosts, and the debugging escape hatch.- Sending mail: SPF, DKIM, DMARC,
PTR: a DANE note —
outbound needs no configuration; publishing
_25._tcp.<mx-host>TLSA records in a DNSSEC-signed zone protects your own inbound mail, with the recommended3 1 1form, the openssl digest recipe, and key-rollover guidance. - Threat-model subsection updated: DANE is now implemented and closes both MTA-STS residuals (trust-on-first-use and cache lifetime) for recipient domains that deploy DNSSEC + TLSA.
2026-07-16 — v0.11.6 (sithbitd default-port corrections)
PATCH — documentation/example corrections only (no code change;
the binds themselves never moved): the sithbitd docs and example
config claimed default ports the code never had. The in-code defaults
are SMTP 2525, IMAP 1430, POP 1100 (imap_server/src/config.rs,
pop_server/src/config.rs), and the submission listener has no
distinct default — disabled by default, it would inherit SMTP’s
2525, so its bind_addr must be set explicitly when enabled. The
2143/2110/2587 numbers are the docker-compose files’ explicit rebind
convention, not defaults. Corrected in the sithbitd
page, the listener-section
table,
the deploy quick-start, and
mail_spooler/sithbitd.example.toml (whose [store] prose also now
lists the cloudflare kind alongside the other backends).
2026-07-16 — v0.11.5 (production import documents for the cloud config stores)
PATCH — deployment content and repo-side tooling only (nothing a
deployed binary does changes: the cloud config tier itself shipped at
v0.11.0, and importing these documents is an operator opt-in): the
repository now ships ready-to-import production configuration for a
complete six-service sithbit.com deployment — sithbitd, account-api,
mail-grpc, domain-sithbit, sithbit-ipfsd, sithbit-gateway — for both
cloud config stores, under iac/appconfig/.
- AWS AppConfig: six commented per-service TOML documents
(
iac/appconfig/aws/), imported verbatim as freeform hosted configuration profiles — AWS stores the document opaquely, so the TOML comments are the in-store field documentation. These documents are the single source of truth for both clouds. - Azure App Configuration: a generated kvset import file
(
iac/appconfig/azure/sithbit.kvset.json) — per-service-prefixed:-separated keys on the NULL label, each TOML comment carried as the key’sdescriptiontag (the kvset profile is the only import path that preserves per-key metadata). Sparse per-service overrides (iac/appconfig/azure/overrides/) swap the store kind, blob shape, and key sources to their Azure forms; theappconfig-genworkspace tool merges and emits, and the test suite fails on a stale kvset, a document that no longer parses into its service’s real config struct, or a broken cross-service invariant. - Secrets stay out of the store by construction: the documents carry
key-source coordinates (Secrets Manager / Key Vault) and obvious
CHANGEdummies, machine-enforced by pinned placeholder tests. - The cloud app-config
section
points at the import documents (and now lists all six bootstrap
prefixes — the two IPFS binaries were missing); the
Production deployment bullet gains
the same pointer; the store-creation and import runbooks live in
iac/README.md.
2026-07-16 — v0.11.4 (store-name refresh on the extension pages)
PATCH — documentation only (no code change): the store-install sections now link the stores themselves, and Microsoft’s rebrand is reflected.
- Chrome: Installing from the store — “Chrome Web Store” now links to the store.
- Outlook: Installing from the store — Microsoft AppSource has been renamed Microsoft Marketplace; the section says so (linking the store) and uses the new name throughout. The v0.11.2 entry below keeps its historical “AppSource” wording. The in-client Apps → Get Add-ins flow is Outlook UI and is unchanged.
- External links open in a new window via the site-wide
external-links.jshook, as usual — no per-link markup.
2026-07-16 — v0.11.3 (PROXY protocol trusted-proxies allowlist)
PATCH — additive hardening setting, default off-path (the defaults
preserve prior behavior exactly; no on-chain ABI or economic-model
change): listeners running with proxy_protocol = true can now
restrict which socket peers are permitted to speak the preamble,
instead of trusting whoever reaches the port.
- New
proxy_trustedkey in the shared[*.server]section: a CIDR allowlist (e.g.["10.0.0.0/8", "2001:db8::/32"]; bare addresses count as /32 or /128, and v4 entries match v4-mapped peers on dual-stack listeners) of the peers allowed to send a PROXY preamble. Untrusted peers are refused before a single header byte is read, closing the address-spoofing hole a directly reachable client would otherwise have. Empty (the default) trusts any peer — the pre-allowlist behavior, suitable when only the balancer can reach the port. Ignored unlessproxy_protocolis on; a malformed entry fails serve startup with an error naming it. - The four annotated example configs (
sithbitd.example.toml,smtp_server.toml,imap_server.toml,pop_server.toml) show the default (proxy_trusted = []) commented out besideproxy_protocol, house style.
2026-07-16 — v0.11.2 (extension store-install instructions)
PATCH — documentation only (no code change; the extensions are not
yet published to any store): the three extension-client pages each gain
an Installing from the store section ahead of the build-and-sideload
path, with obviously-placeholder listing tokens
(_todo_store_listing_name_ / _todo_store_listing_url_) that resolve
when the real store listings go live, plus an honest note on what each
store offers for pre-release distribution.
- Thunderbird: Installing from the
store —
addons.thunderbird.net search/listing install; MailExtensions need no
signing, so the self-distributed
.xpistays a fully supported permanent channel (ATN listings are public-only). - Chrome: Installing from the store — Chrome Web Store “Add to Chrome”; the Web Store’s Unlisted/Private visibilities and trusted-tester draft sharing allow a non-public pre-GA listing.
- Outlook: Installing from the store — AppSource / in-client Get Add-ins search; AppSource is public-only, so the private paths are sideloading and the Microsoft 365 admin center’s Upload custom app tenant-wide deployment.
- The GUI clients overview points at the three new sections with the placeholder caveat.
2026-07-16 — v0.11.1 (commodity hosting: generic VM + Postgres + S3)
PATCH — documentation only (no code change; the recipe rides existing backends): the vendor-independence claim gets its commodity chapter — any provider with a VM, Postgres, and S3-compatible object storage runs the full stack — plus a ranked six-provider comparison.
- New Hosting on a generic VM: Postgres + any S3-compatible
storage
section: the two-edit recipe (
[store] kind = "postgres"+[store.blobs] kind = "s3", with[ipfs.blobs]riding the same trait), the four operational caveats a big cloud would otherwise absorb (build features, certbot with a restart--deploy-hookfor the load-once TLS acceptor, file-based key sources, outbound port 25), and a six-provider ordered list — Hetzner, OVHcloud, Scaleway, Linode, Vultr, DigitalOcean — ranked on port-25 posture and PTR/rDNS control first, managed-Postgres availability second. - Containers behind a PROXY-protocol balancer are documented as
viable for the mail tier (decision 2026-07-16), superseding the
older VM-only guidance: the listeners’ existing
proxy_protocol = truesupport recovers the real client IP for DNSBL/limits/SPF, so LB-fronted containers qualify when the balancer injects the preamble; proxies without it stay ruled out. (iac/README.md’s client-IP constraint note was revised to match — outside this book.)
2026-07-16 — v0.11.0 (cloud app-config sources)
MINOR — additive capability (no on-chain ABI or economic-model
change): every TOML-config binary can now pull its settings from AWS
AppConfig or Azure App Configuration — a new resolution tier
directly above the config file, opted into per binary by a single
bootstrap env var ({PREFIX}_AWSAPPCONFIG / {PREFIX}_AZAPPCONFIG) and
skipped entirely when neither is set, so the zero-config contract is
untouched. Settings only, never secrets — key material keeps going
through key sources.
- New Cloud app-config sources: AWS AppConfig or Azure App
Configuration
section: the bootstrap variables, the per-provider payload idiom
(AWS: one whole TOML document, deep-merged; Azure: per-key values
nested on
:, case-sensitive), the neither/both/compiled-out rules (awsconf/azconffeatures), ambient authentication, and the env-gated live probes. - How a setting
resolves: the
chain gains the cloud tier between the TOML file and
./.env—{PREFIX}_{PATH}env overrides still win over cloud values. - Container images and Production: config can arrive from a cloud app-config source instead of a mounted TOML file; the mail-grpc keypair callout notes only key-source coordinates travel through it.
- The three annotated example files (
sithbitd.example.toml,mail_grpc.example.toml,domain_sithbit.example.toml) spell the cloud tier into their layer-chain headers; the loader’s crate-level reference isapp_config/README.md(outside this book — the configuration section is the operator-facing description).
2026-07-16 — v0.10.0 (MTA-STS outbound enforcement)
MINOR — additive behavioral change (no on-chain ABI or economic-model
change): the outbound relay now discovers and enforces recipient domains’
published MTA-STS policies (RFC 8461) by default on direct-to-MX delivery —
an enforce-mode policy means verified TLS to a policy-matching MX or a
deferral, never a plaintext fallback — behind a new [spooler] mta_sts
switch (default on). Send-side only: SithBit publishes no policy endpoint of
its own.
- New RFC 8461 conformance section: policy discovery/parsing, the enforce branch and its defer semantics, the §5.1 policy cache, testing-mode logging (no TLS-RPT), and the send-side-only scope.
[spooler]— outbound workers: themta_stskey and a paragraph on the three policy modes, the defer semantics, and the debugging escape hatch.- Outbound mail and port 25: direct-to-MX delivery honors recipient policies by default; smarthost deployments are unaffected.
- Sending mail: SPF, DKIM, DMARC,
PTR: an MTA-STS note —
outbound needs no configuration; publishing the
_mta-stsTXT record and policy file protects your own inbound mail. - New threat-model subsection: the STARTTLS-downgrade threat on MX-to-MX delivery, what opportunistic TLS does not protect against, and the trust-on-first-use / cache-lifetime residuals.
2026-07-16 — v0.9.3 (hosting on Google Cloud)
PATCH — no ABI or economic-model change (docs + infrastructure templates only; zero application code). SithBit’s third hosting cloud, proving the vendor-independence seams end to end:
- New Hosting on Google Cloud
section in the deployment chapter: blobs = a GCS bucket over its
S3-interop endpoint (HMAC credentials,
region = "auto"— the existings3blob kind, no new backend); tables/leases/queue =kind = "postgres"against Cloud SQL; secrets = the v0.9.3gsmkey source; outbound port 25 is unconditionally blocked on GCE (unlike AWS/Azure, no lift on request) so the smarthost is the supported outbound shape (inbound MX unaffected); the mail-port tier belongs on a GCE managed instance group behind an external passthrough Network LB (source-IP preservation — the GCP analog of the VMSS-not-ACI rule), while the private mail-grpc gateway fits Cloud Run. - New
iac/gcpTerraform module: the GCS bucket + dedicated service account + HMAC key always; an optional customer-managed Cloud KMS key; opt-in Cloud SQL Postgres; an opt-in internal-only Cloud Run v2 mail-grpc unit with thegsmkeypair selector.iac/awsgains the matchingmail_grpc_keypair_asmselector (task-roleGetSecretValue) as the volume-free alternative to the EFS mount. - Scaling out, the glossary (new GCS entry), migration, monitoring, and the production compose example now name the GCS/Cloud-SQL shapes where they list backends.
2026-07-16 — v0.9.3 (multi-cloud secret managers)
PATCH — no ABI or economic-model change (a config/deployment
capability; every existing config parses byte-identically). Key
sources
now fetch from AWS Secrets Manager (kind = "asm") and Google
Secret Manager (kind = "gsm") alongside the existing Azure Key Vault
(kind = "akv") and local files, everywhere a key source is accepted —
JWT/DKIM/credential-sealing keys, every server’s TLS pair, the
domain-sithbit delegate key, and mail-grpc’s signing keypair:
- Configuration reference rewritten: the key-sources section (heading
renamed — old deep links to
#key-sources-files-or-azure-key-vaultnow target the cloud-secret-managers anchor) documents all three clouds’ TOML shapes, auth chains (managed identity / AWS credential chain / ADC), and the live-probe env vars; per-field tables and the account-api, domain-sithbit, and mail-grpc pages generalize their file-or-Key-Vault phrasing. - Per-cloud cargo features (
akv/asm/gsm, all default-on): the build-features caveat in Deploy now describes the real mechanism — compile out the clouds you don’t use; a compiled-out kind still parses and fails at load naming the feature. - Cloudflare deliberately absent: its secrets products are write-only over the API (no fetch path), noted in Deploy and the configuration reference.
- Every example TOML’s commented
akvline gains an(or kind = "asm" / "gsm")pointer.
2026-07-16 — v0.9.2 (the Marketplace topic & campaigns)
PATCH — documentation only, no ABI or economic-model change (the participant beacon, campaign CLI, and their money flows all shipped in v0.9.0; this surfaces them in the user-facing guide). A new top-level Marketplace topic under “Using SithBit” introduces the three things that trade on SithBit — alias names, domains, and attention — with two subtopics: Trading names (the alias/domain resale market, linking the existing per-name how-tos) and Campaigns, an audience-facing introduction to opt-in inbox monetization written for both advertisers and non-technical participants, with a hand-drawn campaign-lifecycle diagram. Supporting changes:
- Campaigns highlighted as a headline feature. A new campaign feature
card on the Welcome page and a new
campaignterm icon (megaphone) across the icon system (legend). - Economics gains a Campaigns section tracing the campaign-wallet-funded per-recipient flow (rent + postage + bounty + fees) as a batch of existing flows, and Economics moved ahead of “GUI clients” in the reading order.
- The marketplace pane doc now documents its Participants tab, reconciling a gap with the shipped web surface.
- Running a mail server opens with a vendor-independence pitch (the storage, blob, IPFS, and secret seams are trait-abstracted with multiple backends), and its subtopics are reorganized into a motivated arc — Go-live essentials, The services, Day-2 operations.
- Welcome page card grid rebalanced. The feature cards no longer strand “Works with the inbox you already use” alone on its own row: the spam-pricing hero card keeps its full-width row, and the remaining six cards now flow three across in two even rows (“No gatekeeper” keeps its accent border but joins the grid).
2026-07-16 — v0.9.1 (mail-grpc honors JSON_RPC_URL)
PATCH — config surface, no ABI or economic change. The mail-grpc
gateway now honors a bare JSON_RPC_URL environment variable
(precedence: env > the configured json_rpc_url > the Solana CLI
config), the one legacy env name kept from the clean break, for parity
with the sithbit CLI and the standard Solana convention. See
the mail-grpc chapter migration note and the
json_rpc_url row in the
configuration reference. This also fixed an integration-suite singleton
race (the in-process gateway’s config::get() no longer force-initializes
the process-wide config, so a read-only gateway boot can’t pre-empt the
binary’s one config::install).
2026-07-16 — v0.9.0 (the sithbit campaign CLI)
MINOR — additive CLI surface over the existing beacon ABI (item 44, the
group-offer authoring flow
of the participant-pool marketplace). No new on-chain instruction: the
command tree drives the create/update/close beacon instructions that
shipped with item 43 and the existing SendMail, so nothing about the ABI
moves. What is new is the chain-direct authoring surface a participant and a
campaign wallet use:
- A new
sithbit campaignCLI reference documents the whole tree — a participant’screate/update/close(opt in, rewrite, opt out; the advertised price is the mailboxdefault_postage, so a beacon needs a mailbox first) and a campaign wallet’ssearch/quote/send.searchruns the trustlessgetProgramAccountsscan and recovers each match’s sendable wallet from the beacon’s on-chainownerfield (the D-P1 append this session);quoteprices the matched set term-for-term against the on-chainSendMailfunding math;sendexecutes N direct-signed bountied sends, continuing past a per-recipient failure so one bad address can’t strand a paid campaign. - The participant-marketplace note
and its item-44 line
are the design record; each
campaignbounty rides the ordinary reply-bounty escrow, refundable to the campaign wallet if a recipient never replies.
2026-07-16 — v0.9.0 (participant-pool web surface)
MINOR — additive web/API surface (item 45, the
browser read path of the
participant-pool marketplace
design). The browser read path adds no on-chain ABI itself; the beacon’s
on-chain layout shipped with item 43 under this same v0.9.0 and was
extended this session with an appended 32-byte owner field
(PARTICIPANT_BEACON_LEN 113→145; tags stay first at offset 0) so the
trustless scan recovers each participant’s sendable wallet from the PDA.
The opted-in participant pool is now browsable end to end:
a new ListParticipants gRPC RPC on mail-grpc runs the trustless
on-chain beacon scan (getProgramAccounts + a memcmp filter over the
fixed-offset tag bitmap), account-api proxies it as the authenticated
GET /v1/chain/participants?tags=… index route
(account-api), and the
name marketplace grows a Participants tab
beside its For sale / Expired / Sold tabs — a lazy-loaded, JWT-authenticated
browse-and-filter surface over the pool. A beacon must carry every filtered
tag bit to match. Known limitation: the browser clients have no shared
tag-name vocabulary yet, so both the filter input and each row render tags
as raw on-chain bit positions (the mail_model TAG_* constants),
not human labels; group-offer authoring (quote/send) stays CLI-first
(item 44).
2026-07-16 — v0.9.0 (RFC 8314: production implicit-TLS mail posture)
PATCH — docs and config defaults only; no on-chain ABI, instruction, error-code, or economic change (item 47). The reference stack’s transport posture is hardened to RFC 8314 (“Cleartext Considered Obsolete”) — TLS on connect for submission and access, credentials refused before the connection is protected — and documented end to end. Nothing about what the servers can be configured to do changed at the wire level (STARTTLS listeners and the plaintext loopback dev stack still work); what moved is the advertised production default and the prose describing it.
- Protocol conformance
gains an RFC 8314 subsection and checklist item citing the three
on-by-default
require_tlsenforcement guards — SMTP submission (530withAUTHhidden from EHLO), IMAP (LOGINDISABLED+NO [PRIVACYREQUIRED]), and POP3 (-ERR Must issue STLS command first). mail_spooler/sithbitd.example.tomlgrows the commented production implicit-TLS stack —[submission.server]/[imap.server]/[pop.server]on 465/993/995 withimplicit_tls = trueand matching[*.tls]— with the STARTTLS 587/143/110 listeners demoted to opt-in secondaries, anddocker-compose.prod.example.ymlpublishes those same 465/993/995 (plus 25 MX) as the primary host ports.- Running a mail server: Production and a
new configuration production-posture
subsection
document the implicit-TLS primaries, the MX-on-25 exception, and the
require_tls-on-by-default rule. domain-sithbit’s advertised submission default flips 587/STARTTLS → 465/implicit-TLS (SSL) acrossMailHostsConfig::default, the Mozilla autoconfig (socketType=SSL) and Outlook autodiscover (Encryption=SSL) documents it serves, the[mail_hosts]reference default, and the DNS setup submission caveat. STARTTLS on 587 remains a supported opt-in; the ports now match the implicit-TLSSRVrecords that same page recommends.
2026-07-16 — v0.9.0 (threat-model prune)
PATCH — docs only. Removed the threat model subsection “History before the cutover shows the old postmaster key” — it advised rotating away from a pre-cutover single-postmaster key at adoption, but there has never been a production deployment, so no such historical key or pre-adoption chain history exists to rotate away from. The custody model itself (ceremony seeds + rotate-on-schedule delegate) is unchanged.
2026-07-16 — v0.9.0 (client-access SRV records)
PATCH — docs only. DNS setup
gains a section on RFC 6186 / RFC 8314 SRV records for client
autoconfiguration: the implicit-TLS labels SithBit’s production posture
prefers (_imaps 993, _pop3s 995, _submissions 465) and the STARTTLS
secondaries (_imap 143, _pop3 110, _submission 587), the RFC 2782
priority/weight/port/target fields, the .-target convention for
disabling a protocol, and how these relate to the autoconfig/autodiscover
documents and to the DHT-based service
discovery that avoids DNS altogether.
Ports match the
[mail_hosts]
defaults.
2026-07-16 — v0.9.0 (on-chain participant beacon)
MINOR — additive public ABI (item 43, the first build-out of the
participant-pool marketplace
design): three MailInstruction variants appended —
CreateParticipantBeacon (39), UpdateParticipantBeacon (40),
CloseParticipantBeacon (41) — plus the ParticipantBeacon account
(fixed 113-byte layout; the coarse tag bitmap sits at account offset 0 so
getProgramAccounts memcmp search works without deserializing), the
append-only 24-tag starter vocabulary in mail_model constants (32-byte
bitmap = 256 slots; bits are deliberately NOT validated on-chain, so
vocabulary appends never need a redeploy), the participant_beacon PDA
seed, and error codes 86–90. Creating a beacon requires the wallet’s
mailbox to exist, because the advertised participation price is the
mailbox’s default_postage
(decision 5);
closing it refunds the rent — opting out is free and complete. See the
program reference
for the instruction/seed/error tables. CLI authoring (sithbit campaign,
item 44) and the web surface (item 45) build on this next.
2026-07-16 — v0.8.11 (trustless webmail: external-wallet flavor on the Balances pane)
Client-side only: no on-chain ABI, instruction, error-code, or economic
change — balancesPane.buyStamps() now supports the external
Phantom/Ledger signing flavor (the unsigned wasm builders plus
sendUnsigned), mirroring mailboxConfigPane.commit()’s existing
split. Item 40 (v0.8.9) deliberately scoped this to the compose card
only; this fills in the Balances pane, so PATCH per the v0.8.7
precedent.
- No frombox yet? Prepay inline notes the Balances pane’s stamp purchases now ride both signing flavors too, matching the compose card’s inline prepay.
- Creating the frombox on first purchase cross-references the Balances pane alongside the compose card as riding the same create-or-top-up decision, now in both flavors.
2026-07-16 — v0.8.10 (screenshot manifest: curated shared-file lists replace wholesale hash)
Tooling-only: no on-chain ABI, instruction, error-code, or economic
change — a fix to check_screenshots.py’s own drift detection, so
this is a PATCH bump.
mail_docs/screenshots.manifest.jsonno longer hasheswebclients/sharedwholesale for every client. Each ofwebmail,onboarding, andmarketplacepreviously carried a blanketwebclients/sharedsource entry, so editing a shared file only one client actually reaches (e.g.connection-settings.js, webmail-only) falsely flagged the other two as needing a re-shoot — the same false-positive class the item-40 docs commit (ee30da5) had to re-pin around after an unrelatedwebclients/sharededit landed. Each client’ssourceslist now names only the shared files itsapp.js/index.htmlactually reach (traced via the import/fetch/ mount closure), while the client’s own directory stays wholesale (rglob’d) as before.check_screenshots.py’siter_source_fileshashes an individual file directly when asourcesentry names one rather than a directory, alongside the unchanged wholesale rglob. A new--selftestmode fixture-proves both directions: a one-client-only file edit leaves the other two clients untouched, and a shared-by-all file edit (e.g.panes.js) still flags all three.
2026-07-16 — v0.8.9 (docs: participant-pool marketplace design note)
Documentation-only: the version tags the unchanged protocol state.
- New design note:
The participant-pool marketplace
records the settled design for advertiser/survey campaigns over reply
bounties — the on-chain participant beacon (coarse tag bitmap + sealed
detail CID, coarse-by-construction privacy), mail-native key handout
for the detail blob, the two search paths over one fixed-offset
layout, the CLI-first
sithbit campaignauthoring surface, the advertised-price-is-default_postageidentity, the rejected alternatives, and the three implementation items it spawns. Nothing in it is implemented yet.
2026-07-16 — v0.8.9 (trustless webmail: inline prepay on the compose card)
Client-side only: the trustless compose’s no-frombox refusal becomes an
inline Prepay & send — quote, purchase, and automatic re-send of the
held draft, in both signing flavors. The new wasm exports
(create_frombox_unsigned/add_stamps_unsigned,
postoffice_account_address/decode_postoffice_account) are client
surface over unchanged instructions — no on-chain ABI, instruction,
error-code, or economic change (the prepayment economics shipped long
ago; this is an affordance over them) — so this is a PATCH bump per the
v0.8.7/v0.8.8 precedent.
- No frombox yet? Prepay inline documents the card — the stamp-count input (the ≥1-stamp non-owner floor), the exact per-stamp funding quote (postage + settlement surcharge + the postoffice’s live protocol fee, owner-waived), the fresh create-vs-top-up read at click time, and the deliberate no-auto-retry on a still-pending purchase.
- Creating the frombox on first purchase
cross-references the webmail surface riding the same
create-or-top-up decision as
frombox stamp.
2026-07-16 — v0.8.8 (trustless webmail: reply + bounty authoring)
Client-side only: the trustless webmail now authors what it could
already display — the reader gains a Reply on-chain action and the
compose card gains reply-bounty fields. No on-chain ABI, instruction,
error-code, or economic change (the compose threads SendMail’s
existing bounty/expiry/reply parameters through the already
parity-fenced builders, both signing flavors), so this is a PATCH bump
per the v0.8.7 precedent. This closes the v0.8.7 entry’s “future work”
note for this surface.
- Replying, and attaching a bounty
documents the new compose surface — Reply pre-fills the decrypted
sender and carries the parent message’s account address (the
blake3-hashed
--reply-tolinkage, no bounty required); the bounty fields mirror--bounty/--bounty-windowwith the same 7-day default window, and a born-expired window is refused in the page before anything is pinned — the same rule the chain enforces. - Attaching a bounty names the trustless compose as an authoring surface — and restates the standing decision that bounty authoring is direct-signed only: sends composed through a mail server stay bounty-less.
2026-07-15 — v0.8.8 (trustless webmail: send-lifecycle and pin-caveat diagrams)
Documentation-only: no ABI, instruction, error-code, or economic change — two hand-authored diagrams illustrating already-documented behavior.
- Sending without a server gains a lifecycle diagram covering the four client-side steps (resolve, check mailbox, check frombox, seal) through the pin step and the in-page-wallet/external-wallet signing branch to submit-and-poll.
- The pin lifecycle caveat gains a comparison diagram showing the operator’s server-delivery pin lifecycle and a trustless client’s pin lifecycle as independent paths converging on the same CID — why GC never reclaims a client-made pin on the operator’s behalf.
2026-07-15 — v0.8.7 (trustless webmail: external-wallet send)
Client-side only: the trustless webmail compose can now send through a
connected external wallet (Phantom/Ledger) — previously it required
an in-page wallet. No on-chain ABI, instruction, error-code, or
economic change (the external flavor emits the byte-identical SendMail
wire transaction through the already-parity-fenced unsigned builder), so
this is a PATCH bump per the kit-migration precedent.
- Sending without a server documents the two signing flavors — an unlocked in-page wallet signs in the page; a connected external wallet approves the same transaction built unsigned with it as fee payer, with sealing always happening in the page before anything leaves it. Bounty and reply fields remain future work on this compose surface (they exist in the CLI and the builders today).
2026-07-15 — v0.8.6 (domain-sithbit compose parity: mounted TOML, dead env var retired)
Deployment-surface only: the compose files move the last
env-configured service onto the mounted-TOML pattern — no on-chain
ABI, instruction, error-code, or economic change, and no server
behavior change (no binary is touched) — so per this file’s own rules
this is a PATCH bump, following the v0.8.4 compose-migration
precedent. It is also a correctness fix: the
production example still set
DOMAIN_SITHBIT_POSTMASTER_KEY_FILE, a config field removed by
v0.8.2’s hard break (the field is now delegate_key_file), and
because unknown DOMAIN_SITHBIT_* variables fail startup loudly,
copying the example verbatim crash-looped the domain-sithbit
container.
- The production example gains
sithbitd/account-api/mail-grpc parity —
domain-sithbitwas the last service configured through a wall of env vars:docker-compose.prod.example.ymlnow mounts a realdomain_sithbit.toml(viaDOMAIN_SITHBIT_CONFIG; start fromdomain_sithbit/domain_sithbit.example.toml) plus a separate read-only delegate-keypair mount the TOML’sdelegate_key_filenames, with a minimal-TOML sketch and the Azure Key Vault table-form alternative inline — mirroring the mail-grpc block v0.8.4 shipped. - The dead
DOMAIN_SITHBIT_POSTMASTER_KEY_FILEvar is retired from everything runnable: the production example’s crash-looping setting is gone, anddocker-compose.yml’s stale comment telling operators to set it now points at the current contract (delegate_key_filein the mounted TOML). The surrounding prose also stops calling it the “postmaster key” — the signer is the postoffice’s standing delegate key.
Deployment-surface only: the iac/ templates gain opt-in units that run
the unchanged published image — no on-chain ABI, instruction,
error-code, or economic change, and no server behavior change (no
binary is touched) — so per this file’s own rules this is a PATCH bump,
following the v0.8.4 deployment-surface precedent. It lands item 34,
the last of the three hardening items queued with the
gateway topology decision.
- Both IaC templates gain an opt-in
mail-grpcunit (deploy_mail_grpcin Terraform,deployMailGrpcin Bicep; default off — a plain apply/deploy keeps producing the store footprint with zero diff): ECS Fargate on AWS (security group + cluster/task/service), a VNet-integrated ACI container group on Azure. Both are BYO network (an existing VPC + private subnets, or an existing delegated subnet — the templates never create one) and private-only by construction: no public IP or load balancer, ingress on the gRPC/health ports only from caller CIDRs or the VPC’s own CIDR — the private-network posture as infrastructure rather than convention. See Provisioning with IaC andiac/README.mdfor the full parameter ↔ config mapping. - Keypair delivery splits per cloud, because the gateway’s
keypairis a key source (a file path or a Key Vault secret — never key content in an env var): AWS mounts an optional EFS volume read-only and pointsMAIL_GRPC_KEYPAIRat the file; Azure wires the AKV source through the nested env overlay (MAIL_GRPC_KEYPAIR__KIND=akv+__VAULT_URI/__SECRET_NAME) authenticated by the container group’s system-assigned managed identity — the operator grants that identity secret read on the vault (themailGrpcPrincipalIdoutput exists for exactly that role assignment). - Durable constraint recorded on the Azure unit: ACI cannot pass through the client source IP — acceptable for mail-grpc (private gRPC; callers are our own servers), but a future SMTP-server unit must be a VM scale set, because SPF/DNSBL need the real peer IP.
2026-07-15 — v0.8.4 (compose files onto the mail-grpc TOML/env config)
Deployment-surface only: the compose files, smoke script, and dev
scripts move onto the configuration surface v0.8.3 shipped — no
on-chain ABI, instruction, error-code, or economic change, and no
server behavior change (the binaries are untouched) — so per this
file’s own rules this is a PATCH bump. It lands item 35, queued by the
v0.8.3 hard break, and closes that break’s last loose end: nothing
runnable in the repo drives mail-grpc with the retired
GRPC_SERVER_ADDRESS/DEFAULT_KEYPAIR names any more.
- The dev
chainprofile is operative again:docker-compose.ymlwiresmail-grpcthroughMAIL_GRPC_*overrides (bind, RPC URL, alias-index path), and the signing keypair is a file mounted read-only —SITHBIT_CHAIN_KEYPAIRnames the host path (default: the checked-in devnet test key the retired.envflow held as JSON content) — keypair content in an env var is gone for good.SITHBIT_CHAIN_RPCstill retargets the cluster; the OTLP overlay now setsMAIL_GRPC_OBSERVABILITY__OTLP__ENDPOINT. - The production example gains
sithbitd/account-api parity:
docker-compose.prod.example.ymlmounts a realmail_grpc.toml(viaMAIL_GRPC_CONFIG) plus a separate read-only keypair mount, with a minimal-TOML sketch and the Azure Key Vault alternative inline. docker/smoke.shnow statically parses the chain profile (docker compose --profile chain config -q), so a compose regression there fails the smoke run;mail_docs/screenshot-tools/serve-stack.shandwebclients/README.md— the last live dead-name consumers — swept onto theMAIL_GRPC_*overrides.- Trap for compose authors: compose (v2.29.7) interpolates
${VAR:?}even in inactive profiles, so the profile’s variables take defaults (${VAR:-…}) rather than being required.
2026-07-15 — v0.8.3 (docs: sithbit CLI glossary entry)
Documentation-only: the version tags the unchanged protocol state.
- New glossary entry:
sithbitCLI (Operations & infrastructure section), disambiguated from the external Solana CLI it’s a substitute for in thesithbit config/sithbit wallet createworkflow. CLI Quickstart’s first mention of “CLI” now links into it, picking up the sitewide hover/focus definition previewjs/glossary-tooltip.jsalready gives every glossary link — no new JS or CSS needed.
2026-07-15 — v0.8.3 (docs: marketing landing page)
Documentation-only: the version tags the unchanged protocol state.
- New landing page: Welcome, now the book’s
index.html— mdBook always renders a source tree’sREADME.mdtoindex.htmlregardless ofSUMMARY.mdorder, so the new landing content took over theREADME.mdfilename and the Prelude moved to its ownprelude.mdfile (rendering asprelude.html) to make room;SUMMARY.mdstill lists Welcome ahead of the Prelude for the sidebar reading order. The landing page itself is a hero with the SithBit lockup and tagline, a feature-card grid ordered by end-user value proposition (spam priced out at the source, getting paid for your own inbox, an address tied to your wallet, sealed end-to-end mail, drop-in SMTP/IMAP/POP compatibility, no gatekeeper operator model), and closing links onward into the Prelude and Introduction. Styled by the newcss/landing.css, scoped under.sb-hero/.sb-grid/.sb-cardso it never affects the rest of the book; reuses the existing term-icon set and mdBook theme variables rather than introducing new artwork or colors.
2026-07-15 — v0.8.3 (mail-grpc onto TOML config; [grpc]-only verification for sithbitd)
Server-behavior changes, config surface only: no on-chain ABI,
instruction, error-code, or economic change, so per this file’s own
rules this is a PATCH bump, following the v0.8.2 precedent
(config-surface breaks and server behavior outside the protocol ABI
move PATCH). It is not docs-only — previously-required environment
variables are now ignored, a boot that previously refused without them
now comes up on in-code defaults, and a [grpc]-only sithbitd now
verifies recipients it previously could not.
- HARD BREAK —
mail-grpcmoved onto the layered TOML/env configuration every other SithBit binary uses (item 32(a); a clean break, user decision 2026-07-15). The legacy env-only surface is gone:GRPC_SERVER_ADDRESS,JSON_RPC_URL,DEFAULT_KEYPAIR(and its_VAULT_URI/_SECRET_NAMEcompanions),ALIAS_INDEX_DB,ALIAS_INDEX_POLL_SECONDS,ALIAS_CACHE_SECONDS, andHEALTH_BINDare no longer read. Config now comes frommail_grpc.toml(orMAIL_GRPC_CONFIG) withMAIL_GRPC_*env overrides; every key has a dev-friendly default, so an empty file runs a loopback gateway on127.0.0.1:50051— the private-network posture is now the default, not a convention — with the chain endpoint and signing keypair falling back to the operator’s Solana CLI config, exactly like thesithbitCLI. The keypair-content-in-an-env-var shape is gone with it: the TOMLkeypairis the sixth key source (a keypair-file path, or an Azure Key Vault secret). See the rewritten mail-grpc chapter and its configuration table. sithbitd’s[grpc]section now stands alone (item 32(b)):[grpc]without[ipfs]enables RCPT-time recipient verification (alias resolution + postage checks), at-rest sealing key reads, and alias logins, with the chain pipeline off (delivered copies stayreceived; boot logs the verification-only posture at info) — the MX posture that previously demanded an[ipfs]provider the edge never used.[ipfs]without[grpc]warns and boots with chain access disabled. Both sections together remain the full pipeline, unchanged. See the chain-pipeline section and the updated role-split presets.
2026-07-15 — v0.8.2 (domain-sithbit delegate key source; postmaster_key_file removed)
Server-behavior change, config surface only: no on-chain ABI, instruction, error-code, or economic change, so per this file’s own rules this is a PATCH bump, following the distinguishable-suspend-replies precedent (server behavior outside the protocol ABI moves PATCH). It is not docs-only — a previously-accepted config key is now refused at boot (second bullet) — and pre-launch, a config-surface break does not rise to the on-chain-ABI bar MAJOR is reserved for.
domain-sithbit’sdelegate_key_fileis now a key source — the fifth of the file-loaded secrets to take one. A bare string stays a local file path, byte-for-byte compatible with existing configs;{ kind = "akv", vault_uri = …, secret_name = … }opts into fetching the keypair JSON from an Azure Key Vault secret instead (a kind-less{ path = … }table is also a file). The hot-rotation custody contract is preserved: the key is loaded fresh from the configured source on everyPOST /domain(forakv, a fresh vault fetch per request), so rotating the delegate still needs no restart. Boot validation covers whichever source is configured — a bad vault secret fails startup exactly like a bad file did; unset still meansPOST /domainreplies 503.- HARD BREAK — the deprecated
postmaster_key_filealias is removed (user decision 2026-07-15). The config struct rejects unknown keys, so a config still namingpostmaster_key_filenow fails startup loudly instead of being accepted with a warning. Operators must act: rename the key todelegate_key_filebefore upgrading. See the domain-sithbit configuration table.
2026-07-15 — v0.8.1 (docs: populated web-client screenshots)
Documentation-only. Adds the populated-state screenshots the web-client
pages were missing: a mail-in-it inbox on
the webmail app, the signed-in
settings dashboard (balances + postage),
and live marketplace listings.
Captured by driving the real client bundles against a local mock
account-API that serves the same response shapes the clients are
unit-tested against (mail_docs/screenshot-tools/, Option C) — no chain,
store, or devnet dependency, so the frames are deterministic. Registered
in screenshots.manifest.json; protocol version unchanged.
2026-07-15 — v0.8.1 (docs: onboarding wizard steps 2–4 screenshots)
Documentation-only. Completes the browser-onboarding walkthrough in
Web onboarding: the browser wizard
with screenshots of the remaining wizard steps — claim-your-handle,
set-your-price, and review. These required a running backend (the wizard
calls the account API to establish the wallet and check mailbox
ownership), so they were captured against a local account-api +
mail-grpc→devnet stack with a fresh throwaway wallet. Registered in
screenshots.manifest.json; protocol version unchanged.
2026-07-15 — v0.8.1 (docs: mail-grpc gateway topology design note)
Documentation-only: the version tags the unchanged protocol state.
- New design note:
The mail-grpc gateway topology —
records the 2026-07-15 decision that
mail-grpcstays a separate service (three roles in one process: write gateway, read gateway, alias/sales indexer; options considered; what would reopen it), the two-key custody clarification (the gateway’s fee-payer keypair is notdomain-sithbit’s standing delegate), and the now-explicit private-network-only posture — the gRPC surface has no TLS or authentication, so it must never be publicly reachable. - mail-grpc chapter gains the network-posture
callout (prefer loopback/private binds over
0.0.0.0); Scaling out notes the gateway is not a fleet member — many workers share one gateway safely because store leases serialize each wallet’s writes.
2026-07-15 — v0.8.1 (docs: onboarding wallet-generation screenshot)
Documentation-only. Adds a screenshot of the onboarding wizard’s
“Create a new wallet” step — the one-time secret-key reveal, passphrase,
and “I have saved it” gate — to
Web onboarding: the browser wizard.
Captured from the standalone (no-backend) client with the generated
secret key redacted. Deeper wizard steps (handle/price/review) are not
included: advancing past the wallet step requires the account-API
backend, so those await a stacked capture. Registered in
screenshots.manifest.json; protocol version unchanged.
2026-07-15 — v0.8.1 (distinguishable suspend replies & operational polish)
Server-behavior changes, all backward-compatible: no on-chain ABI, instruction, error-code, or economic change, and nothing previously accepted is refused — so this is a PATCH bump, not the MINOR that at-rest sealing took (which changed what the system does with mail). The version moves because reply texts on the wire are behavior, not documentation.
- Suspended accounts now hear why (user decision 2026-07-15:
distinguishable everywhere). SMTP AUTH answers
535 5.7.13 Account disabled(RFC 3463 “user account disabled”, was the deliberately indistinguishable 5.7.8), IMAP answersNO [CONTACTADMIN] account disabled; contact your administrator(RFC 5530), and POP answers-ERR [SYS/PERM] account disabled; contact your administrator(RFC 3206). Safe disclosure: every disabled reply is issued only after the credentials verified, so only the account holder ever sees it. See the per-surface refusal table. sithbit-migratecarries the abuse controls. The account pass now copies the suspend flag and replays the rolling hour/day outbound-usage totals as of the migration instant (bucket timing is not recoverable through the store surface — caveat recorded); the run summary printsaccounts: N (M suspended). See the migration page.- Undatable dead jobs are pruned, not spared. Every storage
backend now stamps the bury time into the dead message itself, and
the hourly retention prune treats an entry with no readable date as
older than any cutoff — previously such entries escaped pruning
forever. The prune (
[spooler] dead_retention_days, default 30) is now documented under The job queues. - Mail listings surface reply and bounty facts.
sithbit mail get’s per-message listing appendsReply-to-hash:,Bounty:, andBounty-expires:lines when set (absent otherwise — a plain send’s listing is byte-identical to before). See Get mail. - The trustless viewer marks replies. The web/plugin viewer panes
render a “Reply to
<hash>…” line for reply messages, mirroring the CLI listing’s reply-to-hash treatment. - Internal: the sealed-envelope decompression cap now reports a distinct, operator-diagnosable error when a payload claims to inflate past the 64 MiB cap (a corrupt stream stays opaque, anti-probing). The cap itself is unchanged.
2026-07-15 — v0.8.0 (Solana clusters & RPC-endpoint appendix)
Documentation only; no code, ABI, API, or CLI change — the protocol version is unchanged per the versioning note above.
- A new appendix: Solana clusters and RPC endpoints. One page answering the questions every “configure an RPC endpoint” step assumes away: what Solana’s public clusters (devnet, testnet, mainnet-beta) are, which ones SithBit uses today — devnet hosts the live test deployment, local work runs on surfpool, mainnet-beta awaits launch — and what the URL you configure actually points at. CLI Quickstart introduces it at the point you first configure an endpoint.
- Book-wide cross-links. The natural “RPC endpoint” mentions across onboarding, deployment, the configuration reference, the GUI-client pages (Thunderbird, Outlook, Chrome, Lockbox), and the glossary now link to the appendix, so the term resolves to its explanation from anywhere in the book.
2026-07-15 — v0.8.0 (docs: first web-client screenshots)
Documentation-only. First screenshots of the browser clients, captured
from the standalone (no-backend) first-run states and embedded in their
pages: the webmail first-run wizard, the
web onboarding wizard,
and the marketplace sign-in screen. These are
now guarded by check_screenshots.py (registered in
screenshots.manifest.json), so a webclients/** UI change that isn’t
re-shot fails the docs gate. Protocol version unchanged.
2026-07-15 — v0.8.0 (docs: Apple Mail extensibility note)
Documentation-only. New reference appendix
Apple Mail extensibility (MailKit)
records Apple Mail’s supported extension surface (the four MailKit extension
points, the Sonoma removal of legacy mail bundles) and why SithBit ships no
Apple Mail client today — MEMessageSecurityHandler could unseal mail on
macOS, but there is no MailKit on iOS/iPadOS and no room for the shared
account pane. Protocol version unchanged.
2026-07-15 — v0.8.0 (at-rest sealing goes live in production)
The item-27 at-rest sealing machinery — shipped 2026-07-14 as a fixture-proven capability — is now wired on in production. No on-chain change; the bump is MINOR because the running system’s behavior changes for end users and one previously-accepted SMTP credential shape is now refused.
- Sealing is automatic on chain-connected deployments. Any
sithbitdor account API with a chain gateway seals password-less accounts’ delivered mail at spool time; there is no config setting (decided: the per-account rule — stored password ⇒ plaintext — is the only gate). The chain-less dev stack stays plaintext. See What your operator holds and sithbitd: At-rest sealing. - The IPFS copy is sealed at spool time too (decided: pin format
“seal-for-IPFS at spool”).
crypto_box_sealis non-deterministic, so the spool-time bytes are the canonical artifact the worker pins — a crash-window rerun re-pins identical bytes and the recorded CID never drifts. Reply-linkage ids are parsed in the same pass and persisted (a sealed body can never be re-parsed). Spool-time facts are canonical: a reading key rotated between delivery and pin takes effect from the next message. - SMTP refuses the reading-secret suffix (decided: reject). A
wallet-signature
AUTHwhose password carries the.base58(secret)login suffix is refused with a normal 535 on the submission path — the secret belongs only where reading happens (IMAP/POP/webmail login). - Wrap hygiene: deleting a message’s last copy now drops its DEK wrap rows and any not-yet-pinned sealed IPFS artifact alongside the blob bytes, on every storage backend.
2026-07-15 — v0.7.0 (alias-transfer consent — BREAKING)
A breaking protocol change: every alias transfer now requires the
recipient’s consent — the escrowed offer/accept flow is the only transfer
path, and the unilateral TransferAlias refuses. This reverses the
recorded 2026-07-05 decision (user decision, 2026-07-15): the
“never planted on a wallet that didn’t ask for
it” guarantee is now
protocol-wide instead of contradicting the old immediate path. Per the
versioning preamble MAJOR stays 0 pre-launch (the enum stayed
append-only in place), so this lands as a MINOR bump with the break
stated plainly: transactions submitting TransferAlias no longer
execute.
TransferAliasis disabled. Discriminant 1 still decodes (history replays cleanly, e.g. in the gRPC indexer) but the dispatch arm refuses with the appended error 85 (UnilateralTransferDisabled, “Unilateral TransferAlias is disabled; stage an OfferTransferAlias (fee may be 0) for the recipient to accept”). See Transfer an alias.- Zero-fee offers are legal.
OfferTransferAliasno longer requires a positive fee:alias transfer initstages a free hand-off by default (--feedefaults to 0, and--expires-inno longer requires it). The recipient still accepts — consent is structural on every path (accept/buy/bid signatures).OfferFeeZero(51) is retired in place, kept only for the frozen error-code ABI. - The flat transfer fee moved to the zero-fee accept. A free
hand-off’s
AcceptTransferAliascharges the delegate-tunableALIAS_TRANSFER_FEE_LAMPORTS(payer → postoffice), waived when the offer’s holder is the standing delegate — the waiver identity moved from the old path’s payer to the holder, keeping bulk-reservation hand-offs fee-free end to end. Priced offers keep the pure 90/10 split; no flat fee rides on top. - Clients follow. The CLI’s
transfer initis one offer-staging code path (the accept surfaces the flat fee or its waiver before signing);mail_wasmretirestransfer_alias_tx/transfer_alias_unsigned, and the web clients’ transfer pane stages a zero-fee offer with “recipient must accept” copy. The CU table swaps the TransferAlias row for OfferTransferAlias (18,894) and the zero-fee AcceptTransferAlias (13,838).
2026-07-14 — v0.6.0 (the domain-program split — BREAKING)
A breaking protocol change: the domain registry moved out of the mail
program into a new, third on-chain program. Per the versioning preamble
MAJOR stays 0 pre-launch (the instruction enums themselves stayed
append-only in place), so this lands as a MINOR bump with the break stated
plainly: transactions that submit domain instructions to the mail program
no longer execute.
- A third on-chain program owns the domain registry.
domain_program, IDDmaiNcmXsPw2juV9JoZSC47V5epAysQi3DJVk3fiBuUv(devnet twinDmaiNHGvprK2op7xqZHXp8UVXXmPUtkas96Goh5sCJQn), carries the domain lifecycle, the DNSSEC-proof authorize/reclaim flows, the domain marketplace, and its ownAdminCloseAccount(discriminant 16) asDomainInstructiondiscriminants 0–16. The domain, domain-listing, pending-deactivation, pending-reclaim, and proof-witness PDAs now derive under and are owned by the domain program. See the reworked Program & PDA reference. - The sixteen mail-side domain discriminants are retired. Sending
9–12, 22–24, 26–28, 31–33, or 35–37 to the mail program is rejected with
the appended error 84 (
InstructionMoved, “This instruction has moved to the domain program”).SetDomainFee(17) andSetRootKsk(25) stay mail-side: they mutate the postoffice, which remains a mail-program account the alias and domain programs read cross-program (fees, root KSK, delegate gate) — the split moved the registry, not the treasury. - The mail program is now unconditionally modexp-free. The
dnssec-proofCargo feature — and thesol_big_mod_expdeployability problem it gates — moved to the domain program (default-on there); the mail and alias programs’ default builds now deploy on any cluster. The modexp-free build page now describesdomain_program, the only program that still needs it. - No client-facing surface changed. The
sithbit domain …commands, the postmaster domain admin flows, the proof staging, the gRPC gateway’s domain/listing scans and sale-history walk, and domain-sithbit’sPOST /domainall follow the domain program transparently — account-meta lists are byte-identical pre/post split.sithbit postmaster reclaimnow drains all three programs’ accounts, postoffice last.
2026-07-14 — v0.5.9 (cleanup bundle: per-cause POP sealed refusals)
Server/client maintenance only; no on-chain ABI, economic, API-contract, or CLI change.
- POP3 now says why a sealed message can’t be served. Retrieving a
DEK-sealed message a session cannot read now answers with a cause-specific
-ERR [SYS/PERM] message is sealed at rest: …line — no reading key in this session, no wrapped key for this reader, or reading key does not match — using the same sealed-refusal vocabulary as the account API. Previously every such fetch collapsed to the generic-ERR [SYS/TEMP] message unavailable, which still covers genuine storage trouble (retryable). - Trustless clients decode the whole mailbox account. The web clients’
direct-RPC chain reader now surfaces
default_postage,domain, andno_ipfsalongsidemail_count, matching the wasm decoder — a strict superset of what the account-API proxy returns.
2026-07-14 — v0.5.8 (web clients: web3.js → @solana/kit codec bundle)
Client build/packaging maintenance only; no on-chain ABI, economic, API, or CLI change.
- The web clients’ vendored Solana library shrank by ~74%. The shared
client library’s vendored
@solana/web3.jsbundle (web3.esm.js, ~682 KiB) is replaced by a codec-only bundle built from@solana/kit7.0.0 (kit-codec.esm.js, ~178 KiB). The external-wallet bridge (Phantom/Ledger transaction signing) now rides kit’s wire codecs behind the same interface — no behavior change for any client. All six shells (webmail PWA, marketplace, onboarding, Outlook, Thunderbird, Chrome) rebuild and repackage against the new bundle.
2026-07-14 — v0.5.7 (trustless webmail, at-rest mail sealing)
No on-chain ABI or economic change — client, server/API, storage-schema, and infrastructure work only.
- Trustless webmail. The webmail PWA can now run with no account API at
all: leave the API URL blank in connection settings and the app unlocks
with the wallet alone, reads the chain over direct RPC (the same wasm
signing/decoding module the plugins use), enumerates the on-chain inbox,
opens sealed bodies locally, and sends — sealing to the recipient’s
published key, pinning through a configured pin service
(
sithbit-ipfsd), and submitting theSendMailtransaction itself. The recipient’sno_ipfsopt-out is honored client-side. Bodies pinned by the client sit outside the operator’s unpin/settle sweep — the client owns that pin’s lifecycle. See Trustless webmail. Both IPFS HTTP surfaces (sithbit-ipfsd,sithbit-gateway) now answer cross-origin browser requests (permissive CORS). - At-rest mail sealing (deployment capability). For accounts without a
stored mail password, a server deployment can envelope-encrypt delivered
copies at rest: each body sealed once under a fresh per-message
AES-256-GCM key, wrapped per reader with the sealed-box construction.
The client-derived reading secret rides the wallet-signature login
(IMAP/POP password suffix;
reading_secreton the account API token exchange), lives only in session memory, and unlocks decrypt-on-read over IMAP FETCH, POP RETR, and/v1/mail. Sessions without the key get a clear refusal, never ciphertext. Storage gains a per-reader wrap table (all six backends). Honest scoping — what this does and does not protect against — in What your operator holds. - Cleanups. The DNSLink config no longer prints its API token in debug
output; the AWS Terraform module’s DynamoDB GSI moved off the
provider-deprecated
hash_key/range_keyarguments; pin/unpin mentions across the book carry a pin icon (see the icon legend).
2026-07-14 — v0.5.6 (customer-managed KMS, first IaC, secret-log hygiene)
No on-chain ABI or economic change — a new optional store setting, deploy templates, and cleanups.
- Customer-managed KMS keys. The AWS store gains an optional
kms_master_key_idunder[store.aws](key ID, alias, or ARN): set, the DynamoDB table is created with KMS-backed SSE and the SQS queues switch from SSE-SQS to SSE-KMS under the same key; unset (the default) keeps today’s provider-managed encryption. See Cloud-store overlays. - First infrastructure-as-code. A new
iac/directory at the workspace root provisions what the servers otherwise create at startup: a Terraform module for the AWS store (DynamoDB + SQS, optional CMK, optional default-off S3 blob bucket) and a Bicep module for the Azure storage stack. Templates are statically validated only — the binaries remain fully zero-config-capable without them. - Secrets kept out of logs. The IPFS provider configs (Pinata JWT, Filebase secret key, remote daemon token) now redact their credentials from debug output, matching the store configs.
- Docs. A committed fragment-link validator (
mail_docs/check_anchors.py) now guards the book against silently broken anchors; the blake3 appendix’s “postoffice commitment set” icon matches its term; account API and IPFS benefits link to per-recipient pin providers.
2026-07-14 — v0.5.5 (per-recipient pin providers, docs repairs)
No on-chain ABI or economic change — a new operator-local account setting plus a docs pass. Storage gains three internal account columns for the sealed provider credentials (nullable, backward-compatible).
- Per-recipient pin providers. A mailbox owner can register their own
IPFS pinning provider (Pinata, Filebase, or a self-run
sithbit-ipfsd) with their mail server via the account API (GET/PUT/DELETE /v1/account/pin-provider, JWT wallet auth); delivery then pins their inbound sealed bodies to that provider in addition to the operator’s default pin — best-effort, never affecting delivery or chain state, and the operator pin stays authoritative. Credentials are sealed under the server credential key like mail passwords; theno_ipfsopt-out continues to suppress all pinning. See Per-recipient pin providers. - Anchor-link repairs. Seven intra-book fragment links to headings with a mid-heading icon were written with a single hyphen where mdBook’s slugifier emits a double hyphen, and silently pointed nowhere; all fragment links across the book now resolve.
- TOC nesting. The name marketplace and Lockbox pages are now nested under the GUI clients parent in the sidebar — they are features riding the clients, not top-level topics.
- Postoffice terminology. “Postmaster commitment set” is corrected to “postoffice commitment set” in the blake3 appendix and glossary, matching the code — the Merkle commitment lives on the postoffice account.
2026-07-13 — v0.5.4 (at-rest SSE, DMARC report completeness, GUI-client docs)
No on-chain ABI, economic, or public-API change — server-side hardening, DMARC report content, and a docs pass. Storage gains four internal DMARC columns (nullable, backward-compatible).
- Encryption at rest on cloud stores. The AWS backend now requests server-side encryption when it auto-creates its resources — SSE on the DynamoDB tables (AWS-owned key) and SSE-SQS on its queues — with no key configuration. Azure Storage/Tables and Cosmos are always encrypted at rest by the platform. Customer-managed KMS keys remain a deferred option. See Scaling out and Deploying.
- DMARC aggregate reports carry the published policy. RUA reports now emit
the evaluated
<policy_published>p/sp/adkim/aspf(previously left unset), stored per-record across every storage backend. See[spooler.dmarc_report]. - DMARC forensic reports carry the message envelope. RUF/ARF failure reports
now include the RFC 5965
Original-Mail-From,Original-Rcpt-To, andOriginal-Envelope-Ididentifiers. See[spooler.dmarc_ruf]. - blake3 documentation & naming. The blake3 appendix
intro and table now enumerate all five blake3 uses (adding the postoffice
Merkle commitment set); the PDA-derivation helpers’ hash parameters were
renamed
*_sha256→*_blake3to match what they actually carry (cosmetic — PDA values unchanged). - Threat model — per-authority accountability (S1). The threat model now documents the MX spoof-burn trust gap as a known, policy-mitigated assumption, with cryptographic per-authority accountability recorded as deferred work.
- GUI-client docs regrouped. Thunderbird, Outlook, webmail, and Chrome are now sibling subtopics under a new GUI clients landing page, and the browser onboarding wizard counts Chrome as its fourth shared-wizard web client.
2026-07-13 — v0.5.3 (Chrome extension, installable webmail, docs backfill)
No ABI, API, CLI, or storage change — two new client-side surfaces and a docs pass. Nothing on-chain is renumbered or relaid-out.
- Chrome extension. A fourth web-client shell (
webclients/chrome), an installable Manifest V3 popup for onboarding and wallet management — equivalent to the Thunderbird/Outlook shells, not a Gmail integration and not an in-popup mail reader (mail read/send rides any IMAP/POP/SMTP client). Reuses the shared Alpine+wasm core over a newchrome-store.js(chrome.storage) adapter;build.shproduces a loadablestaging/tree and a packagedsithbit-chrome.zip. See The Chrome extension. - Installable webmail (PWA). The webmail app now ships
a web app manifest + a static-shell service worker, so a browser can install
it (desktop “Install app” / mobile “Add to Home Screen”) and load the shell
offline. Mail content stays live — the service worker never caches the
account API (
/v1/*). - Reference/docs backfill. The Program & PDA reference
MailInstructiontable is now complete (all 39 variants); the glossary blake3 entry is corrected to its five current uses; and hand-writtentarget="_blank"was retired from the remaining pages (the global external-links hook governs them). - Docs landing page. The Prelude (
README.mdat the time; moved toprelude.md2026-07-15 when the marketing Welcome page took over theREADME.md/index.htmlslot) was the book’s root landing page; the Introduction moved to its own page.
2026-07-13 — v0.5.2 (SithBit brand identity)
Presentational only — no ABI, API, CLI, or storage change. A shared visual identity now spans the mdBook docs, the four web shells, and the two browser plugins.
- One brand, everywhere. A “dark-side” palette (near-black backgrounds, a
violet primary, a crimson accent used sparingly), an
S-monogram mark +sithbitwordmark, and a matching favicon/plugin-icon set. The docs, webmail, marketplace, onboarding, Thunderbird, and Outlook all carry it. See Brand & identity. - Single source of truth for the tokens. The palette is defined once as
--sb-*CSS custom properties inwebclients/shared/brand.css(consumed by the shells and plugins) and mirrored onto mdBook’s per-theme variables inmail_docs/css/brand.css; the plugin icons are rasterized from one canonical mark SVG.
2026-07-13 — v0.5.1 (reach: discovery keyserver, incoming delivery, key headers)
No on-chain ABI change — an additive gRPC field (AliasRequest.domain), a new
public HTTP endpoint, and a client mail-header feature build “reach” on top of
v0.5.0’s domain-scoped namespace. Nothing on-chain is renumbered or relaid-out.
- Incoming mail to
user@verified-domain. A SithBit MX now accepts inboundRCPT TO:<user@domain>for a verified domain: the recipient domain threads through the gRPC gateway’s domain-scopedDomainAliaslookup (global-alias fallback preserved; empty domain = the legacy path) to the designated wallet’s mailbox. Completes the delivery leg of the domain-scoped namespace — those addresses can now receive mail, not just be registered and resolved by a native client. See Receiving mail at a domain-scoped address. - Public discovery keyserver —
GET /v1/chain/cert?email=. An unauthenticated account-API endpoint (HKP/WKD-style) resolves an email / alias / wallet to the recipient’s published X25519 key so any sender can discover it. Empty key ⇒ 200 (seal to the wallet itself); unknown recipient ⇒ 404. The data is already public on-chain; the endpoint is a convenience and a public enumeration surface operators may wish to rate-limit. See thecertkeyserver. - Autocrypt-style key headers on plugin mail. The lockbox
plugins now advertise the sender’s published key in an opportunistic
X-SithBit-Keyheader on outgoing mail and cache it from received mail, so a correspondent’s key is auto-discovered without a chain round-trip on replies. SithBit-specific (X25519, not OpenPGP Autocrypt); the chain stays the source of truth. See Autocrypt-style key discovery.
2026-07-13 — v0.5.0 (domain-scoped aliases)
Additive on-chain ABI: three new AliasInstruction variants
(RegisterDomainAlias, RemoveDomainAlias, UpdateDomainAlias), a new
DomainAlias account, and three appended error codes. Nothing existing is
renumbered — the protocol stays append-only and pre-launch.
- Domain-scoped alias namespace —
user@verified-domain → wallet. A verified domain’s authority can now map[email protected],[email protected], … to wallets in a namespace only that authority may write to — distinct from the shared global-alias namespace, and with no registration fee (the authority already owns the domain). New CLI:sithbit alias register-domain <local@domain> --wallet <k>,alias update-domain(repoint in place),alias remove-domain(refund rent). See Domain-scoped aliases. - Resolution precedence.
sithbit alias get user@domain— and the lockbox plugins’ recipient resolver — now resolve a domain-scoped mapping first and fall back to the global alias when none exists, so existing global aliases keep resolving unchanged. Lockbox mail touser@verified-domainseals to the domain-designated wallet. - Trust model. The domain authority alone controls its
user@domainmappings (create/repoint/remove) — the same authority already trusted to relay the domain’s mail. See the threat-model note.
2026-07-13 — v0.4.5 (lockbox mail v1)
New client capability; no on-chain instruction, account layout, or error-code
change (it reuses the existing SetMailboxKey instruction and the sealed-box
crypto). One additive CLI flag.
- Lockbox mail — client-side end-to-end encryption over ordinary email. The Thunderbird extension and Outlook add-in can now seal a message body to its recipient before it leaves your machine and unseal it after it arrives, so the mail server, relay, and stored copy all see only ciphertext. v1 seals to SithBit-native recipients (a raw wallet or a global alias); a recipient that can’t be resolved is sent ordinary plaintext, and sealing is all-or-nothing per message. Both ends need the plugin. See Lockbox: end-to-end encrypted mail.
- Recoverable reading key.
sithbit mailbox set-key --derivepublishes a reading key derived from the wallet (a deterministic wallet signature run through a KDF), so it regenerates on any device — including a hardware wallet — with nothing to back up. The trade-off (anyone who can make the wallet sign the fixed message learns the key) is documented in the threat model. - The
user@verified-domainnamespace is planned but not yet shipped — v1 aliases are domain-blind, so[email protected]and[email protected]resolve to the same globalalice. A domain-scoped namespace owned by each verified domain’s authority is the next step.
New client surface; no on-chain instruction, account layout, error-code, or CLI
change (the on-chain CreateMailbox/CreateAlias/SetMailboxKey instructions
the flow uses already existed).
- Onboard with Phantom or Ledger. The web onboarding wizard — in all three mail clients and on the standalone get-started page — gains a third wallet path alongside create/import: connect an external browser wallet. Your funds-holding signing key never enters the browser (you approve the mailbox create in the extension); because a hardware wallet cannot open sealed mail, a low-value delegated reading key is generated in the browser and published in the same one-approval transaction, and mail reading routes through it. The honest trade-off (a browser-held reading key you save once, rotatable, whose loss costs only already-received mail) is documented. See Web onboarding.
- Add another wallet from inside a client. Each signed-in client dashboard now has an “Add another wallet” button that re-opens the wizard for a fresh wallet, so onboarding is no longer a first-run-only flow. See Onboarding a second wallet.
2026-07-12 — v0.4.3 (standalone onboarding page)
A new client surface; no on-chain instruction, account layout, error-code, API, or CLI change.
- A standalone “get started” page. The five-step onboarding wizard — create
or import a wallet, claim a mailbox and an optional handle, set your default
postage — is now also served on its own shareable URL (the
webclients/onboarding/bundle), so a brand-new user can be pointed straight at it with no mail client installed. It runs the identical wizard the webmail, Outlook, and Thunderbird clients show at first run, and is served same-origin byaccount_apilike the standalone marketplace page. See Web onboarding.
2026-07-12 — v0.4.3 (self-contained web clients & dependency maintenance)
Build, packaging, and dependency maintenance; no on-chain instruction, account layout, error-code, API, or CLI change.
- The web clients no longer load code from a CDN.
@solana/web3.jsis now vendored into the shared client library and served from the same origin, so the webmail, Outlook, and Thunderbird clients (and the standalone marketplace page) fetch no third-party script at runtime. This removes the Thunderbird extension’s last remote-code reference — the blocker for an add-on–store submission — and lets the clients run fully self-hosted and offline. - Dependency housekeeping. OpenTelemetry (operator telemetry) moved to the
0.32 release train; every wildcard (
*) workspace dependency was replaced with a proper version floor andmail-authpinned exactly, hardening reproducible builds. No runtime behavior change.
2026-07-12 — v0.4.2 (marketplace GUI & modexp-free deploy)
Client-surface, tooling, and operator additions; no on-chain instruction, account layout, or error-code change — the new deploy build gates code out without touching the default ABI.
- The name marketplace, in the web clients and plugins. Browse
aliases and domains listed for sale, buy them, and
list your own — as a standalone web page and as a pane inside the webmail,
Outlook, and Thunderbird clients, with For sale / Expired / Sold filters
(default: For sale). Buying and listing sign with a connected Phantom or Ledger
wallet (external signing), distinct from the in-wasm keypair used elsewhere;
browsing and sale history read the
/v1/chain/listingsand/v1/chain/salesendpoints. See The name marketplace. - A modexp-free deploy build for
AdminCloseAccount.mail_programgained adnssec-proofCargo feature (default on); a--no-default-featuresbuild drops thesol_big_mod_expsyscall so postmaster reclaim — and everything else — can deploy to devnet/mainnet-beta today, where that syscall is still inactive, at the cost of DNSSEC-by-proof coverage in that build. See The modexp-free deploy build.
2026-07-12 — v0.4.1 (marketplace read API, wallet-adapter builders & privacy docs)
Off-chain API, client tooling, and documentation additions; no on-chain ABI change.
- Browse listings and sale history. New read endpoints back the marketplace:
GET /v1/chain/listings(aBrowseListingsscan of every alias and domain listed for sale) andGET /v1/chain/sales(ListSales— full alias + domain sale history, parsed from program logs). See the account API. - Wallet-adapter (unsigned) transaction builders.
mail_wasmgained unsigned builders for the marketplace and onboarding instructions, so a Phantom or Ledger wallet can sign externally — the basis for the marketplace GUI’s external-signing path. - What’s public and private. Two new pages map SithBit’s privacy model end to end: a plain-language What’s public and private overview and the exhaustive field reference — covering the harvest-now-decrypt-later trade-off and public marketplace-purchase metadata. Cross-linked from the threat model.
2026-07-12 — v0.4.0 (postmaster reclaim)
Adds an on-chain administrative instruction; it is append-only, so no existing client breaks.
- Reclaim and reset accounts. A new
AdminCloseAccountinstruction (in both programs) lets the standing postmaster delegate close program-owned accounts and refund their rent — the basis of a newsithbit postmaster reclaimtool (behind a compile-timereclaimfeature, with a mainnet typed-confirm guardrail). See The Postmaster.
2026-07-12 — v0.3.1 (postmaster CLI regrouping & custody docs)
CLI-surface and documentation changes; the underlying on-chain instructions are unchanged.
- Postmaster commands shortened.
postmaster install-commitmentbecomespostmaster commitment, andpostmaster rotate-delegatebecomespostmaster delegate(command labels only — theInstallCommitment/RotateDelegateinstructions are unchanged). See Postmaster key custody. - New reference material. A per-server RFC-coverage table and two service-discovery diagrams.
2026-07-12 — v0.3.0 (alias auctions & web onboarding)
- Alias auctions. Aliases can now be sold by ascending-bid
auction, not only at a fixed price: new
SellAlias(auction mode),BidAlias, andSettleAuctioninstructions, with an anti-snipe extension and a 90/10 fee split. Drive it withsithbit alias sell --auction/bid/settle-auction. See Auction an alias. - Guided web onboarding. A 5-step first-run wizard (create wallet → mailbox
→ alias → keys → earnings) now greets new users across the webmail, Thunderbird,
and Outlook clients, mirroring the CLI
setupflow.
2026-07-11 — v0.2.1 (CLI tooling & ergonomics)
CLI-surface changes only; no protocol ABI or economic change.
- Build a proof witness from live DNS. New
sithbit domain gather-witness <domain>collects a domain’s signed DNSSEC chain from a recursive resolver and serializes the witnessdomain authorize/domain reclaimstage, re-walking it locally before it is ever submitted (behind the opt-ingatherbuild feature). See Building the witness withgather-witness, and the zone-setup notes — including Cloudflare-hosted domains — in Publishing the DNS records the proof needs. - Root-KSK commands regrouped under
ksk.postmaster set-root-kskbecomespostmaster ksk set,postmaster root-ksk-from-ianabecomespostmaster ksk iana, and a new read-onlypostmaster ksk getprints the fingerprint currently anchored on thePostOffice(orunset). See Prerequisite: publish the root KSK. - Derive the root-KSK fingerprint from IANA.
sithbit postmaster ksk ianaturns IANA’s published root trust anchor (root-anchors.xml) into the base58 valueksk setwants — a pure offline conversion. Its new--fetch-anchors <DIR>downloads the anchor, its detached S/MIME signature, and ICANN’s CA bundle, then prints theopensslverification command and the follow-up derive step (it does not derive until you have verified). During a root-KSK rollover (two active anchors, as with the current KSK-2024 introduction) it warns and recommends the newest byvalidFrominstead of erroring blindly, and a new--key-tag <TAG>pins a chosen anchor. See Rollovers: more than one active anchor, Downloading and verifying the anchor, and Getting ICANN’s CA independently. - Fee getters grouped.
sithbit postoffice fee stamp/fee domain/fee aliasreplace the flatfee/domain-fee/alias-fee, and the delegate setters are nowsithbit postmaster fee stamp/fee domain/fee alias(wasset-stamp-fee/set-domain-fee/set-alias-fee). See The Postmaster → Checking status. - Alias transfer grouped.
sithbit alias transfer init/transfer accept/transfer cancelreplacetransfer/accept-transfer/cancel-transfer. See Transfer an alias. - Alias listing cancel folded in.
sithbit alias sell <alias> --cancelreplacesalias cancel-sell. See List an alias for sale → Cancelling a listing. - Alias create is variadic.
sithbit alias createnow takes one or more aliases (reading stdin when none are given), absorbingalias create-bulk, which is removed. See Bulk reservation. mailbox credentials.sithbit mailbox derive-passwordis renamedsithbit mailbox credentials(it prints the mail username + password pair).
2026-07-11 — v0.2.0 (Set 7)
- Frombox prepayment. A third-party sender’s first stamp purchase must now
include at least one stamp; a zero-stamp frombox can only be created by its
owner. The standalone
frombox createcommand was removed —frombox stampnow creates the frombox on first purchase. See Add stamps → The prepayment rule and Creating the frombox on first purchase. - Set a price before the frombox exists.
frombox updatenow creates the frombox first (as a zero-stamp, owner-only account) when it does not yet exist, so a recipient can set their per-sender price up front. See Update postage → Setting a price before the frombox exists. - Escrowed alias transfer in the web clients. The escrowed offer / accept / cancel transfer flow is now available in the web and email-plugin marketplace pane, matching the CLI. See Transfer an alias → Selling an alias: escrowed transfer for a fee.