Skip to content

[finding] spec ships a three-layer metadata-customization protocol (MetadataOverlaySchema, field-level change tracking) with zero consumers — published reference docs describe an unimplemented customization architecture #12057

Description

@claude

packages/spec/src/kernel/metadata-customization.zod.ts declares a complete three-layer
customization protocol — MetadataOverlaySchema (scopes system/platform/user), per-field
FieldChangeSchema (originalValue/currentValue/changedBy), lockedFields/customizableFields
whitelists, and a 3-way-merge upgrade story. It is a public export
(packages/spec/api-surface/kernel.json:213) and it is published as reference documentation
(content/docs/references/kernel/metadata-customization.mdx, auto-generated from the module's
TSDoc), presenting itself as "the overlay system for managing user customizations on top of
package-delivered metadata".

Measured at origin/main 0b048393faa98151600598bcebf2ad905ee7021f:

POSITIVE CONTROL  grep MetadataOverlaySchema|CustomizationOriginSchema|FieldChangeSchema|MetadataCustomizationState|CustomizationConflict
                  -> finds the definitions in packages/spec/src and the api-surface row
ZERO              same grep across packages/** excluding packages/spec:            0 matches
ZERO              same grep across the local ../objectui checkout @ 2ecc9c7cb2:    0 matches

The real, enforced overlay mechanism (ADR-0005: sys_metadata rows keyed by organization_id,
five allowOrgOverride types, OVERLAY_ALLOWED_TYPES in objectql/src/protocol.ts) shares no
code and no vocabulary with this module. Nothing implements the user scope, the field-level
change tracking, lockedFields, or the 3-way merge — and the published reference page describes
them as the platform's customization architecture anyway.

This is the ADR-0049 declared-but-unenforced shape (same family as #11777), on the exact surface
the #12049 customization-model ADR governs: a reader (human or AI) planning post-install
customization from the reference docs lands on a protocol with zero consumers, and the
ServiceNow-style per-field overlay layer it describes is precisely what the #11513 ruling recorded
as deliberately NOT chartered.

Suggested disposition (whoever picks this up, after #12049's ADR settles the model): retire the
module (ADR-0049 remove side — export removal + api-surface regen + the generated reference page
disappears with it), or re-scope it to document only what ADR-0005 actually implements. Not
scoped here; the #12049 ADR records the model-level disposition.

Blocked-by: #12049 (the ADR is the model-level ruling this retirement should cite).

Found while surveying customization mechanisms for #12049; out of that card's scope (⛔ no
packages/spec edits there).


Generated by Claude Code

Activity

  1. yinlianghui-tw commented on Aug 25, 2026

    @yinlianghui-tw
    Collaborator

    Triage: finding → pm:blocked + domain:spec, Task — the body already carries the machine-readable Blocked-by: #12049 line, and the sequencing is correct: the retire-vs-re-scope disposition should cite the customization-model ADR that #12049 produces, not pre-empt it. The unlock scan picks this up when #12049 closes; on unlock, re-verify on the merged ref whether the ADR itself already dispositioned this module before dispatching (the ADR is the most likely place this card gets absorbed). Route on unlock stays ADR-0049 enforce-or-remove through the spec seat.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions