Skip to content

Tracking: ship 1676–1680 as one stance — the SDK is a witness, not a translator #1685

@bokelley

Description

@bokelley

Five issues were filed in a row from the same probe (a 3.0-strict seller — Wonderstruck). On their own they read as five spot fixes. They aren't. They're one bug wearing five hats: at every seam between adopter input and the seller wire, the SDK is being polite instead of honest.

That politeness was invisible against permissive sellers. Against a 3.0-strict seller it surfaces all at once.

The five hats

# Politeness move What it hides PR
#1676 Invents account from brand.domain Adopter never wired account resolution #1683
#1677 Accepts pre-3.0 product_ids[] / object budget and rewrites in place Adopter never migrated to 3.0 shape #1681
#1678 Ships literal {{runner.webhook_url:…}} when no receiver is configured Test config gap that should be not_applicable #1690
#1679 Flattens wire-level INVALID_REQUEST detail to {} The other four become silent — grader sees no diagnostic #1684
#1680 Grades unrunnable scenarios as partial Inflates cert scores; "couldn't run" reads as "got close" #1682

The rule that emerges

The SDK is a witness, not a translator. Don't fabricate, don't normalize stale shapes, don't placeholder when prereqs are unmet, don't flatten the wire diagnostic, don't upgrade a skip to a partial pass.

Fail closed at every seam. The same principle already governs capability declarations (capabilities must match actual behavior — see the precedent set in #931 where a test-mode flag that changed runtime behavior was required to flip the capability block). These five extend that principle one layer up: requests and grades, not just the capabilities body.

Merge order matters

#1684 (for #1679) ships first. It's the keystone — purely visibility. While step.error arrives as {}, the other four can regress silently because every failure looks like INVALID_REQUEST: ¯\\_(ツ)_/¯. Land #1684 and every future politeness regression becomes a tripwire. Land the others first and the next one sneaks back in unannounced.

Suggested order:

  1. fix(comply): forward structured adcp_error from failed storyboard steps #1684 (closes comply() ComplianceResult drops step.error to {} — wire-level INVALID_REQUEST detail lost #1679) — visibility keystone. Unblocks everything.
  2. fix(client): remove account_from_brand fabrication shim in normalizeRequestParams #1683 (closes request-normalizer fabricates account from brand on create_media_buy — silently ships invented data as 3.0 #1676) and fix(normalizer): fail closed on pre-3.0 PackageRequest shapes #1681 (closes PackageRequest normalizer accepts pre-3.0 shape (product_ids[] / object budget) — should fail closed #1677) — fabrication twins. Can ship in either order after fix(comply): forward structured adcp_error from failed storyboard steps #1684.
  3. fix(conformance): grade storyboards not_applicable when required_tools are missing #1682 (closes comply() grades storyboards 'partial' when required_tools are missing — should grade not_applicable #1680) — not_applicable routing.
  4. fix(comply): autodetect webhook_receiver requirement from token presence #1690 (closes comply() sends relative push_notification_config.url — 3.0-strict sellers reject #1678) — autodetect webhook_receiver requirement. Builds on fix(conformance): grade storyboards not_applicable when required_tools are missing #1682's not_applicable plumbing.

What this is, what this isn't

Is: a coordination issue so the five PRs ship as a coherent rewrite with a single migration story in CHANGELOG and the migration guide. Reviewers should land #1684 first and read the others against this framing.

Isn't: a new spec PR. No adcontextprotocol/adcp change is needed — the spec already says fail closed at each seam; the SDK was being lenient anyway.

Closes when: all five PRs are merged and the migration guide entry calls out "politeness moves removed" as a section.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions