Skip to content

spec: register UNIQUE_SCOPE_CONFIRMATION_REQUIRED — the install seam's posture-gate refusal reaches a wire unregistered #9246

Description

@os-steve

Found by the widened check-dispatcher-error-vocabulary scan in #9223 (PR pending). Filed unassigned; nobody is on it. Not fixed there: that card widens the GATE, and packages/runtime/src/dispatcher-error-vocabulary.ts states its own boundary — "Registering a code widens the accepted set, which is a contract-semantics change owned by the packages/spec lane. Nothing here edits the ledger." #9223 lands the classification row; this card is the registration.

The finding

UNIQUE_SCOPE_CONFIRMATION_REQUIRED is in neither StandardErrorCode nor ERROR_CODE_LEDGER, and it reaches a wire as error.code:

  • Producerpackages/cloud-connection/src/marketplace-install-local-plugin.ts, the ADR-0120 D5e posture gate stopping an install: c.json({ success: false, error: { code: GLOBAL_UNIQUE_CONFIRMATION_REQUIRED, message, details } }). The constant is packages/types/src/unique-scope-install-gate.ts.
  • Live reader off the wirepackages/cli/src/commands/package/install.ts branches on res.body?.error?.code === 'UNIQUE_SCOPE_CONFIRMATION_REQUIRED' to print the per-index decision list. So the spelling is load-bearing, not incidental.
  • The seam already speaks registered vocabulary, which is what makes this a gap rather than a design choice: every sibling code in the same file (PLUGIN_MANIFEST_INVALID, MARKETPLACE_UNAVAILABLE, INVALID_REQUEST, RESOURCE_NOT_FOUND, CLOUD_FETCH_FAILED, MARKETPLACE_STORAGE_FAILED, …) is in the ledger already — which is precisely why the gate never reported them. This one member is the exception.

Why it hid until now

It is stamped through a constant in an object literal — the exact blind spot #9223 closes. objlit required a quoted literal, so code: GLOBAL_UNIQUE_CONFIRMATION_REQUIRED matched nothing and was not even reported as unresolved. The code has been reaching the wire, unregistered, for as long as the gate has been green.

Disposition already landed in #9223

The site carries a row with verdict: 'pending-registration', door: 'plugin-route', so PENDING_LEDGER_REGISTRATION is non-empty again and the ratchet is armed: when this registration lands, error-envelope.conformance.test.ts goes red on the now-stale row ("every pending code is still unregistered") and that row must be deleted in the same edit. That is the intended hand-off, not a conflict.

Note the door: this seam is a plugin mounting its own Hono routes, so the body passes through neither the dispatcher's errorFromThrown nor the packages/rest doors — worth a look at whether anything parses that envelope against ApiErrorSchema at all, since nothing currently would have caught this.

Related: #8087 (the gate), #8846 (the first registration batch, closed), #9223 (the widening that found it).


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions