contributing
Contributing — validation and QA
src/data/devsnips/docs/contributing/validation.md
CI (.github/workflows/ci.yml) runs the always-on gates on every push and pull request. The browser QA layers are still manual, so a pull request must state which commands were run and what they printed.
The command matrix
| Scope | Command | Passing condition |
|---|---|---|
| Always (minimum bar) | python scripts/tooling/validators/validate.py |
Prints VALIDATION PASSED - architecture, metadata, and index all consistent., exit 0 |
| File-set changes | python scripts/tooling/validators/deep_check.py |
No failures reported (also covered by validate.py) |
| Any content added/removed/renamed | python scripts/tooling/indexing/rebuild_index.py |
Prints Wrote snippets-index.json — not NOT writing index due to validation problems |
| Index drift check (what CI runs) | python scripts/tooling/indexing/rebuild_index.py --check |
Prints Index is up to date (--check).; does not write |
| After index regeneration | python scripts/tooling/indexing/validate_indexes.py |
Exit 0 (indexes match the repository) |
| Markdown edits / file moves | python scripts/tooling/validators/check_md_links.py |
OK: all relative Markdown links resolve |
| Agent-facing docs edits | python scripts/tooling/validators/check_agent_doc_paths.py |
OK: all path references in scanned agent docs resolve |
| Validator/indexer changes | python -m unittest discover -s scripts/tooling/tests -t scripts/tooling/tests |
All tests pass |
| Vanilla component changes | python scripts/qa/resources/qa_vanilla.py --only-failures |
failing required checks: 0 |
| CLI changes | cd cli && npm test |
All suites pass |
| Visual/interactive changes | Relevant Playwright harness under scripts/qa/resources/ |
No console errors, no horizontal overflow at mobile width |
Python scripts resolve the repository root from their own file location, so the working directory does not matter. Playwright is not declared in any manifest — install it in your environment before running browser harnesses.
The full validation layers
Every verification layer, what it checks, and where it lives:
| Layer | Enforcing file | What it covers |
|---|---|---|
| Architecture | validate.py (check_architecture) |
Allowed/forbidden dirs per tech |
| Metadata validity | validate.py (check_metadata_validity) |
JSON parse, type value + bucket match, required files per tech |
| Index ↔ disk consistency | validate.py (check_index_vs_disk) |
Two-way coverage, duplicate paths, stale paths |
Template AGENTS.md |
validate.py (check_template_agents) + rebuild_index.py (validate) |
Existence + non-empty |
| Per-tech file sets | deep_check.py (merged into validate.py) |
Required/optional files per tech + type |
| Markdown links | check_md_links.py |
Relative links in every *.md resolve, and file.md#fragment anchors match a real heading slug |
| Agent doc paths | check_agent_doc_paths.py |
Path-like backticked refs in agent-facing docs (agents/resources/*.md, library/**/AGENTS.md, MCP) resolve |
| Python tooling tests | scripts/tooling/tests/ (unittest) |
Unit tests for the validators and indexer ordering/leaf detection |
| Vanilla quality bar | qa_vanilla.py (invoked by validate.py) |
a11y/animation/dark-mode per Vanilla component |
| Index regeneration safety | rebuild_index.py (validate) |
Refuses to write on mismatch |
| CLI behavior | cli/test/*.test.js |
Path/file/context behaviors |
| Browser QA (React) | scripts/qa/resources/_qa_react_*.py |
Runtime, layout, theme, a11y per family |
| Browser QA (templates) | scripts/qa/resources/_qa_template.py |
Overflow, console errors, interactions |
Structure checks
check_architecture() (in validate.py):
- each of
library/Vanilla,library/Tailwind,library/Reactmay contain onlyComponents,Sections,Templates(ALLOWED_DIRS); Utilities,Resources,Snippets,Pages,Toolsare forbidden under every tech.
The is_leaf() predicate (in validate.py, deep_check.py, and rebuild_index.py) defines what counts as a resource — see Resource model for the deliberate difference between the indexer's predicate and the validators' predicate.
Resource (file-set) checks
check_metadata_validity() in validate.py:
- Tailwind
Components/andSections/leaves must havecode.htmlandpreview.html; - Tailwind
Components/leaves must additionally have a non-emptyREADME.md; - React
Components/andSections/leaves must havecode.tsxandpreview.html; - invalid JSON in any
metadata.jsonis a failure.
deep_check.py is a standalone, stricter file-set checker whose collect() is merged into validate.py's main() (so a validate.py pass includes it; it is still runnable on its own for a focused report). It enforces per-tech file sets and is stricter about README.md and code.jsx in places where validate.py is not: React Components need code.tsx, preview.html, README.md; React Sections need code.tsx, preview.html; a missing React code.jsx is a warning only; any Section with an empty README.md is a failure. check_template_files() requires a non-empty AGENTS.md for every template, plus preview.html (Tailwind/React) or preview.html or non-empty pages/ (Vanilla), plus README.md (Vanilla).
Metadata checks
typemust be present and one ofcomponent/section/template;typemust match the folder bucket via explicit cross-checks (type=component outside Components/, etc.);- Duplicate IDs are collected per technology/type/subcategory. A collision within one technology, content type, and subcategory fails (two leaves in the same collection cannot share an id). Ids echoed across technologies (Tailwind and React
team-minimal, etc.) are expected id-parity reported as a NOTE, because the registry keys on the tech-first path.
What qa_vanilla.py checks
Per Vanilla component .html under both the Components and Sections trees: accessibility and interaction semantics (keyboard operability, focus visibility, ARIA on custom widgets), reduced-motion guards on animations. Dark-mode support is computed but not yet an emitted pass/fail check. Flags: --only-failures, --json, and advisory --tokens (--ds-* adoption vs raw hex; always exits 0). It runs inside validate.py, so a required-check failure fails overall validation.
Browser QA harnesses
Per-family Playwright scripts under scripts/qa/resources/:
_qa_react_*.py— React component/section families. Serve the repo with document rootlibrary/on:8765(python3 -m http.server 8765 --directory library), then invoke per slug:python3 scripts/qa/resources/_qa_react_button.py split-button_qa_template.py— generic template harness (works for Tailwind/Vanilla templates too); takes apreview.htmlpath and loads it overfile://(no server needed).
Harnesses exist for most — not all — families. Check the directory before assuming one exists.
Common failure classes and fixes
| Message | Meaning | Fix |
|---|---|---|
VALIDATION FAILED - N problem(s): |
Any of the layers above | Read the listed paths; fix the content, not the validator |
indexed variant missing on disk / on-disk leaf not indexed |
Leaf added/renamed without regenerating | Run rebuild_index.py |
type=section outside Sections/ |
Resource moved without updating metadata type |
Update that leaf's metadata.json |
Tailwind component missing README.md |
Missing or empty README | Add/complete it |
Architecture: unexpected dir |
New top-level dir under a tech tree | Remove it or justify a schema change |
Template … is missing AGENTS.md |
New template without agent instructions | Add a non-empty one |
FAIL <path> <check> (reduced-motion/focus-visible/…) |
Vanilla quality bar | Fix the component |
Duplicate id within one technology/type |
Two leaves in the same tech/type/subcategory share an id |
Give one a unique id/slug; cross-tech echoes are only a NOTE |
NOT writing index due to validation problems |
Disk and registry disagree | Fix the listed problems, re-run — this is a failure, not a no-op |
npm test failure in cli/ |
CLI behavior regressed | Read the failing suite (cli/test/*.test.js) |
The fix procedure
1. Run the failing command and read the raw error text.
2. Locate the producing code:
validate.py messages → scripts/tooling/validators/validate.py
"NOT writing index …" → scripts/tooling/indexing/rebuild_index.py
CLI error text → cli/src/utils/errors.js
quality-bar FAIL lines → scripts/qa/resources/qa_vanilla.py
3. Inspect the offending artifact.
4. Fix the cause — never silence a validator to make a change pass.
5. Re-run the full command matrix for your scope before reporting success.If a failure is pre-existing and unrelated to your change, report it in the PR instead of fixing unrelated content.
Standard verification sequence after a change
1. rebuild_index.py (only if leaves were added/removed/renamed or metadata changed)
2. validate.py (must print VALIDATION PASSED, exit 0 — includes the file-set layer)
3. deep_check.py (optional focused file-set report)
4. scripts/tooling/tests (validator/indexer changes)
5. qa_vanilla.py (Vanilla changes)
6. cd cli; npm test (cli/ changes)
7. relevant browser harness (visual/interactive changes)
8. Report exact commands + observed results — not a general claim of successGo deeper
This page is the human-facing QA reference. The implementation-anchored reference (the exact check functions, the deliberate duplicate-ID policy, and the per-harness invocation contracts) is maintained for agents in agents/resources/qa.md.