Observation found while implementing #8184 (PR #8353). Filed, not fixed: it lives in saveMetaItem's ADR-0070 D1 gate, a different region of protocol.ts from #8184's fenced one, and adjacent to #7748's declared surface.
What is shadowed
#8146 (7f02367c1) gave BOTH package-door emitters in SysMetadataRepository a hatchOpen remedy selection:
That second clause cannot be reached through saveMetaItem on any topology. The ADR-0070 D1 gate a few hundred lines above the repository call throws first, on a strictly wider condition:
intent === 'runtime-only' && request.packageId != null && !this.isWritablePackage(request.packageId)
The repository's create door fires on the same predicate plus namedBase (non-empty string) plus "no registry limb returned". Every write that would reach it has already been thrown by D1 — which is topology-independent, so this is not a per-kernel divergence like #8184 was.
Why it is worth recording
The code and status agree (WRITABLE_PACKAGE_REQUIRED / 422), and D1's sentence does not prescribe setting OS_METADATA_WRITABLE, so this is not the retry-forever false-prescription trap #8146 closed on the override side. It is the milder half: an operator who has the hatch open and attempts a runtime-only create into a read-only base is told the base is read-only, and never told that the hatch they set does not reach the package dimension. The override side explains it; the create side does not.
Secondary: it means the create-side hatch clause is only exercised by direct repo.put callers (promoteDraft / restoreVersion / revertCommit), not by the authoring surface it was written for — so a change to that sentence would read as covered while the surface that matters never emits it.
Not proposing a shape
Two readings, and neither is obvious enough to act on unasked: teach D1 the same hatchOpen selection, or let D1 delegate to the repository emitter the way #8184 just did on the override side. The second is the one-emitter direction this lane keeps choosing, but D1 fires before the repository exists in the call and carries its own docs pointer, so it is a real design call rather than a mechanical move.
Related
Generated by Claude Code
Observation found while implementing #8184 (PR #8353). Filed, not fixed: it lives in
saveMetaItem's ADR-0070 D1 gate, a different region ofprotocol.tsfrom #8184's fenced one, and adjacent to #7748's declared surface.What is shadowed
#8146 (
7f02367c1) gave BOTH package-door emitters inSysMetadataRepositoryahatchOpenremedy selection:readOnlyBaseOverrideError—403 ITEM_LOCKED, override side. Reachable, and The metadata write refusal answers a different code per TOPOLOGY:saveMetaItem's scoped-kernel branch refuses before the repository's package door ever runs #8184 now makes it reachable on scoped kernels too.readOnlyBaseCreateError—422 WRITABLE_PACKAGE_REQUIRED, runtime-only create side. Its hatch clause reads: "OS_METADATA_WRITABLE is set for 'X': it unlocks the metadata TYPE, not package writability, so it does not make a read-only package a writable base."That second clause cannot be reached through
saveMetaItemon any topology. The ADR-0070 D1 gate a few hundred lines above the repository call throws first, on a strictly wider condition:The repository's create door fires on the same predicate plus
namedBase(non-empty string) plus "no registry limb returned". Every write that would reach it has already been thrown by D1 — which is topology-independent, so this is not a per-kernel divergence like #8184 was.Why it is worth recording
The code and status agree (
WRITABLE_PACKAGE_REQUIRED/ 422), and D1's sentence does not prescribe settingOS_METADATA_WRITABLE, so this is not the retry-forever false-prescription trap #8146 closed on the override side. It is the milder half: an operator who has the hatch open and attempts a runtime-only create into a read-only base is told the base is read-only, and never told that the hatch they set does not reach the package dimension. The override side explains it; the create side does not.Secondary: it means the create-side hatch clause is only exercised by direct
repo.putcallers (promoteDraft/restoreVersion/revertCommit), not by the authoring surface it was written for — so a change to that sentence would read as covered while the surface that matters never emits it.Not proposing a shape
Two readings, and neither is obvious enough to act on unasked: teach D1 the same
hatchOpenselection, or let D1 delegate to the repository emitter the way #8184 just did on the override side. The second is the one-emitter direction this lane keeps choosing, but D1 fires before the repository exists in the call and carries its owndocspointer, so it is a real design call rather than a mechanical move.Related
saveMetaItem's scoped-kernel branch refuses before the repository's package door ever runs #8184 / PR fix(metadata-protocol): the metadata write refusal stops depending on deployment topology (#8184) #8353 — the override side, made topology-independent.OS_METADATA_WRITABLEunlocks a write on a read-only package while Studio renders a "Read-only" badge — which one is telling the truth? #8146 (7f02367c1) — where thehatchOpenselection landed.Generated by Claude Code