Metrics and audit

Metrics and audit

Every published number has a registry entry: a definition, formula, inputs, basis, source layer, coverage tier and verification mode. The audit is regenerated from the published payloads on every publish.

Registry 3.11.0, reviewed 2026-10-24. Dataset 2026-10-27T12:06:31+00:00-c598315, audited 27 Oct 2026, 12:06 UTC.

Metrics83/830 failed
Parameters26/260 failed
Auditpass60 provenance-only
Validationpass42 checks · 0 errors

Audit trail

Registry and audit artefacts

Registry version
3.11.0
Registry checksum
sha256:47f21daf427a0926a215591849c408fc3f0fab8495fc3e784803708449392cb7
Audit status
pass
Audit checksum
sha256:53e66eee321b37f151a43e43f49d4e41de57c1cf199782db0511c01dc3785902
Rows checked
4042
Fields checked
1855733
Allowlist
none
Expires
—

A pass proves the published values reproduce from the corpus where the mode is recompute, agree across payloads where it is cross_surface, and are present with an active source layer where it is provenance_only. It does not prove upstream provider accuracy or that a curated fact is true.

Validation: pass, 42 checks, 0 errors, 0 warnings. Report checksum sha256:54df2ddcce033536f5938b8ee09071a8614668185118aab2beb72cd15ca4d000.

Registry

Metric definitions

83 metrics

/competitions/

Registered metrics for the /competitions/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
table.recordLeague table recordPer-team league record and ranking inputs.
gd
gf - ga
played
won + drawn + lost
points
raw_points - deduction
raw_points
3*won + drawn
measuredleague_standingsmatchrecompute46 rows · 462 numeric leavespass
table.cutoffsLeague cutoffsLeague positions and cutoff labels.Configured league cutoffs; positions are read from config/competitions.yaml, not recomputed from results.curatedleague_standingscuratedprovenance_only4 rows · 15 numeric leavespasspresent, not recomputed
competition.indexCompetition indexCompetition identity, coverage and match counts.One row per configured competition; counts are fixtures or table rows joined by competition_id; coverage states come from the source frame.mixedleague_standingsderivedprovenance_only1 rows · 14 numeric leavespasspresent, not recomputed

/competitions/league-cup/

Registered metrics for the /competitions/league-cup/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
cup.leagueLeague CupLeague Cup groups, rounds, ties and qualifiers.Group tables: points = 3*won + drawn + shootout bonus; ties and rounds counted from cup fixtures; qualifiers read from config/cups.yaml.mixedcup_fixturesderivedprovenance_only1 rows · 1435 numeric leavespasspresent, not recomputed

/competitions/scottish-cup/

Registered metrics for the /competitions/scottish-cup/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
cup.scottishScottish CupScottish Cup rounds, ties and coverage.Rounds and ties counted from cup fixtures; coverage compares published ties with the configured official round count.mixedcup_fixturesderivedprovenance_only1 rows · 389 numeric leavespasspresent, not recomputed

/matchday/

Registered metrics for the /matchday/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
matchday.formMatchday formRecent and split form for both teams.
ga_pg
ga / played
gd
gf - ga
gd_pg
gd / played
gf_pg
gf / played
played
won + drawn + lost
points
3*won + drawn
ppg
points / played
measuredleague_results_currentmatchrecompute9 rows · 244 numeric leavespass
matchday.strengthMatchday strengthLeague strength, percentiles and comparison.ppp = points/played; ppg = points/played; gf_pg = gf/played; ga_pg = ga/played; gd_pg = (gf-ga)/played; shots_for_pm = shots/matches; shot_share = team shots/(team + opponent shots); rank = 1 + count of better teams (lower is better for ga_pg); league_size = teams in the league; position_gap and ppg_gap = team value minus opponent value. Percentiles set the bar length; ranks set the visible label.inferredleague_standingsderivedcross_surface4 rows · 57 numeric leavespass
matchday.styleMatchday styleShot profile, approach index and style lean.Approach index is the mean of within-league percentiles for shots, shots on target, goals and corners; possession is not used. Style lean is the sign of the approach index against the league median.inferredleague_team_statsderivedprovenance_only1 rows · 146 numeric leavespasspresent, not recomputed
matchday.lineupPredicted XIPredicted lineups, scores, selection weights, selection confidence and availability.Player score = 0.20*form + 0.10*minute_share + 0.15*recent_rating + 0.15*role_fit + 0.18*recency_start + 0.22*start_rate. Availability counts curated entries; opponent availability is not modelled.inferredlineups_roleseventprovenance_only1 rows · 411 numeric leavespasspresent, not recomputed
matchday.coverageMatchday coverageSnapshot, lineup and form coverage.age_hours = (generated_at - snapshot_at)/3600; lineup_coverage = fixtures_with_lineups/fixtures; counts are from the opponent snapshot.measuredleague_results_currentmatchcross_surface2 rows · 4 numeric leavespass
matchday.head-to-headHead-to-headRecent meetings and results.League meetings joined by date and team ids; result is W/D/L for Aberdeen; score is the final score, with shootouts shown separately.measuredhistorymatchprovenance_only1 rows · 6 numeric leavespasspresent, not recomputed
matchday.next-fixturesNext fixturesUpcoming club fixtures.Upcoming competitive club fixtures from the merged season schedule, ordered by local date and kickoff; current plus the next five are rendered on matchday. Conflict-review and friendly rows are excluded from the lookahead.measuredclub_fixturesmatchprovenance_only1 rows · 0 numeric leavespasspresent, not recomputed

/recruitment/

Registered metrics for the /recruitment/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
needs.summaryNeeds summaryFamily counts and availability summary.
availability_known
count squad players with availability.status != unknown
availability_unknown
squad players - availability_known
counts
count families by category
families
len(families)
inferredneedsderivedrecompute8 rows · 5 numeric leavespass
needs.familyNeeds familiesPer-family depth, quality, availability, market and roster metrics.measured_score = 100 * sum(w*x)/sum(w) over available drivers: depth_gap 0.30, quality_gap 0.20, top_share 0.10, availability_risk 0.25, age_risk 0.15. availability_risk = (out + 0.5*doubtful)/known projected players; null when known = 0.inferredneedsderivedprovenance_only1 rows · 314 numeric leavespasspresent, not recomputed
needs.roster-spaceRoster spaceRoster current/max and outgoing-first policy.roster current = senior squad players under contract; max from config/needs.yaml; outgoing-first policy is a config flag, not a measured value.curatedneedscuratedprovenance_only1 rows · 0 numeric leavespasspresent, not recomputed
needs.coverageNeeds coverageNeeds coverage and availability status.Counts of known and unknown availability entries, contract data and squad rows; states are available, partial or unavailable.mixedneedsderivedprovenance_only1 rows · 21 numeric leavespasspresent, not recomputed
rumours.profileRumour profileAdvisory recruitment profile weights and buckets.Advisory profile from active incoming external_target rows only; current squad, current non-official and former players are excluded, and return links are listed separately. Buckets are descriptive, not probabilities or recommendations.inferredrumoursderivedprovenance_only1 rows · 13 numeric leavespasspresent, not recomputed

