Skip to content

Draft: open the catalog and entry objects to unrecognized members (ADR-0028) - #131

Draft
tadasant wants to merge 1 commit into
mainfrom
tadasant/unrecognized-members
Draft

tadasant wants to merge 1 commit into
mainfrom
tadasant/unrecognized-members

Conversation

@tadasant

Copy link
Copy Markdown
Contributor

Disclosure: exploratory, AI-assisted draft. This PR was drafted with AI assistance (Claude) and steered by @tadasant. It is a starting point for discussion, not a settled position, and will likely need more iteration. Tadas will revise the content and remove this notice once he has thoroughly reviewed and rewritten it. Until then, treat it as a placeholder for the idea, not as his finished position.

Summary

Make the AI Catalog top-level object and Catalog Entry objects explicitly open to members the specification does not define, and say precisely what a consumer does with them: nothing, except not rejecting them, preserving them where it can, and keeping them in signed payloads.

The goal is to keep AI Catalog simple and extensible without taking a stance on any particular convention. Some folks have indicated a desire to use JSON-LD-style conventions (a @context prefix map plus namespaced members at the entry level). Others want private annotations in internal catalogs, or a way to ship a candidate field and gather experience before proposing it. This change leaves room for all of those while the specification itself defines, references and interprets none of them. extensions stays the one extension point the spec does define.

Why now

The prose and the schema currently disagree:

  • Version Handling tells consumers to ignore unrecognized fields.
  • The signature sections require unrecognized members to be retained in signed payloads, and Catalog Snapshot Coverage says the catalog signature covers "unknown fields".
  • The CDDL preamble says the schema "describes recognized members".
  • But the AICatalog and CatalogEntry CDDL maps are closed, so the normative schema rejects exactly what the prose tells consumers to accept.

An implementer reading the schema and one reading the prose build different validators. This PR resolves it in the direction the prose already went.

What changes

specification/ai-catalog.md

  • New top-level section Unrecognized Members (before Version Handling) with four consumer rules: MUST NOT reject; MUST NOT derive core semantics from them; SHOULD preserve on republication (best effort, so strongly typed SDKs may drop them); MUST retain in signed payloads (already required elsewhere).
  • A no-stability-guarantee clause: any undefined name MAY be defined by a future version, with any meaning, without coordinating with outside conventions. The collision risk sits with whoever relies on undefined names; extensions is the stable, namespaced alternative. A future major version MAY narrow or close the objects again depending on how the ecosystem uses them.
  • A trust and signing note: unrecognized members are outside any Trust Manifest subject and are not publisher claims; catalog signatures cover them as bytes, not meaning. The Subject and Publisher and Policy Metadata sections get matching one-line additions.
  • A comparison table of extensions vs. unrecognized members, and three illustrative examples (explicitly non-normative): a linked-data style @context with prefixed members; local annotations in a private catalog; a prototyped lifecycle field.
  • CDDL: * text => any added to AICatalog and CatalogEntry; preamble updated. TrustManifest is deliberately not opened (it is a signed payload and other specs treat it as opaque).
  • One-line pointers from the top-level object and Catalog Entry member lists, the Extensions intro, and Version Handling.

adr/0028-open-catalog-and-entry-objects.md — context, decision, rationale, trade-offs, alternatives considered, revisit clause. Supersedes the closed-core rationale of ADR-0012; the extensions decision from ADR-0017 stands.

docs/guides/creating-a-catalog.md, docs/guides/consuming-catalogs.md — a short "Members beyond the specification" subsection and a one-word tweak to the consumer checklist.

No existing catalog document changes meaning or validity. The change is additive and fits the 0.9 → 1.0 line.

Trade-offs (what we lose)

Stated plainly, and hopefully not much:

  • Validators stop catching misspelled optional member names. descripton becomes an unrecognized member instead of an error. Mitigation in the text: conformance tooling MAY report unrecognized members as informational output.
  • Bare names share one namespace with future core members. A producer using lifecycle today may find a later version defines it differently. The spec promises nothing here on purpose; that is what keeps it dependency-free.
  • Strongly typed bindings drop unknown members, so preservation is a SHOULD, not a MUST.
  • A second, undefined place for data beside extensions. The distinction is defined vs. undefined, which is a real distinction rather than two ways to do one thing, but some data will land at the root that would have been better namespaced.

Alternatives considered (details in the ADR)

  • Keep the objects closed: leaves the prose/CDDL contradiction and rules out outside conventions entirely.
  • Reserve only a syntactic space (names starting with @ or containing :): covers prefixed terms but not terms a prefix map aliases to bare names, and adds a rule whose only purpose is to describe someone else's syntax.
  • Publish a JSON-LD profile or context document: takes a stance the TSC has declined to take.
  • A media-type profile parameter: does not match how catalogs are published.

Open questions for the TSC

  1. Is SHOULD-preserve the right strength, given typed SDK bindings? (MAY would be more honest for SDKs; SHOULD better serves federation.)
  2. Should conformance tooling warn on unrecognized members by default?
  3. Should HostInfo and Publisher also be opened, or stay closed as sub-objects?
  4. Any objection to the illustrative @context example appearing in the spec at all, versus only in the ADR?

Verification

  • uv run tools/build_spec.py builds; the new anchors (#unrecognized-members, #no-stability-guarantee, #trust-and-signing, #relationship-to-extensions) resolve and no internal link in the built HTML is dangling.
  • uv run --group docs mkdocs build --strict passes.

🤖 Generated with Claude Code

…-0028)

Exploratory draft. The prose already tells consumers to ignore unrecognized
fields and to retain them in signed payloads, but the CDDL maps for
AICatalog and CatalogEntry are closed. This makes both maps explicitly open
(`* text => any`), adds an Unrecognized Members section with four consumer
rules (do not reject, derive no core semantics, preserve on republication,
retain in signed payloads), states that undefined names carry no stability
guarantee and are outside the Trust Manifest subject, and keeps
`extensions` as the only extension point the specification defines.

Adds ADR-0028 with rationale, trade-offs and alternatives, and updates the
creating/consuming guides.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
github-actions Bot added a commit that referenced this pull request Oct 29, 2026
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Preview: https://ai-catalog.io/pr/131/

This comment is updated automatically while the pull request preview is available.

github-actions Bot added a commit that referenced this pull request Oct 29, 2026

This branch has not been deployed

No deployments
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.

1 participant