Found while implementing #13331 (which had to answer where the cluster payload contract lives). Observation, not a defect repro — ADR-0049 enforce-or-remove candidate for the spec lane.
Measurement (origin/main at 2bff79a)
packages/spec/src/kernel/cluster.zod.ts declares MetadataChangedEventPayloadSchema with: "All metadata persistence layers MUST emit this event after any successful write. Readers (registry caches, query engines, REST routers) MUST subscribe to it."
Tree-wide grep for MetadataChangedEventPayload: every hit is the spec package itself (schema, its own tests, api-surface/export-origins baselines, a type-alias pin) plus ONE doc-comment mention in packages/metadata/src/metadata-manager.ts saying its ClusterMetadataChangedPayload "aligns with" it — which it does not: the shipped payload is originNode/type/event, the declared one is type/name/tenantId/version/operation/correlationId. Zero runtime producers, zero subscribers, zero imports outside spec.
Both shipped cluster channels ignore it:
Structural note: the declared version field is z.bigint(). JSON.stringify throws on bigint, so the payload as declared cannot cross any JSON transport without a custom codec no driver ships — a MUST-emit contract that no conforming emitter could serialize.
What this card asks
The spec seat's enforce-or-remove call: either a consumer materializes (and the shipped channels are migrated onto it — which #13331's ruling argues against for the registry lane, since peers deliberately re-read rather than version-compare), or the declared payload is retired via the ADR-0087 route. Not this lane's file surface (packages/spec single owner).
Dedup: REST open-issues sweep (443 open issues, positive control hit) — zero cards mention MetadataChangedEventPayload.
Generated by Claude Code
Found while implementing #13331 (which had to answer where the cluster payload contract lives). Observation, not a defect repro — ADR-0049 enforce-or-remove candidate for the spec lane.
Measurement (origin/main at 2bff79a)
packages/spec/src/kernel/cluster.zod.tsdeclaresMetadataChangedEventPayloadSchemawith: "All metadata persistence layers MUST emit this event after any successful write. Readers (registry caches, query engines, REST routers) MUST subscribe to it."Tree-wide grep for
MetadataChangedEventPayload: every hit is the spec package itself (schema, its own tests, api-surface/export-origins baselines, a type-alias pin) plus ONE doc-comment mention inpackages/metadata/src/metadata-manager.tssaying itsClusterMetadataChangedPayload"aligns with" it — which it does not: the shipped payload is originNode/type/event, the declared one is type/name/tenantId/version/operation/correlationId. Zero runtime producers, zero subscribers, zero imports outside spec.Both shipped cluster channels ignore it:
metadata.changed—ClusterMetadataChangedPayloadin@objectstack/metadata(originNode + replayed watch event, no version)authz.invalidated— payload in@objectstack/core's authz-invalidation-channel module (epoch hint)metadata.mutated(new, runtime: TS-config boot registers a 'metadata' service without attachClusterPubSub — cross-node invalidation disabled; new object gives OBJECT_NOT_FOUND on non-writing replicas, never heals #13331) —ClusterMetadataMutationPayloadin@objectstack/metadata-protocol(address-only signal; peers re-read their own DB, ruled 2026-09-01, so the declared version-compare protocol is the opposite of the ruled receipt semantics)Structural note: the declared
versionfield isz.bigint().JSON.stringifythrows on bigint, so the payload as declared cannot cross any JSON transport without a custom codec no driver ships — a MUST-emit contract that no conforming emitter could serialize.What this card asks
The spec seat's enforce-or-remove call: either a consumer materializes (and the shipped channels are migrated onto it — which #13331's ruling argues against for the registry lane, since peers deliberately re-read rather than version-compare), or the declared payload is retired via the ADR-0087 route. Not this lane's file surface (
packages/specsingle owner).Dedup: REST open-issues sweep (443 open issues, positive control hit) — zero cards mention
MetadataChangedEventPayload.Generated by Claude Code