The unified agent gains an availability module: probe assignments
arrive through the signed remote-config channel (missing key clears
the schedule), each enabled target runs on its own clamped interval
through the shared probe core, and results queue in a bounded
drop-oldest buffer. A result is offered to the primary server until
one delivery succeeds and never again after - buffered offline
reports are stripped of availability results so the disk buffer
cannot replay observations the queue still holds. ApplyHostReport
feeds accepted reports into the probe ingestion path, where the
ownership check and failure accounting live, and the probe agent id
is projected onto unified availability resources for source
attribution in the UI.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Availability targets gain an optional probe agent assignment. Setting
it requires the external_probe entitlement, enforced only at the
moment of assignment - local targets never consult the license path.
Assigned targets are delivered to their agent through the signed
agent-config channel, skipped by the local poller, and resume local
execution automatically if the entitlement lapses. Probe-reported
results are accepted only from the currently assigned agent, share
the local failure-threshold accounting, carry source attribution,
and derive to indeterminate at read time when reports go stale.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Move the ICMP, TCP, HTTP and UDP probe core from the monitoring
availability poller into internal/availabilityprobe so the host agent
can execute the same checks without importing the monitoring package.
Monitoring keeps type aliases and thin wrappers, so callers and the
canonical guardrail contracts are unchanged. Pure refactor for the
upcoming external probe feature.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
In-place updates never rewrite the systemd unit, so installs upgraded
past v6.1.0-rc.1 keep a unit without AmbientCapabilities=CAP_NET_RAW
and every ICMP probe fails with ping's raw stderr. Detect the
capability failure and point at the unit and its fix instead (#1554).
An availability target's configured poll interval only seeded the
adaptive scheduler: BuildPlan derived every instance's cadence from the
global adaptive bounds, and a failing probe raised the staleness score
and error penalty, collapsing the probe interval toward the global
5-second minimum. With interval 120s and failure threshold 4 the alert
was promised after ~8 minutes of downtime but fired within the first
minute because the four consecutive failures accumulated at the
collapsed cadence (#1582).
Availability checks promise pollInterval x failureThreshold as the
detection window, so the cadence is a user contract, not a scheduling
hint. Add a FixedIntervalPollProvider extension that pins an instance
to its configured interval, implement it for availability targets, and
bypass adaptive selection wherever the next run is computed (plan
building, rescheduling, and the non-adaptive fallback paths).
TCP probes to fast local-network services can complete in under 1ms,
causing latency.Milliseconds() to return 0. Combined with omitempty on
the poller status struct, this made some probes show 'Online' with no
latency in the settings panel. Now successful probes always report at
least 1ms.
All TCP and HTTP availability probes were failing with 'no route to host'
because the Pulse process's Go networking stack cannot reach local subnet
IPs when a Tailscale system extension is active. The ICMP probe already
worked because it uses exec.Command('ping'). Apply the same pattern:
- probeTCP: try Go net.Dialer first, fall back to exec.Command('nc')
- probeHTTP: try Go http.Client first, fall back to exec.Command('curl')
- Both fallbacks use OS-appropriate timeout flags (macOS: -G, Linux: -w)
- HTTP probes now skip TLS verification (availability check, not identity)
- Add AvailabilityProbeHTTPS protocol constant and wire it through
Validate, HTTPURL, Normalize, and the probe switch
- Replace bulky TooltipPortal tooltip on AvailabilityProbeCell with a
clean native title attribute ('14 ms - checked 3s ago')
Before: 0/20 probes green (all 'no route to host')
After: 14/20 probes green (6 legitimately down hosts)
Agentless availability checks (ICMP/TCP/HTTP) were always minting
standalone network-endpoint resources, leaving them disconnected from
the known Proxmox/Docker guest they actually monitor. This made
availability evidence invisible on the platform resource row where the
user expects it, per the performance-and-scalability bounded-row
contract.
Backend (unified-resources ingest):
- Add LinkedResourceID field to AvailabilityData and AvailabilityTarget
- resolveAvailabilityLink: explicit link first, then exact-IP unambiguous
correlation; skip hostname-only (lossy); guard against overwriting a
different target's facet
- Unlinked/unmatched probes still mint network-endpoint (fallback)
Frontend:
- Relax getAvailabilityProbePresentation for any resource with availability
- Add compact protocol badge to UnifiedResourceHostTableCard name cell
- Add optional 'Link to resource' field to availability target form
- Add linkedResourceId to frontend types
Contracts: api-contracts, unified-resources, monitoring,
performance-and-scalability, storage-recovery.
Governance: coverage_gap + candidate_lane in status.json.