ETOT
ETOT
TOOL · RESEARCH SYNTHESIS
Motif
type
agentic loop
version
1.1
surface
CLI · MCP · Figma plugin
author
Eric Frye
date
09.2026
addendum
2026-09-06
license
MIT · data CC-BY-NC
part 2
the critic anywhere
part 3
the plugin as product
Launch repository ↗

A synthesis that checks its own work.

AI can turn fifteen interview transcripts into findings in minutes. It also invents quotes, overstates confidence, and hides what it dropped. Motif is an agentic loop that produces the findings, then tries to knock them down — and shows you what survived. I designed the loop, built it, measured it against a human baseline, and shipped it.

insight · run 20260903-195307-C · full corpus · 15 transcriptsI-06 of 20

Consent given today cannot promise what happens to data years from now

Researchers across disciplines flag that one-time consent cannot capture unknown future uses of archived qualitative data, and argue for ongoing or dynamic consent mechanisms rather than a single sign-off.

confidence
high  4 participants · no counter-evidence
sources
jamie · jim · kelly · michelle
jamie:0024 “even if a participant says ‘Oh yeah, I want it to be open access’. You would have to have ongoing and dynamic conversations about the ethics of what that means”
kelly:0029 “you can't really necessarily control who uses the data, and what”
michelle:0054 “you can't, you can't anticipate that kind of thing”
jim:0053 “that might not necessarily mean they give consent to their data being used by other researchers for other purposes”
opportunity
Template consent language and a process for periodic re-contact or withdrawal after embargo, rather than treating initial consent as a permanent, one-off decision.
CONTESTED — unsupported: only jamie argues for ongoing or dynamic consent. kelly, michelle and jim describe the problem of unpredictable future use without proposing a mechanism. The prescriptive half of the claim goes beyond three of the four cited participants; ‘high’ is not warranted for that dimension.
One insight from the shipped output, verbatim. Each receipt is a quote checked mechanically against the transcript. The flag is the critic’s unresolved objection when the loop stopped — four people support the problem, one supports the remedy, and the report says so.
1.7 → 0.7unsupported claims per four checked, vs a single prompt
1.3 → 0.7confidence errors per report
30 min · $4.53fifteen transcripts, one command · manual baseline ≈ 9 h
2 daysbrief to public repo · 23 runs · 2 evals
role
Designer and builder — research design, loop architecture, critic rules, evaluation design, packaging
team
Solo, with Claude as pair programmer and second reader
timeline
September 2026 · two days
surface
Command-line tool, public repository. MCP server and a Figma plugin have since shipped.
tools
Python · Claude API (Haiku 4.5, Sonnet 5) · Claude.ai · GitHub
the problem

Research synthesis is the slowest step in discovery and the one AI does worst: fast, fluent, and unaccountable. A design team can’t act on a finding whose evidence it can’t check.

the solution

A loop, not a prompt. Synthesis produces; a critic with readable rules checks against the transcripts; revision repairs; the loop stops on a pass, on no progress, or after three rounds — and the report says which.

01

Fast, fluent, and unaccountable

context

After a round of interviews, someone reads everything, codes it, clusters it, and writes findings. It takes days. Single-prompt AI does it in minutes and produces something that looks like the same document — with quotes that don’t exist, patterns built from one person, “high confidence” resting on two, and the dissenting participant quietly dropped.

The tools that sell this step — Dovetail, Notably, FigJam AI — compete on speed. None of them visibly verify a citation, run an adversarial check, or tell you what the reviewer still objected to.

why it’s a design problem

A finding a designer can’t trace is a finding they can’t act on. The output has to carry its own evidence, name its own confidence honestly, and show its own dissent. That’s a design brief for the shape of the output, before it’s an engineering brief for the thing that makes it.

The product is trust in the output, not speed of producing it.

02

A loop is agentic when it can tell it’s wrong

the distinction

A chain is a fixed sequence of prompts. A node graph is a pipeline a human wired. Neither checks itself. A loop is agentic when the model plans, acts, evaluates its own output against criteria it can read, and decides when to stop. The critic and the stop condition are what make Motif a loop rather than a chain.

what that rules out
  • 01No hidden judgementEvery rule the critic applies is a paragraph of plain language in a config file a team can edit.
  • 02No silent approvalA critic that returns nothing fails the check. This rule was learned, not designed — section 05.
  • 03No deletion as repairAn insight the critic objects to is fixed or downgraded, never quietly removed.
three shapes called “agentic”only one can notice it’s wrong
● CHAIN promptpromptprompt Fixed sequence. Nothing reads the output. ● NODE GRAPH imagepromptmodeloutput Human-wired. Runs the graph, then stops. ● LOOP producecheckrevise stop when:critic passesno progress3 rounds
The check and the stop condition are what make a loop. Without them it’s a chain with extra steps.
03

Before the tool, the answer key

how

Fifteen real interviews from a University of Sheffield study of researchers’ attitudes to open data — ethically cleared, CC-BY-NC, public. Before any code, I hand-synthesised five of them the way I would at work: 74 evidence items, 11 insights, each with cited evidence, sources, confidence, counter-evidence, and an opportunity. Two hours fifty. Then I read the researchers’ own report from all fifteen.

findings
  • 01Nine of my eleven matched theirsA five-transcript pass validated against the full corpus.
  • 02Five themes lived in transcripts I hadn’t readCopyright, political economy, the arts vocabulary gap, DMP templates. A full-corpus run has to find those.
  • 03Twelve trapsPlaces the corpus invites a bad synthesis: one private-sector voice, one dissenter on deletion, a concept the researchers introduced that the participants didn’t.
  • 04The codebook didn’t existThe dataset readme promised one; it was never deposited. Ground truth was built from the report plus the manual pass instead.
ground truth · docs/ground-truth.mdabridged · 12 of 16 themes, 6 of 12 traps
idthemefound by
T-01Context doesn't travelboth
T-02Process transparency is the tractable halfboth
T-03Consent to an unknowable futureboth
T-04Anonymisation: costly, never completeboth
T-05Awareness low; navigation is the barrierboth
T-06Reproducibility framing rejectedboth
T-08Reuse is aspirational, not practisedboth
T-10Openness is externally drivenEric only
T-11Deletion experienced as wasteEric only
T-12Political economy, extraction, scoopingreport only
T-13Copyright and ownership unclearreport only
T-14'Data' vocabulary doesn't fit the artsreport only
idtrapfailpass
P-01Penni is the only private-sector voicestate as patternsingle-source, low
P-02Michelle: deletion is integrity, not wasteT-11 with no countersurface the dissent
P-03Penni wants qual more like validated quantunanimous rejectionsurface Penni
P-08'Re-renderability' is the researchers' termparticipants said itattribute to authors
P-10Bruce re-coded his own data'nobody reuses'reuse vs reanalysis
P-12T-01 and T-04 are different findingsone merged insighttwo, cross-referenced
Sixteen themes, twelve traps, one scoring rubric. Every later number is measured against this.
04

Four roles, two kinds of rule, one unit of evidence

the roles

Intake reads one transcript and maps its topics with turn references. Synthesis reads all of them and writes eight to fourteen insights. The critic reads the insights, the exact text of every cited turn, and the full transcripts, and reports failures against the rules. Revision repairs. A controller runs check → revise until the critic passes, the failures stop changing, or three rounds are up.

the unit of evidence

Every transcript is split into numbered turns — michelle:0028 — and a turn ID is the only thing an insight may cite. That makes “unsupported” a check, not a vibe: the critic is handed the literal text behind every citation.

two kinds of rule
  • 01Deterministic, in codeThe cited turn exists; the speaker is a participant, not the interviewer; the verbatim receipt appears in the turn; confidence matches the source count — high needs four participants and no counter-evidence. Free, instant, can’t hallucinate.
  • 02Model-judgedThe turn supports the claim as stated; a dissenting participant is missing; two findings are merged; a theme present in three or more transcripts has no insight. The critic reads for these.
architecturecore/ + synth/ + config/synth.yaml
transcriptsdocx · txt ingest[name:0042] intakeHaiku · ×N synthesisSonnet deterministicchecks turn exists · not the interviewerreceipt matches the transcriptconfidence ≤ sources · no deletion criticSonnet · full corpus unsupported · missing countermerged · vague · missing theme revise ×≤3 config/synth.yamlmodels · thresholdsrules, plain language runs/<id>/every prompt, every verdict report.mdcontested flags on stop: critic_pass · no_progress · max_iterations
Anything that can be checked mechanically is checked before the model is asked. The model is asked only what only a reader can answer.

A rule the fixer can’t satisfy is a bug in the rule. Anything you can compute, don’t ask the model for.

05

The loop approved things nobody had checked

run one

