tencent/skillhone-prd
>- Interactively gather a PRD (Product Requirements Document) for an agent skill that is about to be built or optimized by SkillHone. Use when the user says things like "I want to write a new skill", "help me spec this skill", "what should <x>-skill do", or before running `skillhone new` / `skillhone optim` on a skill whose requirements aren't fully nailed down. The interview is driven through the `AskUserQuestion` tool — every round is a small set of dependent multi-choice questions, and the skill keeps asking until the user says stop. Final artifacts are three files in the paired `<skill>-eval` visible, scoring rubric redacted), and `PRD.choice.md` (the AskUserQuestion transcript). Also mirrors the appropriate pages into Forgejo wiki checkouts when available.
npx skills add https://github.com/Tencent/SkillHone --skill skillhone-prd
Before SkillHone can meaningfully optimize a skill, three things must be unambiguous: what the skill is trying to achieve (goal), what environment it runs in (tools), and how its outputs will be judged (evaluation — both the structural format and the scoring rubric). Writing ordinary product PRDs doesn't cut it — a skill PRD is primarily an evaluation contract, not a feature list.
This skill drives a multi-round interview via AskUserQuestion and emits three files into the paired <skill>-eval repo:
PRD.md — full PRD, including evaluation criteria. Visible to the eval agent only.PRD.improver_only.md — same PRD with section 4 (Evaluation) stripped. Visible to the improver / iter agent.PRD.choice.md — full question/answer transcript. Eval artifact; never published to the skill wiki.The split is deliberate: if the improver sees its own grading rubric, Goodhart's Law takes over within a few iterations.
A skill PRD is structurally analogous to an RL problem spec:
| RL concept | Skill PRD dimension | Why it comes when it does |
|---|---|---|
| Task goal | Goal | Without a goal, you can't pick what tools matter or what to measure. |
| Environment | Environment (tools, runtime) | Tools = the action space; sets the ceiling on what's testable. |
| Reward | Evaluation (incl. output format) | Reward is meaningful only relative to a fixed goal and environment. |
> Output format is part of evaluation, not separate from it. Format validity is the *structural* reward gate; metrics and thresholds are the *content* reward. They're rendered as two sections (3 and 4) so that the improver-only file can keep the format spec visible while redacting the scoring rubric.
PRD section order in PRD.md is fixed: ## 1. Environment → ## 2. Goal → ## 3. Output format → ## 4. Evaluation. The interview order is independent — the script reorders for you.
If the user pushes to jump ahead ("let's talk metrics first"), briefly redirect: *"reward depends on what the agent can actually do — let's pin down the goal and the tools first, or we'll just be optimizing a metric that doesn't correspond to the task."*
AskUserQuestion, alwaysDrive every round through the AskUserQuestion tool. Do not paste numbered lists into your text reply — the tool gives the user a real picker UI and structured answers come back to you, which removes parsing ambiguity.
Language: match the language of the user's most recent message for all user-facing text (questions, options, your prose). Keep file names, the four dimension keys (environment, goal, output_format, evaluation), and the generated-PRD headings in English — the script depends on them.
header ≤ 12 chars. Crisp nouns: Tools, Goal, Format, Metric.label = what the user picks; description = why. Both required.multiSelect: true only when more than one option can legitimately apply.For the full catalogue of worked examples, anti-patterns, and dimension-by-dimension question templates, see references/question_playbook.md. Load that file if you're unsure how to phrase a question for a specific dimension.
Maintain an in-memory choices list. After every AskUserQuestion result, append exactly what you asked and what the user answered:
{
"round": 1,
"dimension": "goal",
"why": "Determines the primary PRD goal and downstream eval metric family.",
"questions": [ /* passed to AskUserQuestion verbatim */ ],
"answers": { "What's the primary optimization target?": "Total accuracy" }
}
Rules: record questions exactly as sent; record answers exactly as returned; do not summarize in choices; include the Stop? question like any other. Pass the list to scripts/write_prd.py; it renders PRD.choice.md from it.
Before each AskUserQuestion call, confirm:
If any answer is no, don't ask. Either infer and state the assumption, or ask a narrower upstream question.
Treat free-text answers as more authoritative than the offered options.
Keep launching AskUserQuestion rounds until the user explicitly says stop. No question budget, no auto-stop on convergence.
Starting with round 2, include a Stop? question in every round (default No):
{
"header": "Stop?",
"question": "Stop collecting requirements and write the PRD now?",
"options": [
{"label": "No", "description": "Keep going — I have more to say"},
{"label": "Yes", "description": "Looks clear enough; write the PRD"}
]
}
On Yes → exit and write PRDs. On No or free-text → next substantive round (including Stop? again). You can also stop immediately if the free-text reply is an unambiguous stop signal — anything that clearly means "stop / done / just write it" in any language.
If the user stops while a dimension is half-baked, write the PRD anyway with the gap flagged: _(deferred — not pinned down in the interview)_. Do not guess.
This skill is not a state machine. A reasonable default:
unknown | partial | settled from the user's opening message.Stop? from round 2 onwards.scripts/write_prd.py. Use --out-dir. Pass --eval-wiki-dir / --skill-wiki-dir if wiki checkouts are available.scripts/validate_prd.py. If either PRD exits non-zero, fix inputs and re-run. Don't hand back an invalid PRD.All three files go to the root of the eval repo, not the skill repo. Detection order:
<skill-name>-eval exists next to the current skill repo, write into it.$SKILLHONE_EVAL_DIR is set, write into it../PRD.md, ./PRD.improver_only.md, ./PRD.choice.md in CWD and print:note: couldn't auto-detect eval repo; copy PRD.md, PRD.improver_only.md, and PRD.choice.md into <skill>-eval/
Reason: if the full PRD or choice transcript sits inside the skill repo, the improver eventually trains against its own rubric and Goodhart takes over.
Forgejo wikis are git-backed. Clone the two wiki repos into a scratch area, pass those checkouts to scripts/write_prd.py, then commit/push after user authorization. Derive wiki clone URL by replacing the repo suffix: <repo>.git → <repo>.wiki.git.
| Forgejo wiki | Page | Source | Visibility |
|---|---|---|---|
| <skill>-eval wiki | PRD.md | PRD.md | Full eval-visible contract |
| <skill>-eval wiki | PRD-Choices.md | PRD.choice.md | Full interview transcript |
| <skill> wiki | PRD.md | PRD.improver_only.md | Training/improver-visible only |
Never publish PRD.md, PRD.choice.md, scoring rubrics, validators, or eval dataset details into the <skill> wiki. The skill repo wiki is improver-visible — treat it as part of the skill repo for leakage purposes.
python3 scripts/write_prd.py \
--skill-name <skill> \
--data collected_prd.json \
--out-dir <skill-eval-dir> \
--eval-wiki-dir <checked-out-skill-eval-wiki> \
--skill-wiki-dir <checked-out-skill-wiki>
The script writes files but does not git commit/push; do that separately with the user's Forgejo credentials.
| Content | PRD.md / eval wiki | PRD.improver_only.md / skill wiki | PRD.choice.md / eval wiki |
|---|---|---|---|
| 1. Environment | ✅ full | ✅ full | ❌ |
| 2. Goal | ✅ full | ✅ full | ❌ |
| 3. Output format — schema, examples | ✅ full | ✅ full | ❌ |
| 3. Output format — auto-validation rule | ✅ full | ❌ redacted | ❌ |
| 4. Evaluation (metrics, thresholds, dataset) | ✅ full | ❌ entire section removed | ❌ |
| AskUserQuestion raw Q/A | ❌ | ❌ | ✅ full |
The redaction, choice-log rendering, and wiki split are enforced by scripts/write_prd.py. Do not hand-edit to bypass them.
PRD.improver_only.md is generated by the script, not written by you. If you hand-edit it, you'll eventually leak the rubric.PRD.choice.md must never go into the skill wiki — only the eval wiki. The script enforces this; don't wiki.py create it yourself in the wrong repo.PRD-Choices.md, not PRD_Choices.md).write_prd.py validates its input JSON schema. If it exits non-zero on the first run, fix your choices/data payload before re-running.validate_prd.py on PRD.md, the interview skipped Evaluation. Resume with a Scoring question rather than hand-authoring the section.AskUserQuestion.write_prd.py renders. Load only if debugging PRD output.Three files at the target path:
PRD.md — full PRD, eval-agent-visible.PRD.improver_only.md — redacted PRD, improver-agent-visible.PRD.choice.md — AskUserQuestion transcript.Both PRD files must pass scripts/validate_prd.py before you hand back. PRD.choice.md is an audit artifact — no redaction, but only publish to the eval repo/wiki.
Take tencent/skillhone-prd from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.