Skip to content

finding: the ADR-0010 envelope-declaration gate cannot see UNREGISTERED_KIND_SCHEMAS — the blind spot that let #6362 survive #6245 #6931

Description

@os-zhuang

Split out of #6362 (PR #6900). Recording only — not claimed, not queued.

The observation

metadata-type-schemas.test.ts holds the ADR-0010 invariant that every metadata
type either declares ...MetadataProtectionFields or is named on an explicit
debt list. UNDECLARED_ENVELOPE is currently empty, and its own comment
calls that "the end state", so the gate reads as total coverage.

It is not. The gate iterates listMetadataTypeSchemaTypes(), which returns
Object.keys(BUILTIN_METADATA_TYPE_SCHEMAS) plus runtime extras — and
deliberately not UNREGISTERED_KIND_SCHEMAS. That exclusion is documented
and intentional (the trailing comment in metadata-type-schemas.ts explains
that enrolling webhook / connector / sharing_rule there would claim a KIND
status #6245 was careful not to grant, leaving #2657's B/C decision open).

The side effect was not intended, though: those three names are bound as real
parse doors — #6245 wired them to PUT /api/v1/meta/:type/:name — while the
invariant that exists to catch "declares no envelope" never runs over them.

Evidence that this is the actual cause, not a theory

connector sat in exactly that gap and the gate stayed green throughout:

So all three were judged one at a time, by hand, for a property the repo already
has an automated structural walker for.

Why this is observation-class, not a defect

Nothing a user hits today: as of PR #6900 all three bound kinds declare the
envelope, so the gap is currently empty of bugs. The exposure is prospective —
a fourth entry added to UNREGISTERED_KIND_SCHEMAS inherits the same
silence, and the next one may be non-strict too, in which case the failure is
again a silent strip rather than a 422.

Possible directions (deliberately not chosen here)

  1. Give the existing suite a second it.each over Object.keys(UNREGISTERED_KIND_SCHEMAS)
    asserting only the envelope-declaration property — without enrolling them
    in listMetadataTypeSchemaTypes(), so none of the other KIND obligations
    (create seeds, MetadataTypeSchema membership, the campaign count) attach and
    Studio metadata coverage gaps: surface remaining types + promote un-typed concepts #2657 stays unprejudged.
  2. Export the bound-kind names so the walk derives the set rather than
    hand-listing it.
  3. Leave as-is and rely on review, if the set is expected to stay at three.

Direction 1 looks like the cheap one and appears to preserve every boundary
#6245 drew, but it is a decision about a contract surface's coverage rules, so
it should be triaged rather than assumed.

Refs: #6362 / PR #6900 (connector, the silent-strip case), #6245 (bound the three
doors; fixed sharing_rule's 422 case), #4001 batch 11 (webhook's spread),
#2657 (the open B/C kind-promotion decision), ADR-0010.

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