Ctrl K
ComunidadGuías…

docs/homarr-gatus-implementation.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Gatus Link implementation — #280

## Contract

Normalized by the retained common registry custodian against frozen main
`6b82c55fb890c11a1388bd4e5a2f10b632ff4f7c`, merged normally while preserving
leaf `c3aca1a6d3a8cff2d5d39ca96913960e9ce4b2c8` and its reviewed local-provenance
corrections. Only this peer's `gatusTarget()` registry call is added in this branch.
Frozen common reconciliation, compatibility, ownership and freshness remain unchanged.

Homarr's authenticated supported API is `2.4.1`, image tag
`ghcr.io/homarr-labs/homarr:v2.4.1`. The resolved image revision
`3d4150e59f600876b7e308f857b2f21572b75348` Gatus provider was checked for these
exact count semantics; tagged research baseline
`ebbd4876d25a51151444a009ab596e1154d62880` remains a separate identity.

`gatusTarget()` uses `http://gatus:8080` for Homarr's server connection;
the browser Address remains independently resolved. It explicitly returns
`[]secret{}`. Upstream declares `requiredSecrets: [[]]` and accepts an empty
`secrets` array in its create/update schema. There is no credential generation,
rotation or fallback from an authenticated connection. A protected status API
fails; existing authentication is not disabled.

The only native widget is shared Stats, with `up`, `down`, `unknown`, `total`.
These are endpoint counts, not uptime percentages: Homarr reads
`/api/v1/endpoints/statuses`, uses the last result's `success`, and counts empty
result arrays as unknown. Native Stats accepts both endpoint arrays and records;
the pinned Gatus v5.37.0 API returns an array. No dedicated Gatus widget or
selector identifier is invented.

## Readiness and verification

Gatus Setup retains `/health` readiness and additionally polls its status API
at `/api/v1/endpoints/local_gatus-self/statuses`, whose pinned handler reads only
the local store, for the starter endpoint. The existing `ConfigValue` helper
reads the Project's App configuration: that monitor must be uniquely configured,
enabled (including Gatus's enabled-by-default mode), and use GET at the exact
starter destination `http://127.0.0.1:8080/health`. A matching name or loopback
hostname alone is insufficient; other ports and paths are not adopted.
The key is derived from that verified configuration's group and name. Under
Gatus v5.37.0 key semantics, the permitted lowercase `local` and `gatus-self`
values need no character replacement, yielding `local_gatus-self`. The returned
key/name/group must corroborate that configuration. No identifier is guessed.
Aggregate `/api/v1/endpoints/statuses` appends remote-instance records without
provenance markers; a same-key remote success therefore cannot prove the owned
local check. Its absence (404 or no local results) stays an actionable wait.
Its recorded latest result must explicitly succeed, have HTTP status 200, and
report the starter loopback hostname `127.0.0.1`. Its timestamp must not be in
the future or older than the configured monitor interval, using `h.Now()`;
omitted/zero intervals use Gatus's one-minute default. Stale records poll during
Setup and otherwise return an actionable retry, including retained SQLite
results for disabled monitors. The single-key handler does not use the aggregate
API cache; no guessed freshness allowance is applied. Homarr's native Stats
still uses the aggregate endpoint and legitimately counts its remote records;
the local readiness proof does not change those upstream count semantics.
Checks probe afresh. The starter config
and image `ghcr.io/twin/gatus:v5.37.0` are unchanged: one local health check,
one-minute interval, SQLite history, no external monitor traffic.

The Link verifies Gatus directly. After the native check succeeds, the shared
Stats SDK reads the authenticated catalog and obtains one sample with its owned
integration ID. It reads `widget.stats.snapshot`, then forces `widget.stats.refresh`, requiring
a successful, non-stale snapshot with a timestamp strictly advanced from the
before-snapshot (or a positive timestamp when the before-snapshot was unfilled).
A forced refresh that returns without updating because of a distributed lock
or unavailable queue slot is an actionable wait, not acceptance of Homarr's
one-hour cache. The pure Gatus Stats callback requires all four catalog units to
be `count`, all four explicit nonnegative integer counts and
`up + down + unknown == total`. Zero down/unknown counts are valid. A valid
empty dataset is distinct from an API error, but cannot establish this Setup's
required local monitored result; it remains actionable, not tile-only success.
Snapshots are observations, not proof that unrelated monitored Apps work.
Each verification invocation uses one refresh; the Step's separate apply and
Check invocations can collect multiple samples. Native record clock limits stay
in the Gatus owner; Stats timestamps retain the SDK's finite, positive, advancing
requirements without an additional clock policy.

Existing Projects lacking or changing the local check receive a retry hint to
preserve their monitors and review the starter loopback check; Setup does not
create an unsolicited monitor, name-only adopt another target, or rewrite their
configuration or remove authentication. No new dependencies or secrets are used.

## Evidence and acceptance gaps

The normalized source-activated tree passed the full local gate again, including
TUI/Activity/Gatus/Homarr/Catalog race checks. This is source/fake verification,
not live peer acceptance; final normalized-head reviews remain parent-owned.

The repository local gate passed: gofmt, build, both vet commands, all existing
tests, race checks for TUI/Activity/Gatus/Homarr, and installer shell syntax.
Existing Gatus tests cover recorded local data and repeat Setup; the existing
failure test additionally rejects a protected API, HTML navigation page, empty
data, absent success field, failed result and nonlocal result. These are fake
transport fixtures, not live integration proof.

The source correction for the three review findings adds configuration and
interval validation plus snapshot timestamp advancement. Only the existing
Gatus fixture was aligned with its fake clock and Project config contract; no
new test cases/files were added. The three corrected boundaries still need
fresh independent source review and approved runtime evidence; compilation and
the existing fixture suite are not claimed as dedicated live regression proof.

The remaining owned-record provenance correction switches verification to the
local-store-only single-key route and aligns only the existing fixture route
and object response shape. It does not touch Homarr's descriptor or the
before/after forced-refresh advancement check. Fresh source review at the new
head remains required; no remote traffic or live proof was used.

The descriptor is source-activated through the custodian's single registry call.
The forward merge of SDK `ecc21d9f95664ef6245863ddfb05930bf4cde3a3`
preserves that registration. Gatus's `verify` retains native local-store and
configured-monitor provenance; its `stats` callback validates the same central
sample without another Stats request. Nil preflight leaves cleanup and scheduling
unchanged. The public Link fixture covers two verification invocations on first
apply, one on each rerun and none on removal; each has one catalog/snapshot/refresh.
Fresh parent-owned Standards/Spec reviews of the normalized final head and approved
disposable runtime acceptance remain open. Registration is not live native,
rendered, authentication, both-installation-order, ownership lifecycle or genuinely
cross-kind shared-binding acceptance. Those gates remain held.
No Docker, browser, installer, real Project or protected files were accessed.
No resolved image digests, real Homarr widget rendering or lifecycle proof is
claimed. The old Gatus navigation proof is not native integration proof.

## First-party sources

- [Homarr Gatus guide](https://homarr.dev/docs/integrations/gatus/)
- [Resolved-image Gatus Stats provider](https://github.com/homarr-labs/homarr/blob/3d4150e59f600876b7e308f857b2f21572b75348/packages/integrations/src/stats/providers/gatus.ts)
- [v2.4.1 Gatus Stats provider](https://github.com/homarr-labs/homarr/blob/ebbd4876d25a51151444a009ab596e1154d62880/packages/integrations/src/stats/providers/gatus.ts)
- [v2.4.1 integration definitions](https://github.com/homarr-labs/homarr/blob/ebbd4876d25a51151444a009ab596e1154d62880/packages/definitions/src/integration.ts)
- [v2.4.1 create/update schema](https://github.com/homarr-labs/homarr/blob/ebbd4876d25a51151444a009ab596e1154d62880/packages/validation/src/integration.ts)
- [v2.4.1 Stats router](https://github.com/homarr-labs/homarr/blob/ebbd4876d25a51151444a009ab596e1154d62880/packages/api/src/router/widgets/stats.ts)
- [v2.4.1 Stats snapshot semantics](https://github.com/homarr-labs/homarr/blob/ebbd4876d25a51151444a009ab596e1154d62880/packages/request-handler/src/stats.ts)
- [Gatus v5.37.0 status API](https://github.com/TwiN/gatus/blob/v5.37.0/api/endpoint_status.go)
- [Gatus v5.37.0 single-key status route](https://github.com/TwiN/gatus/blob/v5.37.0/api/api.go)
- [Gatus v5.37.0 key derivation](https://github.com/TwiN/gatus/blob/v5.37.0/config/key/key.go)
- [Gatus v5.37.0 endpoint result](https://github.com/TwiN/gatus/blob/v5.37.0/config/endpoint/result.go)
- [Gatus v5.37.0 enabled and interval defaults](https://github.com/TwiN/gatus/blob/v5.37.0/config/endpoint/endpoint.go)
- [Gatus v5.37.0 monitoring and retained results](https://github.com/TwiN/gatus/blob/v5.37.0/watchdog/endpoint.go)
- [Gatus v5.37.0 API cache lifetime](https://github.com/TwiN/gatus/blob/v5.37.0/api/cache.go)