Repository navigation
Society votes: members amend the charter by liking a proposal - #15
Merged
Merged
Conversation
A proposal is a member's cast naming the charter's current head and the changes (+/- member, +/- moderator, as signed mentions). An approval is a member's like, from any app; once seen it counts for good. It passes when more than half of that version's members approve; leaving needs only your own. The charter becomes an append-only log of the founder's charter plus each passed proposal with its signed likes, so anyone can replay it from their own node. No deadlines: author timestamps can be backdated. - core: votes.ts (format, parser, replay, tally, advance, compareLogs, propose, announce); Verifier.voteKey checks key ownership and gasless key scopes; likesByCast and repliesTo; buildCast takes mentions and sends casts over 320 bytes as LONG_CAST (fixes 321-1024 byte casts) - CLI: charter proposals | propose | announce | import; verify replays logs - web: Votes section in the Society card - docs: README "Society votes", TRUST.md "What a society vote proves" - tests: 20 new (90 total), fake node world and a local demo Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ut7NR5KyubX7WMMggTFNEb
|
Caution Review failedThe pull request is closed. Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
census, feed, join, proposals, propose and announce accepted any log that replayed, including one whose majority rests on approvals with keys no node lists, as a hand-made log with made-up keys would have. A forged log could then change the member list (and join would follow it). They now refuse such a version unless --trust-unrecountable is given, as import already did, and charter verify exits 1 for it. The web client already asks before using such a log. Found by the automated security review of the previous commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ut7NR5KyubX7WMMggTFNEb
The site lists votes under what is different, explains them in the societies step with the three commands, and adds a known gap: votes have not run on mainnet yet. AGENTS.md gains the property that a charter changes only by a majority of its members' likes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ut7NR5KyubX7WMMggTFNEb
This was referenced Oct 23, 2026
# Conflicts: # README.md # src/core/index.ts
Spider333
marked this pull request as ready for review
October 24, 2026 18:10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Society votes: members change their charter by liking a proposal, in any Farcaster app, and anyone can recount the result from their own node. Outpost already had exit (Leave); this adds voice.
Draft. Do not merge before the prize deadline (Sat 24 Oct 14:47 UTC). David decided on 23 Oct: merge after the deadline without the live mainnet test. Before merging: mark ready, bring in
main(merges cleanly as of 23 Oct), CI green. Merging tomainredeploys the hosted client on GitHub Pages.The four rules (
src/core/votes.ts)+/- member,+/- moderator), each account as a signed mention.No deadlines: Farcaster timestamps are author-set and can be backdated (Snapchain only refuses dates more than 10 minutes ahead), and block times survive 3 days on a node, so a deadline could not be re-checked later. A proposal stops counting once another passes, because it then names an old head.
What is in it
advance(appends what passed, refuses to adopt when two proposals pass at once),compareLogs(same / extends / behind / fork / other society),propose,announce.Verifier.voteKeychecks that the key belongs to the account and, for gasless keys, that its scope allows the message type (Snapchain refuses out-of-scope likes, but a hand-made log could contain them). Likes must be mainnet. Keys revoked since a vote are labelled "cannot be re-checked now", and an amendment whose majority rests on them is "not recountable from scratch"; importing such a log needs an explicit yes.likesByCastandrepliesTo(plain GETs, so the society gate needs no change; a gate test covers it).buildCasttakes mentions and sends casts over 320 bytes asLONG_CAST. This also fixes a pre-existing bug: casts of 321 to 1024 bytes were sent asCAST, which the node rejects.charter proposals | propose | announce | import,charter verifyrecounts logs;census,feedandjoinuse the current version.test/votes-demo.ts: a fake node with a 5-member society and an open proposal, to try the web client without mainnet accounts.Tests and checks
npm test: 91 pass (70 existing + 21 new intest/votes.test.ts, including end-to-end CLI runs against HTTP fake nodes, tamper tests, forks, conflicts, revoked keys, out-of-scope keys, testnet likes, clock skew, forged logs).--trust-unrecountableis given, andcharter verifyexits 1. Not adopted: treating unlisted keys as forged, because a legitimately revoked gasless key looks the same, so honest history would stop replaying.tscstrict, plus--noUnusedLocals --noUnusedParameters: clean.npm run build: clean. jscpd: 0 clones.reactionByIdignored the reaction type (the client correctly rejected its answer as "not matching the request"); fixed in the test world.Not done
Pre-existing, not changed here
verify.ts(comment nearcheckKey) andsecondnode.tsstill say Snapchain revokes a removed key's messages. Since engine V14 it does not, so feeds may drop genuine old casts of accounts that rotated keys. Proposed as a separate PR.verifyMessageaccepts some encodings that do not change signed content (a hex prefix other than0x, renamed null fields, non-canonical base64 padding). For votes this fails safe: a log with such a field is shown as a fork, never merged.🤖 Generated with Claude Code
https://claude.ai/code/session_01Ut7NR5KyubX7WMMggTFNEb