hub-core/docs/platform-access-inventory.md

341 lines
24 KiB
Markdown
Raw Normal View History

# Platform-root access inventory — 2026-09-28
This is the coverage baseline for HUB-WP-0012-T01, not an access grant or a
passing security test. It enumerates 161 Hub source surfaces (88 runtime route
registrations, 42 embedded router operations, 31 MCP tools), 39 observed cluster
namespaces and nine additional extension/native-management boundaries. All 250
observed Deployment/StatefulSet/DaemonSet/CronJob/Service/Ingress objects map to
exactly one namespace row. Scaled-down revisions and legacy workloads remain
listed so they cannot become unnoticed rollback bypasses.
The [machine-readable inventory](platform-access-inventory.json) is authoritative
for this snapshot. Rows inherit audience, actor/target tenant, action/resource
mapping, enforcement point and test owner from their named profile. Platform
rows additionally identify responsible repositories and exact Kubernetes objects.
Audience candidates and ownership inferred from deployment names are explicitly
pending owner confirmation; none establishes an effective platform-root grant.
## Scope and reproducibility
Hub source revision is recorded in the JSON. Runtime routes are constructed
locally without running startup, sending requests or connecting to a database.
The optional inbox router is included separately. Compatibility aliases and
FastAPI built-in documentation endpoints are included even when absent from
OpenAPI; disabled compatibility groups still belong in the coverage contract.
Embedded factories are scanned with their default prefixes and include optional
operations: host mounting and feature flags determine effective deployment paths.
MCP extraction asserts coverage against CORE_TOOL_NAMES and records its HTTP calls.
Cluster collection used the explicit railiance01 kubeconfig and metadata-only
projection of six resource kinds. No Secret, environment value, mounted file,
service-account token or authentication credential was collected. This is not a
scan of every CRD, Pod/Job, host process, external provider or tenant application
endpoint. Native execution and external-control rows keep those inventory gaps
visible. Root administration of tenant infrastructure is distinct from an
unreviewed grant to its business data.
Run from hub-core:
```sh
PYTHONDONTWRITEBYTECODE=1 .venv/bin/python tools/build_access_inventory.py \
--inventory docs/platform-access-inventory.json --check
```
Omit `--check` to refresh source rows after intentional changes, then review the
diff. Cluster metadata is a dated reviewed input, not silently refreshed by this
command. The checker detects source drift, missing profile/test references and
missing/duplicate cluster-object mappings. It does not test authorization. Live
allow/deny cases remain marked `not-run`; the [source candidate](access-profile-v1.md)
adds local enforcement tests. Implementation tasks must still supply the
client fixtures, isolated mutations, independent readbacks and live receipts.
## Findings that affect implementation
1. **Documentation routes have overlapping handlers.** GET `/docs` and `/openapi.json`
each register both FastAPI's built-in handler and a compatibility alias.
Protecting only the compatibility handler leaves another dispatch path.
T04 must test effective routing, including HEAD and slash normalization.
2. **MCP is not synonymous with the standalone runtime.** Many tools call
`/messages`, `/domains`, `/state/summary` and other host routes rather than
`/ports/...`. T04/T05 need an explicit backend/migration mapping and per-caller
authentication. A successful native-port test does not cover these tools.
3. **Embedded APIs are independent entry points.** The host owns authentication,
policy injection and any prefix overrides; an Ingress change cannot protect
a host that mounts the SDK elsewhere. Inventory actual consumer mounts before
freezing T01, using the retirement route/caller ledgers.
4. **39 namespaces do not mean 39 login surfaces.** Controllers, backing stores,
scaled-down revisions and the notice page should be managed through their
owner/Kubernetes path, not exposed as new human-facing services. Each owner
must split management and application audiences within its namespace row.
5. **Extensions/native administration still need owner evidence.** Ops Hub's
manifest names `service.ops-hub.http`, a framework API, console and CLI;
standalone live resolution is unproven. Fabric hosting is independently
blocked under RAIL-FAB-WP-0028. SSH, Kubernetes, GitOps, host jobs and provider
control planes need their own root entitlement receipts.
## Proposed acceptance cases
Every non-health surface runs ROOT, OTHER, INVALID, REVOKE, OUTAGE, BYPASS and
CALLER from the JSON; native privileged actions additionally run APPROVAL.
`/healthz` gets HEALTH instead of pretending anonymous probes should be denied.
These are test specifications, not completed tests:
| Case | Required observation |
| --- | --- |
| ROOT | Verified immutable root identity + current entitlement + AAL2 succeeds; independent readback and actor audit |
| OTHER | Ordinary user and tenant administrator cannot perform platform operations or learn unauthorized tenant data |
| INVALID | Anonymous, forged username/header, wrong audience/issuer and expired token rejected without side effect |
| REVOKE | Grant removal, account suspension and logout deny within the specified bound; current authority rechecked for privileged mutation |
| OUTAGE | Untrusted/unavailable policy or required audit cannot authorize mutation |
| BYPASS | Direct Service, aliases, MCP and embedded hosts enforce the same decision |
| CALLER | Named workload receives only its grant; spoofed sender, delegation and inherited root authority fail |
| APPROVAL | Full root entitlement does not skip action-specific confirmation/approval; use reversible or isolated targets |
| HEALTH | Anonymous liveness reveals no subject, tenant, dependency or business details |
## Hub surface register
The table lists every discovered source operation. JSON retains factory/handler,
source location, current gate observation and MCP target call expressions.
Duplicate runtime method/path rows are intentional separate registrations.
| Kind/profile | Operation | Source/handler |
| --- | --- | --- |
| runtime-http / hub-api | `GET /annotation-categories` | `annotation_categories` |
| runtime-http / hub-api | `GET /annotations` | `empty_collection` |
| runtime-http / hub-api | `GET /api-consumers` | `list_consumers` |
| runtime-http / hub-api | `GET /api/v2/annotation-categories` | `annotation_categories` |
| runtime-http / hub-api | `GET /api/v2/annotations` | `empty_collection` |
| runtime-http / hub-api | `GET /api/v2/api-consumers` | `list_consumers` |
| runtime-http / hub-api | `GET /api/v2/decision-records` | `empty_collection` |
| runtime-http / hub-api | `GET /api/v2/deployment-records` | `empty_collection` |
| runtime-http / hub-api | `GET /api/v2/docs` | `docs` |
| runtime-http / hub-api | `GET /api/v2/event-types` | `event_types` |
| runtime-http / hub-api | `GET /api/v2/hub-capability-manifests` | `list_manifests` |
| runtime-http / hub-api | `GET /api/v2/hub-registry` | `hub_registry` |
| runtime-http / hub-api | `GET /api/v2/hubs` | `list_hubs` |
| runtime-http / hub-api | `GET /api/v2/interaction-events` | `list_interactions` |
| runtime-http / hub-api | `GET /api/v2/openapi.json` | `openapi_json` |
| runtime-http / hub-api | `GET /api/v2/openapi.yaml` | `openapi_yaml` |
| runtime-http / hub-api | `GET /api/v2/outcome-signals` | `empty_collection` |
| runtime-http / hub-api | `GET /api/v2/policy-scopes` | `policy_scopes` |
| runtime-http / hub-api | `GET /api/v2/requirement-candidates` | `empty_collection` |
| runtime-http / hub-api | `GET /api/v2/widget-types` | `widget_types` |
| runtime-http / hub-api | `GET /api/v2/widgets` | `list_widgets` |
| runtime-http / hub-api | `GET /console` | `console` |
| runtime-http / hub-api | `GET /decision-records` | `empty_collection` |
| runtime-http / hub-api | `GET /deployment-records` | `empty_collection` |
| runtime-http / hub-api | `GET /docs/oauth2-redirect` | `swagger_ui_redirect` |
| runtime-http / hub-api | `GET /docs` | `swagger_ui_html` |
| runtime-http / hub-api | `GET /docs` | `docs` |
| runtime-http / hub-api | `GET /event-types` | `event_types` |
| runtime-http / minimal-health | `GET /healthz` | `healthz` |
| runtime-http / hub-api | `GET /hub-capability-manifests` | `list_manifests` |
| runtime-http / hub-api | `GET /hub-registry` | `hub_registry` |
| runtime-http / hub-api | `GET /hubs` | `list_hubs` |
| runtime-http / hub-api | `GET /interaction-events` | `list_interactions` |
| runtime-http / hub-api | `GET /openapi.json` | `openapi` |
| runtime-http / hub-api | `GET /openapi.json` | `openapi_json` |
| runtime-http / hub-api | `GET /openapi.yaml` | `openapi_yaml` |
| runtime-http / hub-api | `GET /outcome-signals` | `empty_collection` |
| runtime-http / hub-api | `GET /policy-scopes` | `policy_scopes` |
| runtime-http / hub-api | `GET /ports/messaging/messages` | `list_messages` |
| runtime-http / hub-api | `GET /ports/projections/repository-navigation/facets/{facet_kind}/{facet_value}` | `query_facet` |
| runtime-http / hub-api | `GET /ports/projections/repository-navigation/repositories` | `query_repositories` |
| runtime-http / hub-api | `GET /ports/projections/statehub-inbox` | `inbox` |
| runtime-http / hub-api | `GET /ports/projections/workloads/resolve` | `resolve_workload` |
| runtime-http / hub-api | `GET /ports/projections/workloads` | `query_workloads` |
| runtime-http / hub-api | `GET /ports/projections/{projection_id}` | `query_projection` |
| runtime-http / hub-api | `GET /ports/registry/registrations/{hub_slug}/audit` | `registration_audit` |
| runtime-http / hub-api | `GET /ports/registry/registrations/{hub_slug}` | `resolve_registration` |
| runtime-http / hub-api | `GET /readyz` | `readyz` |
| runtime-http / hub-api | `GET /redoc` | `redoc_html` |
| runtime-http / hub-api | `GET /requirement-candidates` | `empty_collection` |
| runtime-http / hub-api | `GET /widget-types` | `widget_types` |
| runtime-http / hub-api | `GET /widgets` | `list_widgets` |
| runtime-http / hub-api | `HEAD /docs/oauth2-redirect` | `swagger_ui_redirect` |
| runtime-http / hub-api | `HEAD /docs` | `swagger_ui_html` |
| runtime-http / hub-api | `HEAD /openapi.json` | `openapi` |
| runtime-http / hub-api | `HEAD /redoc` | `redoc_html` |
| runtime-http / hub-api | `PATCH /api/v2/hub-capability-manifests/{manifest_id}` | `patch_manifest` |
| runtime-http / hub-api | `PATCH /hub-capability-manifests/{manifest_id}` | `patch_manifest` |
| runtime-http / hub-api | `POST /annotations` | `accept_deferred` |
| runtime-http / hub-api | `POST /api-consumers/{consumer_id}/api-keys` | `create_key` |
| runtime-http / hub-api | `POST /api-consumers` | `create_consumer` |
| runtime-http / hub-api | `POST /api/v2/annotations` | `accept_deferred` |
| runtime-http / hub-api | `POST /api/v2/api-consumers/{consumer_id}/api-keys` | `create_key` |
| runtime-http / hub-api | `POST /api/v2/api-consumers` | `create_consumer` |
| runtime-http / hub-api | `POST /api/v2/decision-records` | `accept_deferred` |
| runtime-http / hub-api | `POST /api/v2/deployment-records` | `accept_deferred` |
| runtime-http / hub-api | `POST /api/v2/hub-capability-manifests/{manifest_id}/activate` | `activate_manifest` |
| runtime-http / hub-api | `POST /api/v2/hub-capability-manifests` | `create_manifest` |
| runtime-http / hub-api | `POST /api/v2/hubs` | `create_hub` |
| runtime-http / hub-api | `POST /api/v2/interaction-events` | `create_interaction` |
| runtime-http / hub-api | `POST /api/v2/outcome-signals` | `accept_deferred` |
| runtime-http / hub-api | `POST /api/v2/requirement-candidates` | `accept_deferred` |
| runtime-http / hub-api | `POST /api/v2/token` | `token` |
| runtime-http / hub-api | `POST /api/v2/widgets` | `create_widget` |
| runtime-http / hub-api | `POST /decision-records` | `accept_deferred` |
| runtime-http / hub-api | `POST /deployment-records` | `accept_deferred` |
| runtime-http / hub-api | `POST /hub-capability-manifests/{manifest_id}/activate` | `activate_manifest` |
| runtime-http / hub-api | `POST /hub-capability-manifests` | `create_manifest` |
| runtime-http / hub-api | `POST /hubs` | `create_hub` |
| runtime-http / hub-api | `POST /interaction-events` | `create_interaction` |
| runtime-http / hub-api | `POST /outcome-signals` | `accept_deferred` |
| runtime-http / hub-api | `POST /ports/events/interaction` | `append_interaction` |
| runtime-http / hub-api | `POST /ports/events/progress` | `append_progress` |
| runtime-http / hub-api | `POST /ports/messaging/messages` | `send_message` |
| runtime-http / hub-api | `POST /ports/registry/registrations` | `register_extension` |
| runtime-http / hub-api | `POST /requirement-candidates` | `accept_deferred` |
| runtime-http / hub-api | `POST /token` | `token` |
| runtime-http / hub-api | `POST /widgets` | `create_widget` |
| mcp / mcp-client | `accept_capability_request` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `append_progress` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `check_repo_doi` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `get_alerts` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `get_capability_request` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `get_doi_summary` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `get_domain` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `get_domain_summary` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `get_gdpr_report` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `get_messages` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `get_repository_navigation_facet` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `get_risks` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `get_state_summary` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `ingest_tpsc_tool` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `list_capabilities` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `list_capability_requests` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `list_domain_repos` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `list_domains` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `list_services` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `mark_message_read` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `query_repository_navigation` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `query_workloads` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `register_capability` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `register_repo` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `register_service` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `reply_to_message` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `request_capability` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `resolve_workload_reference` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `send_message` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `update_capability_request_status` | `hub_core/mcp/server.py` |
| mcp / mcp-client | `update_repo_path` | `hub_core/mcp/server.py` |
| embedded-http / embedded-host | `GET /capability-catalog/` | `create_capability_catalog_router` |
| embedded-http / embedded-host | `PATCH /capability-catalog/{entry_id}` | `create_capability_catalog_router` |
| embedded-http / embedded-host | `POST /capability-catalog/` | `create_capability_catalog_router` |
| embedded-http / embedded-host | `GET /capability-requests/` | `create_capability_request_read_router` |
| embedded-http / embedded-host | `GET /capability-requests/{request_id}` | `create_capability_request_read_router` |
| embedded-http / embedded-host | `PATCH /capability-requests/{request_id}` | `create_capability_request_write_router` |
| embedded-http / embedded-host | `PATCH /capability-requests/{request_id}/status` | `create_capability_request_write_router` |
| embedded-http / embedded-host | `POST /capability-requests/` | `create_capability_request_write_router` |
| embedded-http / embedded-host | `POST /capability-requests/{request_id}/accept` | `create_capability_request_write_router` |
| embedded-http / embedded-host | `POST /capability-requests/{request_id}/dispute` | `create_capability_request_write_router` |
| embedded-http / embedded-host | `POST /capability-requests/{request_id}/reroute` | `create_capability_request_write_router` |
| embedded-http / embedded-host | `GET /domains/` | `create_domains_router` |
| embedded-http / embedded-host | `GET /domains/{slug}` | `create_domains_router` |
| embedded-http / embedded-host | `PATCH /domains/{slug}` | `create_domains_router` |
| embedded-http / embedded-host | `PATCH /domains/{slug}/archive` | `create_domains_router` |
| embedded-http / embedded-host | `PATCH /domains/{slug}/rename` | `create_domains_router` |
| embedded-http / embedded-host | `POST /domains/` | `create_domains_router` |
| embedded-http / embedded-host | `GET /messages/` | `create_messages_router` |
| embedded-http / embedded-host | `GET /messages/thread/{thread_id}` | `create_messages_router` |
| embedded-http / embedded-host | `PATCH /messages/{message_id}/archive` | `create_messages_router` |
| embedded-http / embedded-host | `PATCH /messages/{message_id}/read` | `create_messages_router` |
| embedded-http / embedded-host | `POST /messages/` | `create_messages_router` |
| embedded-http / embedded-host | `POST /messages/{message_id}/reply` | `create_messages_router` |
| embedded-http / embedded-host | `GET /policy/{name}` | `create_policy_router` |
| embedded-http / embedded-host | `PUT /policy/{name}` | `create_policy_router` |
| embedded-http / embedded-host | `GET /progress/` | `create_progress_router` |
| embedded-http / embedded-host | `GET /progress/alerts` | `create_progress_router` |
| embedded-http / embedded-host | `GET /progress/risks` | `create_progress_router` |
| embedded-http / embedded-host | `POST /progress/` | `create_progress_router` |
| embedded-http / embedded-host | `GET /repos/` | `create_repos_router` |
| embedded-http / embedded-host | `GET /repos/by-fingerprint` | `create_repos_router` |
| embedded-http / embedded-host | `GET /repos/by-remote` | `create_repos_router` |
| embedded-http / embedded-host | `GET /repos/{slug}` | `create_repos_router` |
| embedded-http / embedded-host | `PATCH /repos/{slug}` | `create_repos_router` |
| embedded-http / embedded-host | `POST /repos/` | `create_repos_router` |
| embedded-http / embedded-host | `POST /repos/{slug}/paths` | `create_repos_router` |
| embedded-http / embedded-host | `GET /tpsc/catalog/` | `create_tpsc_router` |
| embedded-http / embedded-host | `GET /tpsc/catalog/{slug}` | `create_tpsc_router` |
| embedded-http / embedded-host | `GET /tpsc/report/gdpr` | `create_tpsc_router` |
| embedded-http / embedded-host | `GET /tpsc/snapshots/` | `create_tpsc_router` |
| embedded-http / embedded-host | `POST /tpsc/catalog/` | `create_tpsc_router` |
| embedded-http / embedded-host | `POST /tpsc/ingest/` | `create_tpsc_router` |
## Platform and extension register
All rows require owner review and root acceptance. The JSON contains exact
object names, hosts, desired/ready replicas and service types for cluster rows.
This mapping identifies accountable review destinations, not completed review.
| Boundary | Owner / test owner | Coverage |
| --- | --- | --- |
| `namespace:activity-core` | activity-core | 22 observed objects |
| `namespace:approval-engine` | approval-engine | 2 observed objects |
| `namespace:argocd` | railiance-platform / railiance-enablement | 8 observed objects |
| `namespace:audit-core` | audit-core | 3 observed objects |
| `namespace:bao-notice` | railiance-platform | 4 observed objects |
| `namespace:canned-prompts` | rapp-canned-prompts | 2 observed objects |
| `namespace:cert-manager` | railiance-platform | 6 observed objects |
| `namespace:cnpg-system` | rapp-postgres | 2 observed objects |
| `namespace:core-hub` | hub-core / rapp-core-hub / repo-manager | 6 observed objects |
| `namespace:coulomb` | railiance-platform (probe owner to confirm) | 3 observed objects |
| `namespace:coulomb-social` | coulomb-social | 3 observed objects |
| `namespace:databases` | rapp-postgres / railiance-platform | 18 observed objects |
| `namespace:default` | railiance-platform | 1 observed objects |
| `namespace:email-connect` | email-connect | 2 observed objects |
| `namespace:external-secrets` | railiance-platform | 5 observed objects |
| `namespace:flex-auth` | flex-auth | 12 observed objects |
| `namespace:forgejo` | railiance-forge / railiance-platform | 6 observed objects |
| `namespace:informed-decision` | informed-decision | 4 observed objects |
| `namespace:inter-hub` | prj-state-hub-retirement / railiance-platform | 2 observed objects |
| `namespace:issue-core` | issue-core | 2 observed objects |
| `namespace:knative-serving` | rail-knative / railiance-platform | 11 observed objects |
| `namespace:kourier-system` | rail-knative / railiance-platform | 3 observed objects |
| `namespace:kube-system` | rail-kubernetes / railiance-platform | 10 observed objects |
| `namespace:mfa` | net-kingdom / key-cape | 7 observed objects |
| `namespace:openbao` | rapp-openbao / railiance-platform | 8 observed objects |
| `namespace:platform-pg-drill` | rapp-postgres | 2 observed objects |
| `namespace:policy-nexus` | policy-nexus | 4 observed objects |
| `namespace:rapp-qonto` | rapp-qonto | 28 observed objects |
| `namespace:rapp-qonto-egress` | rapp-qonto | 2 observed objects |
| `namespace:rein-aharness` | rein-aharness | 1 observed objects |
| `namespace:reuse` | reuse-surface | 7 observed objects |
| `namespace:sbom-nexus` | sbom-nexus | 2 observed objects |
| `namespace:sso` | net-kingdom / key-cape | 15 observed objects |
| `namespace:state-hub` | state-hub | 4 observed objects |
| `namespace:target-revenue` | target-revenue | 6 observed objects |
| `namespace:telemetry` | rapp-telemetry / railiance-platform | 12 observed objects |
| `namespace:tenant-engine` | tenant-engine | 2 observed objects |
| `namespace:user-engine` | user-engine | 9 observed objects |
| `namespace:vergabe-demo-company` | vergabe-demo-company | 4 observed objects |
| `management:ops-hub` | ops-hub | service.ops-hub.http, framework /api/v2, ops-console, ops-bootstrap |
| `management:financial-fabric` | fin-hub / railiance-fabric | financial graph owner API and projection/export |
| `management:repo-manager` | repo-manager | registry/work projections, governed CLI/Git mutations, Forgejo-backed publisher |
| `management:kubernetes` | rail-kubernetes / railiance-platform | realm:kubernetes/railiance01; API, RBAC, nodes, workload lifecycle |
| `management:ssh-tunnels` | ops-warden / ops-bridge | railiance01 SSH certificate/principal and named tunnels |
| `management:gitops-deploy` | railiance-platform / railiance-enablement | ArgoCD Core CLI, repo authorization, per-workload release/rollback |
| `management:secrets-engine` | secrets-engine / railiance-platform | credential issue/rotate/revoke and approval-bound OpenBao operations |
| `management:host-jobs` | railiance-platform / activity-core | host systemd timers, cron, backup/restore and DR execution |
| `management:external-control` | railiance-platform / net-kingdom | DNS, registrar, hosting, object storage and off-cluster recovery administration |
## Remaining T01 decisions
- NetKingdom/User Engine: verify root `(iss, sub)` and the entitlement mapping;
confirm registered audiences, MFA journey and measurable revocation bounds.
- flex-auth/Tenant Engine: ratify action/resource names, authoritative fact
checks, cross-tenant root administration and decision/audit obligations.
- Hub/extension owners: map effective embedded mounts, legacy MCP destinations,
active extension discovery and public/health exceptions; resolve duplicate docs.
- Railiance owners: confirm namespace ownership, enumerate per-service audiences
and endpoint catalogs, CRD/Job/host/provider management paths, and the native
SSH/Kubernetes/GitOps grants. Unknown surfaces cannot be marked passed.
- All reviewers: approve the versioned profile and supply executable enforcement
fixtures/receipts. Until then T01 remains in progress and public exposure stays
gated. No new workplan or live configuration change was made by this inventory.
Related evidence: [access blueprint](netkingdom-access-blueprint.md),
[HUB-WP-0012](../workplans/HUB-WP-0012-netkingdom-platform-root-access.md),
`ops-hub/registry/hub-extension/v0.1.0/ops-hub.extension.json`, retirement project
`inventory/routes.yaml` and `inventory/jobs-callers-ops.yaml`.