Skip to content

Catalog button lands on search #83

Open

Description

@ecv

Summary

Every alert Datum sends to Slack carries a catalog button. For some services it lands the responder on a search page instead of the service.

The alert named that service by a name the catalog has retired.

Backstage can resolve the name when the button is clicked, rather than the sender guessing in advance which names will resolve.

Acceptance criteria

  • A request naming a retired service reaches the service that absorbed it
  • A request naming a current service reaches that service
  • A name the catalog cannot place falls back to search, as today
  • The alert sender no longer needs to know which names resolve

How it works today

The sender decides. The button carries a list of the services the catalog defines, generated from the catalog and committed, so it holds the current names and never the retired ones. A retired name misses the list and goes to search, even though the catalog can place it.

Retired names keep resolving on purpose. Routing honors them so a rename never sends an alert to the wrong room, and the link is the only thing that degrades.

The list also goes stale on any change to the set of services, including a rename that changes nothing else. That has broken the check twice in one evening, and it is a standing trap for whoever renames a service next.

Notes

Retired names are first-class in the catalog. Each service records the names it used to carry, and those names already resolve an owning team. This asks the entity lookup to use the same list the ownership resolution already uses.

Background on the generated list and the renames that exposed it: https://github.com/datum-cloud/infra/issues/5641 and https://github.com/datum-cloud/infra/issues/5627.

Activity

  1. changed the title [-]Alert links land on search, not the service[/-] [+]Catalog button lands on search[/+] on Sep 17, 2026
  2. ecv commented on Sep 17, 2026

    @ecv
    ContributorAuthor

    The catalog already holds the answer. Every retired name a service absorbs is emitted as a tag on that service's System entity, alongside a "Formerly" sentence in the description, so control-plane carries activity-compliance, catalog-search and notifications today. Nothing reads those tags when a link is built, because the link is built by the sender.

    The plan is a resolver route in the app, no backend change. A frontend module mounts a page at /s, and /s/<name> asks the catalog for a System whose metadata.name or metadata.tags matches the name, in one request with the two filters ORed. An exact name match wins. A single tag match resolves to the service that absorbed the name. Anything else redirects to /search?query=<name>, which is where those names land today.

    A backend route was the other option and is worse here. It needs its own auth policy to answer an unauthenticated click, and it would edit the same backend entrypoint that #82 is already changing. The frontend route rides the session the browser already has, which is the same session the current button relies on.

    Once this ships, the alert sender stops choosing. The button becomes a link to /s/ plus whatever service the alert carries, and the generated list of current service names in the infra repository can go, along with the three-place wiring that keeps it from going stale. That is a separate pull request in that repository, after this one.

    Two limits worth recording. Tags are lowercased and stripped of anything outside [a-z0-9-] when they are generated, so a future retired name carrying a dot or a capital would not match the label the alert sends. Every retired name in the catalog today is already lowercase and hyphenated, so nothing is broken now, and an explicit annotation would be the durable key if that changes. The other is that tags on a System mean "retired name" only because this catalog generates every System from one source. A hand-written System elsewhere with an unrelated tag could collide, which is why an exact name match takes precedence and two tag matches fall back to search rather than guessing.

    The generator already refuses to map one retired name onto two services, so the ambiguous case should not reach the resolver at all.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions