$npx -y skills add opendatahub-io/ai-helpers --skill doc-validateUse when you need to validate AsciiDoc documentation for technical accuracy using Extract-Identify-Validate pattern. Runs Vale, asciidoctor, lychee, YAML syntax checks, and LLM-powered cross-reference validation. Produces workspace/validation-findings.json.
| 1 | # doc-validate |
| 2 | |
| 3 | Validate AsciiDoc documentation files for technical accuracy, style compliance, and structural correctness. |
| 4 | |
| 5 | ## Parse arguments |
| 6 | |
| 7 | `$ARGUMENTS` contains: |
| 8 | 1. **Target**: file path, directory, or glob pattern for AsciiDoc files to validate |
| 9 | 2. **--context** (optional): path to context package for cross-reference validation (defaults to `workspace/context-package.json`) |
| 10 | |
| 11 | ## Step 1: Discover files |
| 12 | |
| 13 | Resolve the target argument to a list of `.adoc` files: |
| 14 | - If a single file: validate that file |
| 15 | - If a directory: glob for `**/*.adoc` |
| 16 | - If a glob pattern: expand it |
| 17 | |
| 18 | ## Step 2: Run deterministic validators |
| 19 | |
| 20 | Execute the validation script on all discovered files: |
| 21 | |
| 22 | ```bash |
| 23 | python3 "${CLAUDE_SKILL_DIR}/scripts/validate-artifacts.py" "${file1}" "${file2}" ... |
| 24 | ``` |
| 25 | |
| 26 | This runs: |
| 27 | - **Vale**: prose style compliance |
| 28 | - **Asciidoctor**: compilation check (can the file be built?) |
| 29 | - **Lychee**: link checking (are URLs valid?) |
| 30 | - **YAML syntax**: validate embedded YAML code blocks |
| 31 | |
| 32 | Collect all findings from the script output. |
| 33 | |
| 34 | ## Step 3: Extract embedded artifacts |
| 35 | |
| 36 | For each AsciiDoc file, extract embedded technical artifacts: |
| 37 | |
| 38 | 1. **YAML blocks**: Content within `[source,yaml]` delimiters |
| 39 | 2. **CLI commands**: Content within `[source,bash]` or `[source,terminal]` delimiters |
| 40 | 3. **Configuration references**: Attribute references like `{attribute-name}` |
| 41 | 4. **API paths**: URLs or paths in the format `/api/v1/...` |
| 42 | 5. **CRD references**: Kubernetes resource kinds and API versions |
| 43 | |
| 44 | ## Step 4: Cross-reference validation (LLM) |
| 45 | |
| 46 | If a context package is available, use LLM judgment to cross-reference extracted artifacts against the gathered context: |
| 47 | |
| 48 | For each extracted artifact: |
| 49 | - **YAML blocks**: Compare against CRD schemas and config examples in context |
| 50 | - **CLI commands**: Verify flags and options against --help output or source code in context |
| 51 | - **API paths**: Check against API specs or route definitions in context |
| 52 | - **CRD references**: Verify kind names, API versions, and field names against type definitions |
| 53 | |
| 54 | Ask the LLM: |
| 55 | - Does this artifact match the authoritative source in the context? |
| 56 | - Are there incorrect field names, wrong API versions, or invalid options? |
| 57 | - Is the example complete and would it work as shown? |
| 58 | |
| 59 | ## Step 5: Structural validation |
| 60 | |
| 61 | Check AsciiDoc structure requirements: |
| 62 | |
| 63 | Source the AsciiDoc conventions helper (which internally sources `scripts/load-env.sh` for credentials and uses `scripts/parse-product-config.py` to resolve module prefixes): |
| 64 | |
| 65 | ```bash |
| 66 | source "${CLAUDE_SKILL_DIR}/scripts/asciidoc-conventions.sh" |
| 67 | for file in <files>; do |
| 68 | adoc_validate_structure "$file" |
| 69 | mod_type="$(adoc_module_type "$file")" |
| 70 | if [[ "$mod_type" == "unknown" ]]; then |
| 71 | # record structural finding: filename prefix does not map to a known module type |
| 72 | : |
| 73 | fi |
| 74 | done |
| 75 | ``` |
| 76 | |
| 77 | Verify: |
| 78 | - Module ID present (`[id="..."]`) |
| 79 | - Content type attribute set (`:_mod-docs-content-type:`) |
| 80 | - Level-1 heading present |
| 81 | - Module type matches filename prefix (enforced via `adoc_module_type` check) |
| 82 | |
| 83 | ## Step 6: Compile findings |
| 84 | |
| 85 | Merge all findings from Steps 2-5, deduplicating and normalizing: |
| 86 | |
| 87 | ```json |
| 88 | { |
| 89 | "validated_at": "2026-04-14T10:40:00Z", |
| 90 | "files_validated": 5, |
| 91 | "findings": [ |
| 92 | { |
| 93 | "file": "modules/serving/pages/con_model-serving.adoc", |
| 94 | "line": 42, |
| 95 | "severity": "high|medium|low", |
| 96 | "category": "vale|asciidoctor|lychee|yaml_syntax|cross_reference|structure", |
| 97 | "tool": "vale|asciidoctor|lychee|yaml_syntax|llm|structural", |
| 98 | "rule": "RedHat.Spelling", |
| 99 | "message": "Description of the issue", |
| 100 | "suggestion": "How to fix it" |
| 101 | } |
| 102 | ], |
| 103 | "summary": { |
| 104 | "high": 0, |
| 105 | "medium": 3, |
| 106 | "low": 5, |
| 107 | "total": 8, |
| 108 | "tools_run": ["vale", "asciidoctor", "yaml_syntax"], |
| 109 | "tools_skipped": ["lychee"] |
| 110 | } |
| 111 | } |
| 112 | ``` |
| 113 | |
| 114 | ## Step 7: Write findings |
| 115 | |
| 116 | Write `workspace/validation-findings.json` with the compiled results. |
| 117 | |
| 118 | ## Output |
| 119 | |
| 120 | Primary: `workspace/validation-findings.json` |
| 121 | Report to caller: total findings by severity, which tools ran vs skipped. |
| 122 | |
| 123 | ## Gotchas |
| 124 | |
| 125 | - Vale, asciidoctor, and lychee are optional dependencies; if any are missing, that validator is silently skipped. Check `tools_skipped` in the output to confirm which ran. |
| 126 | - Cross-reference validation (Step 4) requires a context package; without it, only deterministic checks run and the results may miss technical inaccuracies. |
| 127 | - Link checking via lychee can be slow on files with many external URLs and may produce false positives for rate-limited sites |