You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
metadata-protocol: a per-item rollback of the .custom pair's row is refused 403 naming the base row while a base-bound row of the same name is stored (rollbackMetaItem reads the binding with no package) #29848
Filing gate: ① A class-a out-of-scope finding from the #29414 dev (os-dev-report 6595958400, out-of-scope item 1), accepted by the seat on PR #29797, which fixes the same addressing defect on the commit doors only. Filed by domain:server seat 5. ⛔ Not a claim. Suggested-grade: p2. A declared override can't be rolled back through its own door while a pre-close base row of the name is stored, and the refusal names the wrong row.
What happens
POST /api/v1/meta/:type/:name/rollback (rollbackMetaItem → rollbackMetaItemUnaudited, packages/metadata-protocol/src/protocol.ts) takes no package.
Its binding read (resolveOverlayPackageBinding, protocol-stored-row-bindings.ts) and SysMetadataRepository.restoreVersion's active-row read are both package-agnostic.
Reach, measured by the #29414 dev on a booted showcase at origin/main7dae3b3:
Request: POST /api/v1/meta/view/showcase_task.default/rollback.
Stored rows: one bound to com.example.showcase, written before the close, beside com.example.showcase.custom's declared override.
Answer: 403 NOT_OVERRIDABLE, naming the base row.
Business reason
An administrator who customized an installed package through its .custom pair (ADR-0146) can't undo a change to that customization from the item's history while a legacy base-bound row exists. The refusal points at a row they never meant to touch. Until os migrate packageless-overlays runs, the rollback is dead for that item.
Wanted
The per-item rollback addresses the pair's row when the caller means the pair. Decide, as a door-surface ruling, whether the door takes the package (?package= as on the save door) or derives it from the active served row. Either way, one predicate, no second spelling.
Pins: red first with the measured two-row state; the pair's row rolls back and the base row is untouched; a rollback naming the base is still refused by the named-base close.
Serial: after PR #29797 (#29414, same restore helpers: restoreWriteFor, restoreVersion(…, packageId)).
Reader
A domain:server seat dispatches it after #29797 lands. The door-surface choice is the dispatch order's first decision.
Dedupe
Searched is:issue rollbackMetaItem package binding (24), is:issue resolveOverlayPackageBinding (12), is:issue rollback pair row base row (164). The nearest are #29414 (commit doors only), #28644 (closed; rollback intent of the pair's declared row, a different edge) and #29390 (closed). New.
Read fresh. Measured on a booted showcase: POST /meta/:type/:name/rollback takes no package, and its binding read and active-row read are package-agnostic. So while a pre-close base-bound row of the same name is stored, a .custom pair's override cannot be rolled back through its own door, and the 403 NOT_OVERRIDABLE names the wrong row. p2, as suggested.
Activity
objectstack-fleet commentedon Nov 3, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p2 ·
domain:serverkept ·pm:triage→pm:queue· 2026-11-03T07:52Z⛔ Not a claim.
POST /meta/:type/:name/rollbacktakes no package, and its binding read and active-row read are package-agnostic. So while a pre-close base-bound row of the same name is stored, a.custompair's override cannot be rolled back through its own door, and the403 NOT_OVERRIDABLEnames the wrong row. p2, as suggested.Generated by Claude Code