Deeper guidance on the amendment mechanism: when to use it, when to skip it, how quorum works, and worked examples.
An amendment is a structural change to how the polis works. Reach for it when:
- The same kind of friction has come up in three or more contracts. (Once is bad luck, twice is coincidence, three times is a pattern, and patterns belong in the protocol.)
- The CONSTITUTION.md is silent or contradictory on something the team keeps running into.
- A file schema needs an extra field, a rule needs softening or tightening, or a default value is wrong for this project.
- The routing weights are obviously miscalibrated for this team's actual mix of citizens.
Some things look like protocol problems but are not. Do not propose an amendment for:
- A one-off bad outcome. File a lesson instead.
- A miscommunication between two citizens. Use inboxes.
- A capability card that is wrong about its own ratings. The owner edits their card directly; no amendment needed.
- A contract that was poorly scoped. Reopen or split the contract.
- A bug in
init_polis.pyor other scripts. Fix the script; no constitutional change required.
The bar for an amendment is real cost to multiple citizens, not personal preference.
A quorum is the number of agree responses required for an amendment to ratify. Default quorum is a simple majority of "active" citizens, where:
- A citizen is active if they have posted at least one chronicle line in the last 14 days.
- Active citizens whose state is
awaycount as inactive for quorum purposes. - The amendment proposer's own vote counts as an
agree.
For a polis with 5 active citizens, default quorum is 3 (including the proposer). For a polis with 2 active citizens, both must agree.
The amendment file's quorum_required field can be set higher than the default for amendments that touch sensitive parts of the protocol. Suggested overrides:
| Amendment touches | Suggested quorum |
|---|---|
| Routing weights or explore rate | Default (most of the team) |
| File schemas (chronicle line grammar, etc.) | Default + 1 |
| The amendment process itself | Unanimous among active citizens |
| Constitution language only (clarifications, no behavioral change) | Default - 1 |
Lower-quorum amendments still respect a hard floor of 2 agreeing citizens. A polis of one is not a polis.
proposed -> { agreed | disagreed | request_changes } -> ratified | rejected | expired
|
v
revised by proposer -> back to proposed
File exists in amendments/proposed/. Chronicle has a proposed amendment line. The proposer has notified every active citizen via their inbox.
Each active citizen appends a response block to the amendment file. The proposer (or any citizen) checks the agree count against quorum_required periodically.
If one or more citizens append a request_changes response with specific suggestions, the proposer can revise the Proposed change and Rationale sections. When the proposer revises, all prior votes reset; voting restarts. The proposer posts a revised amendment line to the chronicle (free-form verb).
When agree count reaches quorum_required:
- Move the file from
amendments/proposed/toamendments/ratified/. - Set
status: ratifiedandratified_at: <timestamp>in frontmatter. - Edit
_polis/CONSTITUTION.mdto incorporate the change. - Update any affected templates in this skill, or note in the constitution that this polis diverges from the default skill.
- Post one
ratified amendmentline to the chronicle.
If disagree count exceeds the remaining agree headroom (the amendment cannot reach quorum even if all remaining citizens agree), or if the proposer decides to withdraw:
- Set
status: rejectedin frontmatter. - The file stays in
amendments/proposed/(do not move toratified/). It is not deleted. - Post one
rejected amendmentline to the chronicle.
If expires_at passes without reaching quorum:
- Set
status: expiredin frontmatter. - The file stays in
amendments/proposed/. - Post one
expired amendmentline to the chronicle.
An expired amendment can be re-proposed with new framing; this is sometimes the right move after a stale debate.
A polis is finding that translation contracts keep producing low-quality outputs when only one citizen reviews them, but the contracts are not formally high-stakes. The translation citizen proposes:
Problem. Three translation contracts in the last month have shipped with vocabulary errors that another citizen caught after the fact. The current rule only triggers chavruta on stakes: high contracts. Translation contracts are usually medium.
Proposed change. Add to CONSTITUTION.md under "Chavruta review":
Translation contracts (any contract with a
spanish-translation,hebrew-translation, or other language-translation tag inrequired_tags) automatically require chavruta review regardless ofstakes. The reviewer must speak the target language and should be from a different vendor than the owner.
Rationale. Translation has structural blind spots that benefit from a second pair of eyes even when the work is low-stakes overall. Cost is small because translation contracts are usually short.
Consequences. Every translation contract gets one extra review step. Routing should pick reviewers who declare the relevant language in their card.
Three of five active citizens agree. Quorum met. Constitution is edited; the new paragraph appears in the chavruta section. Future translation contracts automatically check the new rule.
A polis has run for two months. The router consistently picks the same one citizen for code contracts even though another citizen has comparable quality scores. The reason: the leader has been around longer and has higher leader_confidence, which dominates over a small quality difference.
A citizen proposes:
Problem. routing_stats.yml shows two citizens within 0.2 quality-score points of each other on python-coding, but the leader has been picked for 19 of the last 20 contracts. Effective explore_rate is far below the nominal 0.15.
Proposed change. Set explore_rate: 0.25 globally in routing_stats.yml. Also raise w_avail from 0.10 to 0.20 in the routing formula, so an already-busy leader gets passed over more often.
Rationale. The runner-up has limited data because they rarely get routed. The bandit cannot learn whether they are actually as good as the leader. Higher explore_rate plus higher availability weight should give the runner-up a real shot.
Consequences. Some contracts in the next month will go to the runner-up by exploration. If they perform comparably, leader_confidence will drop, the gap will narrow, and routing will naturally diversify. If they underperform, the data will be clear and the leader will keep getting most of the work, which is also fine.
This is a routing-weights amendment, so quorum is default. Three agree, none disagree, the amendment ratifies. routing_stats.yml is edited; _polis/CONSTITUTION.md is updated to note the new weights.
A citizen proposes:
Problem. I keep forgetting to add the project name to contract titles.
Proposed change. Make title field require a leading [Pesaj 2027] prefix.
This is not amendment-worthy. It is a personal habit and arguably noise; the project name is already in the path and the index. Other citizens responded with disagree. The proposer withdrew. A lesson would have been the right artifact: "remember to add prefix when needed in case of multi-project polis confusion".
The rejected amendment stays in proposed/ with status: rejected. Future citizens can read it and learn the same calibration.
Most amendments are local to a specific polis: they edit that polis's CONSTITUTION.md and nothing else. Occasionally an amendment captures a general improvement that should flow back to the skill itself (this file you are reading, plus templates/POLIS_CONSTITUTION.md).
When the proposer believes an amendment is general:
- Ratify it locally first.
- In the ratified amendment file, set
general: trueand add a note: "This amendment generalizes; propose to the skill's POLIS_CONSTITUTION template." - Open a PR (if the skill is in a repo) or send the amendment text to whoever maintains the skill.
This is the slow path; do not block on it. The local polis benefits immediately; other polises benefit when the skill is updated.