Skip to content

Commit 9e5cd71

Browse files
os-justinclaude
andauthored
fix(rest): the shipped objectQLProvider absorbs only the branded never-registered rejection (#14250)
* fix(rest): objectQLProvider absorbs only the branded never-registered rejection (#13904) The shipped provider collapsed three distinguishable registry facts into one undefined, so the wiredEngineOrLoud transport seam never saw a wired-and-broken engine on the single-kernel wiring. It now resolves through kernel.getServiceAsync and absorbs only the branded isServiceNotRegisteredError rejection: never-registered stays quiet (pinned), a factory-registered engine resolves, a failed construction re-raises into the 503 outage. KernelBase-shaped hosts keep the sync leg, whose only fault is never-registered. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015YPiiDdw96RGS25WLctCQP * chore(changeset): re-declare @objectstack/rest as minor per the launch-window convention The at-tier contract review's one finding: the #13476 family's changeset (engine-unresolvable-fails-loud.md, PR #13910) ships the identical class of public-door behaviour change as minor and names the convention; this change goes strictly further (one refused -> served row), so patch was an undeclared divergence. Declaration and convention now named in the body. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015YPiiDdw96RGS25WLctCQP --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 035951f commit 9e5cd71

3 files changed

Lines changed: 444 additions & 1 deletion

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
"@objectstack/rest": minor
3+
---
4+
5+
fix(rest): the shipped `objectQLProvider` stops collapsing "the engine is wired and broke" into "no engine is wired" (#13904)
6+
7+
Runtime behaviour change on a public REST door, shipped as `minor` under the
8+
repo's launch-window convention — the same convention the #13476 family's
9+
changeset (`engine-unresolvable-fails-loud.md`, PR #13910) and #13279's name
10+
for the identical class of change on this same door. This change additionally
11+
moves one row refused → served (a factory-registered engine now resolves and
12+
serves), so it sits strictly inside the class that convention governs.
13+
14+
`rest-api-plugin.ts` handed `RestServer` an engine provider shaped
15+
`try { return ctx.getService('objectql'); } catch { return undefined; }`. The
16+
sync accessor throws for three distinguishable registry facts — never
17+
registered (the supported no-data-plane embedder), registered as a factory
18+
(wrong accessor for it), and a registration that failed to build — and the
19+
catch-all answered all three with the `undefined` the seam contract reads as
20+
"no engine is wired". So the #13476 transport repair (`wiredEngineOrLoud`,
21+
which turns a provider REJECTION into the loud 503 outage) never fired on the
22+
shipped single-kernel wiring: the provider absorbed one layer before the seam
23+
could see the fact.
24+
25+
The provider now resolves through `kernel.getServiceAsync`
26+
`PluginLoader.getService` and absorbs ONLY the branded "never registered"
27+
rejection (`isServiceNotRegisteredError`, #13905) — the registry's own
28+
classification, never message text, closed set, loud default. Observable
29+
changes, all in the wired-single-kernel deployment:
30+
31+
- an embedder that never wired a data plane keeps its quiet answer, unchanged
32+
and pinned (403 at the package door, as before);
33+
- an engine registered as a service FACTORY now actually resolves and serves
34+
(previously the sync accessor could only throw `is async - use await`, read
35+
as "no engine": the door refused a wired, constructible engine);
36+
- an engine whose registration FAILS TO BUILD now rejects loudly, so the door
37+
answers 503 `SERVICE_UNAVAILABLE` instead of telling an authenticated
38+
administrator they lack a capability.
39+
40+
A KernelBase-shaped host (`LiteKernel`, no async accessor, no factories) keeps
41+
both of its answers byte-identically through the sync fallback leg.

0 commit comments

Comments
 (0)