/transfers/

Registered metrics for the /transfers/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
transfers.summaryTransfer summaryRegister totals, players and period.
confirmed
count verification_status == confirmed
curated
count verification_status == curated
players
distinct player_key
seasons_covered
distinct season
total
len(transfers)
windows_covered
distinct (season, window)
curatedtransfer_registercuratedrecompute230 rows · 6 numeric leavespass
transfers.windowTransfer windowsPer-window arrival/departure and valuation counts.
arrivals
count direction == in
departures
count direction == out
curatedtransfer_registercuratedrecompute21 rows · 420 numeric leavespass
transfers.rowTransfer rowsPer-move fee, loan and verification values.One row per confirmed move; fee is disclosed/reported/inferred/undisclosed; inferred ranges are modelled, never treated as fees; loan terms are unknown unless confirmed.curatedtransfer_registercuratedprovenance_only1 rows · 792 numeric leavespasspresent, not recomputed
transfers.valuationTransfer valuationModelled fee ranges and calibration counts.Fee range from disclosed comparables by position, age and league; calibration counts are the rows with a disclosed or reported anchor used to fit the range.inferredvaluationderivedprovenance_only1 rows · 14 numeric leavespasspresent, not recomputed
transfers.sell-onSell-on clausesSell-on percentages, basis and summary.Sell-on percentage is published only where confirmed; summary counts confirmed, reported and unknown clauses; unknown is not zero.curatedtransfer_registercuratedprovenance_only2 rows · 19 numeric leavespasspresent, not recomputed
transfers.plausibilityTransfer plausibilityWithheld suspect rows and plausibility counts.Counts of rows withheld or flagged by the plausibility audit; the audit compares fee, age, position and window against the published register.curatedtransfer_registercuratedprovenance_only1 rows · 1 numeric leavespasspresent, not recomputed
transfers.auditTransfer completeness auditSeniority review, position coverage and gap ledger counts.Counts by seniority, position coverage and gap status; the ledger records unresolved or duplicate identities, not transfer claims.curatedtransfer_registercuratedprovenance_only1 rows · 72 numeric leavespasspresent, not recomputed
transfers.coverageTransfer coverageAudited/curated window coverage.Windows are audited or curated partial; counts are confirmed rows per window; earlier windows are partial, not silently complete.curatedtransfer_registercuratedcross_surface2 rows · 0 numeric leavespass

/loans/

Registered metrics for the /loans/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
transfers.loansTransfer loansLoan-in and loan-out slices.Loan-in and loan-out rows from the confirmed register; one row per loan; parent club, dates and terms are source-linked.curatedloanscuratedprovenance_only2 rows · 124 numeric leavespasspresent, not recomputed

/history/

Registered metrics for the /history/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
history.scorecardHistory scorecardEra aggregates: seasons, managers, honours and positions.seasons = covered seasons; best/worst_position = min/max league position; average_position = mean season position; average_points = mean season points; manager_count = distinct people with a league match; honours_total = register count.mixedhistorycuratedcross_surface9 rows · 57 numeric leavespass
history.seasonHistory seasonsSeason-level history rows.One row per season; league position/points from the club payload; cup and European outcomes from season documents; manager spells kept separate.mixedhistorycuratedprovenance_only1 rows · 0 numeric leavespasspresent, not recomputed
history.staffHistory staffManager/staff stints and records.One row per manager or staff stint; played, points, gf and ga are league matches only; interim spells are separate.curatedhistorycuratedprovenance_only1 rows · 117 numeric leavespasspresent, not recomputed
history.baselineHistory baselineLeague-only baseline window.
average_points
mean(points)
average_position
mean(position)
count
len(seasons)
measuredhistorymatchrecompute7 rows · 77 numeric leavespass
history.coverageHistory coverageHistory season/backfill coverage.Counts of seasons with history documents, backfilled lineups, staff and honours; missing seasons are labelled unavailable.mixedhistorycuratedcross_surface2 rows · 90 numeric leavespass
history.season-documentHistory season documentsPer-season history documents.Document envelope: one per season with review, style, selection, staff, transfers and honours; measured facts and the labelled assessment are kept separate.mixedhistorycuratedprovenance_only8 rows · 1746 numeric leavespasspresent, not recomputed
history.defeatsHeavy defeatsCormack-era defeats by four or more goals, newest first.goals_for/goals_against are the final score for each defeat with a margin of four or more; one row per fixture, newest first; the threshold is a display parameter, not a modelled value.measuredcomputedmatchprovenance_only1 rows · 48 numeric leavespasspresent, not recomputed

/squad/

Registered metrics for the /squad/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
squad.summarySquad summarySquad size, official-roster reconciliation, loans, role evidence and coverage counts.
by_status
count players by status
loans_in
count status == loan_in
loans_out
count status == loan_out
total_players
len(players)
measuredsquad_identityeventrecompute35 rows · 72 numeric leavespass
squad.loan-scopeLoan scopesOfficial team-list loans, current-register loans and all-time register loans, with the reconciliation between them.official_list counts status loan_out in the official squad rows; register_current counts confirmed loan rows for the current season; register_all_time counts every confirmed loan row. The three are published separately and never substituted for one another.mixedloanscuratedcross_surface7 rows · 24 numeric leavespass
squad.playersSquad playersPer-player totals, playing time, role, position and official-roster reconciliation fields.Playing time reconstructed from lineups and substitution events; starts and minutes are competitive-only; role shares use starting-XI observations; totals sum competition rows.mixedsquad_identityeventprovenance_only2 rows · 7033 numeric leavespasspresent, not recomputed
squad.metaSquad metadataRole/career/position/attribute coverage metadata.Coverage flags for role, career, position and attribute data; unknown fields are null, not filled.mixedsquad_identityeventprovenance_only9 rows · 285 numeric leavespasspresent, not recomputed

/players/