The critic spent its whole output budget thinking and returned no verdict. My fallback treated “no failures found” as a pass. The loop declared the synthesis clean; no one had read it.

run seven

The synthesis hit its output cap and returned nothing. The critic looked at an empty list, found nothing wrong with nothing, and passed in five seconds. The loop approved an empty report.

run nine

A deterministic rule flagged “sources without cited turns” three rounds running. The model counted counter-evidence participants as sources; my rule didn’t. Three rounds arguing about a definition neither side could see.

run 1 · critic returned nothing
[synthesis] claude-sonnet-5 79260→14083 tok · deterministic checks: 0 failure(s) [critic] claude-sonnet-5 87162→8000 tok 89.0s · iteration 1: 0 failure(s), pass=True run …: 1 iteration(s), stop=critic_pass $ inspect calls/007_critic.json stop_reason: max_tokens json_error: no JSON found in response text: ""
run 7 · synthesis returned nothing
[synthesis] claude-sonnet-5 82360→32000 tok 317s · deterministic checks: 0 failure(s) [critic] claude-sonnet-5 64535→248 tok 4.91s · iteration 1: 0 failure(s), pass=True run …: 1 iteration(s), stop=critic_pass 0 insights -> runs/…/output.md nothing to check ≠ nothing wrong
run 9 · a rule the fixer couldn't satisfy
=== 01_check 16 failures I-08 bad_citation sources without cited turns=['bruce','penni'] === 02_check 8 failures I-08 bad_citation sources without cited turns=['bruce','penni'] === 03_check 7 failures I-08 bad_citation sources without cited turns=['bruce','penni'] the model counted counter-evidence participants as sources. the rule didn't.
Kept, not deleted. Bad runs are evidence — every one of these directories is still in the repo’s history.
what changed
  • 01Silence failsA critic with no verdict, a synthesis with no insights, an empty list — all hard failures. Every layer.
  • 02ReceiptsEach citation carries a verbatim quote, checked against the transcript in code. Deterministic failures on round one went from three to zero. The synthesis writes more carefully when it knows the check exists.
  • 03Confidence is arithmetic“Overconfident” was whack-a-mole until the threshold was a number in the config.
  • 04Sources are computedNot asked for.

A checker’s absence must never read as approval.

06

Precision up, coverage down

method

Three conditions on the same five transcripts, three runs each: single prompt, intake plus synthesis, full loop. Nine reports anonymised, headers and critic flags stripped, scored against the ground truth — theme coverage, trap failures, four evidence spot-checks per report, confidence calibration. AI-assisted rating reviewed by me.

findings
  • 01Unsupported claims halved1.7 to 0.7 per four checked.
  • 02Confidence errors went to zeroThe numeric threshold did that, not the model.
  • 03Trap failures fell2.3 to 1.3.
  • 04Coverage dropped eighteen points75% to 57%. Reuse, a core theme, was absent from every loop run and present in five of six others.
  • 05Intake alone changed nothingThe map isn’t the value; the checking is.
why coverage fell

The critic only checked what was on the page. The reviser’s cheapest fix for an objection was to delete the insight. Nothing in the loop watched for what went missing.

eval 1 · 5 transcripts · 3 runs per condition · blinddocs/eval1-results.md
020406080757257Theme coverage %232013Traps failed ×1017177Unsupported /4 ×1013130Miscalibrated ×10A single promptB intake + synthesisC full loop
Every error measure moved the right way. Coverage moved the wrong way. A null result on coverage is the most credible thing in this project — it shows the eval could have said no.
07

Teach the critic to look at the corpus

what changed
  • 01A recall ruleThe critic now receives the intake topic maps and must flag any topic present in three or more transcripts with no insight covering it. The intake step, which had made no measurable difference, became the input to the check that recovered coverage.
  • 02No silent deletionThe reviser must list anything it drops, with a reason; a vanished insight without one is a failure.
  • 03Profiles for the criticSector, career stage, method — with an instruction to look hardest at the outlier.
findings
  • 01Coverage recovered51% to 69%, against 75% for a single prompt.
  • 02Reuse went from 0 of 3 runs to 3 of 3The recall rule, doing exactly what it was built for.
  • 03Precision heldUnsupported claims unchanged at 0.7; confidence errors 0.7.
  • 04Nothing was silently deletedIn three runs.
  • 05The best single report of any condition in either evalNine of twelve themes, zero unsupported, zero miscalibrated.
