Skip to content

impairment.coherence: make terminal-buy carve-out explicit for the health-iff rule #4635

Description

@bokelley

Problem

The impairment.coherence invariant landed in #4601 (adcp#2859) with three rules:

  • Forward — every impairments[] entry references a currently-offline resource.
  • Inverse — any offline resource referenced by a non-terminal buy MUST appear in impairments[].
  • Health-iffhealth == "impaired" whenever impairments[] is non-empty (and ok when empty).

The Out-of-scope block in lifecycle.mdx § Compliance reads:

Buys in terminal status (completed, canceled, rejected) MAY remain unreported even when a referenced resource is offline; the buy is no longer serving and the synchronisation cost is wasted.

The runner implementation in adcp-client#1801 extends this carve-out to all three rules including the health-iff biconditional — i.e., a completed buy with health: "impaired" and empty impairments[] is graded not_applicable rather than failing the biconditional. The runner's reasoning: once a buy is terminal, the seller may stop syncing impairments altogether, so the biconditional can break in either direction without operational consequence.

That's a reasonable pragma but it's not what the spec text says. Read strictly, the biconditional binds every buy regardless of status. The current carve-out only addresses "MAY remain unreported" — it doesn't say the health field is allowed to drift from impairments[] cardinality.

Proposal

Make the carve-out explicit. One-line edit to lifecycle.mdx § Compliance § Out of scope:

Out of scope. Buys in terminal status (`completed`, `canceled`, `rejected`)
MAY remain unreported even when a referenced resource is offline; the buy
is no longer serving and the synchronisation cost is wasted. The
`impairments[]` ↔ `health` biconditional likewise relaxes on terminal
buys — sellers MAY leave stale `health: "impaired"` with an empty
`impairments[]` (or vice versa) once a buy reaches a terminal state.
Materiality (the requirement that `package_ids` be non-empty) is enforced
at the schema layer by `package_ids: minItems: 1` on `impairment.json`
(#2855) and is not re-checked here.

Plus a one-line addition to compliance-catalog.mdx's Cross-resource invariants table to mirror the relaxation.

Why this matters

  • Sellers building against the strict reading would over-engineer terminal-state impairment cleanup that adds no operational value.
  • Runner authors implementing the spec strictly would surface false-positive failures on completed buys with stale health values.
  • The relaxation matches what real sellers will do (and what adcp-client#1801 already grades).

Acceptance

  • lifecycle.mdx § Compliance § Out of scope extended with the terminal-buy biconditional relaxation
  • compliance-catalog.mdx Cross-resource invariants row updated to mirror
  • Changeset (patch — spec clarification, no schema change)

Related

  • #4601 — spec PR that landed the invariant
  • #2859 — original invariant issue
  • adcp-client#1801 — runner implementation that prompted this clarification

Metadata

Metadata

Assignees

No one assigned

    Labels

    rfcProtocol change — auto-adds to roadmap board

    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