# Netdata Link: source verification, runtime pending Source status, 13 October 2026 (before this docs update): `7e2e7480d1977a1ead494ab7010dd8ba8dd6a46e`. The descriptor is normalized to the Stats SDK and registered in `internal/apps/homarr/targets.go`. This establishes source wiring only; native/rendered data, both installation orders and lifecycle acceptance remain unproved. Earlier dated evidence retains its original scope. Issue: [#287](https://github.com/ajnart/selfhost-skills/issues/287). Reference: [#262](https://github.com/ajnart/selfhost-skills/issues/262) and [the shared Link contract](homarr-integration-contract.md). ## Exact upstream contract Read-only registry inspection on 2026-10-11 confirmed that `ghcr.io/homarr-labs/homarr:v2.4.1` exists, with index digest `sha256:ee67a5e856c051c4e114418a54b89a3fc3cb5507d0689e5cb89c790305c549cd`. Its Linux arm64 manifest is `sha256:308feba8b9845cbdb21eb2e1b05579d49fb815bf3f0a452e58b59fcd4db8ecd2`. The image's OCI revision label is `3d4150e59f600876b7e308f857b2f21572b75348`; its OCI version label is `main`. The actual image revision was checked as well as the reference's release source `ebbd4876d25a51151444a009ab596e1154d62880`: the Netdata credential shape, Stats provider, refresh response and widget compatibility agree. Registry metadata is not a running-version or functional acceptance claim. The common Link must still verify authenticated `info.getInfo` is `2.4.1`. - Kind `netdata`, internal Address `http://netdata:19999`, port `19999`. - The only credential alternative is `[]`; the adapter sends no token. The shared transport serializes an explicit empty array, not `null`. Existing bearer protection or denied access is not disabled or bypassed. - Native widget `stats`, metrics `warnings` and `criticals`, both counts. The provider reads `alarms.warning` and `alarms.critical` from `/api/v1/info`; both must be nonnegative integers, including explicit zero. Missing fields and refresh failures are not an empty alarm dataset. - Netdata is not a supported System Resources or Health Monitoring kind. No dedicated Netdata widget or machine/chart selection is invented. - `widget.stats.refresh` accepts `{integrationId, force: true}` and returns `{values, updatedAt, retryAt, error, stale}`. The verifier requires both false flags, a timestamp from this refresh and both explicit valid counts. This avoids accepting Homarr's ordinary one-hour cached snapshot as fresh. Sources at the registry image's declared revision: - [Integration definition](https://github.com/homarr-labs/homarr/blob/3d4150e59f600876b7e308f857b2f21572b75348/packages/definitions/src/integration.ts) - [Netdata Stats provider](https://github.com/homarr-labs/homarr/blob/3d4150e59f600876b7e308f857b2f21572b75348/packages/integrations/src/stats/providers/netdata.ts) - [Stats router](https://github.com/homarr-labs/homarr/blob/3d4150e59f600876b7e308f857b2f21572b75348/packages/api/src/router/widgets/stats.ts) - [Stats refresh/cache](https://github.com/homarr-labs/homarr/blob/3d4150e59f600876b7e308f857b2f21572b75348/packages/request-handler/src/stats.ts) - [Widget compatibility](https://github.com/homarr-labs/homarr/blob/3d4150e59f600876b7e308f857b2f21572b75348/packages/definitions/src/widget-integration-map.ts) ## Netdata readiness and authority The compiled App remains `netdata/netdata:v2.11.0`, with unchanged Compose. Setup and Check fetch fresh JSON every time, verify explicit local alarm counts, discover the agent CPU chart from `/api/v1/charts`, and query its returned identifier through `/api/v1/data`. Selection uses the declared `netdata.server_cpu` context, `netdata` plugin, `pulse` module and `milliseconds/s` units. A missing or ambiguous identifier stops the probe. Returned identifiers and private machine metadata are not logged or persisted. The JSON sample must contain exactly one `time`, `user` and `system` column, with `time` first and either order for the two native CPU dimensions. Rows must align with all three columns and contain actual non-null nonnegative values, with a sample no older than two minutes; clock skew beyond thirty seconds into the future is rejected. Zero CPU usage is valid. Empty or stale samples do not pass readiness. Access denial is an actionable Manual step; HTML, redirects and unsupported response shapes fail, not a no-auth fallback. The upstream pulse collector reads `getrusage(RUSAGE_SELF)`: this measures Netdata's own process, not total host CPU. Other container-visible metrics may describe the shared Linux kernel or Docker virtual machine. This work adds no host mounts, host PID/network namespace, privileges, capabilities, Docker socket, Cloud enrollment or public Access. Netdata v2.11.0 sources: - [Alarm summary](https://github.com/netdata/netdata/blob/v2.11.0/src/web/api/v1/api_v1_info.c) - [Agent CPU collector](https://github.com/netdata/netdata/blob/v2.11.0/src/daemon/pulse/pulse-daemon.c) - [Chart metadata](https://github.com/netdata/netdata/blob/v2.11.0/src/web/api/formatters/rrdset2json.c) - [Default chart context](https://github.com/netdata/netdata/blob/v2.11.0/src/database/rrdset-index-id.c) - [Chart data API](https://github.com/netdata/netdata/blob/v2.11.0/src/web/api/v1/api_v1_data.c) - [Timestamped JSON samples](https://github.com/netdata/netdata/blob/v2.11.0/src/web/api/formatters/json/json.c) ## Acceptance gaps `target_netdata.go` owns the descriptor; the reference owner has registered `netdataTarget()` in `targets.go`. Common ownership, reconciliation, removal, shared Stats bindings and peer scheduling are reused rather than independently reimplemented. The latest committed reference supplies a read-only preflight seam. Netdata's descriptor uses it to check readiness and denied access before any Homarr resource mutation, with a specific recovery message for Manual prerequisites. Removal does not depend on metric availability or successful preflight. No Docker, browser, installer or user Project was used in this lane. The parent runtime phase must verify exact running versions/digests, meaningful rendered Stats results, both installation orders, late peers, unready/denied retries, reruns/restarts, removal/reinstallation, and retained user-authored resources in an approved disposable Project. Source verification and existing focused tests do not constitute that live acceptance proof. ## Local verification - Existing focused tests: `go test ./internal/apps/netdata/ ./internal/apps/homarr/` passed, with `GOFLAGS=-buildvcs=false`. - `gofmt -l .` was empty; `git diff --check`, `go build ./...`, `go vet ./...`, `go vet -tags e2e ./e2e/`, and `bash -n install.sh` passed. - The complete `go test ./...` gate passes after the authorized fixture correction, with `GOFLAGS=-buildvcs=false`. - `go test -race ./internal/tui/ ./internal/activity/ ./internal/catalog/ ./internal/apps/netdata/ ./internal/apps/homarr/` passed, with `GOFLAGS=-buildvcs=false`. - Before the authorized fixture correction, `go test ./internal/catalog/ -run '^TestGeneratedAppsOnboard/netdata$' -count=1` failed on the empty-200 fixture. It passes with the corrected fixture; that fixture correction did not change production readiness. The parent authorized a precise central test exception in the existing `internal/catalog/generated_test.go`, restricted to Netdata's routes: - `GET /api/v1/info` returns version `v2.11.0` and explicit integer alarm counts `{normal: 0, warning: 0, critical: 0}`. Zero is a valid alarm dataset. - `GET /api/v1/charts` returns the native `netdata.server_cpu` chart with its actual identifier, matching context, `netdata` plugin, `pulse` module, `milliseconds/s` units and `user`/`system` dimensions. - `GET /api/v1/data` requires `chart=netdata.server_cpu`, `after=-60`, `points=1` and `format=json`. Its literal `time`/`user`/`system` labels pair with one `[timestamp, 1, 0]` sample: timestamp is Unix seconds from the existing `deps.Now` clock seam; user/system values are milliseconds/s. Wrong query values return 400, unknown Netdata routes 404 and methods other than GET 405. There is no Netdata empty-200 fallback. Other App fixture behavior is unchanged; no test functions, test files, skips or production seam changes were added. Independent Dashdot work was not imported from dirty files. These synthetic responses validate the existing Setup/Check contract only, not native Homarr/widget or runtime acceptance. The no-host-CPU, unchanged authority and unsupported System Resources caveats remain in force. ## Source-review dimension correction At source head `fb792342c9985274bbbe347d32c435a41a49e094`, on fixed reference base `dce263ef822dc056558a648f8f59ea795a3e56d9`, a fresh numeric sample could pass with unrelated or missing CPU dimensions. The pinned pulse collector defines both `user` and `system`; the readiness filter now requires exactly those dimensions plus the unique first `time` column. Existing per-row alignment, non-null numeric and freshness checks are retained. Zero is still valid, but missing dimensions are never substituted with zero. Direct controls are inside the existing `TestGeneratedAppsOnboard/netdata` body, keeping native info/chart routes and strict data-query validation: - Unrelated dimension, missing user/system, duplicate user/system/time, misplaced time, extra dimension and misaligned columns are rejected by the App's real Check path. - Native all-zero CPU and reversed system/user column order are accepted. The original nonzero-user/zero-system Setup and Check control remains. - The fixture response format is atomically replaced so the HTTP handler and Check controls remain race-safe; timestamp still uses `deps.Now`. Before the production correction, the focused existing command failed with `Netdata Check accepted unrelated dimension`; after correction it passes. After this source correction, the focused Netdata/Homarr tests and complete local gate listed above all pass, including the Catalog/TUI/Activity/App race checks. Build, both vet commands, formatting/diff and installer syntax pass. No test functions, files, comments, external dependencies, shared production seams or registry changes were introduced. These are synthetic Check controls, not real native/rendered acceptance. At that correction, fresh parent Standards/Spec reviews, custodian normalization of the shared freshness guard, registry assembly, real native/rendered data, both installation orders and shared ownership lifecycle remained held. The source-status note above records subsequent SDK normalization and registration, without new runtime proof.