docs: add plan for docs-driven skill generation#35
Conversation
Captures the design for auto-generating Harper skill rules from the documentation repo. Covers concepts (rule/skill/manifest/modes), user stories for automatic and manual workflows, a phased migration starting from today's hand-authored rules, the validation layer, and a documented (but out-of-scope) pointer-strategy fallback. Phase 3 commits to a flat-markdown export from HarperFast/documentation as the source of truth for MDX content, rather than parsing MDX statically from the skills side. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
kriszyp
left a comment
There was a problem hiding this comment.
This is fantastic, this is an excellent approach, thank you for putting this together!
I left some comments to consider as you build this, but I certainly think you can move forward with.
| 2. Skills `generate.yaml` runs: reads `rules.manifest.yaml`, fetches docs at that SHA, detects that the input hash for `querying-rest-apis` changed. | ||
| 3. The generator calls Claude under the rule template, produces a new `rules/querying-rest-apis.md`, refreshes `AGENTS.md`, and updates the lock file. | ||
| 4. Workflow opens a PR: `docs: regenerate rules from documentation@a1b2c3d`. The PR body lists which rules changed and links the upstream docs commit. | ||
| 5. A maintainer reviews the diff — agent-facing prose still reads cleanly, the new edge case is mentioned. Merge. |
There was a problem hiding this comment.
This is the right approach for the beginning, but the goal would be to hopefully eliminate this, based on your guiding principle, right?
Anything that re-renders prose when docs change is automated
There was a problem hiding this comment.
You mean like AI reviewed (or just no review if we trust it enough?)
| ``` | ||
| 2. Runs `npm run generate` locally. The script produces `rules/streaming-uploads.md`, rebuilds `AGENTS.md`, updates the lock file. | ||
| 3. Opens a PR titled `feat: add streaming-uploads rule`. PR includes the manifest change _and_ the generated body so reviewers can see what the agent will read. | ||
| 4. After review and merge, semantic-release publishes a minor version (because `feat:`). |
There was a problem hiding this comment.
And likewise once we gain confidence in updates, hopefully additions would be fully automated (no human) as well per the guiding principle.
|
|
||
| Work in `HarperFast/documentation`: | ||
|
|
||
| - Add a Docusaurus plugin (or remark/rehype pass in the existing build pipeline) that, for each MDX page, walks the AST and emits a flat-markdown rendering at `build/flat/<source-path>.md`. Component handling: |
There was a problem hiding this comment.
Just to clarify, the analysis here is that our current MDX files have too much noise from JSX components/tags, and that stripping it down to cleaner MD files? And that simply offering agent guidance for the renderer ("please ignore JSX components") is likely to be less efficient (for agents/LLMs) than reading docs with AST cleansing?
I don't know if this influences the technique, but I believe our source files are much closer to what we want agents to read than our generated HTML. A technique than can directly translate source to "flat" markdown without dealing with the HTML seems ideal.
I think this also solves the long-standing question of providing agent-optimized Markdown for public AI crawlers, hopefully in an efficient manner.
There was a problem hiding this comment.
Yes and I've started using MDX for reusing certain bits of info. See this example: https://github.com/HarperFast/documentation/blob/547bbfc679fd772f591c88d032be22ab5da67133/learn/getting-started/create-your-first-application.mdx?plain=1#L30
We don't do this in the reference materials yet, but we likely will.
While the <Tab> MDX element isn't much of an issue, the content ones in https://github.com/HarperFast/documentation/tree/main/src/components/learn do need to be like rendered for it to be properly included.
|
|
||
| ### Phase 4 — Awkward and MDX-sourced rules + observability | ||
|
|
||
| With flat-markdown available, take on the remaining rules — including those that source from `/learn` MDX content — and stand up the observability layer that catches automation failures. |
There was a problem hiding this comment.
We are also going to consider regenerating existing skills content from the documentation source, right? I believe we should at least try that. Perhaps there are some existing skills (that would be considered "synthesized") that might be deemed high quality, but in general we want to actually replace our existing content in skills with the generated content (otherwise they are stuck in synthesized state hindering more automated regeneration).
There was a problem hiding this comment.
Yes - this is part of the plan somewhere. We start with everything synthesized, and then we migrate slowly once things start working.
|
|
||
| These should be resolved before Phase 1 begins: | ||
|
|
||
| - Anthropic API key provisioning for the skills repo's Actions runner — who owns it. |
There was a problem hiding this comment.
We have already gone down the path of acquiring an Anthropic API key for PR reviews, so hopefully that can be followed for this. I believe the API key generation is easy, just making sure we have the secret setup.
It seems like it is also worth considering the use of Gemini, and maybe Claude can build an option to use either. Again, we have tons of credits, so if economics start to play into this, that could be helpful (although I suspect this should be relatively inexpensive).
|
|
||
| This section documents a secondary strategy we may pivot to in the future. **It is not part of the implementation scope of this plan** — we are not building for it, designing flags around it, or constraining the generation work to accommodate it. It exists in this document so the team has a known fallback if the generation approach disappoints. | ||
|
|
||
| If after Phase 2 or 3 the team decides generation isn't pulling its weight — auto-PRs are too noisy, prompt tuning never converges, or reviewer fatigue sets in — we pivot to **pointer mode**: embed the docs source directly into the skills repo (git submodule, subtree, or sparse checkout of `HarperFast/documentation`), and have each rule become a thin pointer file (frontmatter + "when to use" + a link into the embedded docs). |
There was a problem hiding this comment.
Is the hypothesis that generated skills/rules should be more succinct and conducive to LLMs remaining attentive to reading them, rather than LLMs starting to "skim" long embedded/linked documentation? Or is it partly the cleansing of JSX that benefits the skill? A "release-asset" (of cleansed flat markdown) as the source of skills could address that. Perhaps we might also want to consider more flexibility/hybrid-ness and offer "synthesized", "generated", and "flat" (or "direct") with the third option indicating that the source (flat) markdown file should be imported as-is without any LLM summarization.
I will say that I do believe the hypothesis that LLM summarization is likely to be better. But these might be good options to retain and compare.
There was a problem hiding this comment.
I love this idea. Really this is just based on the brief conversation in Slack. @dawsontoth seems to prefer we generate rather than use direct. I don't have any reason to back one way or another. I specifically included the direct method as a backup incase we want to go that way. I'll have the plan incorporate it as a third option instead so we can have the best of both worlds immediately.
There was a problem hiding this comment.
The particular word I used was "transform", not generate.
There was a problem hiding this comment.
If its not direct, then what would be the difference between generate and transform?
There was a problem hiding this comment.
These are three modes and the (expanded) alternate names to consider?
- synthesized/manual/human-crafted - Source of truth is in /skills
- generated/transformed - Source of truth in docs (llms.txt plugin output), but summarized by AI into skills.
- direct/flat/linked - Source of truth in docs (llms.txt plugin output), directly copied into skills
I know this is merged, and I am flexible on naming.
There was a problem hiding this comment.
yeah this is just tooling so we can change it easily. I like what exists, but open to changing if others prefer some of the alternatives
Significant revisions to the docs-driven skills plan based on review discussion: - Added formal Manifest Schema and Rule Frontmatter Schema sections with field reference tables. Manifest is the declarative source of truth; rule frontmatter (via `metadata` block) snapshots what was last generated. - Added Generation Lifecycle section detailing the step-by-step regen flow: manifest lint, source resolution, hash skip-check, body production, validation, PR open. - Introduced `direct` mode as a third generation mode alongside `generate` and `synthesized`. Verbatim flat-markdown import with no LLM call, for cases where docs prose is already agent-friendly. - Restructured Validation Layer into four named layers (skill schema, manifest lint, manifest↔frontmatter reconciliation, per-mode body checks) with explicit applicability matrix. - Removed the Alternative: Pointer Strategy section. `direct` mode subsumes its purpose without operational complexity. - Phase 3 now commits to adopting `@signalwire/docusaurus-plugin-llms-txt` rather than building a custom MDX→MD pipeline. Multi-instance docs plugin support and rendered-HTML processing make it the right fit. - Reordered phases so plugin adoption (Phase 1) comes before single-rule end-to-end (Phase 2), since all source resolution depends on the plugin's output. - Offline-first data flow: skills workflow checks out and builds the docs repo locally, reads from build/ output. No network calls to fetch docs content. Local contributors point at a sibling docs checkout via --docs-path or DOCS_PATH. - Developer documentation now targets the existing .github/CONTRIBUTING.MD rather than a new doc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Update for previously-approving reviewers — second commit ( This commit substantially revises the plan based on follow-up design discussion. The high-level goal and guiding principle are unchanged; the implementation strategy and structure are meaningfully different. Worth re-reviewing. TL;DR: The plan grew formal schema sections, added a third generation mode ( What's new
What changed in approach
What was removed
What's unchanged
|
Pure formatting pass — oxfmt normalized markdown table alignment in the docs-driven-skills plan. No content changes. Surfaced when the Phase 0 work ran the full validate pipeline (which includes the oxfmt --check step). Landing this on the plan branch directly so stacked phase branches inherit clean baseline state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
🎉 This PR is included in version 1.4.8 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
The validate pipeline had a structural flaw that silently masked
formatting drift in committed source files:
Before:
validate = build && oxfmt --check && validators
build = node scripts/build.mjs (which ran `npm run format` at the end)
Effect: every CI run invoked the formatter against source files
before checking, so the --check stage always passed against the
just-reformatted tree. Committed files with format drift would
silently get reformatted in the CI working copy and the check
would report green. The drift accumulated until someone noticed
in a `git diff` locally.
This was discovered when phase-0 (#36) rebased onto main after the
plan PR (#35) merged: `programmatic-table-requests.md` from the
intervening PR #34 had oxfmt-incompliant markdown tables that were
never caught, and `npm run build` kept reformatting it locally on
every run.
Structural fix:
- scripts/build.mjs: remove the trailing `npm run format` call. dist/
is in .gitignore, so the formatter was actually skipping it (oxfmt
honors gitignore); the only thing the call did in practice was the
unintended source-file side effect described above. dist/ output is
machine-generated and consumed by npm consumers; it doesn't need to
match the formatter.
- package.json: add `format:check` script ("oxfmt --check"), and
reorder `validate` to run `format:check` *first*, before build.
The gate now sees the committed file content, not a freshly
reformatted version of it.
Before: validate = build && oxfmt --check && validate-skills && validate-generated
After: validate = format:check && build && validate-skills && validate-generated
- .github/CONTRIBUTING.MD: document the npm scripts and the
format-check-first ordering so contributors know to run
`npm run format` before committing.
Also includes the one file that had drifted under the old behavior:
harper-best-practices/rules/programmatic-table-requests.md — pure
formatter change (markdown table column alignment), no content change.
Verified end-to-end:
- `npm run validate` exits 0 on the current tree.
- Introducing a deliberate format violation (trailing whitespace on a
heading) causes `npm run validate` to exit 1 with a clear error,
blocking the rest of the pipeline.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Adds
docs/plans/docs-driven-skills.md— the design for auto-generating Harper skill rules from the documentation repo so they stop drifting from the source of truth.This PR is the plan document only. No implementation, no behavior change. Merging it commits the team to the approach; the work itself is broken into phases inside the doc.
Background
Today the 20 rule files under
harper-best-practices/rules/are maintained by hand — sometimes with agent assistance, but a human still has to notice a docs change, prompt the rewrite, and open a PR. Drift example: therest: trueconfig prereq existed inreference/rest/overview.mdlong before the skill was patched to mention it.What the plan covers
generate(auto-produced from docs) andsynthesized(hand-authored, for content with no canonical docs source).synthesized(no behavior change today)vector-indexing).md-only rulesHarperFast/documentation(Docusaurus plugin that flattens MDX components to plain markdown alongside the HTML build).github/CONTRIBUTING.MDto explain repo anatomy, the generation pipeline, common contributor tasks, and what's automated vs. manual.validate-generated.mjs(manifest completeness, provenance comments, must-cover assertions, MDX leakage, cross-link integrity, AGENTS.md round-trip).Reviewer notes
.mdfiles..github/CONTRIBUTING.MDis the long-lived companion.🤖 Generated with Claude Code