Contract
3.16.0
Tool contract 3.16.0
The control next to every number (docs/reviews/2026-09-19-INTERFACE-REVIEW.md Part 4, Phase 3): every tool that serves a rate, trend, rank or sum carries the control the 3.13.0 principle names, and a note fires only on a detected confound.
players_summary:last_30_days.modes(the window's battles by mode group);top_deckandbest_deckcarrymodesanddominant_mode;trophy_floorwhen the window holds ladder battles; the deck comparability note and the floor note.clans_standingsmembers carrymodes,ladder_battles,mean_level_gapandlevel_gap_battles,log_recordedandrecorded_since; the response carriescomparable(false when two ranked members' dominant modes differ or their gaps are half a level apart, the note naming them) andbasis(recorded|roster_and_war_only).trophy_netreads null whenladder_battlesis 0, where it read an ambiguous 0 before (a field the docs never defined as a sum-or-zero).battles_trendsweeks carrymodes(the week's battles by mode group) and, when the window clips a week,partial: truewithcovers {from, to}and a note; a pooled-modes note fires whenmodewas omitted and a week holds more than one group.battles_meta_decksandbattles_meta_cardsrows carrymodesandmean_level_gap(deck rowslevel_gap_battlesanddominant_modetoo); the response carriescomparable,modes_in_windowwhenmodewas omitted, the pooled-modes note, and on a segment read a note when every returned row is one player's.- The three meta tools take
trophy_band(under_5000,5000_8000,8000_11000,11000_13000,13000_plus: the observation's own player's starting trophies), answered from a banded season rollup once the nightly rebuild has filled it and from the raw rows with a note before;cards_synergy's anchor carriesmodes. clans_pilot_scoresmembers carrymean_starting_trophies,modal_arena {id, name}(the population they were scored in) andcurrent_arena, with a note naming the members whose modal arena inside the window differs from their current one.clans_participationmembers carrylog_recorded,recorded_since,last_battle_time_in_clanandwar_days_battled(per war week, null without coverage); the response carriesbasis(recorded|roster_and_war_only) and the activity-scope note.clans_timelinegains themembers_with_profileaggregate (the denominator of the profile-derived ones);war_rivalsrows carrycolosseum_raceswith a note when any;rankings_timelinenotes whenrated_playersis 0 at every point (an empty field, not a flat one);rankings_clanscarriesfield_size(the placed players the counts were taken over).- The population is named (product call 5): on the six segment tools (
battles_meta_decks,battles_meta_cards,battles_trends,cards_synergy,badges_rarity,badges_holders)segmentalso accepts the strings'mine'(the caller's clan;no_subjectwhen there is none) and'corpus'(the whole recorded corpus, explicitly). The corpus is one population among the others, never a default: a read that omitssegmentstill answers it, carries a note saying so (that note only), and a corpus read carriespopulation {recorded_clans, recorded_players, players_in_window}. 4.0.0 makessegmentrequired.
Additive; migration 0135 adds the band tables and the level-gap columns, empty, filled nightly.