# Clinic TopSQL Supplied-SQL Identity

<!-- auto-oncall-optimization-record
{
  "schemaVersion": "auto-oncall-optimization-record-v1",
  "optimizationId": "clinic-topsql-supplied-sql-identity-2026-08-18",
  "problems": [
    {
      "problemId": "clinic-topsql-ranked-digest-not-bound-to-supplied-sql",
      "summary": "Clinic TopSQL discovery returned ranked Digest rows but discarded normalized SQL before deterministically binding a customer-supplied SQL statement to its workload Digest, so downstream diagnosis treated the target execution as unresolved.",
      "status": "optimized_verified",
      "applicability": "Automatic Clinic TopSQL discovery when the ticket supplies SQL text but no exact Digest and the TopSQL source exposes normalized_sql.",
      "issueKeys": ["TCID-12986"],
      "sourceRefs": ["https://tidb.atlassian.net/browse/TCID-12986#problem:clinic-topsql-supplied-sql-identity"],
      "signalTextIncludesAny": ["not been linked to the customer-supplied SELECT", "supplied_sql_match", "workload identity"],
      "observedThrough": "2026-08-18",
      "effectiveAt": "2026-08-18T11:07:58Z",
      "verifiedAt": "2026-08-18T11:38:10.469Z",
      "attemptedAction": "Carry bounded customer-supplied SQL text only into the runner-owned Clinic context; use validated FROM and JOIN table identifiers for a ticket-candidate TopSQL query alongside a global comparison query over the same source and window; merge them deterministically inside the Provider Executor; confirm identity against TopSQL normalized_sql; emit only supplied_sql_match=true and compact Digest prefixes; retain the safe 50-row maximum; and keep missing, failed, or unmatched candidate data non-blocking.",
      "evidenceUrl": "https://tidb.atlassian.net/browse/TCID-12986?focusedCommentId=23357171"
    }
  ]
}
-->

- Owner: Clinic Provider Executor
- Source: TCID-12986 replay `b403a792-e319-42a2-b5ca-6bc147c0d1f4`
- Implementation status: deployed to staging
- Effectiveness status: optimized_verified

## Bounded problem

The post-deployment replay acquired both canonical TopSQL and Slow Query data.
Slow Query exposed an incident-overlapping `bc6171` execution whose Coprocessor
process and wait addresses both pointed to TiKV-13. The Scenario Diagnostic
Agent still could not use that execution as the ticket target because the
ticket supplied SQL text while the compact Provider handoff supplied only
Digest prefixes. The raw TopSQL `normalized_sql` field was unconditionally
redacted before any deterministic identity comparison.

## Candidate change

- Carry only bounded, customer-supplied SQL-containing text into the
  runner-owned Clinic context.
- Select `normalized_sql` from the same canonical TopSQL rows, compare
  tokenized shapes inside the deterministic Provider Executor, and never put
  the normalized SQL in compact output.
- Use bounded, validated table identifiers from `FROM` and `JOIN` only to rank
  likely ticket-directed candidates ahead of the global CPU ranking. This hint
  is not an identity claim; only the full token-shape comparison may emit
  `supplied_sql_match=true`.
- Split the bounded query slots between the strongest ticket candidates and
  the global CPU leaders, so candidate discovery cannot erase the alternative
  workload needed for contribution analysis.
- Emit only `supplied_sql_match=true` on a positive match. Absence, unsupported
  data, or a mismatch remains neither a query failure nor counter-evidence.
- Preserve the two strongest matching rows in the five-row compact result and
  reserve the remaining positions for global alternatives, so target identity
  does not hide the contribution comparison.

## Verification evidence

The full TypeScript suite passed 903/903 tests on 2026-08-18. A contract test
places the matching SQL at rank six, verifies that it becomes the first compact
row with a six-character Digest and `supplied_sql_match=true`, and verifies
that neither the supplied nor Provider SQL text survives materialization.

A direct production GCP Data Proxy validation over the frozen 09:45–10:00 UTC
window completed with HTTP 200 and 50 ranked rows. The helper identified two
matching `bc6171` plan rows (`2d7c47` and `1dd136`), retained both ahead of the
ordinary aggregate leaders, and left their normalized SQL redacted. The
larger `a862ec` workload remained present for contribution comparison.

The first deployed identity replay exposed a deterministic normalization bug:
the Evidence Agent requested 100 rows, while the helper treated values above
its maximum as invalid and fell back to 20 rather than clamping to 50. The
target rows were therefore omitted even though the same canonical query with
limit 50 matched them. The candidate now clamps any positive TopSQL limit above
50 to 50; invalid or absent values still use the 20-row default.

The limit clamp alone still made target discovery depend on the supplied SQL
appearing in a global TopN. The Provider Executor now splits the bounded row
budget between a simple ticket-candidate query and a simple global CPU query
over the same TopSQL source and window, then merges and de-duplicates their
rows. Global TopN remains the comparison pool, while target location is
ticket-directed and exact local token matching remains authoritative. A failed
candidate query leaves the global result usable instead of failing diagnosis.

A second direct GCP Data Proxy validation used a total 20-row budget split
between the two simple queries. It completed without retry, found seven exact
`bc6171` component/plan rows, retained `2d7c47` and `1dd136` as the two strongest
target TiKV rows, and also retained the larger `a862ec` TiDB and TiKV aggregates
for contribution comparison. Compact output omitted the candidate marker and
kept normalized SQL redacted. The full suite passed 904/904 tests, including a
candidate-query failure case that preserved a complete global TopSQL result.

Staging replay `1f96c079-5492-49bd-a00e-375c7543235c` then proved the deployed
identity path end to end. Its Scenario handoffs retained both supplied-SQL
matches (`bc6171` plans `2d7c47` and `1dd136`) ahead of the comparison pool,
while also retaining the much larger `a862ec` TiDB and TiKV aggregates. The
Scenario Router therefore treated the supplied query as a material contributor
without incorrectly making it the sole cause of the broader TiKV-13 increase.

Final staging replay `68f24ad3-a76d-49c3-a699-ebcbb4cdf5fd` preserved the same
identity and comparison after the Slow Query handoff repair. The Router called
the supplied SQL a direct TiKV-13 CPU and latency contributor, while retaining
the substantially larger competing digest as the material explanation for the
unattributed remainder. The historical initial mapping
`auto-live:v1:TCID-12986:initial` resolved to Jira comment `23357171`; that
exact comment was updated in place and read back with `public=false`, with no
change to the issue's comment count.

## Unresolved gaps

The token-shape match proves workload identity, not causal contribution;
aggregate TopSQL, per-execution Slow Query, plan, and instance evidence must
still establish the mechanism. This case now supplies that independent
mechanism evidence. A future match without it must remain identity-only.

## Next validation action

Monitor later Clinic cases where the supplied SQL is outside the global TopN;
they must retain both the exact matched target and an independent global
comparison workload without exposing normalized SQL.
