Files
our-claude-skills/custom-skills/17-seo-schema-generator/SKILL.md
Andrew Yim 1706a820fe feat(seo-schema-generator): merge site-extraction + source-to-schema into one skill
Unify the two schema-generation scenarios into a single slot-17 skill, both
feeding one claims register -> build -> validate(16) pipeline:

- Mode 1 (existing site): NEW scripts/extract_site_claims.py turns URLs / local
  HTML / a directory into a claims register. Existing JSON-LD -> CONFIRMED;
  title/OpenGraph -> PENDING (never auto-shipped). + site-extraction-methodology.md
  and bundled fixtures/site/ demo pages.
- Mode 2 (not-yet-published site): land the source-to-schema engine
  (build_schema_drafts.py, type_templates.json, claims/source registers, 3 refs,
  sample_claims.csv) from the Desktop builder.
- Rewrite SKILL.md (v2.0) around the two-mode framing; the claims register is the
  shared pivot. Only CONFIRMED, non-conflicting claims become schema; unfilled
  template slots are pruned, never emitted as placeholders.
- Retire the old template-fill generator (code/ + desktop/); update root CLAUDE.md.

Self-tested both chains end-to-end: Mode 2 sample -> build -> validate PASS (P0=0);
Mode 1 fixtures -> extract -> build -> validate PASS (P0=0), JSON-LD round-trips with
nested address intact. Fixed two adapter bugs (nested node promotion; relative-path URI).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 00:38:40 +09:00

127 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 -> 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.