fix(api): drop deactivated NyxID services from system-services facet (#715)#736
Merged
chronoai-shining merged 1 commit intoMay 28, 2026
Merged
Conversation
…715) NyxID's DELETE /services/:id is a soft delete that flips is_active to false. The Ornn DB aggregation behind /skill-facets/system-services reads nyxidServiceId/slug/label straight off skill documents, so any skill ever bound to a now-deactivated service kept surfacing the service as a usable filter chip. Per-caller paths (/me/nyxid-services, /nyxid-services/:serviceId/skills) already filtered is_active=false inside NyxidServiceClient, but the 60-second catalog cache widened the post-deletion visibility lag. Fix: - NyxidServiceClient.listActiveServiceIdsAsPlatform(saToken) (new): SA-token fetch of NyxID's /services projected to a Set<string> of active ids, kept in a one-slot cache (SA view is uniform across callers). Fail-soft: returns null on non-2xx or thrown fetch so callers can fall through to legacy behaviour when NyxID is unreachable. - /skill-facets/system-services intersects the DB aggregation with that active set when the client + SA accessor are wired in; falls through to the raw aggregation otherwise. Bootstrap passes both. - cacheTtlMs 60s -> 10s. After a NyxID deactivation every surface that goes through findVisibleToCaller drops the service within at most 10s instead of 60s. - invalidateCache() also clears the platform cache. Skill detail still shows the historical nyxidServiceId/slug/label even when the service is deactivated — out of scope here. The issue lists multiple acceptable mitigations; closing the discovery surface is the highest-leverage one. A follow-up can mark the detail panel as "service unavailable" if a louder signal is wanted. Coverage: 8 colocated tests in service.test.ts — per-caller is_active drop (defence-in-depth), missing is_active default, platform method URL + auth header, caching, fail-soft on 5xx and network throw, empty-SA short-circuit, invalidateCache re-fetch. 748 tests pass total / 18 unrelated pre-existing failures. Fixes #715
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/skill-facets/system-servicesnow intersects the DB aggregation with NyxID's live active set (via a newNyxidServiceClient.listActiveServiceIdsAsPlatform(saToken)), so services NyxID has deactivated stop appearing as filter chips./me/nyxid-servicesand/nyxid-services/:serviceId/skills(which already filteris_active=false) now reflect deactivations within 10s instead of 60s.service.test.ts.Test plan
bun test src/clients/nyxid/service.test.ts— 8/8 greenbun run typecheck:api— no new errorsornn-apisuite — 730 pass / 18 unrelated pre-existing failures (validateSkillFrontmatter [Bug] [Skill Upload] Some frontmatter validation errors only show genericInvalid input#649)/skill-facets/system-servicesand confirm the service no longer appears.Out of scope: skill-detail still shows the historical
nyxidServiceId/slug/labeleven when the service is deactivated. The issue lists multiple acceptable mitigations; closing the discovery surface is the highest-leverage one. Follow-up can mark detail as 'service unavailable' if we want a louder signal.Fixes #715