eval 2 · v1 vs v2 · same corpus, same rater, blind to versiondocs/eval2-results.md
020406080755169Theme coverage %40060Reuse found (of 3 runs) ×20331313Unsupported /4 ×20272013Miscalibrated ×20A single promptv1 loopv2 loop
Coverage recovered, precision held. The cost: the critic thinks two to three times longer — a run is 22 minutes and $2.28.
08

What the critic actually catches

one insight, three rounds

Round one cited Bruce with a real quote from bruce:0035. The receipt check passed: the words exist. The critic failed it: read whole, the turn says the opposite. Selective quotation, caught by a reader, not a regex. One revision fixed it.

ROUND 1 · three failures

I-01 Decontextualised reuse is epistemically risky

confidence
high
evidence
michelle:0028 · stephen:0022 · bruce:0035
counter
david:0040
bruce:0035 “if you don't know the subject, then you might miss a lot of what's going on”
unsupported — the quote is lifted from the middle of a turn whose overall thrust contradicts the claim: Bruce calls differing readings “entirely legitimate” and doesn't see a problem in principle.
missing_counterexample — Bruce's full turn is the counterexample.
overconfident — one of three sources is miscited and cuts the other way.
ROUND 2 · fixed

I-01 Decontextualised reuse is epistemically risky

confidence
medium
evidence
michelle:0028 · stephen:0022
counter
david:0040 · bruce:0035 · michelle:0107
bruce:0035 counter — “each research will read the data differently and I think that's entirely legitimate”
no failures on I-01 — Bruce moved to counter-evidence, a second dissent found in Michelle, confidence lowered. Exactly where the manual synthesis had Bruce from the start.
ROUND 3 · unchanged

I-01 Decontextualised reuse is epistemically risky

confidence
medium
evidence
michelle:0028 · stephen:0022
counter
david:0040 · bruce:0035 · michelle:0107
michelle:0107 counter
note — the loop ran a third round for other insights; I-01 was done in one. It also cited bruce:0035 twice in its counter list — a duplication the rules don't catch yet. Small, real, on the list.
Receipts stop fabrication. Only a reader stops selective quotation. Each layer has a job — and the record shows one revision was enough.
09

One command, fifteen transcripts, thirty minutes

what shipped

pip install, an API key, and motif ./transcripts --out report.md. The full fifteen-transcript corpus — 101,000 words — runs in one synthesis call: thirty minutes, $4.53, twenty insights. Fourteen of the sixteen ground-truth themes, including four only reachable beyond the five I read by hand. Six findings the ground truth didn’t contain at all, each with receipts a team can open.

what it’s for

Teams and freelancers who synthesise in FigJam with transcripts in a folder — no research platform, just stickies — and who’ve been burned by a confident AI summary. The engine is written to sit under any surface; an MCP server is the next build — one server that reaches Claude Code, Cursor, FigJam, and Miro.

what it’s built on

The loop controller, run logger, LLM client, and config loader are a small reusable core. Motif is the first tool on it. The next — a design critique loop — reuses all of it.

full corpus · one command
$ motif data/raw/Dataset-2 --out report.md ingesting … 15 transcripts, 101,042 words run 20260903-195307-C: condition C, 15 transcripts [intake_ana] … [intake_stephen] 15 calls, Haiku [synthesis] claude-sonnet-5 244253→34115 tok 314s · deterministic checks: 4 failure(s) [critic] claude-sonnet-5 237823→14436 tok 156s · iteration 1: 12 failure(s) [revise] … [critic] · iteration 2: 7 failure(s) [revise] … [critic] · iteration 3: 4 failure(s) run …: 3 iteration(s), stop=max_iterations, 1819.8s, 1,539,500→180,040 tok, $4.5251 20 insights -> runs/20260903-195307-C/output.md
install · README
$ git clone github.com/sleepycobalt/motif $ cd motif $ python3 -m venv .venv && source .venv/bin/activate $ pip install -e . $ echo "ANTHROPIC_API_KEY=…" > .env $ motif ./transcripts --out report.md config/synth.yaml — models, thresholds, critic rules in plain language
Everything a stranger needs is in the README. The fifteen-minute install was verified on me, the first stranger.
10

Honest ledger

