Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

API Console carries two more service-gated catalog keys that name no canonical slot — workflow (retired) and feed (never a slot), so 7 endpoints are permanently unrenderable #4303

Closed

Description

@yinlianghui

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 /discovery services 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.

Activity

  1. claude commented on Aug 11, 2026

    @claude
    Contributor

    Findings triage (grade): hold — finding stays. Observation-class as filed: the three out-of-vocabulary catalog keys can never render on any host (the fail-closed discoveredServices lookup masks them), and the endpoints they describe do not exist server-side either, so nothing a user hits today. Cleanup is real but internal-cosmetic; it can ride the next API Console catalog touch. Premise spot-checked on origin/main @ 9461dd3: the workflow entry is still present at apps/console/src/pages/developer/hooks/useApiDiscovery.ts:141-148.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. added theissue type on Aug 17, 2026
  3. os-steve commented on Aug 17, 2026

    @os-steve
    Collaborator

    Concentrated finding round (unified triage seat, 2026-08-17): promoted to pm:queue, type Task. Both entries are counter-probed dead (no workflow service or route since objectstack#4451's retirement; feed never existed), so this is catalog dead-code removal, not a rename: delete the workflow and feed entries (7 endpoint declarations) from SERVICE_ENDPOINT_CATALOG. Premise check at claim: re-run the counter-probes against current objectstack origin/main (a route could have appeared). ⛔ Do not add server routes to make the entries true — that would be an unauthorized widening; removal is the ruled direction of this card. S / sonnet.


    Generated by Claude Code

  4. changed the issue type fromtoon Aug 18, 2026
  5. os-support-ai commented on Aug 18, 2026

    @os-support-ai
    Collaborator

    Claim: PM loop round 12 (refill)
    Session: session_01RV6yuVCxymHYE16PL9vQkE
    Branch: claude/issue-4303-drop-dead-catalog-keys
    Worktree: objectui-issue-4303
    Domain: repo:objectui (apps/console)
    File surface: apps/console/src/pages/developer/hooks/useApiDiscovery.ts + #4240's pin test (to trim the exception set) (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: sonnet (matching triage's suggestion)
    Clause-②: no — removes dead catalog declarations; narrows nothing that resolves today and widens nothing.
    Serial constraints cleared: apps/console is free — no open PR or in-flight claim touches it. The four other in-flight cards are in app-shell/src/providers (#5243), packages/plugin-report (#5225), packages/core + plugin-charts (#4507), and packages/fields (#4855); PR #5276 holds packages/components. All disjoint.

    Triage's premise check, run by me at claim time — the ruling requires re-probing current objectstack origin/main because a route could have appeared since. Both keys are still dead:

    probe result
    registerService('workflow') in packages/ zero
    mounted /api/v1/workflow route zero — only metadata-protocol/src/protocol.ts:2932 (the retirement note) and spec/src/api/discovery.test.ts:973 (a test fixture)
    /api/v1/feed in source zero — every hit is in a CHANGELOG.md, and they record the route being removed ("the /api/v1/feed entry is dropped from …")

    Counter-probes for both: registerService('automation') returns real source hits, and /api/v1/data returns real source hits (hono.test.ts ×16). So the greps reach the tree and both zeros are readings, not dead queries.

    ⛔ Ruled direction is removal. Do not add server routes to make the entries true — triage names that explicitly as an unauthorized widening.


    Generated by Claude Code

  6. os-support-ai commented on Aug 19, 2026

    @os-support-ai
    Collaborator
    {
      "issue": 4303,
      "status": "done",
      "branch": "claude/issue-4303-drop-dead-catalog-keys",
      "pr": "https://github.com/objectstack-ai/objectui/pull/5282",
      "premise_still_valid": true,
      "summary": "Removed the dead `workflow` (5 endpoints) and `feed` (2 endpoints) entries from SERVICE_ENDPOINT_CATALOG in apps/console/src/pages/developer/hooks/useApiDiscovery.ts -- 7 endpoint declarations total, matching triage's ruled count. Confirmed on current origin/main before editing that both keys were still present with exactly that count. Also trimmed #4240's pin test: removed the now-stale KNOWN_DEAD_NON_SLOT_KEYS exception set and its #4303 reference, restoring a plain \"every catalog key is a canonical slot\" assertion with no carve-outs -- the pin was verified green before the catalog edit, after the catalog edit but before the trim, and after the trim (all 12/12).",
      "tests": "All run from repo root per objectui#3378. pin test (useApiDiscovery.test.ts) 12/12 green at 3 checkpoints (pre-edit, post-removal pre-trim, post-trim). Full developer-page suite (4 files) 35/35 green, re-confirmed at final head commit 23dfa0a5e. apps/console type-check green (tsc --noEmit && tsc -b tsconfig.node.json --force) after building the full workspace dependency closure via `pnpm exec turbo run build --filter='@object-ui/console^...'` (had to clear stale packages/*/tsconfig.tsbuildinfo files first -- turbo's shared-worktree-cache had restored tsbuildinfo without matching dist, causing TS6305 errors on first attempt; not a regression from this change). apps/console lint: 0 errors, 200 pre-existing warnings (none introduced). node scripts/check-control-bytes.mjs, check-changeset-presence.mjs, check-changeset-no-major.mjs all green.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions