Attended, operator-driven acceptance of a just-built tool or feature. Establishes a persistent operating contract on entry, then YIELDS each turn to the operator — you ask questions or point at problems, the agent answers from primary source, fixes small things in-tree on the spot, logs big ones without rabbit-holing, marks UAT coverage as a byproduct, and hands the turn back. Use for post-/build-phase exploration where the operator wants to drive. Invoke as "/user-walkthrough <tool/feature>".
Scanned 9/3/2026
Install to Claude Code
npx -y skills add aberson/skill-mesh --skill user-walkthrough --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of User Walkthrough?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/aberson-user-walkthrough)More formats (shields.io, HTML) on the badges page.
---
name: user-walkthrough
description: Attended, operator-driven acceptance of a just-built tool or feature. Establishes a persistent operating contract on entry, then YIELDS each turn to the operator — you ask questions or point at problems, the agent answers from primary source, fixes small things in-tree on the spot, logs big ones without rabbit-holing, marks UAT coverage as a byproduct, and hands the turn back. Use for post-/build-phase exploration where the operator wants to drive. Invoke as "/user-walkthrough <tool/feature>".
user-invocable: true
---
# User walkthrough
Attended, **operator-driven** UAT. You (the operator) drive; the agent rides along. Each turn
you ask a question or point at a problem; the agent answers from PRIMARY SOURCE (reads the
actual code/artifact, cites `file:line` — never vibes), marks any coverage the exchange earned,
routes issues to fix-now or log-for-later, then **stops and hands the turn back**. Coverage
accrues as a byproduct of poking the build, not as a script you march through.
The ledger it reads and writes is defined once in
[`.claude/references/shakedown-engine.md`](../../references/shakedown-engine.md) — this skill
never redefines the row grammar, slug rule, or status vocabulary; it cites the engine.
## When to use / not
- **Use:** a tool or feature was just built (post-`/build-phase`, post-`/build-step`, or a
fresh `/user-debug`) and you want to poke it yourself — ask how it works, try things, surface
issues — with the agent answering from source, fixing small breakage live, and tracking what
got covered. You want to be in the driver's seat.
- **Don't use** when you want the agent to close out UAT autonomously (that is
`/user-shakedown`), to execute an already-written UAT block for you (`/user-uat`), or to
refine a fuzzy UAT script (`/review-uat`). If you have no build to poke yet, there is nothing
to walk through.
## Invocation
```text
/user-walkthrough <tool/feature> # attended walkthrough of the named build
/user-walkthrough export-button # slug resolves the ledger per the engine's slug rule
```
## Flow
### 1. Entry — orient, establish the contract
1. **Resolve or derive the ledger** per the engine reference: compute the feature-slug, resolve
the ledger path via `git rev-parse --show-toplevel`, and **load it if it already exists**
(never re-seed — a prior walkthrough or shakedown may have started it). If absent, derive it
per the engine's checklist-derivation rules (seed from the plan's `## Manual UAT` /
`Type: operator` M-steps when present; else a lightweight derived expectation set).
2. **State the operating contract once**, then yield: "I'll answer from source with `file:line`,
fix small things in-tree and show you, log big ones, and mark coverage as we go. You drive —
ask or point at anything." Optionally kick off the tool and show its output to seed the first
turn.
### 2. Loop — one operator turn at a time
Per turn the operator asks a question or reports a problem. The agent:
1. **Answers from PRIMARY SOURCE.** Read the actual code/artifact and cite `file:line`. Never
answer a "does it / how does it" question from memory or inference — open the file. A
confidently-wrong answer from vibes is worse than "let me check."
2. **Marks coverage earned this turn.** If the exchange exercised a behavior matching a ledger
row, mark that row `satisfied` with concrete evidence (the command output / observed result /
`file:line`) per the engine's coverage-marking rule — never a bare status flip.
3. **Routes any issue** by size, per the engine's two paths:
- **Small + unambiguous → fix it now, in the live tree.** Edit in place (uncommitted), run
the NARROWEST test, mark the row `fixed` with evidence. Do **not** spin a `/build-step`
worktree; the fix must be visible to the running tool immediately. **Never block on a
(y/n) for your own small fix — just make it and report what you did.**
- **Big → log it, don't rabbit-hole.** Append the row `logged` with a one-line diagnosis and
move on; it becomes a sibling issue at wrap.
4. **STOP and hand the turn back.** One operator ask → one agent response → stop. Do not keep
working, do not chain into the next check unprompted, do not march a script. Yielding is the
whole point of the attended mode.
### 3. Wrap — "did I miss anything?"
When the operator signals they're done (or asks for a wrap), report coverage in three buckets:
`satisfied` (with evidence), still-`open`, and `logged` bigs. Then **offer** — do not execute —
three closers:
1. **Batch-commit the live fixes** as one reviewable diff, using scoped `git add <paths>` of
only the files this walkthrough touched (never `git add -A`).
2. **File the logged bigs** as GitHub sibling issues (via `gh` with `--body-file`) that feed
`/plan-feature` or `/build-step`.
3. **Emit the canonical `/goal` string** from the engine to hand autonomous closure to
`/user-shakedown`:
`/goal "shakedown ledger for <feature-slug> has zero open items"`
The operator picks which closers to run — this is the attended mode; the operator decides.
## Constraints
- **MUST NOT arm a `/goal` DURING the loop.** A `/goal` arms a Stop hook that re-prompts the
*agent* every turn until its condition holds — which makes the session agent-paced and
destroys the operator-driven dynamic (the agent would keep working instead of yielding to
you). The `/goal` string is **emitted at wrap only**, opt-in, for the operator to paste. This
is the single hardest rule in this skill.
- **Never block on a (y/n) for the skill's own small fixes.** Make the fix, run the narrowest
test, report it. The operator is already in the loop every turn; a confirmation gate is noise.
- **Never write into any plan's `## Manual UAT` block.** That block is append-only and owned by
`/build-phase`. The ledger is a SEPARATE task-state artifact (per the engine's path formula) —
status lives there, never in plan.md.
- **Answer from primary source, always.** Every substantive claim cites `file:line`. No vibes.
- **Small fixes stay in the live tree, uncommitted until wrap.** No worktree; scoped commit at
wrap only.
## Limitations — four-mode disambiguation
Four sibling UAT modes; pick by who drives and what shape the input is:
| Skill | What it does |
|---|---|
| `/user-uat` | EXECUTES an already-clear UAT script FOR you (mechanical tier auto-judged). |
| `/review-uat` | REFINES a fuzzy UAT script until every step is unambiguous. |
| `/user-walkthrough` | **This skill.** The operator DRIVES exploration; the agent answers, fixes small, logs big. |
| `/user-shakedown` | The agent AUTONOMOUSLY CLOSES the ledger to zero open items (same engine). |
`/user-walkthrough` and `/user-shakedown` share the same ledger file (same slug rule → same
path), so a walkthrough can hand a half-filled ledger to a shakedown mid-stream.
## Canonical example — one loop turn
> **Operator:** "Does the CSV export respect the active date filter?"
>
> **Agent:** Reads `src/export/csv.py:41-58` — the query is built from `request.filters` and the
> date range is applied at line 47. Cites it: "Yes — `csv.py:47` folds `filters.date_range`
> into the WHERE clause before serialization." Marks ledger row `M1` **satisfied** with
> evidence `csv.py:47 applies date_range`. **Stops, hands the turn back.**
>
> **Operator:** "The export button label says 'Exprot'."
>
> **Agent:** Small + unambiguous → fixes it in the live tree (`templates/export.html:12`), runs
> the narrowest test (`pytest tests/test_export_template.py -k label` → 1 passed), marks the row
> **fixed** with that evidence. No (y/n). **Stops.**
>
> **Operator:** "Export of a 2M-row table times out."
>
> **Agent:** Big → does NOT rabbit-hole. Appends a **logged** row with the one-line diagnosis
> "streaming/pagination needed for large exports; synchronous path blocks." **Stops.**
>
> At wrap: reports `M1` satisfied, the label fixed, the timeout logged; offers to batch-commit
> the label fix, file the timeout as a sibling issue, and emit the `/goal` string for shakedown.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!