Elicit, never persuade.
Civic Filament’s AI mediator is guided by Motivational Interviewing and Nonviolent Communication principles. It is not a fine-tuned MI/NVC therapist; it is a general-purpose LLM operating under an explicit set of instructions we publish here.
What the AI is instructed to do — and never do
DOES
- ◇Elicit values, needs, and constraints behind a stated position
- ◇Ask open questions ("What matters to you about…?")
- ◇Reflect back what a participant said to check understanding
- ◇Sit with silence and complexity — no rush to summarize
- ◇Surface conditions that could change the participant's view
NEVER
- ◇Argue, debate, or attempt to change the participant's mind
- ◇Introduce counter-arguments or "playing devil's advocate"
- ◇Rank, judge, or moralize any position
- ◇Represent other participants' views mid-interview
- ◇Frame follow-up questions to steer toward a target answer
These are the rules baked into the mediator’s system prompt. Deviations are treated as bugs and fixed in place; the prompt is versioned with the app code, and material changes are noted in the changelog.
Interview → extraction → clustering → counted consensus
Roughly 3–7 turn adaptive conversation
A Claude Sonnet 4.6 mediator asks open questions using Motivational Interviewing (OARS: Open questions, Affirmations, Reflections, Summaries) and Nonviolent Communication (observation → feeling → need → request) techniques. Length adapts to what has been captured so far — roughly 3 to 7 participant turns — and when loaded language is detected a debiasing instruction is added to the mediator’s prompt. Both are computed server-side on every turn.
Identifiers removed before the AI sees them
Before any participant text reaches the model or is stored, structured identifiers are redacted by pattern: emails, phone numbers, SSN-style numbers, card numbers, street addresses and URLs. Names cannot be reliably detected, so the extractor is instructed not to carry names or identifying details into the summary, and participants are asked not to share them. The transcript itself stays in the participant’s browser; it is not stored on our servers.
Only real interviews are counted
Every mediator reply carries a server signature over the conversation so far, bound to the issue and to the participant’s anonymous session. A perspective is only extracted from a completed interview whose every mediator turn verifies, so transcripts can’t be fabricated, edited, or replayed under another session. Per-network daily limits (and an optional bot check) cap how many interviews one connection can complete.
One structured extraction per interview
A single Claude Sonnet 4.6 structured (tool-use) call extracts the stated position; stance (support / oppose / conditional / undecided); values, each tagged with a moral foundation; needs; and conditions, each with how much meeting it would shift the participant’s support. Two scores are added without AI: a Discourse Quality Index — a keyword heuristic inspired by Steiner’s DQI — and Schwartz value tags from a keyword classifier.
16 named value dimensions
Claude Haiku 4.5 rates each perspective from 0 to 1 on 16 named value dimensions. If rating fails for any perspective, the entire run falls back to TF-IDF text vectors — the two are never mixed within a run. These are ratings on named dimensions, not semantic embeddings.
DBSCAN, with k-means fallback
Perspectives are clustered with DBSCAN using an automatically tuned epsilon. If DBSCAN finds no usable clusters, the run falls back to k-means. No group with fewer than 5 members is published.
Counted, not estimated
Claude groups the needs and values participants named into concerns that express the same underlying point, and returns which items belong to each. Support is then counted from those participants — the model never asserts a percentage. Strong consensus is a concern raised by at least 70% of participants and at least 5 people. Conditional consensus compares “support without” (participants whose stance is already support) with “support with condition” (those plus participants who named that condition and said it would shift them substantially, ≥ 0.5 on a 0–1 scale); it is reported only when the condition was named by at least 5 people and the difference is at least 5 points.
Divergence is signal, not noise
Genuine divergence is reported for pairs of groups that each hold at least 15% of participants (and at least 5 people) and whose value profiles differ by more than 0.5 on some named dimension. It is not computed when the TF-IDF fallback was used, because those vectors have no named dimensions.
Representation gaps — currently not measured
Representation compares who participated with who lives in the community. After their interview, participants may optionally give an age band, housing tenure and area; when the deploying organization has entered population figures for those groups, each version flags underrepresented groups and reports the stance split reweighted to the population (raking, with weights trimmed so no small group dominates). Groups of fewer than five people are never shown. Weighting corrects who took part, not self-selection within a group, so it narrows but does not remove uncertainty. Without both inputs the section reads “Not measured”.
Credible intervals and honest margins
Each counted share carries a Beta-Binomial 95% credible interval (normal approximation). The margin of error shown is simple-random-sample sampling error. Participation is self-selected, so that margin is a lower bound on the real uncertainty, not a full account of it.
Genuine disagreement is a first-class output.
The Living Requirement Document has a section called Genuine Divergence. It is not an appendix; it is co-equal with Strong Consensus. It names groups whose value profiles genuinely differ — for example, different weightings of liberty vs. safety — rather than averaging them into a middle that nobody holds. Averaging positions to make disagreement disappear is not a supported operation.
Every LRD is versioned and verifiable
Automatic, versioned runs
Synthesis runs server-side shortly after new perspectives arrive (at most once per 15 minutes per issue), plus a daily scheduled run; admins can also trigger one. Only one run per issue can happen at a time. Each run produces a draft that the deploying organization reads and approves before it is published; nothing is published below 10 perspectives. Published versions are numbered and older ones stay viewable at /lrd/[issueId]?version=X.
Merkle-root provenance
Each stored perspective gets a leaf hash: SHA-256 over a domain-separated canonical JSON of the anonymized extraction (no session ID, account ID or transcript). Each version commits to exactly its inputs via a SHA-256 Merkle tree (sorted leaves, domain-separated leaf and node hashing). The root and every leaf hash are published per version at /api/verify, so anyone can recompute the root.
Participant receipts
When your perspective is saved you receive its leaf hash as a receipt, and you can check on the LRD page that a version included it — the proof is verified in your own browser. Limit: provenance proves which perspectives a version was computed from and detects any later change to a version whose root someone saved. It cannot by itself prove nobody was left out before publication; that is exactly what receipts let participants check.