Registered metrics for the /players/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
player.pagePlayer pagesPer-player page panels, two-figure Nightingale rose, availability projection and recent match log.Document envelope: player totals, playing time, role evidence, position stats, the published rose axes, the curated availability projection and the latest competitive match rows for one player. The rose uses league-only rates from the provider season totals; each percentile is the midrank rank of the raw value in the player's league and role cohort (provider-group fallback), with conceded_p90 ranked on negated values. The percentile is null when the cohort or value is unavailable. Where current-season Premiership minutes are below the squad threshold, the rose uses the most recent prior Premiership season with at least 180 league minutes and a same-season cohort; season_used, cohort_season, fallback and fallback_note are published and visible. The summary minutes remain current-season. The match log is a projection of the normalized player-match rows joined to the fixture date, opponent and score; it is not recomputed in React. mixedplayer_match_statseventprovenance_only39 rows · 8430 numeric leavespasspresent, not recomputed

/rumours/

Registered metrics for the /rumours/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
rumours.summaryRumour summaryCurated rumour counts and status.
by_affiliation
count rumours by canonical affiliation
by_confidence
count rumours by confidence
by_direction
count rumours by direction
by_status
count rumours by status
return_links
active incoming former_player rows
targets
active incoming external_target rows
total
len(rumours)
curatedrumourscuratedrecompute2 rows · 3 numeric leavespass
forum.former-profileFormer-player forum profileFormer-player mention lane and external-target profile counts.Signals are labelled by affiliation from the current squad and former register; position and age mixes count external_target only; the former lane is a filtered view of the same signal rows.mixedforum_signalderivedrecompute46 rows · 18 numeric leavespass
rumours.former-laneCurated former-player rumour laneCurated rumours whose subject is a former player.Rows whose canonical affiliation is former_player; a return link is a former player named as an incoming target and is shown separately.curatedrumourscuratedrecompute2 rows · 0 numeric leavespass

/news/

Registered metrics for the /news/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
forum.signalForum signalFan-signal coverage, sentiment and profile.Mention counts from sampled first pages; each name is labelled by canonical affiliation; the position and age profile counts external_target only; topic-level VADER sentiment only; no per-player sentiment score is published.mixedforum_signalcuratedprovenance_only1 rows · 153 numeric leavespasspresent, not recomputed

/sources/

Registered metrics for the /sources/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
provenance.layersProvenance layersLayer/source row counts and truth table.Row counts by source layer; status is the source probe state; coverage gaps remain visible in the truth table.mixedcomputedderivedprovenance_only4 rows · 28 numeric leavespasspresent, not recomputed

/status/

Registered metrics for the /status/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
coverage.surfacesCoverageBuild coverage counts across surfaces.Counts of built pages and published payloads per surface; used by the build status page.mixedcomputedderivedcross_surface3 rows · 1266 numeric leavespass
consistency.summaryCross-surface consistency auditPass/fail counts for the published cross-surface consistency checks, including the former-player, result/form, semantic, epoch and manifest checks.One record per named consistency check; passed + failed = checks.mixedcomputedderivedprovenance_only1 rows · 55 numeric leavespasspresent, not recomputed
manifest.freshnessFreshness thresholdsDataset, availability and per-source freshness states exposed to the client.Read from config/matchday.yaml stale_after_hours, config/availability.yaml policy.max_age_days and the former-player refresh timestamp.measuredcomputedderivedprovenance_only1 rows · 35 numeric leavespasspresent, not recomputed
availability.ledgerAvailabilityAvailability ledger coverage and entries.Entries require a player key, status, source id and verified_at; known/unknown counts are over the current squad; a provider injury boolean is not team news.curatedavailabilitycuratedprovenance_only1 rows · 62 numeric leavespasspresent, not recomputed

/former-players/

Registered metrics for the /former-players/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
former.definitionFormer-player definitionConfigured former-player universe, rival list, development proxy and sell-on policy.Read from config/former_players.yaml; the universe is the latest published permanent/free departure, excluding current squad, returns and loan-outs.curatedformer_player_recordcuratedprovenance_only1 rows · 5 numeric leavespasspresent, not recomputed
former.summaryFormer-player summaryFormer-player counts by departure, destination, current status, rival spell and coverage.One row per canonical former player; buckets count those rows; a missing value is unknown, never zero.mixedformer_player_recordderivedrecompute77 rows · 85 numeric leavespass
former.playersFormer-player rowsOne row per canonical former player with departure, Aberdeen record, post-career summary and sell-on reference.The universe rule, then one Aberdeen tenure aggregation and one post-career league aggregation per player. Provider ratings stay league-relative.mixedformer_player_recordderivedcross_surface78 rows · 3660 numeric leavespass
former.post-seasonsFormer-player post-Aberdeen seasonsLeague season rows and per-season rates after the Aberdeen departure.League-only provider seasons after departure; per-90 rates only above the configured minutes gate; no cross-league percentile.measuredformer_player_recordmatchrecompute78 rows · 2876 numeric leavespass
former.sell-onFormer-player sell-on watchSell-on clause event, receipt and missing-input state.Detect the first permanent/free move away from the buyer; compute a receipt only when percentage, basis and every required public fee are evidenced; otherwise return the missing inputs.mixedsell_on_eventscuratedrecompute5 rows · 18 numeric leavespass
former.scorecardFormer-player development scorecardDescriptive exit cohorts and post-Aberdeen distributions.Counts and distributions over the canonical former players; young exits at the configured age, developed proxy at the configured debut age and starts; no composite score.mixedformer_player_recordderivedrecompute77 rows · 65 numeric leavespass
former.coverageFormer-player coverageBackfill counts, gaps and current-club coverage.Expected player-seasons from departure to current; present league seasons; gaps and provider budget from the local backfill meta.measuredformer_player_recordderivedcross_surface78 rows · 22 numeric leavespass

/

Registered metrics for the / surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
clubs.aberdeenClub payloadAberdeen club summary, history and news rows.Club summary joins league table, recent results, upcoming fixtures and news metadata by club id; no commercial or attendance series is invented.mixedleague_results_currentmatchprovenance_only1 rows · 301 numeric leavespasspresent, not recomputed

/claims/

Registered metrics for the /claims/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
case.documentThe case documentOwner view, chairman frame, thesis and state.Document envelope: owner view, chairman frame, thesis, claims and coverage state; opinion is attributed, measured counts are labelled.mixedthemesderivedprovenance_only4 rows · 0 numeric leavespasspresent, not recomputed
case.claimsThe case claimsThe claim register: order, domain, status and counts.One row per claim; count is the qualifying rows in the claim evidence table; status is supported, partial, can't test yet or not supported; order is editorial.mixedthemesderivedprovenance_only1 rows · 6 numeric leavespasspresent, not recomputed
case.evidenceClaim evidenceThe evidence table attached to each claim.One row per evidence item; count is the observed value, sample is the denominator or qualifying set; source and period are carried with the row.mixedthemesderivedprovenance_only1 rows · 0 numeric leavespasspresent, not recomputed
case.benchmarkPeer benchmarkLeague performance of the other SPFL clubs.League performance of the other SPFL clubs: best/worst/median position and points from the computed tables; current is the latest season position.measuredthemesmatchprovenance_only1 rows · 39 numeric leavespasspresent, not recomputed
case.coverageCase coverageAvailability, history and missing data classes.Counts of known and unknown data classes; unknown is not zero and is listed in the coverage block.mixedthemesderivedprovenance_only1 rows · 0 numeric leavespasspresent, not recomputed
case.claim.team-nowThe team nowLeague record and kick-off shape churn.played = competitive matches in the period; points = 3*won + drawn; gf/ga = league goals for/against; form = last five league results; churn = kick-off shape changes.measuredthemesmatchprovenance_only1 rows · 1 numeric leavespasspresent, not recomputed
case.claim.defenceThe defenceThree-at-the-back record, wide roles and availability.matches = matches with three centre-backs at kick-off; points_pg = points/matches; ga_pm = goals against/matches; wb_starts_pm = wing-back starts/matches; wf_starts_pm = wide-forward starts/matches; denominator = qualifying matches only.measuredthemesmatchprovenance_only1 rows · 1 numeric leavespasspresent, not recomputed
case.claim.attackThe attackGoals, shot share and the set-play/error gap.gf/ga = league goals; shot_share = Aberdeen shots/(Aberdeen + opponent shots); attack_share = goals from wide forwards and strikers/total league goals; roles from the starting-XI grid.measuredthemesmatchprovenance_only1 rows · 1 numeric leavespasspresent, not recomputed
case.claim.managersThe managersManager phases, runs and the cup.played/ppg by manager stint; winning_run/winless_run = longest league run; cup outcome from the honours register; interim spells are separate.measuredthemesmatchprovenance_only1 rows · 1 numeric leavespasspresent, not recomputed
case.claim.squadThe squadArrivals, departures, age, U21 minutes and the Morris sale.arrivals/departures = confirmed register rows in the window; median_age = median current squad age; u21_minutes_share = U21 minutes/total minutes; Morris sale = confirmed transfer.mixedthemescuratedprovenance_only1 rows · 1 numeric leavespasspresent, not recomputed
case.claim.chairman-recordThe chairman's recordThe Cormack-era record, managers, honours and transfers.seasons = covered seasons; positions from computed league tables; honours from the register; manager_count = distinct people; europe from season documents.mixedthemescuratedprovenance_only1 rows · 1 numeric leavespasspresent, not recomputed

/matches/

Registered metrics for the /matches/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
matches.documentMatch documentOne played-fixture document: score, summary, scoreboard, stats, fxG with model and goals ranges, timeline, lineups, player stats, performance, form and coverage.One document per canonical played fixture; final score is authoritative; summary, timeline and scoreboard use regular goals only; missing classes are null with coverage labels; duplicate aliases are separate. The xg block carries fxG, an 80% model range, an 80% goals range, provider xG with its source, shots, penalties, xG per shot and the over/underperformance position.mixedcomputedmatchprovenance_only371 rows · 193006 numeric leavespasspresent, not recomputed
fixtures.indexFixture indexThe fixture index: played results plus the remaining scheduled fixtures.count = canonical played fixtures (duplicate aliases excluded); each played row carries score, result, depth and href. scheduled = remaining canonical fixtures after the played registry and conflict handling. scheduled_count = rows with status scheduled; scheduled_rows_total includes conflict_review rows; conflict_count = conflict_review rows. Conflict-review rows are retained but excluded from forward-looking surfaces.measuredcomputedmatchprovenance_only1 rows · 1152 numeric leavespasspresent, not recomputed
xg.shot-profilefxG shot profileMeasured shots, shots on target, off-target, blocked, inside-box, outside-box and penalty counts behind a team-match fxG value.Counts are carried from the licensed team statistics and event feed; missing values are null, never zero.measuredleague_team_statsmatchprovenance_only370 rows · 4274 numeric leavespasspresent, not recomputed

/analysis/

Registered metrics for the /analysis/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
analysis.summarySeason overviewCurrent position and form, next fixtures, official and derived availability, measured aims, squad-decision lenses and the category bridges.A projection of the current table row, the merged season schedule, the AFC availability ledger, sourced card rules, named-squad membership, matchday contenders, the season expectations and factual squad-decision lenses. No value, fee, wage, contract expiry or medical diagnosis is derived. Counts sum to the active universe (official list minus loanees out); the five official loan-outs are separate. Aims are analyst-set targets with a measured current value and status; they are not club targets. mixedcomputedderivedprovenance_only1 rows · 297 numeric leavespasspresent, not recomputed

/analysis/xg/

Registered metrics for the /analysis/xg/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
xg.documentfxG documentTeam-match expected goals from open-play shot zones, shots on target, blocked shots and penalties; a model range, a goals range, provider-xG calibration, transfer check, provider-style estimate, manager splits, aggregates and coverage.open_play_sot = max(0, shots_on_target - penalty_sot_subtracted); open_play_insidebox = max(0, shots_insidebox - penalty_attempts); fxG_open = a selected linear model on open-play inside-box, outside-box, shots on target, off-target and blocked counts; fxG = fxG_open + 0.76 * penalty_attempts. Coefficients are fitted by OLS to 2026-27 Premiership team rows where provider xG exists. The 80% model range is the 10th-90th percentile of match-clustered bootstrap predictions plus the leave-one-match-out residual pool. The 80% goals range is the convolution of a beta-binomial open-play distribution and a binomial penalty distribution. Aggregate variances are combined, never summed as intervals. provider_estimate = max(0, intercept + slope * fxg) for rows without provider xG; actual and estimated provider values are never summed. manager_splits sum league match rows by date-attributed manager stint, for and against separately.inferredcomputedderivedprovenance_only1 rows · 13980 numeric leavespasspresent, not recomputed
xg.per-shotxG per shotExpected goals divided by shots for a team match or aggregate.fxg_per_shot = fxg / shots; null when shots is zero or unavailable.inferredcomputedmatchprovenance_only373 rows · 1166 numeric leavespasspresent, not recomputed
xg.goals-minusGoals minus fxGObserved goals minus the team-match fxG estimate, with a shifted goals range.goals_minus_fxg = goals - fxg. The shifted goals range is goals_low - fxg to goals_high - fxg.inferredcomputedmatchprovenance_only373 rows · 1176 numeric leavespasspresent, not recomputed
xg.model-rangefxG model rangeThe 80% range for the fxG estimate.10th-90th percentile of match-clustered bootstrap predictions plus a draw from the leave-one-match-out residual pool. Aggregates sum per draw; per-match ranges are never summed as intervals.inferredcomputedmatchprovenance_only744 rows · 1770 numeric leavespasspresent, not recomputed
xg.goals-rangeGoals rangeThe 80% range of goals from the same chances.Convolution of a beta-binomial open-play goal distribution and a binomial penalty distribution; aggregate distributions are convolved across matches. The range is the 10th-90th percentile.inferredcomputedmatchprovenance_only744 rows · 1770 numeric leavespasspresent, not recomputed

/scouting/

Registered metrics for the /scouting/ surface.
MetricDefinitionFormulaBasisSourceCoverageVerificationStatus
scouting.poolScouting player poolOne row per ranked player per league with provider season statistics, within-league role percentiles and profile scores.Per-90 values are stat * 90 / minutes. Completed passes are passes_total * pass_accuracy / 100. Duel and dribble percentages divide by their provider attempts; conversion divides goals by shots; save percentage divides saves by saves + conceded. The rating percentile is the midrank percentile of the provider rating within the league and role family at 450+ minutes; the provider-group fallback is used only when the role cohort is below its minimum. Archetype scores are 100 * Phi(sum(w * shrunk robust z) / sum(abs(w))), with winsorisation at 1/99, median/MAD scaling, minutes shrinkage and weight renormalisation. The rose uses the same league-only rates: each axis is the midrank percentile of the raw value in the same role-family cohort (provider group fallback), with conceded_p90 ranked on negated values. Missing values and insufficient cohorts are null. mixedscouting_poolmatchprovenance_only39 rows · 584252 numeric leavespasspresent, not recomputed
scouting.boardScouting weakness boardAberdeen role-family ratings against the Scottish Premiership cohort, with verified availability evidence.The family average is the appearance-weighted mean provider rating of Aberdeen players at 300+ competitive minutes in the role family. The percentile is the midrank position of that average within the other Premiership players in the same role family at 450+ minutes; Aberdeen are excluded from their own cohort. The reading is structural below 40, at 40-60, above 60; a below-cohort family with one absent first-choice player is cover, two or more is hold. First-choice evidence is 10 starts or 900 minutes in the most recent prior season with at least 450 minutes. mixedscouting_poolderivedprovenance_only2 rows · 561 numeric leavespasspresent, not recomputed
scouting.archetypesScouting archetype profilesWeighted player-profile scores, their feature weights, coverage, the attacker assist/goal split and the dedicated goal-scoring list.Each archetype is a weighted composite of winsorised, robust z-scores within league and role family: z = (x - median) / (1.4826 * MAD), shrunk by minutes / (minutes + 450), combined with signed weights and mapped to 0-100 by the normal CDF. Missing features are removed and the remaining absolute weights renormalised; below 70% coverage the score is null. Weights are in config/scouting/archetypes.yaml and are published with the score. inferredcomputedderivedprovenance_only2 rows · 1353 numeric leavespasspresent, not recomputed
scouting.team-lensScouting team-context lensPlayers outperforming teams that are underperforming in their league.Team points per game = points / played in the provider's current league table. The team points percentile is the midrank percentile of that value among the league's teams. team_lift = player role-adjusted percentile - team points percentile. A team is underperforming when its percentile is at or below the configured maximum (default 40). The lens keeps players with a positive lift at those teams, ordered by lift then scouting priority. A league without a table is unknown, never zero-strength. inferredcomputedderivedprovenance_only36 rows · 430940 numeric leavespasspresent, not recomputed
scouting.squadScouting squad profileAberdeen registered-squad position-specific per-90 output, competitive matches only.The same per-90 and percentage formulas as scouting.pool, applied to the registered Aberdeen squad in competitive matches only (friendlies and loan-club rows excluded), at 180+ minutes. The rating is appearance-weighted; the percentile is within the Premiership role cohort. The rose uses Premiership-only rates against the same league and role cohort. mixedsquad_identitymatchprovenance_only1 rows · 1383 numeric leavespasspresent, not recomputed
scouting.coverageScouting coveragePer-league provider coverage, role coverage and pool counts.Counts of provider player-season rows, rated rows, rows at 450+ minutes, players with at least one starting-XI role, played fixtures and lineups fetched. Role coverage is role players divided by the league pool. Searchable requires at least 25 rated players. measuredscouting_poolderivedprovenance_only3 rows · 1470 numeric leavespasspresent, not recomputed
scouting.value-modelScouting value modelThe 0-100 scouting value index and the anchor-gated GBP value model.Value index = 100 * sum(w_i * component_i) / sum(w_i) over performance (league-adjusted percentile / 100), age curve, minutes reliability (min(1, minutes / 1800)) and best adjusted profile score / 100. Weights are renormalised over available components and the index is null below 70% coverage. The GBP band is fitted only after the public-source anchor gate passes: log(value_gbp) = b0 + b1*adjusted_percentile/100 + b2*age + b3*age^2 + b4*log(minutes) + role-group dummies. The published band is the 80% prediction interval. No GBP value is published before the gate. inferredcomputedderivedprovenance_only2 rows · 70 numeric leavespasspresent, not recomputed
scouting.priorityScouting priorityU23 and European shop-window weighting on top of the value index.scouting_priority = value_index * age_multiplier * europe_multiplier. age_multiplier = u23_multiplier when age <= u23_max_age, else 1.0. europe_multiplier = europe_multiplier when european league-phase minutes >= europe_minutes_threshold, else 1.0. The European flag is built from the league-phase fixtures of the Champions League, Europa League and Conference League and the per-fixture player endpoint; qualifiers and play-offs are excluded. A player not found is none only when coverage is complete; otherwise the status is unknown and the multiplier is 1.0. inferredcomputedderivedprovenance_only43 rows · 585101 numeric leavespasspresent, not recomputed

Parameters

Config-backed thresholds and weights

26 parameters

matchday

Config parameters for matchday.
ParameterValueUnitUsed byConfigVerificationStatus
param.matchday.styleMatchday style policy{"attack_index":60,"attack_shot_share":0.5,"counter_index":40,"counter_shot_share":0.48,"min_matches":4,"overall_weight":0.4,"venue_min_matches":3,"venue_weight":0.6,"weights":{"goals_for":0.2,"shot_share":0.25,"shots_for":0.4,"shots_on_target_for":0.15}}mixedmatchday.stylematchday.styleconfig_matchpass
param.matchday.predictionMatchday prediction policy{"formation_window":6,"min_role_fit":0.3,"position_group_fit":{"D":{"CB":0.3,"DM":0.2,"LB":0.3,"LWB":0.3,"RB":0.3,"RWB":0.3},"F":{"AM":0.2,"LW":0.3,"RW":0.3,"ST":0.3},"GK":{"GK":0.3},"M":{"AM":0.3,"CM":0.3,"DM":0.3,"LM":0.3,"RM":0.3}},"recency_weights":[6,5,4,3,2,1],"role_adjacency":{"AM":{"AM":1,"CM":0.7,"LW":0.6,"RW":0.6,"ST":0.5},"CB":{"CB":1,"DM":0.3,"LB":0.6,"RB":0.6},"CM":{"AM":0.7,"CM":1,"DM":0.8},"DM":{"CB":0.4,"CM":0.7,"DM":1},"GK":{"GK":1},"LB":{"CB":0.5,"LB":1,"LM":0.4,"LWB":0.9},"LM":{"CM":0.4,"LB":0.5,"LM":1,"LW":0.9},"LW":{"AM":0.5,"LM":0.8,"LW":1,"ST":0.5},"LWB":{"LB":0.8,"LM":0.5,"LW":0.4,"LWB":1},"RB":{"CB":0.5,"RB":1,"RM":0.4,"RWB":0.9},"RM":{"CM":0.4,"RB":0.5,"RM":1,"RW":0.9},"RW":{"AM":0.5,"RM":0.8,"RW":1,"ST":0.5},"RWB":{"RB":0.8,"RM":0.5,"RW":0.4,"RWB":1},"ST":{"AM":0.4,"LW":0.5,"RW":0.5,"ST":1}},"scoring":{"form":0.2,"minute_share":0.1,"recency_start":0.18,"recent_rating":0.15,"role_fit":0.15,"start_rate":0.22}}mixedmatchday.lineupmatchday.predictionconfig_matchpass
param.matchday.refreshMatchday refresh and sample policy{"contenders":6,"max_api_requests":24,"min_lineup_matches":3,"recent_fixtures":6,"refresh_after_hours":20,"stale_after_hours":48}mixedmatchday.form, matchday.lineup, matchday.coveragematchdayconfig_matchpass

needs

Config parameters for needs.
ParameterValueUnitUsed byConfigVerificationStatus
param.needs.thresholdsNeeds thresholds{"age_risk_strengthen":0.5,"availability_risk_cover":0.25,"cover_buffer":1,"depth_gap_cover":0.5,"quality_gap_strengthen":0.35,"quality_minutes":900,"ready_minutes":180,"ready_starts":2,"reliance_top_share":0.55,"starter_minutes":450,"starter_starts":5,"trusted_starts":3,"weak_family_delta":-0.15}mixedneeds.family, needs.summaryneeds.thresholdsconfig_matchpass
param.needs.familiesNeeds family policy{"AM/WM":{"label":"Attacking / wide midfield","market":["loan","free_agent","fee"],"max_squad":5,"min_available":3,"scouting_groups":["AM"],"traits":["key_passes_p90","dribbles_success_pct","shots_p90","progressive_carries_p90"]},"CB":{"label":"Centre-backs","market":["loan","free_agent","fee"],"max_squad":5,"min_available":4,"scouting_groups":["CB"],"traits":["aerial_win_pct","duel_win_pct","progressive_passes_p90","clearances_p90"]},"FB/WB":{"label":"Full-backs / wing-backs","market":["loan","free_agent","fee"],"max_squad":6,"min_available":4,"scouting_groups":["FB"],"traits":["crosses_p90","progressive_carries_p90","tackles_p90","duels_won_pct"]},"GK":{"label":"Goalkeepers","market":["loan","free_agent"],"max_squad":4,"min_available":2,"scouting_groups":["GK"],"traits":["saves_p90","save_pct","crosses_claimed_p90","pass_completion"]},"MID":{"label":"Central midfield","market":["loan","free_agent","fee"],"max_squad":7,"min_available":4,"scouting_groups":["DM","CM"],"traits":["progressive_passes_p90","tackles_p90","interceptions_p90","pass_completion"]},"ST":{"label":"Centre-forwards","market":["loan","free_agent","fee"],"max_squad":4,"min_available":2,"scouting_groups":["ST"],"traits":["shots_p90","goals_per_shot","aerial_win_pct","touches_in_box_p90"]},"W":{"label":"Wide forwards","market":["loan","free_agent","fee"],"max_squad":5,"min_available":3,"scouting_groups":["W"],"traits":["dribbles_success_pct","crosses_p90","shots_p90","touches_in_box_p90"]}}mixedneeds.family, needs.roster-spaceneeds.familiesconfig_matchpass

transfers

Config parameters for transfers.
ParameterValueUnitUsed byConfigVerificationStatus
param.transfers.auditTransfer audit thresholds{"manual_finding_aids":{"allowed":true,"automated_access":false,"publication":false},"prior_seasons":["2024-25","2025-26"],"recent_windows":4,"seniority":{"established_min_career_starts":10,"established_min_minutes":450,"established_min_starts":5,"youth_max_age":20,"youth_max_appearances":4},"start_season":"2024-25"}mixedtransfers.row, transfers.coveragetransfers.auditconfig_matchpass
param.transfers.valuationTransfer valuation policy{"currency":"GBP","fx_to_gbp":{"EUR":0.85,"GBP":1,"USD":0.78},"note":"Manual calibration may use restricted pages as a private sanity check only; no restricted value, URL or scraped table is published. Every inferred output is a range with a confidence label.\n","range_high":1.6,"range_low":0.6}mixedtransfers.valuationtransfers.valuationconfig_matchpass

availability

Config parameters for availability.
ParameterValueUnitUsed byConfigVerificationStatus
param.availability.policyAvailability policy{"allowed_hosts":["afc.co.uk","www.afc.co.uk"],"conflict_confidence_downgrade":2,"doubtful_confidence_downgrade":1,"doubtful_weight":0.5,"filter_statuses":["out","suspended"],"fresh_days":7,"max_age_days":21,"require_source_url":true,"returned_weight":0.9,"stale_confidence_downgrade":1,"unknown_confidence_downgrade":1,"unknown_weight":1}mixedavailability.ledgeravailability.policyconfig_matchpass
param.availability.providerAvailability provider policy{"endpoint":"/injuries","league_id":179,"never_sets":["available","returned","suspended"],"require_league_coverage":true,"source":"api_football","use_player_injured_boolean":false}mixedavailability.ledgeravailability.providerconfig_matchpass

competitions

Config parameters for competitions.
ParameterValueUnitUsed byConfigVerificationStatus
param.competitionsCompetition policy[{"api_football_id":179,"code":"SC0","cutoffs":[{"after_position":3,"kind":"europe","label":"European places · 1–3","note":"4th is conditional on the Scottish Cup winner already being in the top three."},{"after_position":6,"kind":"split","label":"Top-six / bottom-six split","note":"The league splits after 33 matches; the bottom six cannot finish higher than 7th."},{"after_position":10,"kind":"playoff","label":"Relegation play-off · 11th","note":"11th plays the Championship play-off winner over two legs."},{"after_position":11,"kind":"relegation","label":"Relegation · 12th","note":"12th is relegated automatically."}],"id":"sco:premiership","matches_per_season":228,"name":"Scottish Premiership","qualification_note":"Scotland has four UEFA places for 2027/28: the champions enter the Champions League second qualifying round, the Scottish Cup winner enters the Europa League first qualifying round, and 2nd and 3rd enter the Conference League second qualifying round. 4th only qualifies if the Scottish Cup winner is already in the top three. The League Cup carries no European place. Subject to the final UEFA access list and cup outcomes.\n","short_name":"Premiership","split_after_matches":33,"teams":12,"tier":1},{"api_football_id":180,"code":"SC1","cutoffs":[{"after_position":1,"kind":"promotion","label":"Automatic promotion · 1st","note":"1st is promoted to the Premiership."},{"after_position":4,"kind":"playoff","label":"Promotion play-off · 2nd–4th","note":"2nd–4th enter the Premiership play-off with 11th in the Premiership."},{"after_position":8,"kind":"playoff","label":"Relegation play-off · 9th","note":"9th enters the Championship/League One play-off with 2nd–4th in League One."},{"after_position":9,"kind":"relegation","label":"Relegation · 10th","note":"10th is relegated to League One."}],"id":"sco:championship","matches_per_season":180,"name":"Scottish Championship","qualification_note":"1st is promoted automatically. 2nd–4th enter the Premiership play-off with 11th in the Premiership. 9th enters the Championship/League One play-off, and 10th is relegated to League One.\n","short_name":"Championship","teams":10,"tier":2},{"api_football_id":183,"code":"SC2","cutoffs":[{"after_position":1,"kind":"promotion","label":"Automatic promotion · 1st","note":"1st is promoted to the Championship."},{"after_position":4,"kind":"playoff","label":"Promotion play-off · 2nd–4th","note":"2nd–4th enter the Championship/League One play-off with 9th in the Championship."},{"after_position":8,"kind":"playoff","label":"Relegation play-off · 9th","note":"9th enters the League One/League Two play-off with 2nd–4th in League Two."},{"after_position":9,"kind":"relegation","label":"Relegation · 10th","note":"10th is relegated to League Two."}],"id":"sco:league-one","matches_per_season":180,"name":"Scottish League One","qualification_note":"1st is promoted automatically. 2nd–4th enter the Championship play-off with 9th in the Championship. 9th enters the League One/League Two play-off, and 10th is relegated to League Two.\n","short_name":"League One","teams":10,"tier":3},{"api_football_id":184,"code":"SC3","cutoffs":[{"after_position":1,"kind":"promotion","label":"Automatic promotion · 1st","note":"1st is promoted to League One."},{"after_position":4,"kind":"playoff","label":"Promotion play-off · 2nd–4th","note":"2nd–4th enter the League One/League Two play-off with 9th in League One."},{"after_position":9,"kind":"pyramid","label":"Pyramid play-off · 10th","note":"10th faces the tier-five group winner; no automatic relegation."}],"id":"sco:league-two","matches_per_season":180,"name":"Scottish League Two","qualification_note":"1st is promoted automatically. 2nd–4th enter the League One play-off with 9th in League One. 10th enters the pyramid play-off against the winner of the Highland / Lowland East / Lowland West champions' group; there is no automatic relegation, and the League Two club hosts the second leg.\n","short_name":"League Two","teams":10,"tier":4}]mixedtable.record, table.cutoffs, competition.indexcompetitions.competitionsconfig_matchpass
param.competitions.historyCompetition history backfill{"all_four_from":"1997-98","default_backfill_from":"2013-14","first_season":"1994-95"}mixedtable.record, table.cutoffscompetitions.historyconfig_matchpass
param.competitions.validationCompetition validation policy{"curtailed":{"2019-20":["SC0","SC1","SC2","SC3"],"2020-21":["SC1","SC2","SC3"]}}mixedtable.recordcompetitions.validationconfig_matchpass

themes

Config parameters for themes.
ParameterValueUnitUsed byConfigVerificationStatus
param.case.thresholdsCase thresholds{"balance":{"medium_matches":6},"depth":{"concentration_high":0.55,"rotation_minutes":90,"starter_minutes":450,"starter_starts":5,"thin_rotation_starts":3},"family":{"high_matches":6,"high_minutes":900,"medium_matches":3,"medium_minutes":450},"mission":{"min_arrivals_for_confidence":5},"shape":{"medium_matches":3}}mixedcase.claim.defence, case.claim.attack, case.claim.managersthemes.thresholdsconfig_matchpass
param.case.scopeCase scope{"bench":"premiership","minutes":"all_competitive","ratings":"premiership","shapes":"all_competitive"}mixedcase.claim.team-now, case.claim.defence, case.claim.attackthemes.scopeconfig_matchpass

xg

Config parameters for xg.
ParameterValueUnitUsed byConfigVerificationStatus
param.xgfxG model policy{"calibration":{"competition_id":"sco:premiership","features":["inside_box","outside_box","shots_on_target","blocked"],"league_id":179,"min_matches":45,"min_team_rows":90,"min_zone_coverage":0.8,"season":"2026-27"},"evaluation":{"calibration_slope_max":1.3,"calibration_slope_min":0.7,"max_abs_bias":0.15,"max_mae":0.55,"method":"leave_one_match_out","validation_season":"2026-27"},"fit":{"before_season":"2026-27","exclude_competition_prefixes":["sco:other:friendlies"],"min_shots_on_target":120,"prior_strength_sot":250},"goals_range":{"level":0.8,"max_dispersion":3,"max_support":5000,"method":"binomial_penalty"},"interval":{"bootstrap_draws":2000,"draws":10000,"level":0.8,"seed":20261022,"z":1.2816},"penalty":{"missed_on_target":true,"source":"fixed historical penalty conversion prior; see docs/xg.md","xg":0.76},"transfer_check":{"competition_id":"sco:premiership","season":"2025-26","source":"api_football"}}mixedxg.documentxgconfig_matchpass

fixtures

Config parameters for fixtures.
ParameterValueUnitUsed byConfigVerificationStatus
param.fixturesFixture record policy{"matching":{"date_tolerance_days":0,"overrides":{}},"pages":{"depth_labels":{"full":"Full record","partial":"Partial record","result":"Result, events and lineups","score":"Score only"},"full_classes":["events","lineups","team_stats","player_stats"],"partial_classes":["events","lineups","team_stats","player_stats"],"result_classes":["events","lineups"],"route_prefix":"/matches","score_classes":[],"summary":{"late_goal_minute":85,"stoppage_time_minute":90}},"scope":{"first_season":"2019-20","friendly_competition_prefixes":["sco:other:friendlies"],"include_friendlies":true,"last_season":"2026-27"}}mixedmatches.document, fixtures.indexfixturesconfig_matchpass

scouting/model

Config parameters for scouting/model.
ParameterValueUnitUsed byConfigVerificationStatus
param.scoutingScouting model policy{"archetypes":{"min_minutes":450,"min_weight_coverage":0.7,"shrink_minutes":450,"winsor_high":0.99,"winsor_low":0.01},"board":{"first_choice_minutes":900,"first_choice_starts":10,"min_minutes":300,"prior_min_minutes":450,"prior_seasons":3,"status_above":60,"status_below":40},"coverage":{"min_rated_players":25},"pool":{"fallback_group_min":15,"low_minutes":900,"min_cohort":15,"min_cohort_by_family":{"goalkeeper":8},"min_minutes":450},"squad":{"min_minutes":180}}mixedscouting.pool, scouting.board, scouting.archetypes, scouting.squad, scouting.coveragescouting/modelconfig_matchpass

scouting/value

Config parameters for scouting/value.
ParameterValueUnitUsed byConfigVerificationStatus
param.scouting.valueScouting value policy{"fit":{"interval":0.8,"max_value_age_days":550,"min_age_bands":3,"min_anchors":60,"min_league_tiers":3,"min_minutes":450,"min_role_anchors":5,"top_tier_share":0.2},"index":{"age_curve":[{"factor":0.5,"max_age":18},{"factor":0.7,"max_age":20},{"factor":0.9,"max_age":23},{"factor":1,"max_age":27},{"factor":0.8,"max_age":29},{"factor":0.55,"max_age":31},{"factor":0.3,"max_age":120}],"min_weight_coverage":0.7,"minutes_full":1800,"weights":{"age":0.15,"minutes":0.15,"performance":0.55,"profile":0.15}},"priority":{"europe_minutes_threshold":90,"europe_multiplier":0.6,"u23_max_age":23,"u23_multiplier":1.3}}mixedscouting.value-model, scouting.priorityscouting/valueconfig_matchpass

player-rose

Config parameters for player-rose.
ParameterValueUnitUsed byConfigVerificationStatus
param.player.rosePlayer rose policy{"min_petals":4}mixedplayer.page, scouting.pool, scouting.squadplayer-roseconfig_matchpass

analysis

Config parameters for analysis.
ParameterValueUnitUsed byConfigVerificationStatus
param.analysisSeason overview policy{"absence":{"confidence_cap":"medium","consecutive_omissions":2,"min_squad_inclusions":5,"min_starts_or_bench":3,"window_fixtures":6},"matchday_lookahead":6,"next_up":3,"selection_watch":3,"squad_decisions":{"low_minutes_age_min":23,"low_minutes_share_max":0.25,"max_per_lens":3,"peak_age_min":27,"peak_minutes_min":450,"percentile_min_cohort":8},"suspensions":{"require_verified_rule":true}}mixedanalysis.summaryanalysisconfig_matchpass

scouting/team-context

Config parameters for scouting/team-context.
ParameterValueUnitUsed byConfigVerificationStatus
param.scouting.team-contextScouting team-context policy{"lens_limit":12,"min_lift":0,"note":"A team is treated as underperforming when its points-per-game percentile is at or below the threshold. A player must have a positive lift. Empty leagues or teams without a current table stay unknown, never zero-strength.\n","underperforming_ppg_percentile_max":40}mixedscouting.team-lensscouting/team-contextconfig_matchpass

former_players

Config parameters for former_players.
ParameterValueUnitUsed byConfigVerificationStatus
param.former-rivalsFormer-player rival list{"rivals":[{"club_id":"sco:celtic","name":"Celtic"},{"club_id":"sco:rangers","name":"Rangers"},{"club_id":"sco:dundee-united","name":"Dundee United"}]}mixedformer.definition, former.summary, former.players, former.scorecardformer_playersconfig_matchpass
param.former-developedFormer-player development proxy{"development":{"debut_age_max":21,"min_starts":10,"young_exit_age_max":23}}mixedformer.players, former.scorecardformer_playersconfig_matchpass
param.former-scorecardFormer-player scorecard thresholds{"scorecard":{"min_post_minutes":90,"min_post_seasons":1}}mixedformer.scorecardformer_playersconfig_matchpass
param.former-sell-onFormer-player sell-on policy{"sell_on":{"allowed_basis":["gross_fee","profit"],"fx_to_gbp":{"EUR":0.85,"GBP":1,"USD":0.78},"require_basis":true,"require_percentage":true,"require_public_fee":true}}mixedformer.sell-onformer_playersconfig_matchpass
param.former-backfillFormer-player backfill policy{"post_career":{"backfill_max_requests":400,"current_season_ttl_hours":24,"historical_ttl_hours":720,"league_tiers":{"39":{"country":"England","tier":1},"61":{"country":"France","tier":1},"78":{"country":"Germany","tier":1},"135":{"country":"Italy","tier":1},"140":{"country":"Spain","tier":1}},"max_requests_per_run":400,"min_minutes_for_rates":180,"refresh_max_requests":180,"request_interval_seconds":0.3,"source":"api_football","transfers_ttl_hours":168}}mixedformer.players, former.post-seasons, former.coverageformer_playersconfig_matchpass

Method

Verification modes

Verification modes, what each proves and what it does not prove.
ModeWhat it provesWhat it does not proveMetrics
recomputeRe-derived from published rows using the registered formula.Upstream provider accuracy.14
cross_surfaceThe same fact agrees across two payloads.Formula correctness.9
config_matchThe registry parameter equals config.The config is analytically right.0
source_checksumThe curated source file is unchanged since audit.The source fact is true.0
provenance_onlyThe value is present and its declared layer is active with rows.Independent recomputation.60

Coverage tiers: event, match, curated, value_only, derived and unknown. The most detailed tier an input supports is declared; a derived or inferred value is never labelled measured.

A number is any value, rate, percentage, count, rank, range, confidence, coverage label, threshold or weight. Changing a formula, denominator, rounding mode, source, coverage tier, confidence rule or parameter needs owner approval, a metric/registry version bump and an entry in the metric changelog.

Related

Sources, method and build status

Provenance

How this page is sourced

Data as of 27 Oct 2026

Dataset 2026-10-27T12:06:31+00:00-c598315. Sources and coverage are listed below; the page keeps its own source and uncertainty labels.

The registry and audit describe definitions; they are not a data table.

Corrections and changes are recorded on Corrections and contact.

Cite this page

Metrics and audit. Dataset 2026-10-27T12:06:31+00:00-c598315, as of 2026-10-27T12:06:31+00:00. Source: published fitba record.