synthesize: anonymous braindump CSV → themed review doc via the co-op gateway

Stdlib-only pipeline for the pre-meeting braindump: CryptPad Form CSV in,
review.md + synthesis.json out. Two model stages (tag atomic points with
verbatim quotes, cluster into themes/novel/dissent) wrapped in deterministic
Python that verifies every quote against the source and computes counts from
item ids, so the model never writes the final document. Defaults to
tinfoil/glm-5.3 with reasoning_effort=low: without it the model spent the
whole 8000-token budget on hidden reasoning and returned nothing (probed
2026-10-19; findings in README). Refuses non-TEE models without a flag.
Content-hash cache so prompt tuning reruns are free. Offline unittest suite
with a fake gateway; smoke-tested live on 5 synthetic responses for ~$0.03.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
solo.istandClaude Fable 5.1 committed 2026-10-19 02:56:50 -04:00
1 parent a8908c84cf
commit 05f4e88867
12 files changed
+2212 -15

No files matched your search

+20
View File
@@ -0,0 +1,20 @@
You are helping a member-governed AI cooperative make sense of an anonymous braindump survey before a members' meeting. You will receive a batch of survey responses. Each response has an id like `r03` and one or more answered questions, each with a question index like `Q2`.
Extract every distinct, atomic point a respondent makes. One point per item. Do not merge different points into one item, and do not invent points that are not in the text.
For each item return:
- `id`: the response id it came from (e.g. `r03`).
- `q`: the question index it came from (e.g. `Q2`).
- `label`: a neutral paraphrase of the point in at most 12 words, written so that similar points from different people would get similar labels.
- `kind`: one of `idea` (something to build, try, or offer), `want` (something that would make membership more valuable to them), `need` (something missing or broken), `goal` (where the co-op should be), `concern` (a worry, disagreement, or criticism).
- `stance`: `for` if the point supports doing or having something, `against` if it opposes or warns against something, `neutral` if it is an observation or question.
- `quote`: a short verbatim excerpt (5 to 30 words) copied exactly from the response text that best evidences the point. It must be a character-for-character substring of the source text. Do not paraphrase, do not fix typos, do not add ellipses.
Skip pleasantries, empty answers, and "nothing to add". Keep the respondent's framing; do not editorialize.
Return exactly one fenced ```json block and nothing else, shaped as:
```json
{"items": [{"id": "r03", "q": "Q2", "label": "...", "kind": "idea", "stance": "for", "quote": "..."}]}
```