--- id: RAIL-FAB-WP-0015 type: workplan title: "Runtime Entity Taxonomy Refinement" domain: railiance repo: railiance-fabric status: finished owner: codex topic_slug: railiance planning_priority: high planning_order: 15 created: "2026-05-21" updated: "2026-05-21" state_hub_workstream_id: "958559cc-c640-40d6-afe3-467ee0e9e973" --- # RAIL-FAB-WP-0015 - Runtime Entity Taxonomy Refinement ## Goal Refine runtime topology discovery and graph rendering so servers, services, applications, ports, and domains are distinct entities instead of variants of the old catch-all `Server` node. ## Background The first runtime topology pass intentionally used conservative `Server`, `NetworkPort`, and `DomainName` nodes. After projecting all candidates into the graph, this proved too broad: - `127.0.0.1:8765` is a port endpoint, not a server. - `gitea.coulomb.social` is an application-facing endpoint, not a machine. - `pink-account.coulomb.social` should be connected through the privacyIDEA service/application topology instead of floating as a repo-declared server. ## Target Model - `Server` is reserved for concrete machine or host addresses such as IPs and localhost loopback addresses. - `RuntimeService` represents a running service target such as a Kubernetes Service DNS name or a declared service endpoint. - `ApplicationEndpoint` represents user-facing application endpoints exposed through domains, ingress hosts, or declared HTTP URLs. - `NetworkPort` remains the separate port/protocol binding node. - `DomainName` remains the DNS name and routes to the port/service/application it describes. ## Tasks ### T01 - Update Runtime Scanner Taxonomy ```task id: RAIL-FAB-WP-0015-T01 status: done priority: high state_hub_task_id: "c19f55e2-dd68-4cb9-8c21-fd9c61a3ab25" ``` Emit refined runtime candidates from Compose, Kubernetes, and Fabric endpoint evidence without using `Server` for domain names or service DNS targets. ### T02 - Update Graph Explorer Runtime Projection ```task id: RAIL-FAB-WP-0015-T02 status: done priority: high state_hub_task_id: "b5caa75d-04bf-4eb3-9b61-f28eb85fe9d4" ``` Render legacy accepted `Server` candidates as the refined presentation kind where their attributes make the intent clear, and stop inferring `host:port` values as server nodes. ### T03 - Preserve Port And Service Relationships ```task id: RAIL-FAB-WP-0015-T03 status: done priority: medium state_hub_task_id: "06b19102-d5f9-4707-af86-7fb248126374" ``` Keep existing port/domain relationships while adding explicit relationships from runtime services and application endpoints to their ports. Deduplicate inferred deployment `runs_on` edges. ### T04 - Verify Fixtures And Live Graph Shape ```task id: RAIL-FAB-WP-0015-T04 status: done priority: high state_hub_task_id: "d14e85b4-4323-4ce6-9e25-bc92293dc351" ``` Update scanner and graph explorer tests, then verify the live graph no longer classifies application domains or `host:port` endpoints as servers. Verification result: - `python3 -m pytest tests/test_graph_explorer.py tests/test_scanner.py -q` passed with 8 tests. - `python3 -m pytest` passed with 35 tests. - Restarted the local registry on port 8765. - Live graph explorer export now shows: - `127.0.0.1:8765` as a `NetworkPort`. - `gitea.coulomb.social` and `pink-account.coulomb.social` as `ApplicationEndpoint` nodes where legacy discovery previously rendered them as `Server`. - `privacyidea.mfa.svc.cluster.local` as a `RuntimeService`. - 0 `Server` nodes whose label contains `host:port`. - 1 `runs_on` edge from `deployment:railiance-fabric.registry:dev`. ## Close Criteria - Scanner tests distinguish `Server`, `RuntimeService`, `ApplicationEndpoint`, `NetworkPort`, and `DomainName`. - Graph explorer tests validate endpoint parsing and duplicate `runs_on` removal. - The local graph export shows application domains as applications, service DNS names as runtime services, and `127.0.0.1:8765` as a port.