T-LHO1-lint-mermaid-blocks-in-skill-docs
Status: closed/superseded · Impact: medium · Complexity: medium
Auto-generated from a /sdlc:task-work post-mortem. Review and
promote to ready before picking up.
The per-skill docs under docs/skills/<slug>.md each carry a Mermaid
flowchart block, but there is no automated check that those blocks
parse correctly. Today the only signal is “GitHub renders it” or “my
eyes say it looks right.” Closing this gap turns AC-2 of
T-H9Q4-document-every-skill-with-mermaid-flowchart (currently
deferred-user) into an automated check, and prevents silent breakage
when SKILL.md edits drive doc rewrites.
docs/skills/<slug>.md contains a fenced ```mermaid block per
file (15 files at task creation time). No tooling validates them.
/sdlc:project-cleanup, the planned /update-skill-doc skill, and any
future regen path could each emit malformed Mermaid and nobody would
notice until a reader hit the file in a renderer.
Proposed
Section titled “Proposed”A lightweight lint command parses every docs/skills/*.md, extracts the
mermaid fenced block(s), and runs each through a real Mermaid parser
(mmdc). Exit code 0 if all blocks parse; non-zero with a per-file report
otherwise. The command is callable locally and is suitable for wiring into
CI later.
Two implementation surfaces:
plugin/scripts/lint_skill_docs.sh— a bash script (minimal requirements:bash+awk/sed+mmdc) that extracts mermaid blocks and pipes each tommdc --input -. Preferred over Python here because the lint job is a thin shell pipeline; staying in bash means the lint itself doesn’t add Python startup overhead beyond what’s already needed for the rest of the plugin. (Python is still a hard plugin dependency for the PEP-723 scripts; this script just doesn’t add a new python entry point when bash suffices.)- A deterministic dependency-check script (e.g.
plugin/scripts/check_dependencies.shor adependenciessubcommand) that/sdlc:setupinvokes. It verifies thatmmdc,python3(>= 3.11 for PEP-723),uv, and any other hard requirements are on PATH and reports missing tools with concrete install instructions. The lint command’s documented prerequisite chain becomes “run/sdlc:setupfirst; it will tell you what’s missing.”
The setup hook makes the lint usable from a clean checkout — without it,
running lint_skill_docs.sh against a project that lacks mmdc fails with
a confusing parser error rather than a clear “install mermaid-cli” message.
Approach
Section titled “Approach”- Add
plugin/scripts/lint_skill_docs.sh. Bash script:- For each
docs/skills/*.md, useawk(orsed -n) to extract the content between```mermaidand```fences. - Pipe each block to
mmdc --input -(ormmdc -i /dev/stdin -o /dev/null --quiet) and capture exit code + stderr. - Aggregate results; exit 0 only if every block parses.
- Print a per-file report on failure (file path, block index, parser error excerpt).
- For each
- Add a deterministic dependency-check script that
/sdlc:setupcalls. Suggested shape:plugin/scripts/check_dependencies.sh— a single bash script that runscommand -v <tool>for each required tool and reports the install command for any that are missing (mmdc→npm install -g @mermaid-js/mermaid-cli;uv→curl -LsSf https://astral.sh/uv/install.sh | sh; etc.). Bash again, so the check itself has minimal prerequisites. - Wire
/sdlc:setupto call the dependency check after creating thedocs/planning/directories. Make it advisory rather than blocking (setup still succeeds; the dependency-check exits non-zero with the list of missing tools as a warning). - Add fixture-based tests under
plugin/scripts/tests/covering one valid and one deliberately-broken doc for the lint, plus a presence / absence smoke test for the dependency checker. - Document the commands in
plugin/skills/README.md(“Validation”) and inplugin/skills/setup/SKILL.md(mention the dependency-check side-effect).
Files to touch
Section titled “Files to touch”plugin/scripts/lint_skill_docs.sh(new) — bash lint pipeline.plugin/scripts/check_dependencies.sh(new) — deterministic dependency-existence check (bash, minimal requirements).plugin/skills/setup/SKILL.md— wire the dependency check into the skill flow (advisory, not blocking).plugin/scripts/setup_planning.py— callcheck_dependencies.shas the final step (or have the SKILL.md drive it; pick whichever keeps the dependency-check reusable from outside/sdlc:setup).plugin/skills/README.md— add a “Validation” subsection pointing at the lint command.plugin/scripts/tests/test_lint_skill_docs.sh(new) — fixtures + test cases (bash test or PEP-723 Python runner that shells out).
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
plugin/scripts/lint_skill_docs.shexists and exits 0 against every currentdocs/skills/*.md. - AC-2: A deliberately-broken Mermaid block (e.g. missing
-->arrow target) makes the script exit non-zero with a file-and-block-index pointer in the report. - AC-3:
plugin/scripts/check_dependencies.shexists and reports the presence/absence of each required external tool (mmdc,uv,python3, plus any others the plugin needs) with concrete install instructions for missing ones. - AC-4:
/sdlc:setupinvokes the dependency-check script and surfaces any missing tools to the user (advisory — setup completes either way). - AC-5: The lint command is referenced from
plugin/skills/README.mdas the canonical way to verify a per-skill doc; the dependency-check is referenced fromplugin/skills/setup/SKILL.md.
Out of scope
Section titled “Out of scope”- Wiring the lint script into CI — that’s a follow-up once the parser toolchain dependency is settled.
- Linting Mermaid blocks outside
docs/skills/(e.g. arbitrary docs). - Auto-formatting Mermaid blocks.
- Auto-installing missing dependencies — the dependency check is informational; the user installs.
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”Spawned by /sdlc:task-work post-mortem of T-H9Q4-document-every-skill-with-mermaid-flowchart on 2026-05-19. AC-2 of that task was deferred to the reviewer because no automated Mermaid validator was available; this task closes that gap.