verbatim-themes
Systematically codes open-ended free-text answers from a survey CSV: theme clusters with frequency, pain points vs. praise, representative quotes. Analyzes ALL answers (not just a sample). Result as M
Files1
View on GitHubSKILL.md.agents/skills/verbatim-themes/SKILL.md
GitHubVerbatim Theme Analysis
Goal: Systematically code the open-ended answers of the question/column named in the
user's request — build themes, count their frequency, back them with quotes. This
is about qualitative depth over the full dataset. Result to reports/.
Tool
python3 scripts/survey.py <cmd> [...] [--file CSV]
Run these from the project root. If scripts/survey.py is not there, check .claude/scripts/survey.py or locate survey.py in the project.
profile— column overview; identifies FREETEXT columns (always first).text COL [--filter "COL=VALUE"]— print all answers of the column (no--sample, so nothing is missed).--jsonfor clean downstream handling.text COL --filter ...— free text of a subgroup (e.g. daily users only).
COL = index (from profile) or an unambiguous name part.
Survey context
If a context document sits next to the CSV (<name>.context.md, or survey-context.md
when the folder holds exactly one CSV), read it before coding. The glossary is the
practical gain here: respondents write in internal shorthand, feature names and
abbreviations, and without the glossary you will either misread them or split one theme
across several. The fieldwork circumstances explain spikes — a release or an outage
during the field period shows up as a theme and should be labeled as such, not read as a
standing complaint.
Code bottom-up regardless: themes come from the answers, never from the context
document's vocabulary or from what someone expected to hear. Expectations listed there are
something to test, never something to support — never inflate a theme because it was
anticipated, and never drop one because it was not. Carry the recruiting limits ("Who is
missing") into the method section. If no such document exists, proceed as before and
mention survey-context once at the end.
Approach
- Profile, pick the target free-text column. Note the fill rate (how many answered? the non-answerers are part of the truth).
- Load all answers with
text COL(no--sample). With very many answers, read in several passes/chunks so none is lost. - Code (bottom-up). Build recurring themes/codes, merge synonyms. An answer can map to several themes. Count mentions per theme (approximate frequency, clearly flagged as an estimate).
- Structure. Order themes by frequency; where useful split into pain points (problems/wishes) vs. praise/valued aspects vs. neutral/behavior.
- Back it up. Per theme, 1–2 verbatim short quotes (unaltered, trimmed with […] if needed).
- Save the report to
reports/(date +%F+ kebab title, never overwrite) and give the top themes + path in your reply.
Report format
# Verbatim themes: <question>
**Data basis:** <file> · answers n = <filled> of <total> · <date>
## Overview
2–3 sentences: what dominates? overall tone (positive/critical/mixed)?
## Themes (by frequency)
### 1. <theme> — ~<N> mentions
Short description. Evidence: "<verbatim quote>" · "<quote 2>"
### 2. …
## Pain points vs. valued aspects
Compact contrast of the main criticism/wish themes and praise themes.
## Implications
What follows for product/UX/prioritization?
## Method
Column analyzed, base population, coding logic, and — from the survey context — who was
surveyed and who could not be reached. Mention counts are qualitative estimates (answers
can belong to several themes).
Rules
- Completeness over convenience: review all answers, not just a sample.
- Use quotes verbatim (no smoothing/inventing); trim only with […].
- Report mention counts honestly as approximations — this is qualitative coding.
- Mention non-answerers and low fill rate (bias risk).
- Don't expose personal details in quotes that could identify an individual.
- Report language = language of the answers (default English).