wc2026-match-report
Skill42 starsChanged 50 days agoMITView on GitHub
Generate a complete single-file HTML intelligence report for the FIFA World Cup 2026 from live Knowledge Graph data. Three report types: match report (a fixture, Team A vs Team B), player report (a single player across the tournament), and analytics scatter report (tournament-wide player comparisons). Pick the player report for single-person requests and the analytics scatter report for cross-player metric comparisons; everything else defaults to the match report.
In this repository45 other files it gives its agents.
- agent-rdf-memory/AGENTS.mdAGENTS.md
- AGENTS.mdAGENTS.md
- a2a-clientSkill
- acp-clientSkill
- csv-to-rdf-det-generatorSkill
- data-twinglerSkill
- dbpedia-query-skillSkill
- document-to-kg-skillSkill
- fediverse-crudSkill
- fuxi-engineerSkill
- infographic-describerSkill
- iodbc-dsn-managerSkill
- kg-generatorSkill
- linked-data-skillsSkill
- llm-routing-skillSkill
- monidSkill
- mpp-stripe-clientSkill
- mtls-curlSkill
- opal-agent-skill-assemblerSkill
- openlink-license-managerSkill
- openlink-license-readerSkill
- openlink-request-broker-configuratorSkill
- opml-rss-readerSkill
- osdi-inclusion-engineSkill
- pinchtabSkill
- rdf-det-variant-generatorSkill
- rdf-infographic-skillSkill
- resource-access-offers-generatorSkill
- rss-feed-generatorSkill
- s3-query-skillSkill
- screencast-recorderSkill
- set-webdav-resource-propertySkill
- sparql-faceted-browserSkill
- ucp-clientSkill
- uriburner-opal-agent-skillsSkill
- virtuoso-rdf-bulk-loaderSkill
- virtuoso-rdf-loaderSkill
- virtuoso-support-agentSkill
- weblog-from-webdavSkill
- website-from-webdavSkill
- wikidata-query-skillSkill
- world-cup-2026-navigatorSkill
- x402-buyerSkill
- xmla-clientSkill
- youidSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 1 is distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 171
Only fall back to hand-building if Python 3 is unavailable — the script is the source of truth for the player report, exactly as …
- Very specific: line 188
Player report?: If the request is about one player, use scripts/player_report_create.py <player_id|name> (see Player Report Mode above) and …
- Very specific: line 229
Use this IRI (not matchId) when querying the analytics graph.
- Very specific: line 253
If the script is unavailable, use references/query-templates.md and build section-by-section.
- Very specific: line 273
Always use MAX(fifa:generatedAt) subquery to pick the latest analytics snapshot.
- Distinctive: line 307
Run before saving. All must pass:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
FIFA World Cup 2026 Match Intelligence Report Skill
Three report types:
| Type | Subject | Script |
| Match report (default) | a fixture (Team A vs Team B) | scripts/report_template_create.py <match_id> <out> |
| Player report | a single player across the tournament | scripts/player_report_create.py <player_id|name> [--out …] |
| Analytics scatter report | tournament-wide player comparisons | scripts/analytics_scatter_report_create.py [--chart …] [--out …] |
Pick the player report whenever the request is about one person ("create a player report for Jude Bellingham", "player intelligence for Olise"). Pick the analytics scatter report for tournament-wide cross-player comparisons ("running data report", "passing volume vs accuracy", "Simon Brunson-style chart"). Everything below with no specific heading refers to the match report.
Analytics Scatter Report Mode
Use scripts/analytics_scatter_report_create.py when the request is about comparing all players across one or two metrics — running data, passing efficiency, physical load, attacking output. This produces a Simon Brunson-style infographic: cream background, bold print-inspired header, numbered Chart.js scatter cards with zoom/pan, auto-generated insights, and click-through to player /describe/ profiles. Data is fetched live by the browser at page-load time — no server-side SPARQL needed.
Trigger phrases:
- "running data report", "Simon Brunson-style report", "scatter chart for all players"
- "compare [metric] vs [metric] across the tournament"
- "passing volume vs accuracy chart", "physical load comparison"
- "who covers the most distance", "speed vs sprint metres"
Script location: scripts/analytics_scatter_report_create.py in simon-bronwell/ style output
Output directory: simon-bronwell/ under the working directory (or specify with --out)
# Running data (reproduces the existing fatigue-index example):
python3 scripts/analytics_scatter_report_create.py \
--title "RUNNING DATA" --emoji "🏃" \
--subtitle "Player-Level Relationships" \
--desc "How total volume, high-speed work, top speed and sprint metres are connecting" \
--note "Players with 45+ tournament minutes" \
--chart "totalDistance,highSpeedDistance,Total distance (m),High-speed distance (m),Total Distance vs High-Speed Distance" \
--chart "topSpeed,sprintMetres,Top speed (km/h),Sprint metres (m),Top Speed vs Sprint Metres" \
--out simon-bronwell/YYYYMMDD-running-data.html
# Passing intelligence:
python3 scripts/analytics_scatter_report_create.py \
--title "PASSING INTELLIGENCE" --emoji "🎯" \
--subtitle "Volume & Accuracy" \
--desc "How passing volume and accuracy relate across all outfield players" \
--chart "passes,passAccuracy,Total Passes,Pass Accuracy (%),Volume vs Accuracy" \
--chart "passes,assists,Total Passes,Assists,Pass Volume vs Creativity" \
--out simon-bronwell/YYYYMMDD-passing-intelligence.html
# Attacking output:
python3 scripts/analytics_scatter_report_create.py \
--title "ATTACKING OUTPUT" --emoji "⚽" \
--subtitle "Shots, Goals & Creativity" \
--desc "Comparing shot volume, on-target accuracy and assist creation across forwards and midfielders" \
--chart "shots,goals,Shots,Goals,Shot Volume vs Goals" \
--chart "shots,shotsOnTarget,Shots,Shots on Target,Shot Volume vs Accuracy" \
--out simon-bronwell/YYYYMMDD-attacking-output.htmlAvailable metric keys (use as xKey / yKey in --chart):
| Key | Description |
totalDistance | Total distance run (m) |
highSpeedDistance | High-speed distance: zones 4+5 (m) |
sprintMetres | Sprint metres: zone 5 only (m) |
topSpeed | Maximum recorded speed (km/h) |
avgSpeed | Average speed (km/h) |
minutesPlayed | Total minutes played |
sprints | Sprint count |
passes | Total passes attempted |
passesCompleted | Passes completed |
passAccuracy | Pass completion % (derived) |
assists | Assists |
goals | Goals |
shots | Shots (attempts at goal) |
shotsOnTarget | Shots on target |
takeOns | Take-ons completed |
crosses | Crosses |
crossesCompleted | Successful crosses |
foulsWon | Fouls won |
foulsCommitted | Fouls committed |
forcedTurnovers | Turnovers forced |
yellowCards | Yellow cards |
corners | Corners taken |
--chart format: xKey,yKey[,xAxisLabel,yAxisLabel[,Card Title]]
Labels default to human-readable names if omitted; card title defaults to "xLabel vs yLabel".
Options:
--title— big uppercase headline (e.g."RUNNING DATA")--emoji— icon beside the headline (e.g."🏃")--subtitle— centre-panel heading--desc— centre-panel description text--note— small italic note (e.g. minimum minutes qualifier)--min-minutes— SPARQL HAVING filter, default45--out— output file path
Design notes (Simon Brunson style):
- Cream/beige page background
#f0ede8, white chart cards, black ink typography - Compact header: brand column | big title | centre meta panel
- Position-coded dots: DF=blue, MF=green, FW=red, GK=grey
- Zoom/pan with reset button; click dot →
/describe/player profile; click clustered dots → selection modal - Auto-generated insight below each chart naming top performers with
/describe/hyperlinks - JSON-LD + OG metadata in
<head>; source attribution in footer
Operating Modality — Read This First
You are a modern UI/UX expert specialising in sports intelligence report design for the duration of any task that uses this skill. This is not a mode you switch into on request — it is your identity when this skill is active.
What this means in practice:
- Report design intent before implementation — before writing any HTML, decide the visual narrative: match header (teams, score, venue), then statistical sections (possession, shots, formation), then event timeline, then player ratings. The layout must feel like a premium sports broadcast graphic, not a data dump.
- Team colour identity — where team colours are available from the KG, use them as accent colours for each team's side of the report (possession bars, formation highlights, stat comparisons). Never use generic blue/red as defaults when real team colours are known.
- Lineup lists are grouped by role, not tabular — display starters grouped as Goalkeeper / Defender / Midfield / Attack, followed by Substitutions, Coach, and Assistant Coaches. Use
fifa:playerStatus(1=starter, 2=sub) andfifa:positionURI code to group. A flat undifferentiated list is a design defect. - Timeline events need iconography — goals (⚽), yellow cards (🟨), red cards (🟥), substitutions (↕), and VAR decisions each need a distinct visual marker in the match timeline, not just text labels.
- Stat bars over raw numbers — wherever a percentage or comparative metric exists (possession, pass accuracy, shots on target), render it as a proportional bar alongside the number. Raw numbers in a table with no visual encoding underuse the medium.
- Colour token discipline — use CSS variables for all base colours; override with team-specific colours only for team-attributed elements.
- First-pass quality — the goal is zero aesthetic corrections from the user. Deliver a report that reads like a professional post-match intelligence brief.
Trigger Phrases
Match report — use when the user says any of:
- "generate a match report for X vs Y"
- "match intelligence report for [Team A] vs [Team B]"
- "produce a WC2026 report for [fixture]"
- "create a FIFA report for [match]"
- "run the match report script for [match_id]"
Player report — use when the request centres on one player:
- "create a player report for [Player]"
- "player intelligence report for [Player]"
- "WC2026 report for [Player]" (a person, not a fixture)
- "run the player report script for [player_id]"
Player Report Mode
When the request is about a single player, run the player generator instead of the match one. It queries the KG live and emits the full player report — hero, tournament snapshot, an assist→goal creation map and a shot map drawn from real event XY coordinates, an in-match temporal "how he changes the game" section (Chart.js line charts + first/second-half split), match log, passing, physical, attacking, squad-comparison charts (assist leaders + creative-profile radar), defensive, progression, SPARQL, and sources.
# By name (resolved to a player id via SPARQL automatically):
python3 scripts/player_report_create.py "Jude Bellingham"
# By numeric player id, with options:
python3 scripts/player_report_create.py 448202 \
--out <output_dir>/jude-bellingham-wc2026-report.html \
--image "https://digitalhub.fifa.com/transform/.../BELLINGHAM_..." # optional hero photoOptions: --out (default <name>-wc2026-report.html), --image (optional hero photo URL — omit if not known), --accent / --accent2 (default: auto from the player's nation, using the same palette as references/team-colours.md).
Behaviour & guarantees (already handled by the script — do not re-implement):
- Name → id: a non-numeric first argument is resolved via
rdfs:labelmatch; ambiguous names print candidates and use the closest. Prefer passing the id when known. - Event coordinates: uses
fifa:eventPlayer+fifa:positionX/Y; attacking direction is normalised per (match, half) so the player always attacks right. Seeworld-cup-2026-navigatorfor the coordinate/temporal model. - Temporal: in-match
fifa:PlayerMatchAnalyticsReportsnapshots keyed byfifa:timePlayed(notgeneratedAt). - KG deep-links: hero name → the player's
/describe; assist markers → the assist event instance; shot markers → the shot event instance. Tooltips are instant, page-CSS styled (no native browser tooltips). - Theming: light/dark aware; charts re-theme via a
data-themeMutationObserver. - Chart.js 4.4.3 is loaded from CDN; the rest is a self-contained single file (Python 3 stdlib only, no third-party deps).
Only fall back to hand-building if Python 3 is unavailable — the script is the source of truth for the player report, exactly as report_template_create.py is for the match report. Do not edit report_template_create.py for player-report work.
Player-report verification (quick gate): no unresolved {placeholders}; 12 <section>s; 6 <canvas> charts; 2 pitch <svg>s; hero name is an <a> to /describe; every svg a[data-tip] href resolves to a /fifa-kg/event-* (assist/shot) or player IRI; --accent matches the nation.
Companion Skills (load before any query or HTML work)
| Skill | Purpose |
world-cup-2026-navigator | Correct SPARQL property URIs, coded values, named graph routing |
rdf-infographic-skill | Visual design, colour contrast, entity-link styling, footer attribution contract |
Execution Routing (priority order)
- Player report? If the request is about one player, use
scripts/player_report_create.py <player_id|name>(see Player Report Mode above) and skip the match steps. - Script —
scripts/report_template_create.py <match_id> <output_path>(preferred when Python 3 is available) - Inline build — fetch data via curl + construct HTML section-by-section per
references/query-templates.md - LLM fallback — synthesise from inline rules in this file (last resort)
Step 0 — Load companion skills
/world-cup-2026-navigator
/rdf-infographic-skillStep 1 — Resolve match ID
SPARQL endpoint: https://demo.openlinksw.com/sparql
Named graph: urn:worldcup:kg:2026
PREFIX fifa: <https://www.openlinksw.com/ontology/fifa#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?match ?matchId ?homeTeam ?awayTeam ?homeScore ?awayScore ?date ?stadium
FROM <urn:worldcup:kg:2026>
WHERE {
?match a fifa:Match ; fifa:matchId ?matchId ;
fifa:homeTeam ?ht ; fifa:awayTeam ?at ;
fifa:homeTeamScore ?homeScore ; fifa:awayTeamScore ?awayScore ; fifa:date ?date .
?ht rdfs:label ?homeTeam . ?at rdfs:label ?awayTeam .
OPTIONAL { ?match fifa:stadium ?s . ?s rdfs:label ?stadium }
FILTER(
CONTAINS(LCASE(str(?homeTeam)), "TEAM_A") ||
CONTAINS(LCASE(str(?awayTeam)), "TEAM_B")
)
}
ORDER BY ?dateReplace TEAM_A / TEAM_B with lowercase name fragments. See references/query-templates.md for full team name aliases.
Match IRI pattern: http://demo.openlinksw.com/fifa-kg#match-{matchId}
Use this IRI (not matchId) when querying the analytics graph.
Step 2 — Determine output filename
Format: YYYYMMDD-hometeam-vs-awayteam.html
- Date = UTC date from
?date(first 10 chars, hyphens removed) - Team names lowercased, spaces → hyphens, special chars dropped
- Home team (per KG) always first
Output path (per model routing rules):
- Claude Sonnet/Opus →
{LLM_ROOT}/Claude Generated/webpages/ - DeepSeek →
{LLM_ROOT}/DeepSeek/webpages/ - (see preferences.ttl
step-outputDirsfor full routing table)
Step 3 — Run the script
python3 /path/to/wc2026-match-report/scripts/report_template_create.py \
<match_id> \
<output_path>/<filename>.htmlThe script handles: SPARQL queries for all 8 data categories, team colours, CSS variables, formation SVGs, analytics bars, pressing gauges, timeline, attribution footer.
If the script is unavailable, use references/query-templates.md and build section-by-section.
Step 4 — Data categories
| # | Data | Graph |
| 1 | Match overview (teams, score, tactics, attendance, weather) | urn:worldcup:kg:2026 |
| 2 | Hero article + image (fifa:hasNewsArticle → schema:image) | urn:worldcup:kg:2026 |
| 3 | Goals (fifa:hasGoal) | urn:worldcup:kg:2026 |
| 4 | Bookings (fifa:hasBooking) | urn:worldcup:kg:2026 |
| 5 | Substitutions (fifa:hasSubstitution) | urn:worldcup:kg:2026 |
| 6 | All coaches — head (fifa:CoachRole-0) + assistants (fifa:CoachRole-1) | urn:worldcup:kg:2026 |
| 7 | Squad / lineup (fifa:hasPlayerAppearance, fifa:playerStatus, fifa:position) | urn:worldcup:kg:2026 |
| 8 | Team analytics (latest MAX(fifa:generatedAt) snapshot) | urn:worldcup:kg:2026:analytics |
| 9 | Player analytics (latest snapshot, cross-ref squad for team assignment) | urn:worldcup:kg:2026:analytics |
Critical notes:
- Analytics graph uses match IRI (
http://demo.openlinksw.com/fifa-kg#match-{id}), notmatchId. UseGRAPHclauses to scope subqueries. fifa:CoachRole-0= Head Coach;fifa:CoachRole-1= Assistant Coach.- Player analytics have no reliable
fifa:team— cross-referenceplayerNameagainst squad appearance data. - Always use
MAX(fifa:generatedAt)subquery to pick the latest analytics snapshot. fifa:Tactic-*entities have nordfs:label— extract formation from URI:BIND(REPLACE(STR(?htac),".*#Tactic-","") AS ?homeTactic).fifa:CardType-*entities have nordfs:label— extract code from URI:BIND(REPLACE(STR(?c),".*#CardType-","") AS ?cardCode). Only two codes exist in WC2026 data:1=Yellow,2=Red card (straight or second yellow — both coded identically).CardType-3is not present in the data.fifa:Position-*entities have nordfs:label— extract code from URI:BIND(REPLACE(STR(?pos),".*#Position-","") AS ?posCode). Code 0=GK, 1=DEF, 2=MID, 3=FWD.fifa:playerStatusonfifa:PlayerAppearance: 1=starter, 2=substitute.- None of the above coded-value entity types carry
rdfs:label— always extract from the URI local name.
Step 5 — Colour rules
See references/team-colours.md for all 48 WC2026 teams.
- Home team colour →
--accentCSS variable - Away team colour →
--accent-dimCSS variable - Comparative bars use
var(--accent)/var(--accent-dim)— never hardcoded hex - Perceived brightness ≤ 128 → white text
#fff; brightness > 128 → black text#000 - For similar-hue matchups → use alternate kit colour for away side
Step 6 — 11-section HTML structure
| Anchor | Section |
#hero | Score banner, stadium, attendance, weather, head coaches |
#goals | Goal log (minute, scorer, team, type, assist) |
#timeline | Chronological event strip (goals + bookings + subs) |
#stats | Head-to-head comparison bars (possession, passes, shots, xG, …) |
#phases | Tactical phase aggregate grid |
#pressing | Pressing intensity & threat gauges |
#formations | Lineup cards: GK / DEF / MID / ATK / Subs / Coach / Assistant Coaches |
#core-players | Top players by distance + Distance & Speed Comparison card |
#sparql | SPARQL accordion (≥3 numbered queries with live links) |
#sources | Attribution footer (7 cards) |
Step 7 — 12-point verification gate
Run before saving. All must pass:
og:imagemeta tag present- Hero image from
digitalhub.fifa.comin captioned<div>with "Image source" line #formationssection contains both lineup cards withlineup-groupelements for GK / DEF / MID / ATK- Substitutions group present in each lineup card
- Coach and Assistant Coaches groups present in each lineup card
- ≥ 10 entity-link player rows in
#core-players - Pressing gauges populated
- Timeline populated (all goals, bookings, subs)
- Red cards (
CardType-2) show 🟥 in timeline and annotations — never 🟨 - Distance & Speed Comparison
compare-blockcard withvar(--accent)/var(--accent-dim)bars --accent≠--accent-dim(visually distinct colours)- Attribution footer has exactly 7
<div class="attr-card">elements - Footer copyright:
© 2026 OpenLink Software · FIFA World Cup 2026 Match Intelligence - Head coaches identified via
fifa:CoachRole-0; assistant coaches viafifa:CoachRole-1 - Section/card
.section-titleand.card-titleelements haveonclick="copyAnchor(this)"and hover tooltip
References
references/query-templates.md— All 8 SPARQL queries, parameterised, with GRAPH clausesreferences/team-colours.md— Hex colours + text colours for all 48 WC2026 teamsreferences/verification.md— Extended verification checklist with grep commands
Scripts
scripts/report_template_create.py— Main generation engine (Python 3, stdlib only)
Example
# Norway vs Senegal (match ID 400021491)
python3 scripts/report_template_create.py \
400021491 \
"{LLM_ROOT}/Claude Generated/webpages/20260623-norway-vs-senegal.html"Output: self-contained HTML, ~84 KB, passes all 12 verification gates.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

