Add skill definition to guide AI coding agents with Diataxis principles - #162
Add skill definition to guide AI coding agents with Diataxis principles#162ertembiyik wants to merge 1 commit into
Conversation
Create a Claude skill that helps agents write, review, and structure documentation using the Diataxis methodology. The skill uses a compressed index in SKILL.md paired with symlinked reference files from the framework repo, following the Vercel research pattern where passive context outperforms active retrieval. Includes the four documentation types (tutorials, how-to guides, reference, explanation) and the compass classification tool. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
gdevenyi
left a comment
There was a problem hiding this comment.
Review: skills/diataxis — Diataxis skill for AI coding agents
Reviewed against skill-authoring craft criteria (invocation cost, information hierarchy, context-pointer wording, pruning, and the usual failure modes — duplication, no-ops, negation, premature completion) and against the actual content of source/*.rst on current main. I checked out the branch, merged it into main, and tested the symlinks rather than reading the diff alone.
The idea is a good one, and the shape is right: a compressed index plus pointers is the correct architecture for a corpus this size (~16,600 words across the 15 referenced files — far too much to inline). Symlinking rather than copying the .rst files is the right instinct. Two things block it as-is, and one design decision undercuts the PR's central claim.
Good news first: Sphinx is unaffected. Makefile sets SOURCEDIR = source and skills/ sits outside it, so the symlinked .rst files are never globbed — no duplicate-document warnings, no Read the Docs breakage. That was the obvious worry and it doesn't apply.
🔴 Blocking: all 15 symlinks break on merge, silently
main has moved every .rst file into source/ (commit c953482, "Added translation machinery and content"). The symlinks target the repo root. They resolve on this branch's stale base, which is why nothing looks wrong in the diff.
$ git checkout -B mergetest origin/main && git merge ertembiyik/diataxis-skill # clean, no conflict
$ for f in skills/diataxis/references/*; do [ -e "$f" ] || echo "BROKEN $f"; done
BROKEN skills/diataxis/references/application.rst
... (15 of 15)The merge is conflict-free, so nothing warns you. Post-merge the skill's ## Source of Truth promise is false and the agent reads nothing at all. Fix for 14 of them is ../../../source/<name>.rst.
🔴 Blocking: complex-hierarchies.rst no longer exists
Removed deliberately in abfae1f — "Tidied up some files; removed complex hierarchies page". It is neither at the root nor in source/, so retargeting the prefix won't save this one. SKILL.md currently advertises it twice (index line 42, pointer line 125). Drop the symlink and both references.
Together these two are the argument for the third point.
🟠 Design: the PR has two sources of truth, and only one of them syncs
The PR body says "Content changes to existing files are reflected automatically via symlinks." That holds for the .rst files. It does not hold for lines 22–126 of SKILL.md, which are a hand-written paraphrase of the same corpus with nothing keeping them honest. Measured against source/ on main today, the paraphrase has already drifted:
| Type | Key principles carried | Dropped |
|---|---|---|
| Reference | 4 / 4 | — |
| Explanation | 4 / 5 | Talk about the subject |
| How-to guides | 4 / 6 | Describe a logical sequence, Seek flow |
| Tutorials | 3 / 6 | Maintain a narrative of the expected, Point out what the learner should notice, Encourage and permit repetition |
That drift is six months old and accumulated without anyone touching this file. It is the same failure as the broken symlinks, in slower motion.
Two ways out, either fine:
- Delete the paraphrase. Keep the frontmatter, the index, and the pointers. The symlinks then genuinely are the single source of truth, which is what the PR claims. Cuts
SKILL.mdto roughly 45 lines and removes the whole drift surface. - Generate it. Derive the per-type bullets from the
.rstkey-principle headings in CI, and fail the build when they diverge.
Option 1 is the smaller diff and matches the stated design.
🟠 Design: the rationale argues against the implementation
The commit message cites "the Vercel research pattern where passive context outperforms active retrieval." What's built is a 126-line passive index plus ~16,600 words behind pointers the agent must actively go and read — that is active retrieval. The design is defensible on its own terms (the corpus is too big to inline), but the cited rationale points the other way. Worth reconciling in the PR body.
🟠 The skill is not self-contained, so it can't be installed the usual way
The normal install is copying the skill directory into ~/.claude/skills/:
$ cp -r skills/diataxis ~/.claude/skills/
$ # 0 of 15 references resolve, 15 dangleRelative symlinks escaping three levels above the skill root mean it only works with the whole repo checked out and the skill invoked in place. That may well be the intent — but it should be stated, in the PR body or a short skills/README.md, because it's the first thing anyone will try. Two related notes: Git and zip/tarball export do preserve the symlinks (I checked, that part is fine), but Windows checkouts with core.symlinks=false write the target path as the file's literal contents.
🟡 Skill craft
Detail is inline; summarised here.
- Description (606 chars, loaded every turn): lines 5–6 are identity already stated in the body, and three branches are written twice. The leading word
Diataxis— the word people actually type — is 8th. Halves cleanly. - Context pointers: all nine read "read X for full principles". A pointer's wording, not its target, decides whether the agent reaches the file; with no triggering condition, reaching is a coin-flip. Give each one a condition.
- Workflow (lines 115–120) diverges from
how-to-use-diataxis.rst, which prescribes four steps, not six, and doesn't include compass classification in the cycle. No step carries a checkable completion criterion and "Repeat" has no exit. - Negation at line 122: "Do not plan a grand restructuring" names the banned behaviour and makes it more available. The source's own heading — Work one step at a time — is the positive form.
- Index accuracy:
theory.rst(176 words) andapplication.rst(255 words) are toctree landing pages, sold in the index as substantive content. - Unsourced phrasings in the at-a-glance table, on a skill whose first instruction is to prefer retrieval over pre-training. Details inline.
🟡 Repo fit
- No maintenance story. New top-level
skills/tree, no README, unmentioned in the repo README, no CI. Both blockers above would have been caught by one line in CI: fail if anyskills/*/references/*entry dangles. Worth adding in this PR — it's the difference between this staying correct and this being the same conversation in another six months. - Translations. The repo builds seven languages through
make gettextoversource/.skills/is outside that tree, so the hand-written English summary is invisible to the translation pipeline — a second, English-only statement of the framework that translators can't reach. Another point in favour of option 1 above.
Summary
Worth landing. To get there: retarget the symlinks to source/, drop complex-hierarchies, add the CI dangling-symlink check, and — the one I'd push hardest on — cut the paraphrase so the symlinks are actually the single source of truth the PR says they are.
| Write, review, classify, and restructure documentation using the Diataxis framework. | ||
| Diataxis defines four documentation types — tutorials, how-to guides, reference, explanation — | ||
| based on two axes: action vs. cognition, and acquisition vs. application. | ||
| Use when writing docs, reviewing docs for quality, classifying existing content into the four types, | ||
| restructuring documentation, deciding what kind of doc to write, or when asked about | ||
| "Diataxis", "documentation types", "tutorial vs how-to", "reference vs explanation", | ||
| "documentation structure", "documentation quality", or "documentation framework". |
There was a problem hiding this comment.
Description: cut roughly half. 606 chars / 77 words, and every one of them sits in the context window on every turn — a description earns harder pruning than the body.
Three issues:
- Identity that's already in the body. Lines 5–6 ("Diataxis defines four documentation types… based on two axes…") restate lines 46–57. A description's job is triggering, not defining.
- Branches written twice.
reviewing docs for quality≡"documentation quality";restructuring documentation≡"documentation structure";classifying existing content into the four types≡"documentation types". Synonyms renaming one branch are duplication — they don't widen the trigger surface, they just cost tokens. - Leading word buried.
Diataxisis the 8th word. It's the word users actually type and the one that should do the invocation work, so front-load it.
Suggested (~300 chars):
description: >
Diataxis documentation framework — classify, write, review, and restructure docs
as tutorials, how-to guides, reference, or explanation. Use when writing or
reviewing documentation, deciding which type to write, or when asked about
"Diataxis", "tutorial vs how-to", or "reference vs explanation".|
|
||
| # Diataxis Documentation Framework | ||
|
|
||
| IMPORTANT: Prefer retrieval-led reasoning over pre-training-led reasoning for any documentation tasks. Always consult the reference files below rather than relying on general knowledge. |
There was a problem hiding this comment.
This instruction is undercut by the ~100 lines that follow it. Lines 46–126 are a pre-training-led summary — hand-written, unsynced, and (see the four-types table below) containing phrasings that don't appear anywhere in the corpus.
If the paraphrase goes and the pointers stay, this line becomes true and can stay. If the paraphrase stays, this line tells the agent to distrust the file it's reading.
|
|
||
| ## Source of Truth | ||
|
|
||
| All reference files below are symlinked from the Diataxis repo and always reflect the latest content. Read them for authoritative guidance. |
There was a problem hiding this comment.
🔴 This is false the moment the PR merges.
main moved every .rst into source/ in c953482. The symlinks point at the repo root, so all 15 dangle after merge — and the merge is conflict-free, so nothing flags it:
$ git checkout -B mergetest origin/main && git merge ertembiyik/diataxis-skill
$ for f in skills/diataxis/references/*; do [ -e "$f" ] || echo "BROKEN $(basename $f)"; done
BROKEN application.rst
... 15 of 15They resolve on this branch's base, which is why the diff looks clean.
Also worth softening "always reflect the latest content" regardless: it's true of the .rst files and false of everything below line 22. That gap is what let this branch go stale unnoticed for six months.
| references/ | ||
| ├── Core | ||
| │ ├── start-here.rst — 5-min primer: the four types + two axes | ||
| │ ├── theory.rst — Full theoretical grounding |
There was a problem hiding this comment.
theory.rst is 176 words: an epigraph, three short paragraphs, and a toctree. It isn't "full theoretical grounding" — it's the landing page for the section that contains it. Same at line 40: application.rst is 255 words of intro plus a list of :doc: links.
An agent sent to either for grounding gets a table of contents, and the :doc: roles don't resolve as plain text outside Sphinx, so the links are dead ends.
The substance those two point at is already in your index — foundations.rst, map.rst, quality.rst, and the four type pages. Either drop the two landing pages or relabel them as section indexes.
| └── Applying Diataxis | ||
| ├── application.rst — Practical application guide | ||
| ├── how-to-use-diataxis.rst — Iterative workflow: assess → decide → act → repeat | ||
| ├── complex-hierarchies.rst — Handling large/complex doc structures |
There was a problem hiding this comment.
🔴 This page no longer exists. Removed deliberately in abfae1f — "Tidied up some files; removed complex hierarchies page" — and it's neither at the root nor in source/ on main.
Unlike the other 14, retargeting to source/ won't fix this one. Remove this line, the pointer at line 125, and references/complex-hierarchies.rst.
| 1. Pick any piece of documentation | ||
| 2. Use the compass to classify it (action/cognition x acquisition/application) | ||
| 3. Assess: does it serve the identified user need well? | ||
| 4. Decide one single improvement action | ||
| 5. Do it and ship it | ||
| 6. Repeat |
There was a problem hiding this comment.
This diverges from how-to-use-diataxis.rst, which prescribes four steps, not six:
Choose something → Assess it → Decide what to do → Do it → back to the beginning
Step 2 here ("Use the compass to classify it") isn't part of that cycle. The compass is presented in compass.rst as a course-correction tool for when you're troubled by doubt — "The compass forces you to stop and reconsider" — not as a mandatory classification pass on every iteration. Making it step 2 changes the method.
Step 3 also flattens the four questions the source actually asks:
What user need is represented by this? How well does it serve that need? What can be added, moved, removed or changed to serve that need better? Do its language and logic meet the requirements of this mode of documentation?
The bolded one is what makes step 4 answerable; without it, "decide one single improvement action" has nothing to draw on.
Two craft points on top of the accuracy one: no step carries a checkable completion criterion, which is what stops an agent declaring a step done and sliding to the next; and "Repeat" has no exit condition, so the loop never terminates. Since this section is the skill's only sequence of steps, it's where a criterion buys the most — e.g. step 4 as "name exactly one action, and the user need it serves", which is both checkable and faithful to the source.
| 5. Do it and ship it | ||
| 6. Repeat | ||
|
|
||
| Do not plan a grand restructuring. Work iteratively, one improvement at a time. Documentation is never finished but always complete. |
There was a problem hiding this comment.
Steering by prohibition backfires — naming "grand restructuring" drags it into context and makes it more available, not less. The negation is a weak modifier over a strongly-activated concept.
The source already gives you the positive form as a heading: Work one step at a time. And how-to-use-diataxis.rst supplies the operative detail:
every step in the right direction is worth publishing immediately
Suggested:
Work one improvement at a time, and publish each before starting the next.
Documentation is never finished but always complete.(The .rst prose uses negation freely — "Don't do that. It's horrible." — but that's prose written to persuade a human. This is a prompt steering a model, and the two behave differently.)
The second half of the line is a faithful quote from Complete, not finished — no change needed there.
| Do not plan a grand restructuring. Work iteratively, one improvement at a time. Documentation is never finished but always complete. | ||
|
|
||
| For full workflow guidance, read `references/how-to-use-diataxis.rst`. | ||
| For complex documentation structures, read `references/complex-hierarchies.rst`. |
There was a problem hiding this comment.
🔴 Second reference to the deleted complex-hierarchies page — see line 42. Remove.
| @@ -0,0 +1 @@ | |||
| ../../../application.rst No newline at end of file | |||
There was a problem hiding this comment.
🔴 Wrong target — applies to 14 of the 15 symlinks in this directory.
../../../application.rst resolves to the repo root, but main moved the framework pages into source/ in c953482. Needs:
../../../source/application.rst
Same fix for compass, explanation, foundations, how-to-guides, how-to-use-diataxis, map, quality, reference-explanation, reference, start-here, theory, tutorials-how-to, and tutorials. (complex-hierarchies is a separate problem — the page was deleted.)
Because they resolve against this branch's stale base and the merge is conflict-free, nothing catches this. Worth adding a CI step in this PR so it can't recur:
- name: skill reference symlinks resolve
run: |
for f in skills/*/references/*; do
test -e "$f" || { echo "dangling: $f -> $(readlink "$f")"; exit 1; }
done| @@ -0,0 +1 @@ | |||
| ../../../complex-hierarchies.rst No newline at end of file | |||
There was a problem hiding this comment.
🔴 Delete this symlink — the target no longer exists anywhere.
complex-hierarchies.rst was removed on purpose in abfae1f ("Tidied up some files; removed complex hierarchies page"). It's absent from both the repo root and source/ on main, so unlike its 14 siblings there's no path to retarget it to.
Also remove the index entry at SKILL.md:42 and the pointer at SKILL.md:125.
AI coding agents increasingly write and maintain documentation, but they default to unstructured output that mixes tutorials, reference, and explanation. This PR adds a skill definition that teaches agents to apply Diataxis principles when writing docs.
The skill uses a compressed index (SKILL.md) with the core framework: the 2x2 matrix, compass, quick rules per type, common mistakes, plus symlinked references back to the repo’s .rst files. Content changes to existing files are reflected automatically via symlinks. Adding or removing .rst files requires updating the symlinks and index accordingly.
What’s added:
No existing files are modified.