Skip to content

Standardize notices field on runner-output-contract (warn-on-skip / forward-readiness surface) #4418

Description

@bokelley

Summary

`compliance/{version}/universal/signed-requests.yaml:34` already mandates:

the runner SHOULD emit an informational notice (not a failure) advising the agent to drop the now-redundant specialism claim and rely solely on `request_signing.supported: true`.

This is the only "SHOULD emit notice" in the universal storyboards today, but the spec doesn't define what an "informational notice" is — there's no field on `runner-output-contract.yaml`, no severity enum, no machine-readable code. The reference SDK runner (`@adcp/sdk`) has not implemented it, and other runners (AdCP Verified, third-party CI gates, dashboards) have no standard place to put one.

Why now

Two 3.0 → 4.0 transitions need an advance-warning channel:

  1. `request_signing` becomes required for spend-committing operations in 4.0 (per get-adcp-capabilities-response.json: "Required for spend-committing operations in 4.0"). A 3.0 seller that legitimately skips `signed_requests` today (because they don't advertise `request_signing.supported: true` — universally legal in 3.0) will fail compliance on the 4.0 cut with no advance warning unless the runner can surface "passed now, planned-required in 4.0."

  2. `webhook_signing.legacy_hmac_fallback` is removed in 4.0 (same schema, line 966). Same shape of forward-required deprecation.

Without a structured notice surface, runners have two bad options: bake the advisory into prose `skip.detail` strings (unparseable by dashboards — see `adcontextprotocol/adcp-client#1702` / PR adcp-client#1703 where the SDK does exactly this as a stopgap), or stay silent and let sellers hit a wall at the 4.0 cut.

Proposed addition to `runner-output-contract.yaml`

Add a `notices` field on the per-storyboard result (and optionally on the overall compliance result for cross-storyboard signals):

```yaml
notices:
description: |
Advisory signals attached to a storyboard result. Distinct from skip
reasons (which name why a storyboard didn't run) and validation
failures (which fail the storyboard). Notices are informational and
MUST NOT change overall_passed. Runners emit one notice per advisory
condition; consumers aggregate by `code`.
type: array
items:
type: object
required: [severity, code, message]
properties:
severity:
enum: [info, deprecation, future_required]
description: |
- `info`: behavior is fine and supported; advisory context only.
- `deprecation`: an agent-side claim or behavior is allowed
today but the spec recommends migration (e.g. legacy
specialism enum values still accepted for back-compat).
- `future_required`: a capability that is optional today will
be required in a named future spec version; agents that do
not advertise it will fail compliance after the cut.
code:
type: string
description: |
Stable machine-readable identifier. Runners MUST NOT change
the code for the same advisory across versions.
message:
type: string
effective_version:
type: string
description: When severity is `future_required`, the AdCP version that flips the requirement.
requirement:
type: string
description: When the notice is tied to a structured `requires:` name, repeat it here.
capability_path:
type: string
description: |
Dotted path into the agent's `get_adcp_capabilities` response
that motivated the notice (e.g. `request_signing.supported`).
```

Canonical first-day notices

Code Severity Spec source
`signed_requests_specialism_deprecated` `deprecation` signed-requests.yaml:34 (the SHOULD that motivated this issue)
`request_signing_required_in_4_0` `future_required` get-adcp-capabilities-response.json:892
`legacy_hmac_fallback_removed_in_4_0` `deprecation` get-adcp-capabilities-response.json:966

Why standardize in the spec rather than the SDK

Multiple runners exist or are planned (`@adcp/sdk`, AdCP Verified, third-party CI gates). If each invents its own advisory shape, downstream consumers (dashboards, JUnit, badge renderers, the agent reporting UI on the AdCP site) have to write per-runner adapters. A single spec field collapses that to one render path.

Refs

  • adcp-client#1702 / PR adcp-client#1703 — runner currently rides 4.0 forward-readiness signal in `skip.detail` prose as a stopgap pending this surface.
  • adcp-client#1704 (SDK-side issue tracking the runner-output extension)
  • signed-requests.yaml:34 (existing unimplemented SHOULD)

Metadata

Metadata

Assignees

No one assigned

    Labels

    claude-triagedIssue has been triaged by the Claude Code triage routine. Remove to re-triage.compliance-suiteneeds-wg-reviewBlocked on a working-group decision — surface in WG meeting agendasrfcProtocol change — auto-adds to roadmap boardschemaJSON Schema source-of-truth: definitions, codegen artifacts, validation, hygiene

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Shipped

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions