Filed as an out-of-scope finding while fixing #4240 (the storage → file-storage catalog key). Observation-class: nothing a user hits today, because the endpoints these entries describe do not exist server-side either — so hiding them is accidentally the right outcome. What is wrong is that the catalog carries 7 endpoint declarations that can never render on any host, and the fail-closed gate is what has been silently masking them.
Measurement
apps/console/src/pages/developer/hooks/useApiDiscovery.ts, SERVICE_ENDPOINT_CATALOG. The key is looked up directly in the /discoveryservices map (discoveredServices[serviceName]), and that map is built only from the framework's SERVICE_CONFIG, whose keys the framework constrains to CoreServiceName members. Measured against the vendored @objectstack/spec@17.0.0-rc.6:
CoreServiceName.options = [metadata, data, auth, file-storage, search, cache,
queue, automation, analytics, realtime, job,
notification, ai, i18n, ui]
Catalog keys checked against it — 7 IN, 3 OUT:
| catalog key | in slot vocabulary | note |
|---|
ai, realtime, notification, analytics, automation, i18n, ui | yes | fine |
storage | no | #4240, being fixed — canonical name is file-storage |
workflow | no | slot retired in objectstack#4451 (v17) |
feed | no | never was a CoreServiceName slot |
The two dead entries
workflow (5 endpoints, /api/v1/workflow/*). The slot was retired in objectstack#4451: core-services.zod.ts carries the retirement note in place of the enum member, and metadata-protocol/src/protocol.ts:1922 reads workflow: { route: '/api/v1/workflow' } retired with the slot (#4451, …). Counter-probed on objectstack origin/main @ 5d24f4b: no registerService('workflow') anywhere, and no mounted /api/v1/workflow route — the only hits are the retirement notes themselves plus spec/src/api/protocol.zod.ts:1024 and spec/src/migrations/registry.ts:1686, both recording that the pre-#3586 dispatcher listed it but never mounted it.
feed (2 endpoints, /api/v1/feed/*). Never a slot, and counter-probed: zero hits for an /api/v1/feed route anywhere in objectstack packages/, and zero for a feed discovery service entry.
So both are hidden for the same mechanical reason as #4240 — key not in the discovery map, fail-closed branch taken (ADR-0076 D12) — but unlike #4240 the remedy is not a rename, because there is no correctly-spelled slot to rename them to.
Why this is not folded into #4240
#4240's scope is the one mis-keyed group whose service is real and whose endpoints work. These two are the opposite case: the key is dead because the capability is. The remedy is a product decision rather than a spelling fix, and each key has a different one:
workflow — the capability is live elsewhere (state_machine validation rules, approval flow nodes per ADR-0019, lifecycle hooks + record_change flows in service-automation). Options: delete the catalog entry, or re-point the group at whatever surface actually serves the capability today.feed — options: delete the entry, or, if a feed surface is planned, leave it and let it enter the catalog with the slot when the implementation lands (implementation-first, per the startup-focus principle).
Tripwire coverage already added by #4240
The PR for #4240 pins SERVICE_ENDPOINT_CATALOG keys against CoreServiceName from @objectstack/spec/system, with these two keys as a documented, exhaustive exception set citing this issue. Consequences worth knowing before acting here:
- a new non-slot key added to the catalog goes red immediately;
- removing
workflow or feed keeps the pin green (the assertion is a subset check), so whoever resolves this issue does not have to touch the test to make it pass — but should trim the exception set and this reference on the way out.
Filed as an out-of-scope finding while fixing #4240 (the
storage→file-storagecatalog key). Observation-class: nothing a user hits today, because the endpoints these entries describe do not exist server-side either — so hiding them is accidentally the right outcome. What is wrong is that the catalog carries 7 endpoint declarations that can never render on any host, and the fail-closed gate is what has been silently masking them.Measurement
apps/console/src/pages/developer/hooks/useApiDiscovery.ts,SERVICE_ENDPOINT_CATALOG. The key is looked up directly in the/discoveryservicesmap (discoveredServices[serviceName]), and that map is built only from the framework'sSERVICE_CONFIG, whose keys the framework constrains toCoreServiceNamemembers. Measured against the vendored@objectstack/spec@17.0.0-rc.6:Catalog keys checked against it — 7 IN, 3 OUT:
ai,realtime,notification,analytics,automation,i18n,uistoragefile-storageworkflowfeedCoreServiceNameslotThe two dead entries
workflow(5 endpoints,/api/v1/workflow/*). The slot was retired in objectstack#4451:core-services.zod.tscarries the retirement note in place of the enum member, andmetadata-protocol/src/protocol.ts:1922readsworkflow: { route: '/api/v1/workflow' }retired with the slot (#4451, …). Counter-probed on objectstackorigin/main@5d24f4b: noregisterService('workflow')anywhere, and no mounted/api/v1/workflowroute — the only hits are the retirement notes themselves plusspec/src/api/protocol.zod.ts:1024andspec/src/migrations/registry.ts:1686, both recording that the pre-#3586 dispatcher listed it but never mounted it.feed(2 endpoints,/api/v1/feed/*). Never a slot, and counter-probed: zero hits for an/api/v1/feedroute anywhere in objectstackpackages/, and zero for afeeddiscovery service entry.So both are hidden for the same mechanical reason as #4240 — key not in the discovery map, fail-closed branch taken (ADR-0076 D12) — but unlike #4240 the remedy is not a rename, because there is no correctly-spelled slot to rename them to.
Why this is not folded into #4240
#4240's scope is the one mis-keyed group whose service is real and whose endpoints work. These two are the opposite case: the key is dead because the capability is. The remedy is a product decision rather than a spelling fix, and each key has a different one:
workflow— the capability is live elsewhere (state_machine validation rules, approval flow nodes per ADR-0019, lifecycle hooks +record_changeflows in service-automation). Options: delete the catalog entry, or re-point the group at whatever surface actually serves the capability today.feed— options: delete the entry, or, if a feed surface is planned, leave it and let it enter the catalog with the slot when the implementation lands (implementation-first, per the startup-focus principle).Tripwire coverage already added by #4240
The PR for #4240 pins
SERVICE_ENDPOINT_CATALOGkeys againstCoreServiceNamefrom@objectstack/spec/system, with these two keys as a documented, exhaustive exception set citing this issue. Consequences worth knowing before acting here:workfloworfeedkeeps the pin green (the assertion is a subset check), so whoever resolves this issue does not have to touch the test to make it pass — but should trim the exception set and this reference on the way out.