Imported from CauchyIO/awow (
dist-telemetry/skills/awow-usage-coach/SKILL.md). Install upstream withnpx skills add CauchyIO/awow --skill awow-usage-coach. Copyright stays with the author.
awow Usage Coach
Starter shape — adjust for your harness and backend. This skill ships expecting input in the shape produced by the bundled
mlflow-exportskill (Databricks MLflow). Teams on a different harness or tracing backend should either (a) emit the same JSON layout from their backend, or (b) extendscripts/awow_extract.pyto read their format. The analysis itself — intent taxonomy, sequence patterns, edit footprint — is harness-agnostic and built aroundworking_directory,files_modified, prompt text, and per-prompt timestamps. Adjust the script's input parser; leave the rubric alone unless the team genuinely wants a different report shape. Customisation lands during/setup-awowStep 8 (Skills review).
Reads sessions captured in an mlflow_export/ directory (or equivalent), filters to the target repo, and produces one of two markdown reports.
The qualitative judgment lives in this skill's instructions, not in the extractor. The script (scripts/awow_extract.py) only counts and extracts — it never grades.
What the skill measures
Three lenses, in priority order:
- Intent shape — every prompt is classified into one of eight labels (
investigate,plan,propose,implement,refine,verify,document,inform, orother). Vocabulary-agnostic — works whether or not the team uses awow's slash commands. - Sequence patterns — bigrams and trigrams of intent transitions per session surface the working rhythm (
investigate→implement→verify,propose→implement→refine, etc.). In self-coach mode, subject vs. team bigrams reveal where rhythms differ. - Edit patterns — each trace carries a
files.modifiedtag. The extractor buckets touched files by location/type (proposal,context,agents-config,code,config,markdown,data,script,other) and crosses this with intent so the report can say things like "when teammates 'propose', 70% of touched files are .md; when you 'propose', 30% are .md and 50% are code".
Awow-specific vocabulary signals (slash commands, proposal-first paths, placement decision tree) are kept as a secondary lens — surfaced when present, but never required for a useful report.
Inputs to collect
--input— required. Path to anmlflow_export/directory (must containtraces.jsonl). If the user hasn't exported recently, suggest running/mlflow-exportfirst.--awow-root— optional. Defaults to../awow(resolved from cwd). Use when running from a sibling repo.--include-path— optional, repeatable. Extra working_directory to treat as a target repo. Use this when the awow repo has no traces yet and you want to evaluate sequence + editing patterns on a sibling repo as a stand-in.--user— optional. Email or short name of the subject developer. Presence of this flag flips into self-coach mode. Absent → team-nudge mode.- Output path — optional. Defaults to
awow_usage_report.mdin cwd.
If the input path is missing or ambiguous, ask before running.
Run the extractor
python3 .agents/skills/awow-usage-coach/scripts/awow_extract.py \
--input <mlflow_export_dir> \
--out /tmp/awow_usage.json \
[--awow-root ../awow] \
[--include-path /path/to/sibling/repo] \
[--user <email-or-short-name>]
The script prints a one-line summary to stdout (intent mix, top bigrams, edit footprint, top slash commands) and writes a JSON with this shape:
{
target_sessions, target_users[], target_working_directories[],
intent_taxonomy[],
known_commands{},
team_aggregate{
n_prompts,
intent{ # the primary lens
intent_counts[(label, n)],
intent_shares{label: share},
bigrams_top15[ {seq, count} ],
trigrams_top10[ {seq, count} ],
per_intent{ # how each intent typically plays out
<label>: {n_prompts, share, n_with_files, files_touch_rate,
file_buckets{}, median_words}
},
session_shapes[ {session_id, user, n_prompts, first_intent,
shape{label:share}, sequence_preview[]} ]
},
edit_footprint{ # raw file-modification rollup
n_prompts_with_files, share_prompts_with_files, total_file_modifications,
unique_files, file_buckets{}, top_files_top20[(path, n)]
},
slash_commands[(name, count)], command_coverage{used,unused,unknown_invoked},
share{...}, # secondary awow-vocabulary signals
proposal_discipline{...}, placement_discipline{...},
prompt_words{median,p75,max}
},
per_user[ {user, n_sessions, n_prompts, intent, edit_footprint, ...} ],
evidence_quotes{
"intent:investigate":[5 quotes], "intent:implement":[5], "intent:propose":[5], ...
"slash:<name>":[...], "proposal_first":[...], "direct_write_to_canonical":[...],
"story_only_no_placement":[...], "bloat_signal":[...], "brevity_signal":[...]
},
subject{...}, baseline{...}, # populated only when --user is set
sessions[ {session_id, user, working_directory, prompts[ {text, files_modified, file_buckets, ...} ]} ]
}
Read the JSON with Read. Skim team_aggregate.intent and team_aggregate.edit_footprint and evidence_quotes first; reach into sessions[*].prompts[*] only when you need additional verbatim grounding.
If target_sessions == 0, stop and tell the user the export contains no sessions from the awow repo or any --include-path. They may need to re-export or pass a different path.
Mode A — team-nudge report (no --user)
Goal: produce proposed additions to .agents/AGENTS.md that an agent can read and apply, both as text edits to the file and as rules to follow in the next session. A nudge is a rule for the agent, not advice for the human prompter.
Length cap: aim for ≤120 lines total. For thin slices (<30 prompts) cap at ≤60 lines. Every section earns its width.
Required sections
-
Header — input path, total sessions in export, target sessions, distinct target users, working directories, date range, include-paths used. One block, ≤8 lines.
-
TL;DR — 3 bullets max:
- the dominant pattern (one sentence)
- the number of nudges proposed and where each lands (file → section, no detail yet)
- the single biggest gap evidence supports
-
Intent shape — table of intent counts + shares from
team_aggregate.intent.intent_counts. One sentence on the dominant labels and one sentence on the size of theotherbucket (>30% = taxonomy under-captures; flag and sample 2 quotes). -
Sequence patterns — top 5 bigrams + top 3 trigrams from
team_aggregate.intent.bigrams_top15/trigrams_top10. One short sentence per pattern on what it means (≤15 words each). -
Edit patterns — from
team_aggregate.edit_footprint:- share of prompts that modified files
- file-bucket distribution
- cross with
per_intentto surface interesting pairings (e.g. "proposeprompts touched 0 markdown files")
-
Awow-vocabulary lens (secondary) — only if there's signal. If all signals are null/zero, replace the section with a single line: "No awow-vocabulary signal in this slice."
-
Patterns that justify a nudge — 2-4 patterns. Three lines each. No more.
- Line 1: one-sentence description anchored in a sequence/edit pattern
- Line 2: frequency from the JSON (real number, not "often")
- Line 3: one verbatim quote (≤20 words; truncate with
…if longer)
-
Proposed nudges — one nudge per justified pattern. Use this strict format:
### Nudge N — <≤8-word title in imperative voice> **Target file:** `.agents/AGENTS.md` **Target section:** `## <existing section name>` or `## <new section name (proposed)>` **Insert verbatim:** > <one or two sentences, addressed to the AGENT in second person, matching awow's existing CLAUDE.md voice> **Evidence:** <frequency> · "<short verbatim quote>" · would change <bigram/trigram/edit-pattern>The
Insert verbatimblock is a single short paragraph. No bullets, no sub-headings, no "you should" hedging. It must read as a rule the agent follows during a session. -
Don't nudge — patterns the data shows but that don't deserve a CLAUDE.md addition. One line each, ≤4 items.
-
Distribution checklist — three lines max: edit
.agents/AGENTS.md, re-run the gather, do not hand-edit mirrored files.
How to write the Insert verbatim block
This is the load-bearing part. The nudge is a rule the agent reads at session start and follows during the session.
Follow awow's agent-directive voice — second person, imperative, ≤2 sentences, no evidence inside the rule. In a vendored install, the agent-directive-voice skill carries worked rewrites (human-aimed → agent-directive) you can use as templates.
Nudge-specific addenda:
- No restating evidence in the rule. Stats and quotes go in the
Evidence:line, not in the rule itself. - If the rewrite cannot be made agent-actionable, the pattern belongs in coaching (Mode B), not a CLAUDE.md nudge.
Quality bar
- Every nudge is anchored. A real frequency number AND a verbatim quote in the
Evidence:line, or it doesn't ship. - Sequence > vocabulary. Prefer nudges driven by bigrams/trigrams or edit patterns over nudges driven only by awow-keyword matching.
- Propose only what's missing. Read
.agents/AGENTS.mdfirst. If the rule already exists, say so in "Don't nudge" rather than reproposing. - Bias toward fewer nudges. Two sharp nudges that an agent can apply tomorrow beat five soft ones it has to interpret. Borderline patterns go to "Don't nudge".
- Length discipline. If the report exceeds the cap, cut analytical prose first, then quotes, then the second-place patterns — never cut the nudge directive itself.
Mode B — self-coach report (--user set)
Goal: help one developer use the project better. Imperative, peer-tone, growth-oriented. Never judgmental. The point is "here's a thing you can try" — not "here's what you got wrong".
Voice rules (load-bearing — do not violate):
- Imperative ("Open more sessions by stating the goal up front …"), not interrogative or hedging.
- Direct comparisons to the team baseline are fine; framing them as punishment is not. "You start 30% of sessions with
investigate; teammates start 60% withplan" is fine. "You don't plan enough" is not. - Lead with strengths. Then offer 3-5 concrete moves.
- Second person. Speak to the developer, not about them.
Required sections
-
Header — subject user, n sessions, n prompts, period covered, target paths used.
-
What the data shows — 1 short paragraph reading
subject.intentandsubject.edit_footprintin plain English. End with a tone-setting sentence: this is a starting point, not a verdict. -
Side-by-side snapshot — small table: subject vs. baseline on
- prompts/session, median prompt length
- intent mix (top 5 labels for each, % share)
- top 3 sequence bigrams (each side)
- share of prompts that touched files; dominant file bucket
- awow-vocabulary signals (only if non-null on at least one side)
-
Strengths — 2-4 things the subject is doing well, each with a verbatim quote pulled from their prompts (use
evidence_quotes[intent:<label>]filtered to the subject's sessions, orsubject.sessions[*]). -
Moves to try — exactly 3-5 imperative suggestions. For each:
### Move N — <short imperative title> <one-paragraph case for the move, written to the subject directly> **Try:** <concrete prompt or workflow they can copy> **Hook in the data:** <one stat from `subject` vs `baseline` (intent share, bigram, or edit pattern), plus a short quote from their own prompts>Each move must be actionable in the next session. Examples of good moves (these are illustrative, not a checklist):
- "Open the cycle by stating the goal before asking Claude to act — your sessions start with
investigate60% of the time; opening withplanmore often correlates with shorter sessions in the team data." - "Draft your story body as a proposal draft first, then promote — even when the change feels small."
- "When you ask for context, point Claude at the knowledge base rather than re-pasting it inline."
- "Open the cycle by stating the goal before asking Claude to act — your sessions start with
-
What you're already doing that teammates aren't — 0-3 bullets. If nothing stands out, omit the section rather than padding.
-
Closing line — one sentence. No grade, no score. Something like "Pick one move and try it in your next refinement session."
Quality bar
- No grades, no scores, no "B+". Describe the shape, point at the next move.
- Quote real prompts. Every claim about how the subject prompts needs at least one verbatim snippet from
subject.sessions[*]orevidence_quotes. - Numbers come from the JSON. Never invent percentages. If
baselineis empty or has only one user (i.e. there's no real comparison group), say so explicitly and switch the report's tone to "patterns in your own sessions" rather than "vs. team". - Stay in scope. General prompt-engineering advice belongs in the
prompt-skill-analysisskill. This skill is about workflow shape (intent sequence, editing rhythm, awow conventions when present).
Interpreting the intent taxonomy
Quick guide for the model when reading bigrams and per-intent stats:
investigate→investigate→investigate— deep exploration chain. Useful in unfamiliar territory; expensive when the answer is already in the knowledge base.plan→propose→implement— the textbook awow rhythm. Reaching for a proposal draft before touching canonical paths.implement→verify→refine— test-driven loop. Healthy when changes are landing.implement→implement→implementwithoutverify— execution without checks. Worth nudging if it correlates withrefinelater (rework).other> 30% — the taxonomy under-captures this team's voice. Quote 3-5otherprompts and let the report acknowledge the gap rather than misclassifying.inform-heavy — the developer talks to Claude (status updates, observations) rather than directing it. Not inherently bad — common in pair-programming style — but if combined with lowplan/propose, it suggests the working approach is reactive rather than structured.
After writing the report
Print 3 short bullets to the user:
- Where the report was saved.
- The headline strength (Mode B) or the top nudge (Mode A).
- The single suggested next step.
Do not restate the report in chat. The markdown file is the deliverable.
Per-session coaching (visual timeline path)
The extractor reads MLflow mlflow_export/ traces. When the team has no tracing wired up, you can still coach off the raw Claude Code logs via project-timeline, which runs ${CLAUDE_PLUGIN_ROOT}/tools/session_timeline.py over ~/.claude/projects/<encoded-path>/*.jsonl and emits sessions.json + an interactive timeline.html. Use that path when asked for a per-session review or a whole-project picture rather than the aggregate Mode A/B reports.
When coaching per session this way, apply Mode B's voice rules unchanged (imperative, lead with strengths, every claim carries a verbatim quote, no grades) and write one <short-id>.md per session that the timeline embeds via --coach-dir. The timeline also surfaces three signals the trace extractor does not, worth reading into the coaching:
- Concurrency / fan-out — how many sessions ran in parallel. High parallelism that compresses many session-hours into a short span is the awow rhythm working; flag it as a strength.
- Idle gaps — stretches where no session logged any event (the human stepped away). Lead any "how long did this take" read with active time, not elapsed span.
- Peak context per session — the fullest prompt size reached. A session crossing the standard window is a signal it was doing two or three jobs that each wanted their own fanned-out session — coach toward splitting, not bigger context.
Reviews and the project overview are private session-derived data — real names, private issue IDs, infra topology, cost figures. Write them only to coach_reviews/ (gitignored). Never write them to any git-tracked path — not a proposal draft, not the team context, nowhere committed: if this repo is public, committing them leaks customer data. Never copy a secret a prompt pasted into a review or overview — flag it to the user out-of-band.
Interplay with sister skills
mlflow-exportproduces the trace input. If sessions are stale, suggest re-running it first.prompt-skill-analysiscovers generic prompt quality (clarity, specificity, length distribution, voice). If the user wants both styles of feedback, run them as two reports against the same export — they don't overlap. This skill is about workflow shape, that one is about prompt craft.project-timelineis the visual, no-tracing sibling: the same workflow-shape lens, rendered from raw Claude Code logs. Reach for it for per-session coaching or a whole-project timeline; reach for the extractor for aggregate team-nudge / self-coach reports and cross-user baselines.
Troubleshooting
target_sessions == 0— the export contains no sessions tagged with the awow working directory or any--include-path. Confirm: did the user actually run Claude Code from inside the target repo during the export window? Is--awow-rootcorrect?- All sessions belong to one user — both subject-vs-baseline comparison and team aggregation collapse. Tell the user and produce a single-user analysis instead of forcing a comparison.
otherintent dominates (>50%) — the taxonomy is undercapturing. Either the team writes very informal/short prompts, or there's a domain phrasing the patterns don't catch. Sample someotherprompts in the report and flag the gap rather than overclaiming intent shape.- No
files_modifieddata — older mlflow exports may lack this tag. The intent + sequence lenses still work; just say in the header that edit-pattern signals are absent. - Subject user not present — check
target_usersin the JSON. The script normalizes emails to the local-part (e.g.someone@example.com→someone); pass the matching form. - JSON is large —
sessions[*].prompts[*].textis truncated to 1200 chars by default. If the file is still big, readteam_aggregate,per_user, andevidence_quotesand only dip intosessionsfor verification.