6b79aa997 bounded WriteBatchSync itself, which broke its read-your-writes
contract on slow disks: CI's metrics write-amplification and 500-node
load tests count committed rows after writing, and mock seeding reads
store coverage straight back, so the 2-second early return failed both
(runs 31475700902, 31494553977). Fast local disks masked it.
WriteBatchSync returns to a full commit wait. The monitoring pipeline's
four sync sites move to WriteBatchBounded, which carries the bounded
enqueue-plus-wait semantics, so the #1437 slow-disk stall fix stays
exactly where the hazard is. Both paths share prepareWriteBatch
validation, and a new regression test pins WriteBatchSync waiting past
the bounded budget.
Refs #1437
Contract-Neutral: behavioral fix: split bounded pipeline writes from synchronous batch writes, restores read-your-writes (#1437 follow-up), no public contract delta
Adaptive polling deliberately stretches an instance's cadence toward its
max interval (5 minutes by default) while data is fresh, but the
connections aggregator judged staleness against the configured cadence
with a 2-minute floor. Any adaptive-enabled install therefore cycled
healthy PVE/PBS/PMG connections into stale for the back half of every
stretched poll gap: the Infrastructure page dropped the source badge
from API + Agent to Agent and connection-degraded alerts fired against
a schedule the poller was honoring.
The aggregator now scales the active-to-stale cutoff by the scheduler's
currently planned interval when that exceeds the configured cadence,
via Monitor.PlannedPollInterval and per-instance planned intervals in
the aggregator inputs. A plan tighter than the configured cadence never
tightens the cutoff, so genuine poll outages still trip the floor on
time. Connection-degraded alerts and the runtime inventory gate consume
the same derived state and inherit the fix.
Refs #1437
Contract-Neutral: behavioral fix: stale cutoff follows adaptive planned interval (#1437), no public contract delta
The reporter-test-image policy named the tag shape and version stamp but
not the build mechanics, so each agent rediscovered them. Name the
hosted_runtime Dockerfile target as the server-only diagnostic image,
warn that BUILD_AGENT=0 does not skip agent artifacts on the default
target, and point at LOCAL_CAPABILITIES.md for the workstation's default
builder.
Refs #1437
WriteBatchSync waited unboundedly for the ingestion worker's commit. The
monitoring pipeline calls it inline from state broadcast, agent ingest,
and poll publish, so a metrics disk slow enough to back up the write
queue froze the monitor after its first cycle: polls stopped being
scheduled, PollStatus.LastSuccess never advanced, and healthy API
sources degraded to stale/agent-only while SQLite ground through
retention maintenance (107s cleanup, multi-second commits on the
reporter's instance).
enqueueAndWait now shares a single 2s budget across enqueue and commit.
A queue that cannot accept the batch within the budget drops it with a
warning, matching enqueueWrite's saturation behavior. A batch that
enqueues but has not committed stays queued and is not lost; the caller
moves on and a rate-limited warning records the backlog. Healthy disks
keep read-your-writes semantics.
Refs #1437
Contract-Neutral: behavioral fix: bound metrics store sync write wait (#1437), no public contract delta
Every attention row on every install (and all 38 rows on the public demo)
carried a warning 'Evidence incomplete; timing unavailable' / 'Evidence
timing unavailable' metadata line. Unknown freshness just means the evidence
source publishes no validity window - only availability-poller evidence does
- so it is not an operator-facing warning, and the 'timing unavailable' claim
was false with per-envelope observation times rendered beside it.
- Presentation: the scan row now surfaces an evidence phrase only for states
worth a glance (unavailable, incomplete, stale, or window-backed current);
complete evidence with unknown freshness stays quiet on the row and shows
a muted 'Evidence recorded' badge in the detail, mirroring the existing
unavailable-protection row rule.
- Alerts bridge: provider incidents without a backing availability check now
carry a first-class complete/confirmed envelope derived from the observed
incident payload instead of falling to the legacy partial shim, and each
sync merges the cycle's freshly observed envelopes into the active alert so
raise-time evidence does not age out while the condition is still observed.
Verified live on a scratch mock instance at 1280px and 744px: all 44+ mock
attention rows now project complete evidence and render without the noise
line; detail shows 'Evidence recorded' with per-observation timestamps.
The Up to date verdict on the Pulse server updates panel can come from the
frontend's 24h localStorage cache, but it rendered with no timestamp, so a
day-old verdict read as a live comparison. A user on rc.9 read Up to date
minutes after v6.2.0 published and concluded the updater was broken.
The status cell now carries the age of the check the verdict came from
(Checked 3 hours ago, or Not checked yet when this browser has never
checked). Copy stays in the updatesPresentation owner, the store exposes
lastCheckedAt for the verdict actually displayed, and the line is hidden
for source builds, where checks are disabled.
Refs #1601
The Plans & Billing navigation entry is suppressed for sessions without
commercial context, which hid the only activation-form entry point from
exactly the customers who need it: a fresh Pro install has no license yet,
so hideUpgrade stayed true until the key the customer could not find a
place to paste was pasted. The compiled Pro binary is only distributed
through the paid broker flow, so a Pro-edition session is commercial
context by construction — edition.IsPro() now sets commercialContext in
securityStatusPresentationPolicy.
Ordinary free self-hosted sessions run the community binary and keep the
opt-in default (the edition marker keys off the compiled binary, never
license state). Demo mode and white-label keep full suppression via
hideCommercial, which wins over edition-derived context. Complements
1b9bc9482 (setup-completion activation pointer); together a fresh Pro
install gets both the first-run pointer and a permanently visible
Plans & Billing entry. api-contracts, storage-recovery, and
agent-lifecycle contracts record the policy delta.
A fresh Pro install has no way to discover where its activation key goes:
the Plans & Billing nav entry is navigation-suppressed until a license or
subscription exists (hideWhenUpgradeHidden), which hides the only panel
holding the activation form exactly while the install is unlicensed. A Pro
customer hit this after the broker download flow and emailed support.
The setup completion panel now probes /api/license/runtime-capabilities
and /api/license/status with the setup token and, only when the compiled
Pro build reports no valid license, renders an Activate Pulse Pro card
linking straight to /settings/pulse-intelligence/billing/plan (direct
routes stay reachable by design). Community builds, licensed installs,
and failed probes all keep the card hidden, so the self-hosted opt-in
commercial posture is untouched. The pro-unlicensed preview scenario
keeps browser proof deterministic; strings are localized in EN/DE/ES;
agent-lifecycle, frontend-primitives, and security-privacy contracts
record the new handoff and catalog boundaries.
Clears the red main streak that began at 63a0adf9a:
- newTestConfigHandlers never stopped its alerts.Manager, leaking a
periodicSaveAlerts goroutine that logs through the global zerolog
logger and races with the authorization-refusal contract test's
logger swap under -race
- InfrastructureAgentDoctorPage used a raw select, tripping the
settings native-select guardrail; converted to the shared labelled
FormSelect primitive
- the metric-title residual pin still expected the removed -1 sentinel
copy; aligned with the Off-control wording from 16179dd0a
Contract-Neutral: test-only CI red fix: stops alerts.Manager goroutine leak in api test helper, converts agent doctor raw select to the canonical FormSelect primitive the frontend-primitives contract already mandates, updates a stale test pin; no public contract delta