primitives
Core primitives
These twelve are universal — every party that runs on partyclip uses them. The framework ships each one; a deployment configures it, and never reinvents it.
Primitive 01
Constitution
A constitution article is a first-class entity. It has a stable ID — CONST-K1-A2.1 — that never changes, a version that increments on amendment, a markdown body, and a mutability setting. It is the bottom layer of every deployment: each patch the system produces is evaluated against it.
Mutability comes in four levels: immutable, amendable by simple majority, amendable by supermajority, and amendable only by referendum. An immutable article rejects any mutation event at the validator level — it cannot be quietly edited. Amendments are not edits at all; they are constitution-classified patches routed through the supermajority pipeline, so a change to the rules leaves the same public trail as any other policy.
Every patch carries a list of citations: references to articles by stable ID, each tagged with a declared relevance — supporting, in tension with, or opposing. This makes a policy's relationship to the constitution machine-checkable and publicly legible. A reader can see which articles a patch claims to honor, and which ones it openly strains.
- stable_id — CONST-K1-A2.1 (never changes)
- mutability — IMMUTABLE | AMENDABLE_SIMPLE | AMENDABLE_SUPERMAJORITY | AMENDABLE_REFERENDUM
- version — incremented on each amendment
- cited by a patch as — supporting | tension | opposing
Primitive 02
Patch pipeline
A patch — the atomic policy artifact — moves through a pipeline that is a state machine, not a script. The default stages are drafting, critique, risk assessment, execution, bias review, operator sign-off, and published. Each stage is a separate agent run, recorded as its own row with the model used, the cost, the duration, and the decision.
Any later stage can reject a patch. A rejection sends it back to drafting with a structured record — a reason code, not free text in v0 — so the loop is auditable rather than conversational. The pipeline itself is defined as YAML in the deployment's content repository: per-stage timeout, retry policy, on-reject behavior, and model overrides are all configuration.
A state machine is chosen over a monolithic chain for four concrete reasons: resumability, so a failed stage does not lose the prior stages' work; reviewability, so each stage's input and output is a discrete artifact; substitutability, so one agent can be swapped for another between deployments; and operator visibility, so "patch 47 is in bias review" is a real, concrete state. A per-pipeline budget cap moves a patch to a killed state if its cost is exceeded.
- DRAFTING · CRITIQUE · RISK_ASSESS
- EXECUTOR · BIAS_MIRROR
- AWAITING_SIGNOFF · PUBLISHED
- side states — REPEALED · KILLED
Primitive 03
Patch classification
Every patch is tagged with one of three classifications — regular, cross-cutting, or constitutional — and the tag decides two things: which pipeline the patch runs through, and which voting rule applies to it.
A regular patch runs the standard pipeline with only the binary critic vote. A cross-cutting patch — one that touches several ministries — adds a cabinet vote at simple majority. A constitutional patch, which amends the constitution itself, runs the constitutional pipeline and requires a cabinet supermajority.
Classification is what lets a single framework serve both a routine ministry adjustment and a charter amendment without special-casing either. The difference between a small fix and a foundational change is expressed as data on the patch, not as separate code paths.
- REGULAR → standard pipeline → Critic vote only
- CROSS_CUTTING → standard + Cabinet Vote → simple majority
- CONSTITUTIONAL → constitutional pipeline → supermajority
Primitive 04
Voting
partyclip has two kinds of internal vote. At the critique stage, a single critic agent casts a binary vote — pass or reject. For larger patches, a cabinet vote collects a yes, no, or abstain from each ministry head, each accompanied by a rationale.
Thresholds are configuration, not constants. A cross-cutting patch needs a simple majority of voting heads — more than half by default — while a constitutional patch needs a supermajority, two-thirds by default. Quorum and both thresholds are set per deployment. Per-vote weight defaults to one; weighted variants exist but are meant to be used sparingly.
External advisory votes are separate. Registered citizens can cast advisory votes, recorded as public-reaction entities. They are advisory by design: they inform the party's deliberation, they do not bind it. Quadratic, preferential, and other weighted schemes are explicitly deferred — v0 keeps voting plain.
- voter_role — Critic, Head:Economy, …
- vote — YES | NO | ABSTAIN, with a rationale
- weight — 1 by default
- thresholds — simple >50% · supermajority ≥2/3 (configurable)
Primitive 05
Dissents
A dissent is a first-class entity, and it is deliberately distinct from a rejection. A rejection says "this patch should not advance" and sends it back to drafting. A dissent says "I disagree, but I will not block this" — and it travels forward with the patch.
Any agent, at any stage, can file a dissent, and a patch may carry several. When the patch is published, its dissents are published alongside it as minority opinions — the parliamentary tradition of the recorded dissent, applied to a pipeline run by AI agents.
This matters because a system that recorded only its final decisions would erase the disagreement that produced them. Preserving dissents as published artifacts means the public sees not just what the party decided, but what it argued about on the way there. Citizens never file dissents directly; their channel is the advisory public-reaction record.
- rejection — "should not advance" → back to DRAFTING
- dissent — "I disagree but won't block" → travels with the patch
- published — printed as a minority opinion beside the patch
Primitive 06
Bias review
The Bias Mirror is a dedicated pipeline stage, and it is not a generic critic. The critique stage handles whether a patch's content is correct. The Bias Mirror handles the patch's priors — assumptions inherited from a model's training data that do not match the configured constitution or the local context.
It reports findings in fixed categories: cultural-default, where Western, English, or market-default priors leak in; linguistic, where source-language idioms surface; constitutional-misalignment, where output drifts from the articles a patch cites; epistemic-overconfidence; and tone-drift. Each finding carries a severity, a quoted passage, an explanation, and a suggested fix. The stage returns an overall decision of pass, flag, or block.
It is built against theatre. The category checks are concrete rather than vibes; external reviewers periodically audit its reports; and a Bias Mirror that never rejects anything is treated as broken, not trustworthy. Like every agent, it sees only the constitution, its own persona, and the patch under review — never the deployment's external framing. An operator can override a block, but only with a public rationale.
- cultural-default · linguistic
- constitutional-misalignment
- epistemic-overconfidence · tone-drift
- overall decision — PASS | FLAG | BLOCK
Primitive 07
Operator sign-off
Awaiting-sign-off is the final stage of the pipeline, and it is the only stage at which an operator may approve. No patch is ever auto-published. Operator sign-off is the framework's load-bearing safety mechanism, and partyclip enforces it — no deployment configuration can remove it.
An operator's power is deliberately asymmetric. They can intercept the pipeline at any earlier stage to pause it, kill a patch outright, or override a vote or a bias block — but they can only approve at the very end. Every override requires a public rationale and is recorded as an operator-action event. The operator can stop anything, anywhere; they can start nothing on their own.
Because that concentrates authority in one role, the framework mitigates the single-point-of-failure directly. If no operator acts within a configured number of days, the system pauses generation — it never auto-approves — and a public "patches in limbo" dashboard shows the world when operator capacity is the bottleneck.
- SIGNOFF — allowed only at AWAITING_SIGNOFF
- INTERCEPT · KILL — any pre-published stage
- OVERRIDE_VOTE · OVERRIDE_BIAS — public rationale required
- REPEAL — post-published only; original stays public
Primitive 08
Audit log
The audit log is event-sourced and append-only. Every state change is an event; the current state of any entity is a projection computed over those events. The log is the truth, and the database is only a cache of it. Any historical state can be reconstructed by replaying events from the beginning.
Nothing is ever mutated or deleted. An override is an event, a dissent is an event, a sign-off is an event, a vote is an event. Corrections do not edit history — they are new events that supersede earlier ones. This is what makes a sentence like "the operator overrode the cabinet on patch 31" a permanently inspectable fact rather than a claim.
There is one boundary. The framework's promise is that party actions are forever public — not that every citizen action is. Citizen-private content, such as private forum threads and registration details, is gated by a visibility class in the projection layer. The underlying events are still logged; what changes is who can see the projection.
- state change → event
- vote · dissent · sign-off · override → event
- current state — a projection over the event log
- corrections — new superseding events, never edits
Primitive 09
Citizen tiers
A deployment exposes the same body of content to three citizen tiers — anonymous, registered (free), and supporter (paid) — alongside operators. What each tier can see and do is per-deployment configuration; partyclip ships zero tiers by default, and the primitive that gates them.
Tiers gate two things: voice and visibility. Anonymous readers can read published artifacts and comment with a captcha. Free registered citizens add advisory votes, the ability to open issues, and full forum access. Paid supporters add petition initiation and real-time access, including raw agent input and output.
Visibility is resolved per artifact. Each artifact carries a visibility class — public, registered, supporter, or operator-only — and an optional delay. Time-delayed access is native to the model: a free tier might see an earlier-stage output after a configurable delay while a supporter sees it in real time. The delays are framework defaults, and every deployment can override them.
- Anonymous — read; comment with captcha
- Free Registered — + advisory vote, open issues, forum
- Paid Supporter — + petitions, real-time access
- visibility_class — PUBLIC | REGISTERED | SUPPORTER | OPERATOR_ONLY
Primitive 10
Forum ingestion
The citizen forum is the one place untrusted, user-generated text enters the system — and exactly one agent is allowed to touch it. The ForumIngestor runs in an isolated execution environment: no tools, no host capabilities, and no access to the constitution, to secrets, or to other agents.
It reads raw forum threads and emits a strictly-typed feedback summary — clusters, trending questions, flagged items — with no free-text fields. Every agent downstream, such as the spokesperson and the analyst, consumes that structured summary and never the raw text. The system is prompt-injection-resistant by construction, not by vigilance.
Citizen voice is also weighted rather than flat. A published formula combines account age, donation commitment, and good-faith engagement, so a brigade of fresh accounts cannot swamp the signal. The formula itself is public; the exact computation of each factor is left to deployment configuration.
- isolated — no tools, no secrets, no other agents
- input — raw forum threads
- output — a typed FeedbackSummary, no free-text fields
- voice weight = account_age × donation_commitment × good_faith_engagement
Primitive 11
Revenue streams
Money in and out is modeled as revenue-stream entities — subscriptions, donations, and grants — each tied to a payment processor through a plugin contract of initiate, webhook, cancel, refund, balance, and list. İyzico, Stripe, Open Collective, Patreon, and others are expected as first-party or community plugins rather than core code.
Every stream carries a transparency level set by the operator: fully public, with individual transactions visible; aggregate public, with totals only; registered-visible; big-donors-only; or operator-only. Anything below fully public requires a transparency reason — and that reason is itself public, so opacity is always accounted for.
The framework also ships compute-budget runway logic. As runway shrinks, the system degrades gracefully — switching non-critical stages to local models, then pausing non-essential pipelines — so a deployment fails safe rather than silently overspending. Tiers, prices, and currency are deployment configuration; partyclip ships none of them.
- FULLY_PUBLIC — individual transactions visible
- AGGREGATE_PUBLIC — totals only
- REGISTERED_VISIBLE · BIG_DONORS_ONLY
- OPERATOR_ONLY — public transparency_reason required
Primitive 12
Disclaimer system
The disclaimer system is a primitive because every deployment needs disclaimers somewhere, but no two deployments need the same words. partyclip owns the placement and the enforcement — it can require a disclaimer at specific points, such as the footer, every press release, the about page, and the donation flow. The deployment supplies the text.
This is the configuration-versus-core split made concrete. That a disclaimer exists, and where it appears, is a framework concern. What it says is a deployment concern. Because the requirement is enforced by the framework rather than by an author remembering, a deployment cannot accidentally ship a press release without its required disclaimer.
- footer · about page
- every press release
- donation flow
- placement enforced by core · text supplied by the deployment
These primitives compose into the seven-layer architecture. The canonical, evolving reference is the framework repository on GitHub — see docs/data-model.md.