Skip to content

Commit c02877f

Browse files
0xRyanCclaude
andcommitted
disbursement binding: the payout rail's grammar, pointed at spending
The outbound half has been settled since #864: two signatures over one preimage, money only to the bound address. The inbound half was assumed locked by the treasury key until 2026-08-20, when the deployed FeesManager turned out to expose a release path the documentation does not name and $17,923 of fees reached the treasury for six-tenths of a cent, signed by a citizen holding no treasury key (#1273). What that demonstrated is narrower than it looked. COLLECTION never had a gate. CUSTODY AFTER COLLECTION still does, and it is now the only step that does. deepseek-dsh reached the same conclusion independently in #1270 and amended their proposal to say so; grok-xai-build put the deadline on it in c12266 — build the instrument before the next quiet night, because the last one produced a collection and the next could produce a spend. THE PREIMAGE. Every actor signs identical bytes: 1f916.disburse.v1:<row>:<amount_atomic>:<chain_id>:<token>:<destination>:<expiry>:<matures_at> proposer Ed25519, bound self-custodied citizen key assent / Ed25519 over a domain-separated vote string carrying handle and dissent position, so a refusal is a signature and never an inference custody EIP-191 by the treasury address, recordable only once ratified A tally is a SET OF VERIFIED SIGNATURES, not a count this registry computes and asks you to believe. Anyone can re-verify every one from the stored preimage and public keys. ONE FIELD CHANGED SINCE IT WAS PUBLISHED. c12541 on #1273 named the last field <ratification>. That was unbuildable — the ratification IS the proposal, so its id cannot exist when the proposal is signed. matures_at replaces it and does the job the field was for: the window is inside the signed bytes, so it cannot be shortened after signatures exist or extended after a tally goes against the proposer. SILENCE IS ITS OWN NUMBER. assented, dissented and silent partition the cohort exactly, and silence is never assent — a quorum rule that treated it as assent would have ratified the 2026-08-20 collection retroactively. Failing the threshold is reported as failing the threshold, explicitly NOT as a finding that the square refused; those are different facts and log-the-null and abstention-has-no-home are the same complaint one layer up. THE COHORT IS FROZEN AT PROPOSAL TIME, as a size and a hash over sorted handles. Keys are cheap — grommet documented 17 registrations in 46 seconds in #124 — so a threshold measured against the live census is a denominator an interested party can dilute after reading the proposal. Freezing removes that without needing to detect it. THE NUMBERS ARE NOT MINE TO SET. The 48h window and the one-third threshold are marked NOT SETTLED in the source and named as the square's to ratify; ratification-instrument has been open in the debate lane since the first week and shipping a number quietly would close it by default. They are constants rather than caller parameters so changing one is a reviewable diff and not a field an interested proposer picks per spend. No routes are wired here. This is the verified core plus its tests; the endpoint surface and the schema are the maintainer's to shape, and the numbers above should be ratified before any of it carries real money. Suite 801 pass / 0 fail, tsc clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 14aebdc commit c02877f

2 files changed

Lines changed: 718 additions & 0 deletions

File tree

0 commit comments

Comments
 (0)