A quiet place to think, and a way for a group to decide together.
Two halves, one app. The individual space is yours alone: what you write, what you are working out, what you believe, and how that has changed. The collective space is where proposals are examined, responded to, decided, carried out, and honestly reflected on — by the people a proposal is actually addressed to, which is either a group who invited each other or everyone in a place.
The first half never becomes the second unless you send it there.
Signing in is an emailed link, and then four steps: who you are and where, the ten Universal Laws read and agreed to, your own values and passions and beliefs, and a short walk through the rest. Where you are matters more than it sounds — proposals are addressed to places, and the lines you write are what decides which ones reach you.
Agreeing to the laws records which revision of each was on the screen. The wording can be amended, so a plain "I agree" would claim your consent to whatever the text later became.
Three tabs, and one of them is yours alone.
Journal is where entries are sat with rather than processed. Unexamined ones appear as banners reading "From three days ago: '…'. Ready to sit with this?" — a pull, not a task. A thirty-day rhythm display shows the shape of your attention.
Ideas triages what you have thought of into concepts. Markdown in, markdown out, with paths preserved so a re-import updates rather than duplicates.
Profile and Values are the living record: values with your own definitions, what you keep returning to, a statement of faith, a purpose. Faith and purpose are revisable and never overwritten — the history stays, and stays private even when the current statement is shared.
AI is the guardian. It never speaks first, is given the values you wrote down and nothing else, holds no verdict or recommendation about any decision, and is the one thing here that can be forgotten.
Chats are private conversation between friends, reaching no proposal and no decision. Drafts never leave your browser until you submit one. Vault is identity, permissions and the contribution record.
There is no policy anywhere that lets another person read any of it.
Writing is a + in the top bar: one page, four modes, and what you write files
itself to the right place without being sorted or tagged at the moment of
writing. It is the only screen with no backlog on it.
The rest of Home is the attention queue — ordered by what is blocked, not by what is new — under a selector for which scale you are looking at.
The governance cycle from the whitepaper, in full:
Propose → Align → Vote → Activate → Reflect
Propose — anyone it concerns writes one, addressed to the lowest scale that can actually decide it, and it does not go anywhere until it has been thought through. Align — the Truth Engine reads it against the ten Universal Laws, and the review layer scores it against the group's own values. Vote — resonance, three sliders, ratified at ≥ 0.618. Activate — it waits until named people have committed the money and the hands it needs. Agreement is not the same as resources. Reflect — what actually happened, which the review layer reads when the next proposal arrives.
Alongside that: predictions made before the vote and marked against reality afterwards, contention for two proposals that cannot both happen, an amendment path for the wording of a law, words — what the group takes its own language to mean, which is the one screen here that records nothing it decided — and people — follow and friendship, which decide whose work reaches your feed and touch eligibility nowhere.
A proposal is not an idea. Six sections — what this is solving, what would change, what it takes, what could go wrong, what else you considered, and optionally the evidence — and the first five have minimum lengths the database enforces. Then a sharpening pass reads the draft before anyone else can, scores it out of 1.00, and says per section what is still unanswered. Below 0.70 the database refuses the submission. Nothing about the draft is stored: the reading records a score, the questions, and a hash of the exact words, and that row is private to its author until a proposal attaches it.
Asking again about the same words can only lower where you stand — the lowest reading of a text governs. A judge that varies between runs is otherwise something to be asked repeatedly until it says yes. To score better, change the proposal.
Without an API key the offline reader does this on structure: is each section there, do the costs carry numbers, do the risks name something that could actually go wrong, were alternatives weighed including doing nothing. It says plainly that no model read it. That is a real filter and it is the honest limit of a reader that cannot read.
A contribution to a debate says what it is. A question, an amendment, an alternative, a concern — the four the whitepaper names — and a reply is a reply. That is not taxonomy for its own sake: a question can be answered and counted, and a thread where everything looks the same is one where nothing has to be answered by anybody.
Questions and concerns are answered in writing, attributed, permanent — the same standard as a flag. They do not block. A flag is the rubric finding something below the group's own floor; a concern is a person disagreeing, and a system where any one person can hold a proposal until satisfied has a veto in it. So an unanswered concern is put in front of everyone before they touch a slider, and recorded on the decision, and then the group decides with it in view.
An amendment can be adopted — the author saying they will carry it into a rewrite. It changes nothing about the live proposal, because the text is fixed at submission and stays fixed.
A mean cannot hide a split. Everyone at 0.50, and half at 0.10 with half at
0.90, both average 0.50 — and they are not the same group. The first is a room
that is unsure; the second is a room that disagrees. Every decision now carries
the spread of alignment and a polarized flag: real dispersion, with both ends
occupied. A polarized proposal still passes if it clears the threshold — but
the record says the group was split, which is "prevents tyranny of slim
majorities" made legible rather than asserted.
While a proposal is open the votes stay hidden, so polarization there is read from the argument instead: whether people are still addressing each other, or have started restating positions at each other. The summary says which, and says plainly that it is a reading of the thread and not of anyone's resonance.
And dispersion cannot see a group that means two things. Two members both resonate at 0.90 on "shared workshop access". One means a rota; the other means a key each. The numbers are identical, so nothing the ledger holds can tell them apart — the disagreement is upstream of everything this system measures. So a group can raise a word and each member writes what they take it to mean, and the readings sit next to each other: no agreed definition, no vote on a reading, and nothing that computes whether two readings match. A similarity figure over two people's sentences would put a number on meaning, be wrong in ways nobody could audit, and look on screen exactly like a fact. Readings are append-only, so the moment a group finds out it meant two things cannot be tidied away afterwards.
The feed is ordered by what is blocked, not by what is new. Home opens on what is actually waiting on you, with the reason attached — not audited yet, a tension unanswered, you have not read the review, you have not responded — and everything you have already answered sinks. A feed sorted by recency asks everyone to read everything, which is how people stop reading anything.
A proposal that ran out of people comes back. Not one that was read and declined — that was decided, and offering it back would be the system quietly asking for a different answer. But a proposal that never reached the floor of responses its scale requires, or that passed and then sat because nobody committed what it needed, appears under Deserves another look. Taking one up writes a new proposal from its words and nothing else: it is sharpened and audited again, because a clearance from one moment is not a clearance now. The new one records what it came from, and both ends of the thread say so.
What has happened is read off the ledger, not assembled from the tables. A second, softer account of the same events is how a record starts disagreeing with itself.
Resonance is three sliders, not a vote. Alignment, confidence and urgency, each 0–1. A yes/no collapses "I think this is wrong", "I have no idea" and "not now" into the same mark.
The averages stay hidden until a proposal closes. Members see how many have responded and their own numbers, never a running average. A visible average changes what people report, which is the entire thing resonance exists to avoid. This is enforced in the database, not in the interface.
Understanding before action. The sliders do not work until a review exists and you have said you read it. That is recorded — not to police anyone, but so the group can tell a proposal three people considered from one three people scrolled past.
A critical flag is answered, never dismissed. Anything the review scores below the group's values floor, or flags as a high-severity risk, needs a written answer naming what changed or why the risk is acceptable — attributed and timestamped. This is the mechanism that lets a weak proposal be retired early without anyone having to be the person who objected.
A project cannot be completed without a reflection. The database refuses. A group that closes projects without recording what happened has a memory that cannot teach it anything, and the retrieval step on the next proposal has nothing to retrieve.
Universal Law sits above everything. Ten laws, from the whitepaper, shipped
as code and readable at /settings/law. Every proposal is read against all
ten. A tension is answered in writing and the proposal proceeds. A
violation ends it — it cannot be voted through, no steward can set it aside,
and there is no policy in the schema that would let one be edited or deleted.
Because an unoverridable verdict from a fallible model would otherwise be
final, members can challenge a reading; the challenge goes back to the audit,
which must address it and may well hold its position.
Ratification is not activation. A proposal that passes is a proposal the group agreed to, and nothing more. It becomes a project when the money and the people it needs have actual names against them. A proposal that needs nothing activates immediately — "it can be done as it stands" is a real answer.
Prompts are versioned configuration, readable by every member. Every score
records the prompt id and version that produced it. Changing a rubric means
bumping the version, never editing in place. A group being scored by a rubric
can read the rubric, at /settings/prompts.
The threshold is the golden ratio. 0.618, as the whitepaper specifies, "so that consensus comes through harmony rather than dominance" — not a number chosen here, and it does not move between scales.
Nobody has to be invited. A proposal is addressed to a group, or to a place at one of five scales — Local, Regional, National, Continental, Global. Where you are is four lines you write on your profile, not a coordinate and not a lookup: a claim, checkable by the people standing next to you. You can read, answer and write proposals at any scale you are in, and you cannot propose for somewhere you are not. Subsidiarity is in the protocol, not in the advice: the compose screen asks for the lowest scale that can decide the thing.
A place has no register, so it has no participation share. A group knows
how many members it has. A city does not, and building that list would be a
surveillance project rather than a governance one. So at place scale the share
is replaced by a floor on how many people actually responded, and the
interface says "4 voices, this scale needs 12" rather than inventing a
percentage. Those floors live in scope_rules, readable by everyone at
/settings/place.
A place has no steward, so the clock closes it. A group's steward decides when deliberation ends. A place has nobody entitled to pick that moment, so a proposal carries a window set at submission and cannot be closed before it expires — and its address cannot be changed afterwards either.
No chain, no token, no ZK. What the whitepaper puts on-chain, this puts
behind interfaces in src/lib/ledger — with an append-only, hash-chained
Postgres table underneath. Tamper-evident, not trustless, and the app says so
in those words rather than implying more. See docs/architecture.md.
You need Node 20+ and a Supabase project. The free tier is enough for a group of fifty. Runs on macOS, Linux and Windows — nothing here is platform-specific.
git clone <this repo>
cd sovereign
./scripts/setup.shThat installs dependencies, writes .env.local, applies the migrations if you
give it a database URL, and tells you the one thing it cannot do for you. It is
safe to run twice — it will not overwrite an existing .env.local.
The rest of this section is what that script does, if you would rather do it by hand or it does not fit your setup.
1. Make a Supabase project at supabase.com.
2. Run the migrations in order — paste each into the SQL editor:
supabase/migrations/0001_schema.sql tables, enums, triggers
supabase/migrations/0002_rls.sql row-level security
supabase/migrations/0003_functions.sql the decision rule, the ledger, retrieval
supabase/migrations/0004_universal_law.sql the ten laws as a gate, and 0.618
supabase/migrations/0005_activation.sql needs, commitments, Activate
supabase/migrations/0006_scope.sql places, scales, the subsidiarity engine
supabase/migrations/0007_readiness.sql the six sections, and the gate on submitting
supabase/migrations/0008_discovery.sql the feed, dormant proposals, lineage
supabase/migrations/0009_debate.sql typed contributions, summaries, polarization
supabase/migrations/0010_projection.sql dated predictions, frozen and marked
supabase/migrations/0011_personhood.sql one person, one nullifier, no name
supabase/migrations/0012_people.sql follow, friendship, the social feed
supabase/migrations/0013_contention.sql two answers that cannot both happen
supabase/migrations/0014_chat.sql private conversation between friends
supabase/migrations/0015_amendment.sql the tenth law made operable
supabase/migrations/0016_guardian.sql a private reader that never speaks first
supabase/migrations/0017_mirror.sql where you and the audit differ
supabase/migrations/0018_accession.sql agreeing to the ten, and to which wording
supabase/migrations/0019_inquiry.sql what the ways of knowing hold, never an answer
supabase/migrations/0020_ask.sql the fourth tab: finding, and asking on its own
supabase/migrations/0021_accession_required.sql you cannot arrive without agreeing
supabase/migrations/0022_search_mine.sql searching your own half, kept apart
supabase/migrations/0023_lexicon.sql what the group means by its words
supabase/migrations/0024_lineage.sql what changed the second time
scope_rules ships with local set to one voice and no waiting period, so a
new instance can get through a decision on its first day. That is the first
number to raise as people arrive:
update scope_rules set min_voices = 3, deliberation_days = 2 where scope = 'local';supabase/raise-the-floor.sql does this for every scale, with the reasoning
for each number written next to it. It is not a migration and is not applied
automatically, because how many voices a place needs is a judgement about who
is actually there and the database cannot make it — a place has no register.
Home shows the rule in force at whichever scale you are looking at, so nobody has to go and read the table to find out what bar a proposal clears.
supabase/reset.sql clears a half-applied install — a migration that fails
partway leaves a database with no way forward, and the error it then gives
says nothing about why.
Or with the CLI: supabase db push.
3. Configure it.
cp .env.example .env.localNEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY come from
Project Settings → API.
ANTHROPIC_API_KEY is optional. Without it, the whole loop still works on an
offline reviewer — scores come from structural signals in the text, and every
review it writes says plainly that no model read it. Add a key when you want a
real reading.
4. Set the redirect URL in Supabase under Authentication → URL
Configuration: add http://localhost:3000/auth/callback, and your production
URL when you have one. Magic links fail silently without this.
5. Run it.
npm run devSign in with your email, name three values you actually hold, and say where you are. A group is optional.
supabase/seed.sql contains one complete loop — a proposal with a real review,
a values flag answered by halving the term, a three-comment deliberation, three
resonance votes, a decision, a project with a budget, and a reflection in which
the group's core assumption turned out to be wrong. It exists to make the shape
legible on first open and to give the retrieval step something to retrieve.
Instructions are in the file's header. It is safe to skip, and everything in it
is removable.
Vercel, with the same environment variables, plus the deployed URL added to Supabase's redirect list — without which magic links fail silently. The order matters and the database goes first: docs/deploying.md.
npm run check # typecheck, lint, test, buildThe build passes with no environment variables set — configuration is read through getters so a missing key produces a readable message at request time rather than a failed build.
The rules that define this product live in Postgres, so that is where they are
tested. supabase/tests/ runs against any local Postgres as a non-superuser,
so row-level security actually applies, and checks four hundred and forty-one
things across eighteen suites — that a member cannot read another member's
journal, that resonance is refused before the review is read, that two unanswered flags fail
a proposal whatever the numbers say, that a project cannot complete without a
reflection, that an edited ledger row is detected, that someone in Totnes
cannot read or answer a proposal addressed to Hackney, and that an author
cannot re-aim a proposal once it is out, that an unsharpened draft is refused
and a sharpening of one text cannot be spent on another, that a proposal
people read and declined is never offered back as dormant, that four people
split two against two are not recorded as a consensus, and that nothing
anywhere computes how much two people's readings of the same word agree, and
that a proposal's history cannot be re-pointed after people have read it. See
supabase/tests/README.md for how to run it.
createdb sovereign_test
psql -d sovereign_test -v ON_ERROR_STOP=1 \
-f supabase/tests/00_supabase_shim.sql \
-f supabase/migrations/0001_schema.sql \
-f supabase/migrations/0002_rls.sql \
-f supabase/migrations/0003_functions.sql \
-f supabase/migrations/0004_universal_law.sql \
-f supabase/migrations/0005_activation.sql \
-f supabase/migrations/0006_scope.sql \
-f supabase/migrations/0007_readiness.sql \
-f supabase/migrations/0008_discovery.sql \
-f supabase/migrations/0009_debate.sql \
-f supabase/tests/00b_support.sql \
-f supabase/tests/01_rules.sql \
-f supabase/tests/02_universal_law.sql \
-f supabase/tests/03_activation.sql \
-f supabase/tests/04_scope.sql \
-f supabase/tests/05_readiness.sql \
-f supabase/tests/06_discovery.sql \
-f supabase/tests/07_debate.sqlNo blockchain, tokens, SOV, wallets, zero-knowledge proofs, DIDs or verifiable credentials. No Proof-of-Alignment consensus, no Spheres of Civilization DAO network, no liquid democracy or delegation, no tiered transparency. No public feeds, public profiles or cross-group discovery. No screen-time features, no streaks, no notifications.
The subsidiarity engine here routes on place names, not geometry: there is no containment relation, so a regional proposal does not automatically reach everyone whose locality sits inside that region — each person states each scale themselves. A gazetteer would fix it and would also be the moment this starts holding real location data, which is a decision worth making deliberately rather than by default.
Most of these are in the whitepaper, and several are good ideas. None of them
help a group of eight decide something on a Thursday, which is the thing that
has to work before any of the rest is worth building. docs/roadmap.md says
what would earn a place next, and what would have to be true first.
docs/architecture.md |
How it fits together, and the ledger seam |
docs/data-model.md |
Every table, and why the constraints are where they are |
docs/design-system.md |
Tokens, type, and the rules for new screens |
docs/roadmap.md |
What V1 is for, how to tell if it worked, what comes next |
CLAUDE.md |
Conventions for anyone — or anything — editing this repo |