Symptom
The registry declares field with allowOrgOverride=false, and the field is artifact-backed — yet the live route accepts the overriding write.
PUT /api/v1/meta/field/showcase_task.title {name:'title', label:'Tampered', type:'text'} with an admin bearer → 200 state:'active'. Reproduced on showcase_task.status.
- The row is persisted and reads back with
_diagnostics.valid=true.
- And the accepted write is inert:
GET /meta/object/showcase_task still reads title.label = 'Title'. A brand-new field written the same way never appears in the object's fields either.
So the door answers success twice over — accepted, and stored valid — for a write the registry forbids and the runtime ignores. The object, view, dashboard and job variants all behave correctly in the same run, and locked-override vs open-create were proven independent there.
Root cause (suspected — located, not proven by a fix)
The gate keys on isArtifactBacked(type, name), which resolves through registry.getArtifactItem(singular, name, currentPackageId) ?? registry.getArtifactItem(type, name, currentPackageId) (packages/metadata-protocol/src/protocol.ts:8678-8679). Fields are not registered as standalone field artifact items — they live inside the object — so getArtifactItem('field', 'showcase_task.title') misses. With the artifact lookup empty, the write is classified as a runtime-only create, and the registry entry for field carries allowRuntimeCreate: true:
{ type: 'field', label: 'Field', …, allowOrgOverride: false, allowRuntimeCreate: true, … }
— packages/spec/src/kernel/metadata-plugin.zod.ts:629 on origin/main.
allowOrgOverride: false is never consulted because nothing on this path believes an artifact is being overridden.
Why the pin stayed green: overlay-precedence.test.ts (27 passing) pins the protocol-level denial. The live field route is not in its coverage, so the gate is proven where it is exercised and absent where it is used.
Stale-premise check: re-verified on objectstack origin/main (00e9196) — the isArtifactBacked resolution and the field registry row are both unchanged.
Reproduction
- Boot the showcase with writable runtime packages; obtain an admin bearer.
PUT /api/v1/meta/field/showcase_task.title with {name:'title', label:'Tampered', type:'text'} → 200 state:'active'.
GET /api/v1/meta/field/showcase_task.title → the row exists, _diagnostics.valid=true.
GET /api/v1/meta/object/showcase_task → title.label is still 'Title' — the accepted write changed nothing.
- Contrast: the same override attempt against
object / view / dashboard / job is correctly refused.
Note for whoever reproduces the object contrast: a trimmed object body hits DESTRUCTIVE_CHANGE first — the full body is needed to reach the registry gate.
Source
Extracted from the QA run #7695 (framework 92f26f7, console 09987b680).
Symptom
The registry declares
fieldwithallowOrgOverride=false, and the field is artifact-backed — yet the live route accepts the overriding write.PUT /api/v1/meta/field/showcase_task.title {name:'title', label:'Tampered', type:'text'}with an admin bearer → 200state:'active'. Reproduced onshowcase_task.status._diagnostics.valid=true.GET /meta/object/showcase_taskstill readstitle.label = 'Title'. A brand-new field written the same way never appears in the object'sfieldseither.So the door answers success twice over — accepted, and stored valid — for a write the registry forbids and the runtime ignores. The
object,view,dashboardandjobvariants all behave correctly in the same run, and locked-override vs open-create were proven independent there.Root cause (suspected — located, not proven by a fix)
The gate keys on
isArtifactBacked(type, name), which resolves throughregistry.getArtifactItem(singular, name, currentPackageId) ?? registry.getArtifactItem(type, name, currentPackageId)(packages/metadata-protocol/src/protocol.ts:8678-8679). Fields are not registered as standalonefieldartifact items — they live inside the object — sogetArtifactItem('field', 'showcase_task.title')misses. With the artifact lookup empty, the write is classified as a runtime-only create, and the registry entry forfieldcarriesallowRuntimeCreate: true:—
packages/spec/src/kernel/metadata-plugin.zod.ts:629onorigin/main.allowOrgOverride: falseis never consulted because nothing on this path believes an artifact is being overridden.Why the pin stayed green:
overlay-precedence.test.ts(27 passing) pins the protocol-level denial. The livefieldroute is not in its coverage, so the gate is proven where it is exercised and absent where it is used.Stale-premise check: re-verified on
objectstackorigin/main(00e9196) — theisArtifactBackedresolution and thefieldregistry row are both unchanged.Reproduction
PUT /api/v1/meta/field/showcase_task.titlewith{name:'title', label:'Tampered', type:'text'}→ 200state:'active'.GET /api/v1/meta/field/showcase_task.title→ the row exists,_diagnostics.valid=true.GET /api/v1/meta/object/showcase_task→title.labelis still'Title'— the accepted write changed nothing.object/view/dashboard/jobis correctly refused.Note for whoever reproduces the
objectcontrast: a trimmed object body hitsDESTRUCTIVE_CHANGEfirst — the full body is needed to reach the registry gate.Source
Extracted from the QA run #7695 (framework 92f26f7, console 09987b680).