Skip to content

Commit 2a62e31

Browse files
MaxBrychclaude
andcommitted
docs(specs): NSP-12 Public Decision Record — the EIP pipeline as a civic event grammar
Design-only draft grounded in the Ethereum governance / Forkcast research: proposal lifecycle (EIP-1 + EIP-7723 mapped to German stages), six event kinds on the existing 32100 grammar, editor/impact agents under the EIP editor mandate, headliner-disciplined Maßnahmenpaket cycles, advisory-only Meinungsbild rail, and the NSP-0/9/10 installer surface. No implementation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent ce74cea commit 2a62e31

1 file changed

Lines changed: 236 additions & 0 deletions

File tree

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
# NSP-12 Public Decision Record — the EIP pipeline as a civic event grammar
2+
3+
**Date:** 2026-07-31
4+
**Status:** DRAFT — design only; no implementation in this slice
5+
**Follows:** [Nostr Citizen identity bridge](2026-07-27-nostr-citizen-identity-bridge-design.md), [NSP-9 federation](2026-07-27-nsp9-federation-design.md), proposal pointers (kind 32100, shipped in `packages/publisher`), [fork-with-fallback](2026-07-31-fork-with-fallback-design.md)
6+
**Companion post:** `Netizen-Labs/apps/web/content/writing/2026-07-31-what-towns-can-learn-from-ethereum-governance.md`
7+
8+
---
9+
10+
## 0. Why this spec
11+
12+
Ethereum runs the largest functioning digital governance system in the world without a
13+
single binding vote. Its actual mechanism is three-layered: a **legible proposal pipeline**
14+
(EIP-1 lifecycle, editors who gatekeep process but never content), **rough consensus among
15+
the people who must implement changes** (client teams; a proposal ships only when an
16+
implementer commits), and **exit rights** (node operators can decline to upgrade;
17+
communities can fork with the state). Since 2025 the Ethereum Foundation added a fourth
18+
layer that turned out to be the most transferable: **legibility tooling**. Forkcast gives
19+
every proposal a plain-language page with per-stakeholder impact, publishes call
20+
transcripts within about two hours, names a champion per proposal, and enforces headliner
21+
discipline (one big thing per upgrade cycle, pitched in an open, calendarized window).
22+
23+
Two lessons drive this design:
24+
25+
1. **The coordination layer is the product, not the vote.** A German Kommune cannot and
26+
should not move formal decisions out of the Stadtvertretung — and Ethereum's model
27+
never asks for that. AllCoreDevs does not bind node operators either. What transfers is
28+
legitimate advisory infrastructure: the pipeline, the record, the translation layer.
29+
2. **Process tooling must outlive its operator.** In July 2026 the EF dissolved the team
30+
that ran Forkcast and the core-dev calls; maintenance of the tooling is now an open
31+
question. The Netizen answer is structural: encode the process in the protocol
32+
(this spec) and the installer (manifest-rendered, per the standing rule that everything
33+
on a node ships through `netizen render`/`up`), so any node operator — including the
34+
community itself — can keep the process alive without Netizen Labs.
35+
36+
The number: NSP-10 is the indexer, NSP-11 is operations. The Public Decision Record is
37+
**NSP-12**.
38+
39+
## 1. Scope
40+
41+
**In.**
42+
- The event grammar: kinds, tags, and lifecycle for proposals, status transitions,
43+
meeting records, Meinungsbild results, impact summaries, and decision cycles.
44+
- Roles and keys: editor-agents, impact-agents, champions, implementers, facilitators.
45+
- The manifest surface (NSP-0) and how NSP-10 (indexer), NSP-9 (federation), and the
46+
agent-watcher consume it.
47+
- Legal rails: advisory-only framing, AI Act Art. 50 labeling, GDPR posture.
48+
49+
**Out**, each deliberately:
50+
51+
| Deferred | Why |
52+
|---|---|
53+
| Binding on-chain votes | Never in scope. Formal decisions stay with the Stadtvertretung; the record mirrors outcomes, it does not produce them. |
54+
| MACI / coordinator-as-a-service internals | Owned by the [coordinator-as-a-service spec](2026-07-31-coordinator-as-a-service-design.md). NSP-12 only defines the *result pointer* event. |
55+
| Meetings plane (calls, transcripts, recording) | Owned by the [Netizen Workspace meetings spec](2026-07-31-netizen-workspace-meetings-ai-design.md) (NSP-7 surface). NSP-12 takes pointers to transcripts, it does not produce them. |
56+
| Honorariums / contributor funding | The Gemeinschaftskasse and Münzen tips already exist; wiring champion rewards is a later, separate decision. |
57+
| New explorer UI build | The explorer page set ("Vorhaben") is sketched here as a consumer but implemented in its own slice. |
58+
| Cross-community proposal portability | Needs the federation trust model from NSP-9 slice 2+. The grammar is shaped so records mirror cleanly, nothing more. |
59+
60+
**Success condition.** A proposal born in the Röbel app exists as a kind-32100 head with a
61+
signed, append-only transition trail, an agent-labeled plain-language impact summary, and
62+
(where run) a Meinungsbild result — all resolvable from the explorer without Supabase
63+
(fork-with-fallback holds), and reproducible on testnode from the manifest alone.
64+
65+
## 2. The lifecycle
66+
67+
German-first stage names, mapped from EIP-1 + EIP-7723. The record never claims decision
68+
power: stages that imply a formal act (`beschlossen`, `abgelehnt`) may only be entered by
69+
mirroring a signed civic notice (kind 32102) from the body that made the decision.
70+
71+
| Stage | EIP analog | Who may move it here | Meaning |
72+
|---|---|---|---|
73+
| `idee` | Idea | any citizen npub | Untracked sketch; becomes tracked when an editor-agent confirms completeness |
74+
| `entwurf` | Draft | editor-agent (process check only) | Structurally complete: problem, proposal, affected parties named |
75+
| `diskussion` | Review | author | Author declares it ready; open deliberation thread |
76+
| `meinungsbild` | Last Call | facilitator (human) | Advisory MACI signal runs; result published as kind 32104 |
77+
| `beschlussvorlage` | Scheduled for Inclusion | implementer | An implementer (Verwaltung, Stadtwerke, Verein) has committed a champion and capacity; forwarded to the formal body |
78+
| `beschlossen` / `abgelehnt` | Included / Declined | mirror of kind-32102 civic notice only | The formal body decided; the record cites the notice |
79+
| `umgesetzt` | Deployed | implementer | Done and verifiable |
80+
| `ruhend` | Stagnant | editor-agent (mechanical: 6 months without activity) | Parked, revivable |
81+
| `zurueckgezogen` | Withdrawn | author | Permanent; also the GDPR withdrawal path (§8) |
82+
83+
Rules carried over from Ethereum verbatim because they are the load-bearing ones:
84+
85+
- **Editors gatekeep process, never content.** An editor-agent may request missing fields,
86+
deduplicate, translate, and park stale drafts. It may never score, rank, or reject an
87+
idea on merit. This is EIP-1's editor mandate, and it is exactly the mandate an AI agent
88+
can hold accountably: mechanical, neutral, auditable.
89+
- **Implementer commitment is the gate**, not enthusiasm. `beschlussvorlage` requires a
90+
named implementer champion — the analog of "client devs signal intent to implement."
91+
- **Facilitation stays human.** Agents structure and translate; a human facilitator runs
92+
Meinungsbild windows and cycle scoping.
93+
94+
## 3. Event grammar
95+
96+
Existing kinds stay untouched: 32100 proposal head (shipped), 32101 menu, 32102 civic
97+
notice. New kinds below are **provisional**; final numbers are claimed in
98+
`packages/publisher/src/mappers.ts` at implementation time, which is the kind registry of
99+
record. All are addressable (parameterized-replaceable) except the transition, which is a
100+
regular immutable event — the audit trail must not be rewritable.
101+
102+
| Kind | Name | Form | Content |
103+
|---|---|---|---|
104+
| 32100 | Proposal head (exists, extended) | addressable, `d` = proposal slug | Markdown abstract + motivation. New tags: `status` (stage from §2), `champion` (`p` tag with role marker), `cycle` (`a` tag to 32106) |
105+
| 2100 | Status transition | **regular, immutable** | `a` tag to the head, `from`/`to` stage tags, free-text reason, signed by whoever §2 authorizes for that transition. For `beschlossen`/`abgelehnt`: an `a` tag citing the 32102 civic notice is mandatory |
106+
| 32103 | Meeting record | addressable, `d` = `<body>-<date>` | Agenda published before the meeting, minutes and transcript pointers after (pointers into the workspace plane, NSP-7) |
107+
| 32104 | Meinungsbild result | addressable, `d` = poll id | MACI tally pointer, parameters (threshold band, anonymity-set size), verification pointer, and an explicit `advisory` tag — always |
108+
| 32105 | Impact summary | addressable, `d` = `<proposal-slug>-<audience>` | "Was bedeutet das für dich" per stakeholder group (`anwohner`, `gewerbe`, `vereine`, `verwaltung`), authored by a labeled agent npub |
109+
| 32106 | Decision cycle | addressable, `d` = cycle slug (e.g. `massnahmen-2027`) | The Meta-EIP analog: list of `a` tags to proposal heads, each with a stage marker (`vorgeschlagen` / `in-pruefung` / `eingeplant` / `nicht-aufgenommen` — the PFI/CFI/SFI/DFI mapping), plus the headliner designation and the pitch-window dates |
110+
111+
Head example (abridged):
112+
113+
```json
114+
{
115+
"kind": 32100,
116+
"tags": [
117+
["d", "radweg-seeufer"],
118+
["title", "Radweg am Seeufer"],
119+
["status", "beschlussvorlage"],
120+
["p", "<champion-npub-hex>", "", "champion"],
121+
["a", "32106:<node-pubkey>:massnahmen-2027", "", "cycle"]
122+
],
123+
"content": "## Problem\n\n## Vorschlag\n"
124+
}
125+
```
126+
127+
**Reference rule (hard):** every cross-reference to a status-bearing document is an `a` tag
128+
(`kind:pubkey:d-tag`), resolved at render time — never an event id. We have already been
129+
burned by replaceable-event id links going stale; NSP-12 makes the addressable form the
130+
only legal citation between decision-record events.
131+
132+
**Deliberation** needs no new kind: replies to the head via standard NIP-10 threading are
133+
the discussion thread, and the explorer renders them under the proposal page.
134+
135+
## 4. Roles and keys
136+
137+
| Role | Key | Mandate | Bounds |
138+
|---|---|---|---|
139+
| Editor-agent | agent npub, NIP-24 `bot: true`, Art. 50 label | EIP-1 editor rule: completeness, dedup, translation, mechanical stage moves (`entwurf`, `ruhend`) | Pinned role in the agent-watcher; kinds and rate bounds in the manifest |
140+
| Impact-agent | agent npub, labeled | Writes 32105 per stakeholder group when a head enters `diskussion` or any later stage, and refreshes on head edits after that point | Same watcher bounds; output always attributed and filterable by key |
141+
| Champion | citizen npub (identity bridge) | Single accountable point of contact per proposal, named in the head | Human only |
142+
| Implementer | org npub (Verwaltung, Stadtwerke, Verein) | Signs the `beschlussvorlage` transition; publishes `umgesetzt` | Human-operated org keys |
143+
| Facilitator | human npub | Opens Meinungsbild windows, runs cycle scoping, chairs the process | Never an agent |
144+
145+
Every agent output is a signed event under the agent's own key: humans can audit, filter,
146+
or ignore any agent wholesale. Display surfaces resolve keys to display names — raw
147+
addresses never appear in UI (standing rule).
148+
149+
## 5. The cycle — Maßnahmenpaket with headliner discipline
150+
151+
One 32106 event per planning cycle (typically the Haushaltsjahr). Imported from Ethereum's
152+
2025 process because it solved scope creep in a body with limited implementer capacity —
153+
which describes a small town better than it describes Ethereum:
154+
155+
- **At most one headliner per cycle**: the single big project, chosen first, everything
156+
else scoped only after the headliner is stable.
157+
- **Open, calendarized pitch window**: dates live in the 32106 event itself. A pitch must
158+
name the problem, the affected groups, the rough cost, and a would-be champion — the
159+
same four things Ethereum requires of headliner pitches (need, impact, readiness,
160+
champion).
161+
- **Stages are re-proposed each cycle**: a proposal not `eingeplant` this cycle does not
162+
carry over silently; it re-enters next cycle's window. Nothing rots in a backlog
163+
invisibly.
164+
165+
## 6. Meinungsbild rail
166+
167+
The 32104 result event is a *pointer*, not a tally system: MACI poll id, the published
168+
tally, its verification artifacts, and the parameters that make the signal honest
169+
(threshold band, anonymity-set size). Two hard rules:
170+
171+
1. The `advisory` tag is mandatory and the explorer renders the advisory framing
172+
unconditionally. Wording is "Meinungsbild", never "Abstimmung" (standing legal rule).
173+
2. A 32104 may only be published by the coordinator pipeline after tally verification —
174+
the same signed path the coordinator already uses, no manual results.
175+
176+
## 7. Manifest and installer surface
177+
178+
Everything above is configuration, rendered by `netizen render`/`up` — nothing hand-wired.
179+
Sketch of the NSP-0 block:
180+
181+
```json
182+
"record": {
183+
"decisions": {
184+
"kinds": { "head": 32100, "transition": 2100, "meeting": 32103,
185+
"meinungsbild": 32104, "impact": 32105, "cycle": 32106 },
186+
"agents": {
187+
"editor": { "npub": "<npub>", "staleAfterDays": 180 },
188+
"impact": { "npub": "<npub>", "audiences": ["anwohner", "gewerbe", "vereine", "verwaltung"] }
189+
},
190+
"bodies": [ { "id": "stadtvertretung", "noticeAuthor": "<org-npub>" } ],
191+
"cycle": { "current": "massnahmen-2027" }
192+
}
193+
}
194+
```
195+
196+
Touchpoints, all additive:
197+
- **NSP-10 indexer**: the six kinds join the indexed set (kind widening is a visible
198+
manifest edit, per existing rule).
199+
- **Agent-watcher**: `editor` and `impact` become pinned roles with the standard bounds.
200+
- **NSP-9 federation**: peers may mirror the decision kinds like any public civic kind;
201+
a town's governance record becomes mirrorable the way archive nodes mirror chains.
202+
- **Explorer / Atlas**: a "Vorhaben" page set — per-proposal page with status, transition
203+
trail, impact summaries, thread, and Meinungsbild result; per-cycle page with the
204+
headliner and stage matrix. This is the Forkcast-shaped surface.
205+
206+
## 8. Legal rails
207+
208+
- **Advisory only, everywhere.** The record informs the formal process; `beschlossen` /
209+
`abgelehnt` enter the record exclusively by citing the signed 32102 notice. Public
210+
framing follows the standing rule: civic technology, never a "Blockchain-Verwaltungsprojekt".
211+
- **AI Act Art. 50**: every agent-authored event carries the already-implemented labeling;
212+
the explorer renders the AI disclosure on 32105 and any agent-signed transition.
213+
- **GDPR**: proposals are voluntarily published public civic content; the only personal
214+
data is the author's key and chosen display name. Withdrawal = `zurueckgezogen`
215+
transition plus deletion honored on the authoring relay; mirrors follow the NSP-9
216+
write-policy behavior. Impact summaries and meeting records must not name private
217+
individuals.
218+
219+
## 9. Slices (each gets its own plan; none started by this spec)
220+
221+
1. **Grammar**: NSP-12 zod schemas in `@netizen-labs/protocol`, kind constants + mappers
222+
in `packages/publisher`, transition-trail validation.
223+
2. **Editor-agent**: pinned watcher role, completeness checks, dedup, `ruhend` sweep,
224+
labeling.
225+
3. **Explorer "Vorhaben"**: per-proposal and per-cycle pages on the index/Atlas surface,
226+
NIP-10 thread rendering, advisory framing for 32104.
227+
4. **First cycle**: publish `massnahmen-2027` as a 32106 with a real pitch window, and run
228+
one proposal end-to-end through the pipeline in Röbel — the dogfood exit test.
229+
230+
## 10. Open questions (for the user, not blockers to slice 1)
231+
232+
- Should meeting records (32103) start with the Stadtvertretung's public agendas only, or
233+
also include Vereins-/Ausschuss meetings from day one?
234+
- Does the champion role require citizen-tier identity, or is resident-tier enough?
235+
- Cycle cadence: strictly the Haushaltsjahr, or a shorter first cycle to dogfood the
236+
pipeline before budget season?

0 commit comments

Comments
 (0)