"""The attack taxonomy. Seven families of constitutional attack. Every scenario in the corpus belongs to exactly one family (sub-vectors are expressed as tags). Scenario IDs are prefixed with the family code, e.g. TD-014 is the fourteenth treasury-drain scenario. The taxonomy is intentionally about *mechanisms*, not motives: a treasury drain executed by an emergency decree is filed under whichever mechanism the scenario primarily stresses. """ from __future__ import annotations from dataclasses import dataclass, field from enum import Enum class AttackTaxonomy(str, Enum): FACTION_CAPTURE = "faction_capture" TREASURY_DRAIN = "treasury_drain" QUORUM_MANIPULATION = "quorum_manipulation" EMERGENCY_RATCHET = "emergency_ratchet" DEFINITIONAL_AMBIGUITY = "definitional_ambiguity" MINORITY_SUPPRESSION = "minority_suppression" PROCEDURAL_DEADLOCK = "procedural_deadlock" @dataclass(frozen=True) class TaxonomyInfo: code: str name: str description: str canonical_precedents: list[str] = field(default_factory=list) kernel_defenses: list[str] = field(default_factory=list) TAXONOMY_INFO: dict[AttackTaxonomy, TaxonomyInfo] = { AttackTaxonomy.FACTION_CAPTURE: TaxonomyInfo( code="FC", name="Faction capture", description=( "A coordinated faction uses legal moves to entrench itself: " "packing the membership with aligned voters, rewriting decision " "rules in its favor, capturing delegation flows, or expelling " "opponents until the faction's grip is self-sustaining." ), canonical_precedents=[ "Court packing and bench capture (US 1937 proposal; Hungary 2010-2013; Poland 2015-2017)", "Enabling-act self-entrenchment (Weimar Germany, March 1933)", "Sybil takeovers of open-membership online communities and DAOs", ], kernel_defenses=[ "membership.max_admissions_per_cycle_fraction", "voting.eligibility_delay_days", "voting.delegation.delegate_cap_fraction", "membership.max_expulsions_per_cycle", "amendments.kernel_paths + ratification_delay_days", ], ), AttackTaxonomy.TREASURY_DRAIN: TaxonomyInfo( code="TD", name="Treasury drain", description=( "A faction (often a bare majority) extracts the common pool: " "single large transfers, salami-sliced serial spends, recurring " "budgets to insiders, exit-timing games, or self-dealing votes." ), canonical_precedents=[ "The DAO drain (Ethereum, 2016) — legal-under-the-code extraction", "51% governance raids on on-chain treasuries (e.g. Build Finance DAO, 2022)", "Classic commons-draining majorities (Buchanan & Tullock, 'The Calculus of Consent')", ], kernel_defenses=[ "treasury.per_proposal_cap_fraction", "treasury.per_cycle_cap_fraction", "treasury.recipient_may_vote = false", "amendments.failed_subject_cooldown_days", ], ), AttackTaxonomy.QUORUM_MANIPULATION: TaxonomyInfo( code="QM", name="Quorum manipulation", description=( "Attacks on the denominator: engineering who counts as eligible, " "scheduling votes when opponents are absent, boycotting to deny " "quorum, or amending quorum itself until a tiny clique can act " "for the whole." ), canonical_precedents=[ "Quorum-busting walkouts (Texas 2003 & 2021; Oregon 2019-2023; Indiana 2011)", "Snap divisions and ambush votes in parliamentary practice", "Quorum hollowing in shareholder and HOA governance", ], kernel_defenses=[ "amendments.min_quorum (invariant floor)", "voting.notice_period_days", "abstentions count toward quorum (boycott is visible, not silent)", "quorum failure preserves the status quo and triggers no cooldown", ], ), AttackTaxonomy.EMERGENCY_RATCHET: TaxonomyInfo( code="ER", name="Emergency-power ratchet", description=( "Emergency authority is acquired legitimately and then ratcheted: " "serial extensions, re-declarations, scope creep of emergency " "powers, or using the expedited clock to push through changes " "that could never survive ordinary process." ), canonical_precedents=[ "Article 48 decree government (Weimar Germany, 1930-1933)", "Permanent states of emergency (Egypt 1981-2012; France 2015-2017 normalization)", "Enabling-act transitions from emergency to entrenchment", ], kernel_defenses=[ "emergency.max_duration_days + automatic sunset", "emergency.max_renewals + renewal_threshold > declaration_threshold", "emergency.redeclaration_cooldown_days", "emergency.prohibited_kinds_during (no kernel changes, expulsions, admissions)", "emergency.powers_available is a closed list", ], ), AttackTaxonomy.DEFINITIONAL_AMBIGUITY: TaxonomyInfo( code="DA", name="Definitional ambiguity exploit", description=( "The text means two things and the attacker picks the convenient " "reading: what counts as a 'cycle', a 'member', a 'single " "subject', 'cast' votes, an 'emergency'. Scenarios in this family " "are run under every listed adversarial reading; the attack must " "be blocked under all of them." ), canonical_precedents=[ "Electoral Count Act ambiguities exploited in the 2020-21 US certification crisis", "'Advice and consent' read as a power of indefinite refusal (Garland blockade, 2016)", "Code-is-law disputes where exploit authors claimed legality (The DAO, 2016)", ], kernel_defenses=[ "review.enabled + challenge window", "the harness's adversarial-reading rule: a wording passes only if it blocks the attack under every plausible reading", ], ), AttackTaxonomy.MINORITY_SUPPRESSION: TaxonomyInfo( code="MS", name="Minority suppression", description=( "A majority targets a minority: facially-targeted rules, " "facially-neutral rules with concentrated disparate impact, " "expulsion campaigns, suffrage games, or making exit so costly " "the minority cannot leave." ), canonical_precedents=[ "Facially-neutral disenfranchisement devices (poll taxes, literacy tests, US 1890-1965)", "Tyranny-of-the-majority dynamics (Madison, Federalist No. 10; Tocqueville)", "Moderation capture and ban waves in online communities", ], kernel_defenses=[ "no-targeted-legislation invariant (challenge grounds: invariant)", "review.disparate_impact_ratio", "membership.max_expulsions_per_cycle + due process + accused_may_vote", "fork.right_to_exit with pro-rata share (locked)", ], ), AttackTaxonomy.PROCEDURAL_DEADLOCK: TaxonomyInfo( code="PD", name="Procedural deadlock", description=( "Weaponized process: blocking everything to extract concessions, " "starving essential budgets, cooldown-and-expiry games, and " "engineered stalemates where the constitution's defaults decide " "who suffers while nothing passes." ), canonical_precedents=[ "US federal government shutdowns (1995-96, 2013, 2018-19) and debt-ceiling brinkmanship", "Liberum veto paralysis (Polish-Lithuanian Commonwealth, 17th-18th c.)", "Belgium's 541 days without a government (2010-11) — continuity rules under stress", ], kernel_defenses=[ "status-quo defaults: standing budgets continue until affirmatively repealed", "quorum failure does not trigger the failed-subject cooldown", "amendments.failed_subject_cooldown_days binds attackers and defenders symmetrically", ], ), } CODE_TO_TAXONOMY: dict[str, AttackTaxonomy] = { info.code: tax for tax, info in TAXONOMY_INFO.items() }