# Governance Semver Software solved "how do we change a thing many people depend on without breaking trust" with semantic versioning: the version number itself encodes the blast radius of a change. We apply the same contract to constitutional text. The current version lives in `constitution/version.yaml` and is bumped mechanically at ratification — never by hand. ## The contract | Bump | Meaning for a citizen | |-----------|------------------------------------------------------------------------| | **MAJOR** | The meta-rules you agreed to live under have changed. Re-read the kernel. Your fork may need a deliberate re-base decision. | | **MINOR** | New capability or module; nothing you relied on changed meaning. | | **PATCH** | Parameters or wording clarified; semantics preserved. | The version is a promise to **forks** above all: a fork tracking upstream can auto-merge patches, review minors, and must make an explicit constitutional decision (its own vote) to adopt a major. `govtool fork sync` enforces exactly this (see [forking.md](forking.md)). ## Classification rules The classifier (`govtool.classifier`) operates on the *structured* diff — it parses base and head YAML and diffs the data, not the text, so reformatting and comment changes never trigger a bump. Rules are evaluated top-down; the first matching rule wins, and when multiple files are touched, **the strictest label across the diff applies to the whole proposal**. ### `kernel-major` — breaking kernel change A diff is `kernel-major` if it does any of the following: 1. Modifies, removes, or reorders any rule in `constitution/kernel/article-03-amendment-procedure.yaml`, `article-04-ratification.yaml`, or `article-05-voting.yaml` — the rules about changing rules are always major. 2. Touches `constitution/invariants.yaml` or `article-06-invariants.yaml` in any way (add, remove, reword). Weakening an invariant is obviously major; *adding* one is also major, because new hard constraints bind every existing citizen and fork. 3. Removes or narrows any right granted by the kernel (citizenship in Article 2, fork rights in Article 7, ledger access in Article 8). 4. Changes any quorum, threshold, voting-window, or eligibility parameter anywhere in the kernel. 5. Removes a kernel article or changes an article's `id`. 6. Expands emergency powers in `article-09-emergency.yaml` (broader triggers, longer durations, weaker sunset) — emergency *narrowing* can be minor; emergency *expansion* is always major. 7. Modifies `citizens/registry.yaml` in a way that removes or suspends an active citizen. (Adding citizens is `kernel-minor`; removing them is a rights question and therefore major.) ### `kernel-minor` — additive kernel change - Adds a new clause to an existing kernel article without modifying existing clauses' semantics (key-level addition only, no mutation of existing keys). - Adds a citizen to the registry. - Narrows emergency powers (shorter sunset, stricter trigger). - Adds interpretation guidance under Article 10 without changing rules. ### `userland-minor` — new userland module - Adds a new file under `constitution/userland/` without touching the kernel. ### `userland-patch` — userland parameter change - Changes parameter values, descriptions, or wording inside an existing userland module (e.g. adjusting the funding pool's disbursement parameters in `userland/funding-pool.yaml`), without adding/removing module rules or touching the kernel. ### Hard edges the classifier enforces - **Mixed diffs take the strictest label.** A typo fix in userland bundled with a kernel threshold change is one `kernel-major` proposal. Keep proposals atomic. - **No structural laundering.** Moving a rule from a kernel file to a userland file (or renaming files to slip kernel content past path-based rules) is detected by content matching against kernel rule ids and labeled `kernel-major`. There are regression tests for this exact maneuver in `tests/test_classifier.py`. - **Unknown files under `constitution/` are rejected at schema validation**, before classification — you can't introduce an unclassifiable category. - **The classifier classifies itself conservatively.** Any diff it cannot confidently place falls through to `kernel-major`. The failure mode is "asked for too many votes", never "asked for too few". ## How labels map to gates The label selects a row from the gate-tier table in `article-03-amendment-procedure.yaml` (defaults at v0: major = 2/3 + 50% quorum, minor = majority + 33%, patch = majority + 25% — see [pipeline.md](pipeline.md)). The mapping itself is constitutional text; changing the mapping is rule 4 above, hence `kernel-major`, hence a supermajority. The system's escalation ladder is self-protecting by construction. ## Disputing a label Classification is code and code has bugs. If a label looks wrong: 1. Reproduce locally: `govtool classify --base main` prints the label *and the rule that fired*, per file. 2. Open an issue with the diff and expected label. Do not restructure the diff to dodge the classifier; anti-laundering rules treat that as major. 3. Classifier fixes go through ordinary code review, and **every dispute — upheld or not — becomes a case in `tests/test_classifier.py`**. The classifier's test corpus is its case law. A note on philosophy: the classifier deliberately has *no override flag*. No maintainer, no majority, no emergency power can hand-assign a softer label. If the classifier is wrong, fix the classifier in the open; the fix applies to everyone, forever, and is itself tested.