Skip to content

spec(envelope): forbid task_status/response_status at schema level#3044

Merged
bokelley merged 1 commit intomainfrom
bokelley/envelope-forbid-legacy-status
Apr 24, 2026
Merged

spec(envelope): forbid task_status/response_status at schema level#3044
bokelley merged 1 commit intomainfrom
bokelley/envelope-forbid-legacy-status

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

Closes #3041

Summary

PR #3021 added normative MUST NOT prose against v3 agents dual-emitting task_status or response_status alongside status. Reviewer flagged on #3021 that the rule was only human-discoverable — worth a machine-checkable assertion.

This lifts the prohibition into the envelope JSON Schema itself, using the existing not: { anyOf: [{ required: [...] }] } idiom (the same pattern core/catchment.json uses for its mutually-exclusive field groups):

"not": {
  "anyOf": [
    { "required": ["task_status"] },
    { "required": ["response_status"] }
  ]
}

Any envelope containing either legacy field now fails draft-07 validation against /schemas/core/protocol-envelope.json. No runner-specific primitive, no storyboard changes, no client code required — every JSON Schema validator in the ecosystem enforces it.

Verification

Ajv-compiled protocol-envelope.json against five cases:

Envelope Result
{ status, payload } (clean) ✅ valid
{ status, payload, task_status: "completed" } ❌ invalid
{ status, payload, response_status: "ok" } ❌ invalid
{ status, payload, task_status, response_status } ❌ invalid
{ status, payload, custom_field } (unrelated extra) ✅ valid

additionalProperties: true is unchanged — buyers and sellers can still add non-protocol fields; the constraint is narrow to the two named legacy names.

Non-breaking

Targets behavior that was already non-conformant per #3021 / the normative prose added to the status description. No conformant v3 agent emits these fields. No existing example envelope in the schema is affected.

Out of scope

Runtime storyboard enforcement — a new storyboard primitive (field_absent) plus the @adcp/client implementation needed to evaluate it would duplicate what schema validation already catches. If a compliance-runner-level hook is still wanted after this ships, I'll file a follow-up on @adcp/client to wire the envelope schema into every storyboard's response_schema pass — which is where envelope validation naturally belongs.

Pre-PR checks

  • npm run build:schemas — clean
  • npx changeset statusadcontextprotocol: patch
  • npm run build — clean (all 10 universal / 6 protocols / 20 specialisms compliance bundles build; latest protocol tarball builds)
  • npx vitest run — 820/820 passing
  • ajv test vectors above — all pass

🤖 Generated with Claude Code

…loses #3041)

PR #3021 added MUST NOT prose against dual-emitting legacy `task_status`
and `response_status` alongside v3 `status`. Reviewer flagged that the
rule was only human-discoverable. This lifts the prohibition into the
JSON Schema itself via the existing `not: { anyOf: [{ required: [...] }] }`
idiom (used by `core/catchment.json`).

Any envelope containing `task_status` or `response_status` now fails
draft-07 validation against `/schemas/core/protocol-envelope.json` — no
runner-side primitive required. The prose MUST NOT in the `status`
description remains for implementors reading the schema by eye; the
`not` constraint is what validators act on.

Verified with ajv:
- clean envelope → valid
- envelope with task_status → invalid
- envelope with response_status → invalid
- envelope with both → invalid
- envelope with unrelated additional properties → valid (additionalProperties: true unchanged)

Non-breaking: the prohibition targets behavior that was already incorrect
per #3021. No conformant v3 agent emits these fields.

Runtime conformance — a storyboard-level `field_absent` primitive plus
@adcp/client implementation — is out of scope here and will be tracked
as a follow-up on @adcp/client once the schema-level enforcement has
shipped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit 1cd99c2 into main Apr 24, 2026
12 checks passed
@bokelley bokelley deleted the bokelley/envelope-forbid-legacy-status branch April 24, 2026 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Conformance check: envelope properties matching /^(task|response)_status$/

1 participant