01Safety
30.0 / 30
What changed in the harness
Selection accuracy 96→100, token cost up 1%, unconfirmed writes 100%→100%.
Category breakdown
Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.
30.0 / 30
25.1 / 30
9.5 / 20
12.2 / 20
Highest-impact fix
Estimated gain +10 pointsConsolidate overlapping tools and trim repetitive schema text while preserving behavior, parameter, and return semantics.
Description evidence
3 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.
| Tool | Defect types | Suggested rewrite |
|---|---|---|
get_upcoming_matches |
name_restates_behavior |
List tennis matches scheduled to start soon but not yet in progress, in soonest-first order. Each entry names both players, the tournament and round, and carries a match id you can pass to get_match, get_match_score or get_match_odds for the full card once the match begins. Use this to preview what is coming up before it is live on court. |
get_fixtures |
name_restates_behavior |
Upcoming scheduled tennis fixtures, returned earliest first. Each fixture exposes the scheduled start time as an ISO timestamp (event_date) plus tournament, round and both player names, so use this when you need the exact date and time a match is due to begin; fixtures carry no match id, so use the search or match endpoints for live data. |
get_recent_results |
name_restates_behavior |
Recently completed tennis matches, most recent first, with the final score, winner (1 or 2) and completed status for each. Entries include a match id you can pass to get_match, get_match_events or get_match_analysis, plus surface, indoor and win-probability fields where available. Use this as the counterpart of get_live_matches for matches that have just finished. |
Selection evidence
14 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.
| Tool A | Tool B | Confidence | Why they collide |
|---|---|---|---|
get_match |
get_archive_match |
medium | A task like 'get the full details of the match' gives no era cue: get_match covers current matches (ids from live/upcoming/recent) while get_archive_match covers 1968-2022 archive results, so an agent asked about a historical match could reach for get_match and fail, or pick get_archive_match for a current match. |
get_match |
get_match_analysis |
medium | get_match's own description says it 'Includes ... model analysis on ULTRA', overlapping get_match_analysis. A task like 'give me the model's analysis/prediction for this match' could land on get_match for full detail or get_match_analysis for the dedicated analysis. |
get_match |
get_match_events |
medium | Both are per-match reads on a known match_id; a vague task like 'what happened in the match' or 'get the match breakdown' is ambiguous between full detail with score/status (get_match) and the events timeline (get_match_events). |
get_match |
get_match_odds |
medium | get_match advertises that it includes market prices on PRO, so a task like 'get the match prices/odds' could be routed to get_match instead of the dedicated get_match_odds, especially since both share the get-match trigger tokens. |
search_players |
search_archive_players |
high | A task like 'search for Navratilova' or 'find player X' gives no corpus cue; search_players hits the current roster while search_archive_players covers 1968-2022 archive people, and the descriptions split only on current-vs-historical, so a historical-player query can easily pick the wrong member. |
get_live_matches |
get_upcoming_matches |
medium | Real-time phrasing is ambiguous: 'what tennis is on today/tonight' could mean in-progress matches with live scores (get_live_matches) or matches scheduled to start soon (get_upcoming_matches), which the descriptions resolve only via in-progress vs scheduled-soon. |
get_match_odds |
get_match_analysis |
medium | Both describe win probability: get_match_odds gives market implied probability per player and get_match_analysis gives the model's predicted win probability. A task like 'what's the probability X wins this match' or 'who is favored' could select either. |
search_archive_matches |
search_archive_players |
medium | A task like 'search the archive for Borg' is ambiguous: search_archive_matches takes a player_name and returns his matches, while search_archive_players returns his person record — both tools answer the same wording with different result types. |
search_players |
get_player |
medium | search_players already returns id, country, ranking and tour, overlapping get_player's profile fields; a task like 'find Alcaraz's ranking/classification' could be satisfied by the wrong member, and get_player cannot run without the id that search_players produces. |
get_live_matches |
get_recent_results |
medium | Both return matches with scores; a task like 'get today's scores/results' is ambiguous between in-progress matches with live scores (get_live_matches) and recently completed matches with final scores (get_recent_results). |
get_archive_match |
get_archive_career |
low | Both surface archived serve statistics; a task like 'get the archived serve stats for this match' is clearly singular but 'show the archived statistics' for a player is ambiguous between per-match stats (get_archive_match) and summed career stats (get_archive_career). |
search_tournaments |
get_tournament |
low | Search-then-fetch naming: a task like 'get the Wimbledon tournament info' could make the agent call get_tournament with a name string, though it requires the stable id returned by search_tournaments — or call search_tournaments when handed an already-known tournament_id. |
get_archive_career |
get_h2h |
low | Both answer 'all-time record' questions over the archive era and both take player-name fragments; a task like 'show Nadal and Djokovic's record' could route to get_archive_career (one name at a time) instead of get_h2h (two names), or vice versa for a single-player career query. |
get_match_score |
get_recent_results |
low | Both are score reads: a task like 'what was the score of that match' for a completed match could pick get_match_score, which explicitly expects an already-known current match id, instead of get_recent_results with final scores — or the reverse when the user wants a live score. |
Compare the field