--- name: 17-seo-schema-generator description: | Generates validation-ready JSON-LD structured data for a site, covering BOTH scenarios: (1) from an existing website — extract facts from live pages; and (2) from collected sources for a not-yet-published site — reconcile conflicting facts into a provenance-tracked claims register. Both modes emit the same claims register, build pruned drafts from type templates (no placeholders shipped), and hand off to 16-seo-schema-validator (generate then validate, gate = zero P0). Triggers: generate schema, create JSON-LD, schema markup, structured data generator, source-to-schema, pre-launch schema, claims register, 스키마 생성, 스키마 저작, 구조화 데이터 생성, 미발행 사이트 스키마, 기존 사이트 스키마 추출. version: "2.0" author: OurDigital / D.intelligence environment: Code --- # SEO Schema Generator (17) Author JSON-LD for a site — whether the pages already exist or the site is not yet published. Both cases are error-prone for the same reason: facts must be turned into schema without leaking conflicts, gaps, or placeholders. This skill makes that reliable by routing **both scenarios through one pivot — a claims register** — then generating pruned drafts that hand off cleanly to the `16-seo-schema-validator` gate. **Generate (17) → Validate (16).** This skill produces drafts; 16 is the QA gate. ## Two modes, one pipeline The only thing that differs between the scenarios is **where facts come from**. Everything after the claims register is identical. | | **Mode 1 — from an existing site** | **Mode 2 — from collected sources** | |---|---|---| | When | Site has pages but lacks (or needs better) schema | Site not published yet (no DOM) | | Source of truth | the live pages | scattered, conflicting sources (DART, Wikidata, brochures) | | Seed the register with | `scripts/extract_site_claims.py` | manual research → `templates/claims-register.csv` | | Hard part | extraction & mapping | authority hierarchy + entity reconciliation | | Conflicts | rare (one source) | frequent → resolve before shipping | ``` Mode 1 (extract_site_claims.py)─┐ ├─▶ claims_register.csv ─▶ build_schema_drafts.py ─▶ drafts/*.jsonld Mode 2 (research + register)────┘ (the pivot) └─▶ schema_drafts_dataset.csv │ 16-seo-schema-validator ▼ (gate: zero P0) ``` ## The claims register — the core idea A **claims register** is a provenance-tracked, conflict-resolved fact table. Columns: `entity_id, entity_type, property, value, lang, url, source_ids, authority, confidence, conflict, status, note`. Dotted `property` paths nest (`address.streetAddress`); pipe-separate array values (`a|b|c`). **Only `CONFIRMED`, non-conflicting claims become schema.** Everything else (PENDING, CONFLICT, REJECTED, EMPTY) is excluded and reported — never shipped. An unfilled template slot is **deleted**, never emitted as `{{…}}` or `TODO` (placeholder leakage is the #1 pre-launch P0). ## How to run ```bash # Try the bundled sample first (Mode 2) python scripts/make_sample.py python scripts/build_schema_drafts.py fixtures/sample_claims.csv --out drafts_out # MODE 1 — existing site → register (URLs, or local .html / a directory offline) python scripts/extract_site_claims.py https://example.com/ https://example.com/about \ --out site_claims # review site_claims/claims_register.csv (confirm PENDING rows), then build: python scripts/build_schema_drafts.py site_claims/claims_register.csv --out drafts_out # MODE 2 — collected sources → register (fill templates/claims-register.csv by hand) python scripts/build_schema_drafts.py path/to/claims_register.csv --out drafts_out # HAND OFF TO THE GATE (must reach zero P0) python ../16-seo-schema-validator/scripts/validate_schema.py \ drafts_out/schema_drafts_dataset.csv --out qa_out ``` ## Outputs - `drafts/*.jsonld` — one pruned draft per entity (× language). - `schema_drafts_dataset.csv` — directly consumable by `16-seo-schema-validator`. - `build_report.md` — entities built + **excluded claims** (PENDING / CONFLICT / EMPTY) with reasons. - (Mode 1 also) `claims_register.csv` + `extraction_report.md`. ## Stage gates (설계→개발→테스트→안정화→런칭 후) - **G1 설계** — Lock the entity→type map (`references/entity-and-type-map.md`). Mode 2: source register complete (≥2 sources/entity). *DoD:* every entity has an assigned type + required list. - **G2 개발** — Seed the register (Mode 1 extract / Mode 2 research), reconcile to `CONFIRMED`, conflicts = 0, run the builder → drafts have **zero placeholders**. - **G3 테스트** — Validate (16): **zero P0**; triage P1; fact-accuracy sign-off via `templates/review-guide.md` (report-based, not raw JSON). - **G4 안정화** — Google Rich Results Test green on a sample; re-run shows no regression. - **G5 런칭 후** — live schema == drafts; GSC "Rich results" no new errors. ## References & templates - Mode 1 SOP: `references/site-extraction-methodology.md`. - Mode 2 SOP (9 steps): `references/source-to-schema-methodology.md`. - Source authority ranking: `references/source-authority-hierarchy.md`. - Entity→type scoping: `references/entity-and-type-map.md`. - Registers + review guide: `templates/claims-register.csv`, `templates/source-register.csv`, `templates/review-guide.md`. ## Templates included `scripts/type_templates.json` covers Organization, WebSite, Hotel, Person, JobPosting, VideoObject, FAQPage. Required props are aligned with the validator's rule set, so a fully confirmed entity passes the gate. **Add a type = add a template block (edit JSON only).** ## Limits & honesty - Quality of drafts == quality of the register. Garbage-in still produces gaps — but reported, never as placeholders. - Mode 1 inference (title/OpenGraph) is seeded as `PENDING` and will NOT ship until a human confirms it; existing JSON-LD is seeded `CONFIRMED`. If a site already has good JSON-LD, prefer auditing it directly with `16` Mode B. - Authoritative rich-result eligibility still needs Google's online test on a sample at G4. ## Integration - **→ 16-seo-schema-validator**: the dataset CSV is the handoff; the gate is `zero P0`. - **→ seo-comprehensive-audit**: post-launch (G5) uses the validator's Mode B as audit stage 4. - This skill is a one-time-per-site authoring workflow, **not** an audit-pipeline stage.