ワンクリックで
data-pipeline-ops
Load when adding/editing race profiles, running enrichment, scraping, or regenerating the site from data.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Load when adding/editing race profiles, running enrichment, scraping, or regenerating the site from data.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Load before any deploy to gravelgodcycling.com or any SiteGround/WordPress operation (push_wordpress.py, mu-plugin edits, cache purge, Elementor pages).
Load when touching race scores, ratings, rankings, testimonials, or any trust-bearing editorial claim.
Load when touching brand colors/fonts/tokens, CI workflows, or Python version/dependency issues.
Load when touching email capture, sequences, Mission Control, athlete replies, or any conversion surface.
Write, revise, or extend Gravel God / Roadie Labs email sequences (Mission Control drip emails, lifecycle triggers, broadcasts). Use whenever the task touches mission_control/templates/emails/, sequence definitions, subjects, or new email-marketing ideas for either brand. Encodes the Physiqonomics-derived voice models, the conversion principles, the hard constraints, and the ship process.
| name | data-pipeline-ops |
| description | Load when adding/editing race profiles, running enrichment, scraping, or regenerating the site from data. |
race-data/*.json (757 profiles, source of truth) → scripts/generate_index.py
builds web/race-index.json (757-entry search/filter index — verified count
matches) → wordpress/generate_neo_brutalist.py renders race pages into
output/ → scripts/push_wordpress.py tar+ssh deploys to SiteGround.
Regenerate the index after ANY profile edit, before regenerating pages — the search/filter UI and JSON-LD read the index, not the profiles directly, and a stale index silently ships old vitals/scores.
python scripts/generate_index.py --with-jsonld # index + per-race JSON-LD
python scripts/generate_index.py --stats # coverage check only
Race pages render from race-data/*.json (new format) via
wordpress/generate_neo_brutalist.py <slug> or --all. It also supports a
legacy data/*-data.json format — don't create new profiles in that format.
CLAUDE.md's HTML Generation section covers the load-bearing ones:
d['race']['gravel_god_rating'] path, _parse_score(), _safe_json_for_script().
Read that first. Additional traps verified against a live profile
(race-data/114-gravel-race.json):
gravel_god_rating holds 14 bare
integer scores + overall_score/tier. biased_opinion_ratings holds the
SAME 14 criteria as {score, explanation} objects in Matti voice.
batch_enrich.py writes biased_opinion_ratings only — it does not touch
gravel_god_rating. A generator reading one and not the other renders a
stale score next to a mismatched explanation.youtube_data, tire_recommendations,
citations, photos, history.notable_moments are absent or [] on
thinner profiles. Guard with .get() chains.rider_intel can exist with every field empty. search_text can be
full of prose explaining that NO usable intel was extracted (transcript was
music/foreign speech/fragmented). A non-empty search_text is not proof of
real intel — check key_challenges/terrain_notes arrays are non-empty too.curated: false videos stay in videos[]. Only curated: true entries
should render; the array holds accepted and rejected results side by side.history.founded / guide_variables.altitude_feet are null-typed, not
absent. Same falsiness risk as CLAUDE.md #4 (esc(0)) — check is None,
not truthiness, on any numeric vitals field here.skills/ dir (NOT
.claude/skills/): skills/RACE_RESEARCH_BRIEF_SKILL_UPDATED.md defines
source-diversity requirements and handoff format; skills/research_prompt.md,
skills/voice_guide.md back it. Prompt/doc system for a human-or-Claude
research pass, not an executable script.python scripts/batch_research.py --auto N → research-dumps/{slug}-raw.md
via Kimi K2 web search.python scripts/batch_enrich.py --slugs <slug>
reads the dump + existing profile, calls Claude for biased_opinion_ratings
explanations, merges into race-data/{slug}.json. Use --dry-run first.python scripts/validate_race_data.py cross-checks vitals
against known_races.py / athletes/config/races.json in the sibling
training-plan-pipeline repo, catches gain-vs-ASL copy-paste errors and
implausible internal values. Also python -m pytest tests/.python scripts/generate_index.py --with-jsonld.python wordpress/generate_neo_brutalist.py <slug>.Adds rider intel (challenges/terrain notes/tips/quotes from race recap
transcripts) and curated thumbnails to a profile's youtube_data block,
rendered as "RIDERS REPORT" callouts.
scripts/youtube_research.py --slug <slug> — populates videos[].
build_search_query() is discipline-aware, reads discipline from the race
JSON. [UNVERIFIED — session memory, Jul 2026: exact term mapping]scripts/youtube_enrich.py --slug <slug> (or --auto N) — curates real
race content (rejects indoor-trainer platforms, slideshows, promo reels,
sub-3min/over-2hr videos), sets curated/display_order.scripts/youtube_extract_intel.py --slug <slug> (or --auto N) — extracts
structured rider_intel from curated-video transcripts.scripts/youtube_thumbnail.py — fetches/scores thumbnails
(maxresdefault.jpg → hqdefault.jpg fallback), caches in
data/thumbnail-cache/ (30-day TTL, gitignored). [UNVERIFIED — session
memory, Jul 2026: exact scoring formula]scripts/youtube_validate.py — schema/format check before shipping.youtube_data across race-data/*.json for current counts
before quoting a percentage].scripts/scrape_utils.py (shared fetch/cache/extract) +
scripts/scrape_official_sites.py (CLI driver) + scripts/fact_check_profiles.py
(compares scraped facts vs profile, proposes fixes). Built for road-race
expansion batches; applies equally here.
Fetcher first, StealthyFetcher (Cloudflare bypass) on
failure. Use str(response.html_content), not response.text.data/scrape-cache/ (7-day TTL, gitignored, SHA-256 of URL). Extracts
land in data/scrape-extracts/{slug}.json (committed).scrape_official_sites.py --delay defaults 3.0s between sites —
don't lower against live race-org sites.road-race-automation git log for current
state before citing batch counts].After any bulk data edit (batch enrich, batch scrape-fix, mass score recompute), before deploy:
.claude/skills/scoring-and-veracity/SKILL.md
(scripts/verify_race_rankings.py, cross-checked against
docs/GRAVEL_GOD_SCORING_SYSTEM.md)..claude/skills/deploy-safely/SKILL.md
(scripts/preflight_quality.py, scripts/preflight.py --deploy).Skipping either on a bulk edit is how a wrong distance/elevation figure or a score/explanation mismatch (section 2) reaches production.
run_pipeline.py, pipeline/, gates/) — that's
the ENDURE athlete intake→plan engine living in this same repo, unrelated to
race-data profiles..claude/skills/deploy-safely/SKILL.md.docs/GRAVEL_GOD_SCORING_SYSTEM.md and
.claude/skills/scoring-and-veracity/SKILL.md.email-sequences skill.pytest tests/
and validate_race_data.py, no need for the full pipeline.