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
The default-project slot has 3 production readers, 0 production registrants — and 6 comments name a registrant function that exists in neither repo #5958
Found while sweeping the REST composition root for #4251 (B4, PR #5953). Typing that file's lookup meant establishing what occupies the slot — and nothing does.
Evidence
Three production readers, all resolving the literal 'default-project':
packages/rest/src/rest-api-plugin.ts defaultEnvironmentIdProvider() → dp?.environmentId
packages/runtime/src/http-dispatcher.ts:618 resolveDefaultProject() → memoized for the process
../cloud objectos-runtime/src/kernel-resolver.ts:193 resolution level 6
Zero production registrants. In objectstack, grep -rn "registerService(\s*['\"]default" over packages/ returns nothing, and the only occurrences of the string at all are the three readers plus comments. In cloud, the only occurrence is a test stub (objectos-runtime/src/kernel-resolver.test.ts:143, getService: (n) => n === 'default-project' ? { environmentId: 'proj_local' } : undefined).
Six comments name the registrant, and it does not exist.createSingleEnvironmentPlugin is referenced as the thing that registers this slot in:
grep -rn "createSingleEnvironmentPlugin" over both repos returns only those comments — no declaration, no export, no call. Same for the cloud checkout.
Why this is observation-class and not a live outage
Every reader has a working fallback and degrades by design:
rest-api-plugin's provider is wrapped in try/catch returning undefined; RestServer then falls through its hostname/header chain.
http-dispatcher.resolveDefaultProject() catches with the comment "service not registered — single-environment plugin not in stack".
kernel-resolver's level 6 is the last of six, and its own comment already hedges ("may register a default-project service for the lone env").
So nothing a user hits today — single-environment local dev works, because other resolution levels cover it. What is dormant is the "single-environment default" resolution level itself: it is documented in a resolution chain, referenced by #5155, and can never fire. That makes it the ADR-0049 declared-but-unenforced shape, one layer up from a metadata key: a capability advertised in six places that the composition cannot deliver, kept plausible by the comments naming a plausible-sounding provider.
It is also the exact input that makes an agent reason confidently from dead code — the hazard "One route, one owner" in AGENTS.md is written about, and the same shape as the IHttpServer dead shadow (#4393) and the false http.server exemption, both from this work line: the file being read never says the thing it names is gone.
Two ways to close it, opposite directions
The plugin should exist — createSingleEnvironmentPlugin was planned or removed, and single-environment hosts genuinely want bare /api/v1/data/... to route into the lone environment's kernel without a hostname. Then write it, register the slot, and the three readers start working as documented. Worth checking HttpDispatcher 把「本请求解析出的 kernel」存在实例字段上(this.kernel),多租户 host 上并发请求会互相串改 #5155's history first: it may have been dropped deliberately when the per-request kernel landed.
The slot should go — the other five resolution levels are sufficient and this level is speculative surface. Then delete the three reads and the six comments, per enforce-or-remove. Note the readers are cheap but not free: http-dispatcher memoizes the answer for the process lifetime.
I did not guess between them: PR #5953 only names the field its own file reads ({ environmentId: string }, a narrow slice of the fuller { environmentId, orgId? } that runtime declares) and changes no behaviour. Filed unassigned.
Found while sweeping the REST composition root for #4251 (B4, PR #5953). Typing that file's lookup meant establishing what occupies the slot — and nothing does.
Evidence
Three production readers, all resolving the literal
'default-project':Zero production registrants. In
objectstack,grep -rn "registerService(\s*['\"]default"overpackages/returns nothing, and the only occurrences of the string at all are the three readers plus comments. Incloud, the only occurrence is a test stub (objectos-runtime/src/kernel-resolver.test.ts:143,getService: (n) => n === 'default-project' ? { environmentId: 'proj_local' } : undefined).Six comments name the registrant, and it does not exist.
createSingleEnvironmentPluginis referenced as the thing that registers this slot in:grep -rn "createSingleEnvironmentPlugin"over both repos returns only those comments — no declaration, no export, no call. Same for thecloudcheckout.Why this is observation-class and not a live outage
Every reader has a working fallback and degrades by design:
rest-api-plugin's provider is wrapped intry/catchreturningundefined;RestServerthen falls through its hostname/header chain.http-dispatcher.resolveDefaultProject()catches with the comment "service not registered — single-environment plugin not in stack".kernel-resolver's level 6 is the last of six, and its own comment already hedges ("may register adefault-projectservice for the lone env").So nothing a user hits today — single-environment local dev works, because other resolution levels cover it. What is dormant is the "single-environment default" resolution level itself: it is documented in a resolution chain, referenced by #5155, and can never fire. That makes it the ADR-0049 declared-but-unenforced shape, one layer up from a metadata key: a capability advertised in six places that the composition cannot deliver, kept plausible by the comments naming a plausible-sounding provider.
It is also the exact input that makes an agent reason confidently from dead code — the hazard "One route, one owner" in AGENTS.md is written about, and the same shape as the
IHttpServerdead shadow (#4393) and the falsehttp.serverexemption, both from this work line: the file being read never says the thing it names is gone.Two ways to close it, opposite directions
createSingleEnvironmentPluginwas planned or removed, and single-environment hosts genuinely want bare/api/v1/data/...to route into the lone environment's kernel without a hostname. Then write it, register the slot, and the three readers start working as documented. Worth checking HttpDispatcher 把「本请求解析出的 kernel」存在实例字段上(this.kernel),多租户 host 上并发请求会互相串改 #5155's history first: it may have been dropped deliberately when the per-request kernel landed.http-dispatchermemoizes the answer for the process lifetime.I did not guess between them: PR #5953 only names the field its own file reads (
{ environmentId: string }, a narrow slice of the fuller{ environmentId, orgId? }thatruntimedeclares) and changes no behaviour. Filed unassigned.