Fix the SDK smoke check for an SMS integration

Review the AI's codeEasy12 min

Your task

An AI agent wired a third party SMS provider's SDK into your notification service, from docs it remembered. The code compiles and reads well, but an agent can invent method names and response fields. Before production, your smoke check compares the surface the code assumes (the methods and fields it touches) with the surface the installed SDK really has.

An assistant wrote sdk_contract_gaps(assumed_surface, real_surface). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • assumed_surface: what the integration code uses, one string per symbol, in the form "kind|name|shape", like "method|client.messages.create|to,body,from" or "field|response.sid|string". The kind is normally method or field. The shape is the parameter list or the type the code depends on.
  • real_surface: the same format, dumped from the installed SDK.
  • Return the list of gaps.

Rules the tests check:

  • Split each entry on |. Skip an entry with fewer than 3 parts. Parts after the third are ignored.
  • Trim whitespace at both ends of the kind, the name and the shape. Skip an entry whose kind or name is empty after trimming. An empty shape is fine.
  • A symbol is a kind plus a name. Kinds, names and shapes compare exactly, and case matters.
  • When real_surface lists a symbol more than once, its first entry counts.
  • Check each symbol in assumed_surface once, using its first entry. Skip later entries for a symbol you already checked.
  • For each assumed symbol, add "missing:<kind>.<name>", with the trimmed kind and name, when the real surface does not have it. Add "shape_mismatch:<kind>.<name>" when it has it with a different shape, so to,body and body,to differ. Add nothing when the shapes are equal.
  • Symbols that only real_surface has add nothing.
  • Return the gaps sorted in ascending order by character code, as a default string sort does.

Examples

sdk_contract_gaps(assumed_surface: list[str], real_surface: list[str]) -> list[str]
Example 1
Inputsdk_contract_gaps(["method|client.messages.create|to,body,from", "field|response.messageId|string", "field|response.error.code|string"], ["method|client.messages.create|to,body,from", "field|response.sid|string", "field|response.status|string"])
Output["missing:field.response.error.code", "missing:field.response.messageId"]
Example 2
Inputsdk_contract_gaps(["method|client.messages.create|body,to"], ["method|client.messages.create|to,body"])
Output["shape_mismatch:method.client.messages.create"]
Example 3
Inputsdk_contract_gaps(["method|client.messages.create|to,body", "field|response.sid|string"], ["method|client.messages.create|to,body", "field|response.sid|string", "method|client.messages.list|limit"])
Output[]