How to read the labels
Evidence tiers used below, weakest to strongest:
- Unit:
*_test.goagainst fakes orhttptestservers. - Live Docker: tests named
*_Live_*or*_live_test.gothat skip when no Docker daemon is reachable and run against a real local daemon (for exampleinternal/pipeline/live_test.go,internal/backup/pitr_live_test.go).nightly.ymlhas adockerlane, buttest/e2eitself is only named in the flake sweep (.github/workflows/nightly.yml:111). - E2E:
test/e2e/*_test.go, which drive the real HTTP API and a real reconciler against real containers on one machine. - Real infrastructure: a fresh VPS, a real public domain, real vendor endpoints. Almost no feature has this evidence in the repository. Multi-node enrollment is the one documented exception so far, verified locally across two real Docker daemons (see its own section below), not against a real VPS or a real WAN. Real public ACME now has one recorded run against a live public VPS (
docs/acme-verification-runbook.md, 2026-10-05); the e2e suite itself still “does not yet exercise a full multi-node mesh or real ACME against a live domain”.
Summary
Evidence per area
Test counts are*_test.go files in the named directory. “CLI” and “web” list test files found in cmd/levelrail-cli and web/src.
AI assistant (MCP server and in-app chat)
- Unit:
internal/ai/(5 files:anthropic_test.go,classify_test.go,engine_test.go,eval_injection_test.go,toolcaller_test.go);internal/mcptools/(31 files, for examplemodes_test.go,tools_apps_clone_images_test.go); APIinternal/api/ai_chat_test.go,internal/api/ai_settings_test.go; CLIcmd/levelrail-cli/settings_ai_assistant_test.go; webweb/src/components/AiChatMessageList.test.tsx,AiToolCallCard.test.tsx,web/src/queries/aiAssistant.test.ts,web/src/components/AiChatHistoryMenu.test.tsx. - E2E:
test/e2e/ai_chat_test.godrives create/send-message/get/list/delete over real HTTP against a real*api.Routerandai.Engine, with a fakeai.Providerandai.ToolExecutor(no live Anthropic call). MCP server itself: none. - Docs:
docs/ai-assistant.mdcoverslevelrail-mcp;docs/ai-assistant-chat.mdcovers the in-app chat. - Real infra: none found.
- Label: MCP server beta (the tool registry is well tested, but the surface is large and unexercised end to end). In-app chat hide-behind-flag (depends on an external model provider, no evidence beyond fakes).
AI models (GPU inference)
- Unit:
internal/models/(13 files, for examplegpunodes_test.go,engines_test.go,gateway_test.go,prober_test.go); APIinternal/api/models_test.go,models_hf_test.go,models_keys_test.go; CLImodels_test.go,models_keys_test.go,models_preflight_test.go; webModelRow.test.tsx,ModelCacheCard.test.tsx,ModelKeysPanel.test.tsx,ModelPreflightPanel.test.tsx. - E2E: none. No live Docker test either.
- Docs:
docs/ai-models.md(264 lines). It states v1 supports NVIDIA GPUs on Linux only. - Real infra: none found. No test touches a real GPU.
- Label: hide-behind-flag. Correctness depends on driver, container toolkit and VRAM behavior that no test in the repo observes.
Load balancer
- Unit:
internal/loadbalancer/(4 files:check_test.go,config_test.go,history_test.go,status_test.go); APIloadbalancer_test.go,loadbalancer_history_test.go,loadbalancer_list_test.go; CLIlb_test.go,lb_history_test.go,lb_list_test.go; webLoadBalancerOverview.test.tsx,web/src/lib/loadBalancer.test.ts; MCPtools_loadbalancer_test.goand two more. - E2E:
test/e2e/loadbalancer_test.go(TestLoadBalancer_Live_RealTrafficAndDrain, plus a gate-off test that expects 404). Live Docker: none beyond that. - Docs:
docs/load-balancing.md(162 lines). - Real infra: none found.
- Label: hide-behind-flag. Multi-replica routing is built on embedded Caddy and verified on one machine only.
Pipelines
- Unit:
internal/pipeline/(14 files, includingengine_test.go,definition_test.go,trigger_event_test.go,pathtrigger_test.go,sync_test.go); APIpipelines_test.go,pipelines_events_ci_test.go,pipelines_iam_test.go,pipelines_sync_test.go; CLIpipelines_test.go,pipelines_all_test.go,pipelines_sync_test.go; web has sixPipeline*.test.tsxfiles. - Live Docker:
internal/pipeline/live_test.goruns a two-job pipeline with artifact handoff and a failing step, then checks nothing leaks. - E2E:
test/e2e/pipeline_run_test.go(TestPipelineRun_Live). - Docs:
docs/pipelines.md(369 lines). - Real infra: none found.
- Label: stable.
Notification channels (all 18)
Kinds, frominternal/alerting/rules.go:87-104: generic, slack, discord, telegram, email, pushover, pagerduty, teams, resend, ntfy, gotify, mattermost, lark, rocketchat, opsgenie, webex, googlechat, webpush. That is 18, matching the README and comparison count. webpush (browser push, internal/webpush/) is the newest and the only kind whose destination isn’t an operator-supplied URL: it fans out to every registered browser subscription instead.
- Unit:
internal/alerting/(28 files). Payload tests live innotify_test.go(TestNotifyTelegram_PostsChatIDAndText,TestNotifyResend_PostsAuthHeaderAndPayload,TestNotifyOpsgenie_PostsAuthHeaderAndPayload) andTestNewNotifier_AllValidKinds_Recognized(notify_test.go:1095). That table test covers a subset of the kinds, so the rest rely on their own payload tests, and coverage is thinnest for pushover, pagerduty and teams. - API
notification_channels_test.go; CLI: no dedicated channel test file found; email retry tests atnotify_test.go:569-629. - E2E: none. Every test posts to an
httptestserver. - Docs: covered in
docs/integrations.mdanddocs/observability.md.docs/integrations.mdis 45 lines. - Real infra: none found. No test sends to a real Slack, PagerDuty, SMTP or other vendor.
- Label: beta. Run a manual send test per vendor before calling any of them stable.
Multi-node and WireGuard mesh
- Unit:
internal/network/(13 files),internal/agent/(about 20 files includinggrpc_transport_test.go,pki_test.go,renew_test.go,mesh_dispatch_test.go),cmd/levelrail/mesh_test.go(skips without Docker); CLInodes_*_test.go(about 14 files); reconcileinternal/reconcile/mesh/controller_test.go. - Live Docker:
internal/agent/live_test.go,internal/agent/build_live_test.go,internal/reconcile/application/placement_live_test.go. - E2E:
test/e2e/node_placement_test.go. Its own header says one Docker daemon cannot exercise the NodeID-to-remote-agent resolution and that it only proves each controller uses the runtime it was built with. - Docs:
docs/multi-node.md(542 lines). - Real infra: the join flow was verified against two real agent processes, each with its own real Docker daemon (separate
docker:27-dindcontainers), running against a real control plane binary. Enrollment, cordon, drain with actual container relocation between the two daemons, and explicit node-id placement pinning all behaved as documented; this also surfaced a real gap, now noted indocs/multi-node.md, where a control plane started withoutAPP_AGENT_ADVERTISE_HOSTset lets enrollment succeed but leaves the node stuck atpendingon a TLS hostname mismatch. This was not run across a real WAN or a second physical host, and the WireGuard mesh itself is unchanged:internal/network/device_test.go:3-11still runs against fakes because real encryption “needs two real hosts and root”, and the mesh’s remote arm (internal/network.ConfigSink) does not span nodes yet. - Label: beta. Single node is the stable promise. Multi-node enrollment now has a documented real verification behind it, but the mesh and cross-host remote transport are still unverified, so the area stays beta.
Platform as code (iac)
- Unit:
internal/iac/(4 files:fake_test.go,filter_test.go,iac_test.go,schema_file_test.go) against 17 source files; APIiac_test.go,platform_import_test.go; CLIapply_test.go,apply_vars_test.go,import_platform_test.go; MCPtools_iac_test.go; webIacPlanView.test.tsx,PlatformImportCard.test.tsx. - E2E:
test/e2e/iac_apply_test.go(TestIaCApply_Live_ExportPlanApplyRoundTrip, plus a gate-off test that expects 404). Live Docker: none beyond that. - Docs:
docs/platform-as-code.md(419 lines),docs/app-spec-reference.md,docs/schemas/. - Real infra: none found.
- Label: hide-behind-flag. The apply path can change many resources in one run, so it stays opt-in until it has more real-world runs.
Log archive
- Unit:
internal/objectstore/archive_test.go,internal/alerting/log_archive_stale_test.go,internal/mcptools/tools_log_archive_test.go,internal/api/storage_destinations_test.go, CLIstorage_test.go. - E2E:
test/e2e/log_archive_test.go(TestLogArchive_Live_ContainerLogsToHTTPDownload): a real container’s real stdout through a realtelemetry.LogCollector, a real*api.Router(real admin login, real storage destination created over HTTP), a real manual dump trigger (POST /api/v1/log-archive/dump), polled to completion, then listed and downloaded over real HTTP. The bucket itself isobjectstoretest’s fake S3 server, the same substitution the unit test makes. - Docs: dedicated page
docs/log-archive.md, linked fromdocs/object-storage.mdanddocs/observability.md, plus route rows indocs/api-reference.md. - Real infra: none found for the bucket leg.
internal/backup/uploader_live_test.go(real S3 round trip) is env-gated byLEVELRAIL_LIVE_S3_*and its own comment says none of those are set in CI, so it skips there. - Label: beta.
PITR and database backups
- Unit:
internal/backup/(34 files, includingpitr_runner_test.go,pitr_restore_test.go,verify_runner_test.go,scheduler_test.go);internal/cpbackup/(9 files) for control-plane backups; CLIbackups_*_test.go,control_plane_backups_test.go,app_volume_backups_*_test.go. - Live Docker:
pitr_live_test.go,dump_live_test.go,restore_live_test.go,clone_restore_live_test.go,volume_live_test.go,volume_clone_restore_live_test.go. - E2E:
test/e2e/pitr_test.go(real API, real reconciler, MinIO bucket, marker-row restore),test/e2e/reconcile/database_test.go(Redis reconcile only,TestDatabase_Live_RedisReconcile). - Docs:
docs/backups-and-storage.md,docs/managing-databases.md,docs/control-plane-backup.md,docs/disaster-recovery.md.docs/roadmap.mdnotes PITR is “Live-Docker-verified end to end”. - Real infra: none found. The real S3 and R2 test is skipped in CI (see log archive).
- Label: stable for PITR and dump/restore/verify on Postgres. Other engines (eight are defined in
internal/store/database.go:16-23) only have the Redis e2e, so treat them as beta until each has a live restore run.
Cloudflare tunnel
- Unit:
internal/reconcile/cloudflaretunnel/controller_test.goandcontroller_half_success_test.go; APIinternal/api/cloudflare_tunnel_test.go; CLIcloudflare_tunnel_test.go; MCPtools_cloudflare.gocovered bytools_platform_visibility_test.go. - E2E: none. Live Docker: none.
- Docs: only in
docs/api-reference.md,docs/cli-reference.md,docs/feature-catalog.md. No dedicated page. - Real infra: none found. Needs a real Cloudflare account and token to prove anything.
- Label: hide-behind-flag.
Deploy approvals
- Unit:
internal/store/deploy_approval_test.go,internal/api/deploy_approvals_test.go,deploy_approval_safety_test.go,deploys_test.go; CLIapps_deploys_control_test.go. - E2E:
test/e2e/protected_environment_test.go(TestProtectedEnvironment_Live_DeployBlockedThenAllowed): two cookie sessions, same-actor approval rejected, container untouched until a different user approves. - Docs:
docs/deploy-safety.md(188 lines). - Real infra: none found.
- Label: stable.
Deploy freeze
- Unit:
internal/deploy/freeze_test.go,internal/store/deploy_safety_test.go,internal/api/deploy_safety_test.go,deploy_queue_test.go,internal/changes/changes_test.go; CLIapps_freeze_test.go. - E2E:
test/e2e/deploy_freeze_test.go(TestDeployFreeze_Live_BlocksThenAllows). - Docs:
docs/deploy-safety.md. - Real infra: none found.
- Label: stable.
Previews
- Unit:
internal/preview/(13 files, for examplemanager_test.go,retention_test.go,sqlstore_test.go);internal/webhook/pull_request_test.go; APIpreview_test.go,preview_comment_test.go; CLIapps_previews_test.go,apps_previews_policy_test.go,preview_mode_test.go; webPreviewPolicyCard.test.tsx,PreviewSettingsCard.test.tsx,PreviewEnvironmentsCard.test.tsx. - E2E:
test/e2e/preview_environments_github_test.goandpreview_environments_gitlab_bitbucket_test.go(open, synchronize, close lifecycles through real webhook handlers). - Docs:
docs/deploy-previews.md(169 lines). - Real infra: none found. Payloads are synthetic. Recent hardening (
13a50c33, caps, fork approval, single comment) landed after these tests were written. - Label: stable for GitHub, beta for GitLab and Bitbucket.
Feature flags
- Unit:
internal/store/feature_flag_test.go,internal/api/feature_flags_test.go, CLIflags_test.goandflagutil_test.go, MCPtools_new_features_test.go. - E2E: none. The
flaghits intest/e2e/metrics_test.goandlive_api_helpers.goare unrelated. - Docs:
docs/feature-flags.md(109 lines). This is an app-level runtime flag system. It is not a platform-level switch for hiding unfinished features. A platform-level hide mechanism does not exist yet. - Real infra: none found.
- Label: beta.
Templates
- Unit:
internal/catalog/catalog_test.go(asserts at least 180 templates, unique IDs) andcatalog_extra_test.go; APIservice_templates_test.go; CLItemplates_test.go; webBrowseTemplatesFields.test.tsx;internal/registrycatalog/client_test.go. - E2E:
test/e2e/template_fleet_test.go(TestTemplateFleet_Live_DeploysAndTearsDownCleanly) deploys a diverse sample of 16 templates through the real one-click route and a real application controller, then tears them down and checks nothing leaks. Batch boot tests (catalog_batch*_live_test.go,catalog_devtools_batch_live_test.go) cover more, but not the whole catalog.test/e2e/compose_healthcheck_test.gocovers Compose readiness generally. - Docs:
docs/templates-and-registry.md(209 lines). - Real infra: none found. Only the 16 sampled templates have deploy evidence, so “works” is unverified for the rest.
docs/templates-and-registry.mdalso notes GPU passthrough is not translated for GPU templates. - Count: 311 entries in
internal/catalog.Templates. ADR 015 cites a 339-template goal, which is not yet the shipped catalog. - Label: beta.
IAM
- Unit:
internal/store/iam_policy_test.go,internal/api/iam_handlers_test.go,iam_test.go,authz_matrix_test.go,require_ability_for_resource_test.go,app_routes_iam_test.go,pipelines_iam_test.go; CLIiam_policies_test.go. - E2E:
test/e2e/auth_lifecycle_test.go(TestAuthLifecycle_Live) covers sessions.test/e2e/iam_policy_enforcement_test.gocovers a session deny policy blocking a real action and a token allow policy scoping one. - Docs:
docs/identity-and-access.md(529 lines),docs/security.md,docs/threat-model.md. - Real infra: none found.
- Label: stable.
Supply chain
- Unit:
internal/supplychain/(gate_fix_test.go,parse_test.go,service_test.go); APIsupplychain_test.go; CLIapps_supply_chain_test.go; webSupplyChainSection.test.tsx,SupplyChainSettingsCard.test.tsx. - E2E:
test/e2e/supply_chain_test.go(TestSupplyChain_Live_GateBlocksAndOverrideThroughRealAPI). Live Docker: none beyond that. - Docs:
docs/supply-chain.md(94 lines). SBOM and scan are off by default. - Real infra: none found.
- Label: stable, and off by default.
Status page
- Unit:
internal/statuspage/statuspage_test.go; APIstatus_page_test.go. - E2E:
test/e2e/status_page_test.go(TestStatusPage_Live_EnableAuthorAndServePublicly). - Docs:
docs/status-page.md(95 lines). Off until enabled. - Real infra: none found.
- Label: stable.
Numbers quoted across the docs
These counts appear in the README, the landing page, and several guides. Re-check them against the code before changing any of those pages.
Two caveats still hold. Idle footprint is measured only on an Apple M4 Max dev build (58 to 96 MB RSS from 0 to 500 apps, see Performance), with no Linux release-build number yet. Real public ACME issuance has one recorded live run (the verification runbook, 2026-10-05); renewal and DNS-01 wildcards are still unproven.