--- name: 16-seo-schema-validator description: | Validates an AUTHORED JSON-LD schema dataset (pre-deployment QA) and audits live structured data (post-deployment). Runs a 5-layer offline validation pipeline (coverage, syntax, vocabulary, Google rich-result requirements, business-logic/consistency) and emits a severity-ranked defect log, a gate decision, and a Markdown report. Fills the "16-seo-schema-validator" slot referenced by seo-comprehensive-audit. Triggers: schema validation, JSON-LD QA, structured data check, schema 검수, 스키마 유효성 검증, 구조화 데이터 검토, rich result eligibility, schema 오류 점검. version: "1.0" author: OurDigital / D.intelligence environment: Code --- # SEO Schema Validator (16) Quality-assure structured data at scale. Built for the kind of failure where a client review of hundreds of authored entries surfaces "too many errors" — by moving the cheap, machine-checkable errors OUT of the human review and INTO an automated gate that runs first. ## Two modes | Mode | When | Input | Adds | |------|------|-------|------| | **A — Dataset QA (default)** | Before deployment, while authoring/reviewing | An authored dataset: `.xlsx` / `.csv` (one row per entry, a JSON-LD column), `.jsonl`, `.json`, or a directory of `.json/.jsonld` | Layer 0 coverage vs the canonical URL list | | **B — Live audit** | After deployment, or feeding `seo-comprehensive-audit` | Live URLs (extract embedded JSON-LD first, then validate) | Layer 5 rendering-reality (schema present in rendered HTML, matches content) | This skill's primary job is **Mode A**: catch errors before the client sees them. ## The 5 validation layers | # | Layer | Catches | Default severity | |---|-------|---------|------------------| | L0 | Coverage | URLs with no entry; entries whose URL isn't in the inventory | P1 / P2 | | L1 | Syntax | invalid JSON, missing/wrong `@context`, no `@type`, encoding corruption | P0 / P1 | | L2 | Vocabulary | unknown type, property not valid for type, bad value formats (URL/date/lang/currency/number) | P1 / P2 | | L3 | Rich-result | Google **required** missing (blocks rich result); recommended absent | P0 / P2 | | L4 | Consistency | NAP mismatch across a property, `@id` dupes/dangling refs, swapped geo, placeholder text, duplicate descriptions | P0 / P1 | Full rationale and the type→requirement matrix: `references/validation-methodology.md`. Severity + category codes: `references/defect-taxonomy.md`. Hotel page-type → schema-type map: `references/hotel-type-map.md`. Client-facing report + P1 decision log: `templates/client-qa-report-template.md`, `templates/decision-log.md`. ## Stage gates (aligned to the project lifecycle 설계→개발→테스트→안정화→런칭 후) - **G1 설계** — Lock the schema spec and the page-type→type map (`hotel-type-map.md`). Approve the entry template. *DoD:* every page template has an assigned schema type and a required-property list. - **G2 개발** — Authors produce entries. Run the validator with `--strict`. *DoD (gate):* **zero P0**, JSON parses for 100% of entries. Entries failing this NEVER reach client review. - **G3 테스트** — Re-run; triage P1 in `defect_log.csv` (assign owner/status). Client reviews ONLY the clean, P0-free entries, against a defect report — not raw JSON. *DoD:* P1 triaged, decisions logged in `templates/decision-log.md`. - **G4 안정화** — Fix → re-run → confirm no regressions. Spot-check a sample in Google Rich Results Test (online, outside this runtime). *DoD:* P0=0, P1 accepted/closed, online validator green on sample. - **G5 런칭 후** — Mode B live audit + GSC "Rich results" report monitoring. *DoD:* deployed schema matches authored dataset; no new GSC structured-data errors. ## How to run ```bash # Mode A — validate an authored dataset (the common case) python scripts/validate_schema.py path/to/schema_dataset.xlsx \ --url-list path/to/URLlist.xlsx \ --out schema_qa_out # Highest signal for the pre-review gate (unexpected props -> P1, drop optional recommended) python scripts/validate_schema.py dataset.csv --strict --no-recommended --out qa_strict # Try it on the bundled flawed fixture first python scripts/make_sample.py python scripts/validate_schema.py fixtures/sample_schema.csv --out demo_out ``` **Input expectations (Mode A tabular):** the loader auto-detects a JSON-LD column (`jsonld`, `schema`, `structured_data`, `스키마`, …) plus optional `url`/`메뉴 URL`, `lang`/`언어코드`, `device`/`PC/MOBILE`, `page_type` columns. Multi-sheet `.xlsx` is supported (each sheet with a JSON-LD column is read). No JSON-LD column → clear error. ## Reading the output - `report.md` — counts, **gate decision (PASS = zero P0)**, defects-by-category, top P0 entries, next step. - `defect_log.csv` — one row per finding with `status/owner/note` columns ready for triage. This is the client-facing artifact (open issues, not raw schema). - `results.json` — full machine-readable results for dashboards / CI. **The rule:** an entry advances to client review only when it has **zero P0**. P1 = triage backlog (fix before launch). P2 = optimization backlog (recommended props, style). ## Limits & honesty - Offline by design — the runtime can't reach schema.org or Google. The bundled rule set (`scripts/schema_rules.json`) is a curated hotel-focused subset; unknown types/properties degrade to warnings (never hard errors) to avoid false positives. - Authoritative rich-result eligibility still requires Google's online testers on a sample at G4. This skill makes that sample small and clean, not redundant. - Adding a new schema type or tightening a rule = edit `schema_rules.json` only. ## Integration `seo-comprehensive-audit` calls this skill as pipeline stage 4 ("Schema Validation"). For that orchestrator, run **Mode B** on a sample of live URLs and return the score (100 − weighted defect penalty) and the issue list. For day-to-day client work, run **Mode A** on the authored dataset.