Verify documentation references against the current codebase, propose updates for diff-affected docs, detect i18n translation drift, and lint translated docs for CJK style issues. Use to check if docs still match reality (broken file paths, CLI commands, config keys, env vars, scripts), to surface docs that may need updating after code changes, or to find stale or style-broken translations.
77
96%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Detect broken references in repo markdown — default glob **/*.md (verify mode), propose LLM-generated patch proposals for docs affected by recent code changes (sync mode), detect structural drift between English source docs and their translations (i18n mode), and lint translated docs for CJK style anti-patterns (lint mode). All modes run on-demand; sync is always interactive.
docs.auto_verify: true and runs oma docs verify --json at completion.web/docs), to find translations (web/i18n/{lang}/...) that drifted or went missing.oma-translator (oma docs i18n / oma docs lint only detect; they never edit translations).oma-explainer (this skill detects drift; it does not author explainers).verify mode: Optional glob path (default **/*.md), optional --json flag, optional --report-file <path>.
sync mode: Optional git diff range (default --cached, fallback HEAD~1..HEAD).
i18n mode: Optional --min-severity <CRITICAL|HIGH|MEDIUM|LOW> (default MEDIUM), optional --json.
lint mode: Optional --locales <list> (comma-separated CJK locales for the cjk-em-dash rule, default ko,ja,zh), optional --json. The default wrong-language rule always scans every locale under web/i18n/ and is not narrowed by --locales.
verify mode:
--json, or full markdown written to file with --report-file.sync mode:
[y] apply [n] skip [d] diff [s] full proposal style).doc-refs.json regenerated after applies.i18n mode:
--json. Report-only: drifting pairs are handed to oma-translator in diff-sync mode.lint mode:
--json. Report-only: restructuring goes through oma-translator.cli/commands/docs/extract.ts: markdown AST + L2 pattern extractor.cli/commands/docs/resolve.ts: deterministic broken-ref checker.cli/commands/docs/reporter.ts: deterministic markdown/JSON report renderer (no LLM call; host LLM does narrative synthesis).cli/commands/docs/sync-propose.ts: git diff intake, reverse lookup, candidate-doc selector with secret redaction (no LLM call; host LLM drafts patches).cli/commands/docs/i18n-drift.ts: EN↔translation structural drift detector (line/heading counts, last-commit recency; no LLM call).cli/commands/docs/lint-i18n.ts: translated-doc linter for selected-locale CJK em-dash style and all-locale wrong-language placeholders (no LLM call, no auto-fix).docs/generated/doc-refs.json: single-direction reference index, regenerated on every verify run. Gitignored — the CLI force-adds docs/generated/ to .gitignore so generated artifacts are never committed.docs/generated/url-drift.json: lychee-produced URL drift report (written by background lychee spawn; gitignored under the same docs/generated/ rule).lychee: external Rust tool for URL link checking. Detected on PATH; install via brew install lychee or see https://github.com/lycheeverse/lychee#installation. Optional but recommended..agents/oma-config.yaml: docs.auto_verify (workflow hook opt-in), docs.check_urls (URL checking on/off, default true), and docs.exclude (glob list of markdown trees the walker must not scan — benchmark artifacts, translation mirrors, etc.; default []) toggles.verify, sync, i18n, or lint.oma-translator.--json, --report-file, LLM availability, and network reachability.verify | sync | i18n | lint). If absent, print help and exit.oma-config.yaml to check docs.auto_verify when invoked from a workflow hook.oma docs verify, oma docs sync) are on PATH.extract.ts) to regenerate doc-refs.json from repo markdown (**/*.md, verify) or build in-memory reverse index from doc-refs.json (sync; a cached index newer than 5 minutes is reused, otherwise regenerated).--json; structured candidate list for sync).doc-refs.json is missing or older than 5 minutes in sync: regenerate via the extractor, then continue.oma docs CLI not found: skip with installation hint (workflow hook: skip silently).doc-refs.json write failure: abort and report the write error; do not emit partial index.doc-refs.json regenerated; session summary printed.| Action | SSL primitive | Notes |
|---|---|---|
| Parse CLI args and mode | READ | First arg selects verify or sync |
| Extract refs from docs | CALL_TOOL | extract.ts: remark AST + L2 patterns → doc-refs.json |
| Check broken refs | RESOLVE | resolve.ts: file, url, cli, script, env, config checks |
| Build reverse index | INFER | sync-propose.ts: in-memory map from doc-refs.json |
| Match diff to candidate docs | RESOLVE | sync-propose.ts: git diff + reverse lookup |
| Redact secrets from diff | VALIDATE | Exclude .env*, *.pem, *.key, id_rsa*; sanitize content |
| Detect i18n drift | RESOLVE | i18n-drift.ts: EN↔translation structural signals + severity |
| Lint translated docs | VALIDATE | lint-i18n.ts: selected-locale CJK style plus all-locale wrong-language placeholders, report-only |
| Generate patch proposals | INFER | Host LLM drafts patches from sync-propose.ts candidate output (no CLI LLM call) |
| Render drift report | RENDER | reporter.ts: markdown (default), JSON (--json), file (--report-file) |
| Apply approved patches | WRITE | git apply on user-confirmed patches only |
| Notify hook summary | NOTIFY | 1-3 line stdout summary for workflow hooks |
cli/commands/docs/extract.ts: remark + unified markdown AST, L2 pattern extraction, escape hatch filter, docs/generated/doc-refs.json writer.cli/commands/docs/resolve.ts: case-sensitive file existence, which for CLI tokens, package.json scripts lookup, ripgrep/git grep for env vars, oma-config.yaml deep-path check. URL kind is filtered out by the verify command and delegated to lychee. (Internal caching strategy: see design doc.)cli/commands/docs/reporter.ts: deterministic markdown + JSON renderer. No LLM call. Friendly summary, severity tagging, fix prioritization are the host LLM's responsibility.cli/commands/docs/sync-propose.ts: git diff intake, reverse index build, secret-pattern + gitignore file exclusion. Returns candidate docs with matched refs only. No LLM call. Patch synthesis is the host LLM's responsibility.cli/commands/docs/i18n-drift.ts: pairs web/docs English sources with web/i18n/{lang}/... translations, emits line/heading/recency drift signals with severity. No LLM call. Translation patching is oma-translator's responsibility.cli/commands/docs/lint-i18n.ts: content-level linter with cjk-em-dash for selected CJK locales and wrong-language placeholder detection across all locales. No LLM call, no auto-fix. Restructuring is the host LLM's responsibility via oma-translator.lychee (background URL link checking; install via brew install lychee).This skill follows the OMA pattern (mirroring oma-scholar): the CLI emits structured data; the host LLM (the agent runtime that invoked the skill) does any natural-language synthesis or judgment.
After oma docs verify --json:
After oma docs sync <range> --json:
{ doc, changedFiles, matchedRefs }).git diff for changedFiles, draft a unified-diff patch reflecting the code change.git apply or by writing the doc directly.After oma docs i18n --json:
oma-translator in diff-sync mode (see that skill's § Diff-Sync Mode).After oma docs lint --json:
oma-translator (e.g. § Stage 4-A em-dash rule); confirm edits with the user before writing.verify mode runs a drift check against the current codebase:
# Default: scan all repo markdown (**/*.md, gitignored files excluded),
# render markdown to stdout.
# URL link checking is delegated to lychee in the background
# (install: `brew install lychee`). Core check ~8s on a 1k-doc repo.
oma docs verify
# Narrow to a path or glob (uses minimatch)
oma docs verify "docs/**/*.md"
oma docs verify cli/README.md
# Machine-readable output for CI / hooks
oma docs verify --json
# Persist full markdown report to a file (works alongside --json too)
oma docs verify --report-file ./drift-report.md
# Skip URL checking entirely (when lychee is run separately, or as a
# one-off override of docs.check_urls=true in oma-config.yaml)
oma docs verify --no-urls
# Block until lychee finishes (CI scenarios needing complete URL data)
oma docs verify --urls-sync
# Exit code: 0 = clean, 1 = broken refs found in core check.
# URL drift, if any, is reported separately at docs/generated/url-drift.json
# and does NOT affect this exit code.sync mode proposes patches for docs affected by a git diff (always interactive, never auto-applies):
# Default: staged changes (--cached), fallback HEAD~1..HEAD
oma docs sync
# Explicit range
oma docs sync HEAD~5..HEAD
oma docs sync main..feature-branch
# The CLI emits the candidate-doc list; the host LLM drafts patches and
# confirms per doc ([y] apply / [n] skip / [d] diff / [s] full proposal).
# Sync regenerates docs/generated/doc-refs.json after applying any patches.i18n mode detects structural drift between English source docs (web/docs) and translations (web/i18n/{lang}/...); report-only, never edits translations:
# Default: severity ≥ MEDIUM, markdown summary to stdout
oma docs i18n
# Machine-readable, custom threshold
oma docs i18n --json --min-severity HIGH
# Output: per-pair drift signals (line/heading diff, EN-newer flag).
# Hand CRITICAL/HIGH pairs to `oma-translator` diff-sync mode.lint mode checks translated docs for content-level style anti-patterns (report-only, no auto-fix):
# Default CJK locales: ko,ja,zh
oma docs lint
oma docs lint --json --locales ko,jaWorkflow hook (opt-in) runs verify automatically at workflow completion when docs.auto_verify: true in oma-config.yaml:
# Hook command emitted by /scm, /work, /ultrawork
oma docs verify --json
# Hook policy: warn-only in v1; non-zero exit does NOT block workflow completion| Scope | Resource target |
|---|---|
LOCAL_FS read | repo markdown **/*.md (extractor input), docs/generated/doc-refs.json (index), web/docs + web/i18n/** (i18n/lint), .env.example, package.json, .agents/oma-config.yaml |
LOCAL_FS write | docs/generated/doc-refs.json (regenerated each verify run), approved sync patches |
CODEBASE read-only | Existence checks for file/cli/script/env/config refs; git diff intake |
PROCESS | git diff, git apply, which, background lychee spawn |
NETWORK | URL checking delegated to lychee (no internal HEAD fallback; see Guardrail 6) |
docs/generated/ is created on demand for the index.cli/commands/docs/ is built and oma binary is on PATH (or invoked directly via bun run).--cached stage or recent commits).web/docs (EN source) and web/i18n/{lang} trees exist.docs/generated/doc-refs.json (always overwrites).doc-refs.json after applies..agents/ files are ever modified..agents/: CLAUDE.md SSOT protection applies in all modes.[y] confirm required per doc.oma-config.yaml language: user-facing report text is localized; code, paths, JSON keys, and CLI commands stay in English..env*, *.pem, *.key, id_rsa*, and gitignored files never appear in candidate changedFiles lists. Host LLM never sees secret file paths.docs.check_urls=true (default), URL refs are checked by lychee running in the background; results land in docs/generated/url-drift.json. If lychee is missing, an install hint is printed and URL checking is skipped (no internal HEAD fallback).oma-scholar's pattern). This makes oma-docs vendor-agnostic: works identically under Claude Code / Codex / Gemini / Qwen / Antigravity.docs.auto_verify: false by default (explicit opt-in required).<!-- oma-docs:ignore-start --> / <!-- oma-docs:ignore-end --> blocks and frontmatter oma-docs: skip are honored; no ref extraction from ignored regions. Use this for illustrative example paths in tutorials (hypothetical project files in inline code) that intentionally do not resolve.file ref whose target does not exist but matches the project's gitignore rules (git check-ignore) is classified as skipped (a documented runtime/generated output such as .agents/results/result-*.md, .agents/state/memories/*, .serena/memories/*, .agents/state/*.json), never as broken. gitignore is the single source of truth for "produced at runtime" — gitignore an output path and it stops being flagged. The skipped count is surfaced (markdown summary + JSON skippedCount) so nothing is silently dropped.docs.exclude: committed-but-non-prose markdown (benchmark run artifacts, translation mirrors validated separately by oma docs i18n) is dropped from the scan by the docs.exclude globs rather than producing unactionable broken refs. An explicit single-file path argument bypasses docs.exclude.oma-translator with per-file user confirmation; the CLI never edits translations.v1 covers verify, sync (broken-only classification, L2 ref extraction), i18n (structural translation drift), and lint (CJK style anti-patterns). The following are explicitly deferred to v2: create mode (generate missing docs), semantic (content-level) translation drift, L3 symbol-level extraction (Tree-sitter/LSP), GitHub Action wrapper, block hook mode.
docs/plans/designs/008-oma-docs.md (full architecture, schema spec, decision log, edge cases).doc-refs.json v1 schema defined in design doc § doc-refs.json Schema.deepinit Step 6 retirement, design doc § Migration: deepinit Step 6.oma-translator (v2 multilingual), oma-skill-creator (SSL-lite validation).3021301
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.