OPENOne dissenter still gets missed. Penni, the only agency researcher, wants qualitative work to be more like validated quant. Five of six reports state the opposite finding without her. Profiles pointed the critic at the outlier; it reached for someone else.
OPENOne finding per turn. Two themes were absent from every report while the turns containing them were cited in every report — for something else. The model extracts one finding from a turn and stops.
OPENThe loop never passes. Every run stops at three rounds with two or three objections outstanding. The report shows them; whether that’s a feature or a ceiling is the next eval.
OPENNo users yet. A CLI in a repo is a portfolio artifact. The MCP server is what turns it into a tool.
PUBLICThe code, the data, the bad runs, the ground truth, and both scoring sheets. github.com/sleepycobalt/motif.

Two days, twenty-three runs, two evals, one honest result.

11

The v3 evaluation

Addendum to this page at /tools/motif/case-study/ — appended 2026-09-06, three months after the loop above shipped.

what it answers

Part 1 ended on a named failure, above: the model was taking one finding per turn and stopping, so themes cited constantly for one thing never surfaced as a claim in their own right. Eval 2 confirmed it — two ground-truth themes, T-11 (deletion as waste) and T-15 (method hierarchy), absent from all six reports while the turns carrying them were cited in all six for something else. That, plus a duplication problem, an outlier-dissent trap that kept failing, and two unanswered questions about the critic model and the iteration cap, became the v3 eval.

Eval 3 tested four conditions against the same five transcripts (33,870 words), the same ground truth, and condition C only: control, the frozen instrument unchanged; all-v3, control plus five candidate changes (second_finding, duplicate_insight, duplicate_receipt, critic_citation, dissent_at_intake); opus-critic, control with Opus 5 as the critic; cap5, control with max_iterations: 5. Ten runs — three each on control and all-v3, two each on opus-critic and cap5, chosen so the eval fit its $25–40 budget with a working margin. All ten valid; none crashed, none re-run. Scored blind by one rater, AI-assisted, four evidence spot-checks per report at fixed positions chosen before scoring began.

the instrument, frozen and checked

The tag is v2.1-eval, commit 3675228, cut before any v3 code was written: v2-eval as scored in Eval 2 plus exactly one deterministic change, the counter-receipt handling of 2026-09-05. That “exactly one” was verified, not asserted — every commit touching the instrument since the Eval 2 runs was read, diffed, and tabulated. A freeze is only worth something if the claim is checked; checking it took one git log -p over four paths.

the bars

Ten pass/fail bars were written into the eval spec, with their Eval 2 baseline arithmetic beside them, before the first paid run.

#barresultverdict
1Second finding: T-11 and T-15 each ≥ 0.5 in ≥ 2 of 3 all-v3 runsT-11: 1.0, 1.0, 1.0. T-15: 1.0, 1.0, 1.0 — 3/3 each at full credit, against 0/3 in Eval 2PASS
2No coverage loss: all-v3 mean over T-01…T-10 ≥ 7.838.5, 8.0, 8.5 → 8.33, identical to the v2 baselinePASS
3No precision loss: unsupported and miscalibrated each ≤ 1.000.0 and 0.0PASS
4Dedupe: 0 near-duplicate pairs across the 3 all-v3 runs0 pairs — but duplicate_insight never fired, in any runPASS, unattributed
5Outlier dissent: P-03 passes in ≥ 2 of 3 all-v3 runs3/3 — but control also passed 2/3PASS, not attributable
6Opus critic: adopt if coverage +≥1.0 or precision −≥0.5, and cost < $5.00/runcoverage 8.67 → 10.25 (+1.58); $3.83/run. Precision could not fall; it was already 0Rule says adopt
7Iteration cap: adopt cap 5 if critic_pass in ≥1 of 3, or coverage +≥1.0 with bar 3 heldcritic_pass 0 of 2; coverage +0.58Do not adopt
8critic_citation: 0 interviewer turns reach the reviser, every strip recordedfired once (R4), stripping bruce:0026, michelle:0073 and david:0049 from two objections before revision; warn recordedPASS
9duplicate_receipt: 0 in each all-v3 final outputfired 1, 1, 3; final count 0, 0, 0. Control finished with 1, 1, 0 and cap5’s R1 with 3PASS
10Unevaluated recommendations sections named in the verdictnot run — the flag is off in all four configs and no live critique_document pass was made; covered by offline tests onlyNOT RUN

These are decision rules, not significance tests: with three runs and a binary outcome, 2/3 against a 0/3 baseline is not significant at any conventional level (Fisher exact ≈ 0.4), and a one-point theme-sum move is inside the rater consistency Eval 2 recorded. Bars 1, 4 and 5 are worth acting on because the baseline is never rather than sometimes. Bars 2 and 3 are guard rails against a recall change that costs precision, not claims of improvement. Bars 6 and 7 rest on two runs, not three, and cannot report a rate.

the one rule that worked

second_finding asks, for each turn a report cites, whether that turn carries a distinct finding no insight uses. It fired 8, 8 and 9 times across the three all-v3 runs and nowhere else — 25 firings, all inside one condition. In iteration 1 of all three runs it named david:0022 and penni:0031 by turn id and said what second finding each carried. Both themes ended present as claims in all three reports, scored by a rater who did not know the rule had fired.

conditiondavid:0022 citedT-11 scoredpenni:0031 citedT-15 scored
control (n=3)1 of 30, 0.5, 03 of 30, 0, 0.5
all-v3 (n=3)3 of 31.0, 1.0, 1.03 of 31.0, 1.0, 1.0
opus-critic (n=2)2 of 20, 0.52 of 20.5, 0.5
cap5 (n=2)1 of 20, 02 of 20.5, 1.0

penni:0031 was cited in 10 of 10 reports and reached a claim in only the three all-v3 ones. Coverage rose without precision falling: all-v3 gained 1.8 theme points over control and 2.2 over Eval 2’s v2, on 5.3 more insights per report, with unsupported and miscalibrated both at zero. The other two changes that earned their place are both deterministic and cost nothing: duplicate_receipt fired 5 times across the three all-v3 runs and every instance was fixed before the final output; critic_citation caught the exact failure it was written for — the critic sending the reviser to an interviewer turn — and stripped it silently but reported it.

Citing a turn was never the problem. Reading it twice was.

what ships

Three of the five v3 changes ship in the default config: second_finding, critic_citation, duplicate_receipt. dissent_at_intake and duplicate_insight stay off — recorded as unproven this round, not deleted. Shipped in the 0.4.0 release, tag v3, commit 7be2813: PyPI etot-motif 0.4.0, the MCP registry entry and the hosted engine both updated, /healthz reporting 0.4.0.

the two that didn’t

A bar can pass and prove nothing, and saying so is the finding.

dissent_at_intake. Bar 5 passed: P-03 passed in 3 of 3 all-v3 runs. So did 2 of 3 control runs, and 4 of 4 opus and cap5 runs — 9 of 10 reports overall. The rule cannot be credited when the condition without it fixed the same thing. Ruling: stays off. Re-test it against the closed baseline, or drop it; it costs intake output tokens for an effect this eval cannot see.

duplicate_insight. Bar 4 passed: zero near-duplicate pairs at the rater’s judgement across the three all-v3 runs. But the rule never fired, in any run, at its 0.55 threshold, and the rater found no pairs for it to fire on — Eval 2’s R4 duplication was not reproduced, so there was nothing to catch. It stays off for this release too, alongside dissent_at_intake, recorded as untested rather than shipped on faith: it is cheap and deterministic, and the failure it guards — over-splitting under missing_theme pressure — is a live risk now that second_finding is adding insights, which makes it a strong v4 candidate rather than a shipped rule this round.

The rule that did ship is a deviation from the spec worth recording, because it changed the cost: the spec asked for a “deterministic-plus-model pass after revise”; it was built instead as a deterministic critic rule — Jaccard over title and claim vocabulary, threshold 0.55 — that the existing reviser acts on like any other failure. That saves one Sonnet call per iteration, about $0.18 per run and $0.55 across the condition.

the P-03 puzzle

Stated as the results file states it: P-03, Penni’s pro-validation dissent, passed in 9 of 10 reports overall, against 1 of 6 in Eval 2 — and dissent_at_intake cannot be credited, because the condition without it fixed it too. This stays open: the likely cause is the one deterministic change in v2.1-eval (counter-evidence receipts now print, so counter-evidence is cheaper to state correctly) or model drift between 2026-09-03 and 2026-09-06, and neither was isolated. The honest reading is that the Eval 2 open item closed on its own, for a reason nobody has confirmed.

the cap stays at 3

Both cap5 runs went the full five rounds, stop_reason: max_iterations, without ever reaching critic_pass or triggering no_progress. Rounds 4 and 5 cost about $1.10 and 7 minutes per run and bought +0.58 theme points on average, inside rater noise. critic_pass was reached in 0 of 10 runs, at cap 3 and at cap 5, and no_progress never fired. Every run stopped on the ceiling with objections outstanding — raising the cap does not converge the loop, it buys more rounds of the same. Eval 2’s open item, whether the cap is a ceiling or a stopping rule the loop reaches, is answered in the negative.

