Coverage Tracker¶
Known documentation gaps and open implementation issues. Update this file when a gap is closed or a new one is identified.
Relationship with roadmap.md: The roadmap sorts work by horizon (near term versus longer directions) and records out-of-scope decisions. This file assigns a discrete status and implementation or documentation notes for each tracked gap. The same topic often appears in both; the roadmap states priority, this file owns current state.
Status values: Missing: does not exist · Stub: exists but incomplete · Known Issue: confirmed bug or limitation · Planned: acknowledged, work not yet started
Documentation¶
| Area | Status | Notes |
|---|---|---|
| Observability operations guide | Missing | Phase 7 deploys Prometheus, Loki, and Grafana. No user-facing guide exists for accessing dashboards, writing alert rules, or querying logs. Implementation notes are in ansible/phases/07-observability/README.md. |
| 5G NF architecture | Stub | ansible/phases/05-5g-core/NF_ARCHITECTURE.md documents Open5GS NF interactions, 3GPP interface references, and message flows in detail but is not linked from the documentation navigation. |
| MEC application development | Missing | No guide covers writing or deploying an application that consumes N6 user-plane traffic on the edge node. |
| Upgrade and migration | Missing | No procedure for upgrading K3s, KubeEdge, or Open5GS in a running testbed. |
| Multi-UE scenarios | Missing | No walkthrough for concurrent UE registration, PDU session management, or QoS differentiation experiments. |
Implementation¶
| Area | Status | Notes |
|---|---|---|
| UPF-Edge CNI route conflict | Known Issue | UPF-Edge pod gets stuck in ContainerCreating due to a CNI route conflict on the edge node. Currently mitigated by setting replicas: 0. Root cause documented in known-issues/upf-edge-cni-route-conflict.md. |
| UERANSIM automated integration | Planned | Simulated-RAN automation on the edge is not actively maintained; integration work is paused. Physical gNB paths are the primary supported RAN mode until this resumes. Listed under Near Term in roadmap.md. |
| CI pipeline | Missing | No automated validation of the deployment. Tests run locally only via make targets in tests/. |
| Physical RAN hot-swap | Planned | Switching between physical and simulated RAN while the core is running is partially supported via the dashboard but not validated end-to-end. |
| CAMARA/positioning phase wiring | Stub | Reworked against the refactored 5g-northbound platform and consolidated into one phase 10-northbound (roles camara_gateway, positioning_engine, placement_editor, frontdoor_gate, positioning_demo); old phases 10/11/12 removed. testbed northbound on enables the feature; phase 08 gates the camara/positioning/placement realm objects behind the flag. Opt-in by deliberate decision. Live-validated on v0.8.0: all pods Ready, the engine fuses from the mock adapter, the gateway serves /capabilities and /assets (seeded), and a CAMARA location-retrieval by assetId returns HTTP 200 with the private-profile extensions (source/kind/altitude). Remaining: interactive browser login for the demo and editor (the editor blueprint round-trip), and external SPA exposure (subdomains) below. |
| placement-editor Keycloak gate (oauth2-proxy) | Stub | The placement_editor role always fronts the no-auth placement-editor with the generic frontdoor_gate (oauth2-proxy, NodePort 31950), admitting g-positioning-editors or g-dashboard-admins. The earlier issuer mismatch is fixed with a dual-URL split (browser to the canonical KC_HOSTNAME issuer, server-side token/JWKS to in-cluster Keycloak) and the placement-editor-proxy client is created idempotently in phase 08. Verified live: oauth2-proxy Running, unauthenticated GET returns 302 to the canonical Keycloak login with PKCE. Remaining: the interactive login-to-editor round trip, and external exposure as a subdomain. |
| Single-origin edge (collapse all surfaces under one hostname) | Planned | Model decided (see docs/security/external-access.md, Routes versus subdomains): path-based for the dashboard, its API, /auth, and the CAMARA API (placement-agnostic); each independent SPA (demo, placement-editor) keeps its own origin (a subdomain at root) because a built SPA's absolute asset paths break under a sub-path without a build-time Vite base. The preset helper and the dashboard should derive both tunnel routes and reachability from a single base domain (not the removed hardcoded convention). Not yet wired. |
| Gateway client secret managed inline, not via the Secret | Stub | camara-gateway consumes CAMARA_CLIENT_SECRET as an inline deployment env (operator-set by ansible from .testbed.secrets). The converged manifests add an optional <svc>-secrets Secret via envFrom, but this value still lives inline (inline env overrides envFrom). Moving it into camara-gateway-secrets (written by ansible) would make the single config mechanism uniform. Functional today; a cleanup. |
| Catalog deploy-from-image does not route sensitive vars to a Secret | Stub | The guided-setup apply (PUT /api/v1/northbound/config/{service}) routes each var by the contract sensitive flag (Secret vs ConfigMap). The on-demand catalog deploy path (POST /api/v1/northbound/deploy, e.g. rest-adapter with WITTRA_API_KEY) still passes env inline; the same sensitive-to-Secret routing should be applied there. |
| Service access control (scoped grants for dynamic services) | Stub | Infra plane (dashboard-admin/viewer) separated from a service plane of per-service action labels: camara-location-read (positioning VIEW) and positioning-edit (EDIT, gating placement-editor via oauth2-proxy alongside g-dashboard-admins), granted via groups (g-camara-users, g-positioning-editors). Scaffolded in the realm template (gated by the northbound flag); takes effect on the next realm import (Keycloak imports once). Remaining: tenant isolation (org as group/claim) and the longer-term per-service resource-server-client + authz-contract model. See docs/security/iam.md. |
| Realm reconcile cannot create new clients | Known Issue | Keycloak imports the realm JSON only on first boot. Enabling northbound on an already-provisioned cluster does not auto-create the camara-gateway/positioning-demo clients; re-import the realm or add them via the admin console. The placement-editor-proxy client is the exception: phase 08 creates it idempotently with a create-if-missing task. A general create-if-missing path for the remaining clients is not yet implemented. See docs/security/iam.md. |
| Blueprint distribution (engine-authority) interactive round-trip not yet validated | Stub | The blueprint is network-distributed with the engine as sole authority: it owns the positioning-blueprint PVC (RWO, engine-only mounter, no shared mount) and serves GET/PUT /blueprint; the editor PUTs (POSITIONING_ENGINE_URL), the demo GETs through the gateway, a cold-start seed ConfigMap covers an empty store. This removes the earlier shared-PVC co-location constraint and the manual edit-propagation step. Wired and deployed in phase 10 on 5g-northbound v0.8.0; the engine is the live blueprint authority (serves positions and GET/PUT /blueprint) and the cold-start seed applies. Not yet exercised: the interactive editor round-trip (placement-editor browser login, PUT authored blueprint, engine, demo GET via gateway). The seed must conform to the upstream schema/layout.schema.json (v2); the engine returns 422 on a violating PUT /blueprint. |
Catalog wifi-positioning deploy has no persistent bindings PVC |
Stub | The on-demand catalog deploy (POST /api/v1/northbound/deploy) now injects the self-registration env (POSITIONING_ENGINE_URL/ADAPTER_NAME/ADAPTER_BASE_URL) so a deployed adapter self-registers (v0.6.0), but still creates only a Deployment + Service. wifi-positioning writes its wifi-config.json bindings (BSSID + calibration) at runtime and needs its own RWO PVC for that to survive a restart; the deploy path does not create one. Relevant only when wifi-positioning is deployed (opt-in). |
Image tags in role defaults, not all.yml |
Known Issue | AGENTS.md says image names/versions belong in all.yml, but every phase pins them in its role defaults/main.yml (09 dashboard_frontend_image/kelt_docs_image, 06 ueransim_image/mec_image, 10-northbound camara_gateway_image and the other northbound tags + oauth2_proxy_image). The new northbound roles match this established pattern, so it is a codebase-wide charter reconciliation (centralize in all.yml vs accept image-in-defaults), not a regression. |
| Asset onboarding UI not built (dashboard) | Stub | The v0.8.0 gateway is the Asset Identity Map authority (GET/PUT /assets, PVC-backed) and a demo asset is seeded; assets are authored today via the gateway API. The KELT dashboard asset editor (CRUD over /assets, validated against the upstream schema/asset.schema.json) and the backend /assets proxy are not yet built. Additive: the stack and demo work without it. See architecture/positioning-adapters.md. |
| Per-consumer CAMARA clients with org claim not minted | Stub | The gateway joins the token org claim against the asset org (v0.8.0, 2-legged enterprise auth); a token without an org claim sees all assets (deliberate operator bypass). KELT still ships only the single shared camara-gateway client (org-less). Per-consumer confidential clients each carrying an org claim (phase 08 realm + idempotent create-if-missing) are not yet wired, so multi-tenant isolation is not exercised. Additive: demo and operator work org-less. See security/iam.md. |
| VXLAN VNIs hardcoded in overlay script | Known Issue | ansible/phases/04-overlay-network/scripts/ovs-setup.sh hardcodes VXLAN VNIs as literals (N1=101, N2=102, N3=103, N4=104, N6e=106, N6c=107, N6m=108) instead of referencing all.yml, against the Networking convention in docs/development/contributing.md. Only n6m_vni exists in all.yml and the script does not even use it. Move all VNIs into all.yml and template or parameterize the script. This missing single source is why handbook VNI values had drifted. |
| Dashboard backend can write the whole repo (ansible-ro is not a real boundary) | Known Issue | The backend runs as vagrant with /vagrant mounted read-write, so the process can write any repo file, including the playbooks that later run under sudo. The read-only ~/ansible-ro mount does not prevent this: it exposes the same host directory, so a write through /vagrant/ansible/... changes what ansible-ro serves. No current exposure: the backend writes exactly two files, with a hardcoded path (.testbed.env in ran_service), and no endpoint builds a path from request input. It is a capability, not a live bug. ansible-ro itself is deliberate and must not be removed casually: it was introduced to work around k3s token and cluster-validation failures during playbook runs, and it fixed them. Narrowing the mount needs its own verification pass on a cluster that can be redeployed; planned alongside the UERANSIM work for v1.0. The writable surface has since been reduced: the version-override file was removed, and the remaining writes are moving behind a single audited allowlist. |