Opus as critic clears its own decision rule: coverage 8.67 → 10.25, +1.58, at $3.83 a run against a $5.00 ceiling. Its strongest report beat every report produced under any condition in any of the three evals. But the bar is running on two runs, and opus-critic’s two-run range overlaps control’s three-run range. Ruling: make it the documented option for a high-stakes run, not the default, and re-test at n=3 if it is ever proposed as the default.

what it cost
runs/20260906-190902-C-e3-control{1,2,3} 3 iters $2.3578 $2.0425 $2.2980 → $6.6983 runs/20260906-193549-C-e3-allv3{1,2,3} 3 iters $2.8470 $2.3092 $2.3643 → $7.5205 runs/20260906-200614-C-e3-opus{1,2} 3 iters $3.7102 $3.9521 → $7.6623 runs/20260906-203138-C-e3-cap5{1,2} 5 iters $3.2523 $3.3629 → $6.6152 grand total $28.4963 against Plan B’s $30.80

Per run: control $2.23, all-v3 $2.51 (+13% for +1.8 theme points), opus-critic $3.83 (+72%), cap5 $3.31 (+48% for +0.58). Every condition came in under its projection.

Combined project API spend after Eval 3: $72.2047. Local spend $66.4209 across 42 runs/*/meta.json; hosted spend (part 3, on the Fly volume) $5.7838.

Eval 1
$13.3645
Eval 2
$6.8362
Eval 3
$28.4963
non-eval/dev
$17.7239 (discarded and development runs)
local total
$66.4209 · 42 runs
hosted (part 3)
$5.7838
combined
$72.2047

Source: docs/case-study-notes.md, 2026-09-06; Motif commit 341c544.

ledger
OPENA recall rule creates a new precision exposure. The insight second_finding adds arrives without counter-evidence, and missing_counterexample did not revisit it in any of the three runs. P-02 failed 3/3 on exactly the insights the new rule had just produced — a v4 item: hand a newly added finding to the counter-evidence search on the next iteration.
OPENThe trap count rose for the condition that found more, and it is again a denominator. On the six traps applicable to every report, the conditions are flat: control 5/18, all-v3 6/18, opus 2/12, cap5 2/12. The second eval running where a recall win prints as a precision loss unless the denominator is checked.
OPENP-05 failed in 5 of 10 reports, including all three all-v3 runs: the guidance-gap insight stated at high confidence with no counter-evidence, while a positive case sits in the same corpus and is often cited elsewhere in the same report. Three reports show it is avoidable.
OPENUnsupported came out 0 of 40 across ten reports, four spot-checks each — zero in a fixed sample, not zero. One out-of-sample defect was found while reading around a sampled insight. The true unsupported rate is unmeasured.
OPENNo rater-consistency measure. No Eval 2 report was re-scored this round; all ten reports in the blind pack are new. Seven scoring conventions were recorded and applied identically instead. Control’s 8.67 is not a like-for-like re-score of Eval 2’s v2 8.33; the comparison that carries weight is within-session, between conditions, scored blind under the same conventions on the same day.
OPENBar 10 was never exercised. report_unevaluated_sections is false in all four configs, and the $0.50 live critique_document pass was not run. Recorded as not run rather than quietly folded into the offline tests that do cover it.
OPENconfidence_threshold scaling with corpus size deferred to v4. Changing what “high” and “medium” mean re-scores every prior miscalibration count and the whole trap set against a new definition — a second scoring session and a second baseline, outside this eval’s budget.
OPENA stopping rule the loop can actually reach. critic_pass is 0 of 10 at both caps. That is a v4 item, not a footnote.
OPENThe P-03 cause is unverified. The likely cause is the one deterministic change in v2.1-eval or model drift between 2026-09-03 and 2026-09-06; no test isolates either as the reason it recovered.
CONTINUEDPart 2 — the critic works on anyone’s summary. One MCP server instead of a plugin; a real run on a FigJam board; FigJam AI’s own summary checked and failed nine for nine; the package fixed before it shipped. September 2026.
Motif · ETOT · research synthesisCorpus: Hanchard & San Roman Pineda 2023, University of Sheffield, CC-BY-NCEric Frye · 2026