Production SignPath signing requests require manual approval in the
SignPath UI, so the previous single-job flow (submit with
wait-for-completion inside a 40-minute window) let approval latency fail
the Windows build, and any re-run rebuilt the binaries and submitted a
second request needing a second approval.
The Windows lane is now two jobs: sign-windows-agent builds the unsigned
executables, submits the SignPath request without waiting, and uploads a
7-day signing-request record; collect-windows-signing absorbs approval
latency by polling the recorded request, downloads the signed artifact
by request id, and keeps the existing verification and evidence steps.
If approval outlasts the 115-minute polling window, the collection job
fails with re-run guidance and "Re-run failed jobs" collects the same
recorded request - no rebuild, no resubmission. The legacy PFX
break-glass backend rides the same two-job shape via an artifact
hand-off. Workflow output wiring, artifact names, and evidence content
are unchanged for downstream consumers.
The shape test now pins the async invariants (no wait-for-completion:
true in the candidate workflow), and the code signing policy plus the
deployment-installability contract describe the two-phase flow.
TestRepositoryDoesNotClaimTelemetryIsAnonymous flags any 'anonymous'
within 120 characters of 'telemetry' on one line. The MSP evaluation
clause landed in c17664b3d legitimately ends one sentence with
'telemetry' and starts the next with 'Anonymous evaluation', tripping
the scan without claiming telemetry is anonymous. State the same
requirement without the word collision.
Contract-Neutral: wording-only: same clause meaning, avoids telemetry-anonymous guardrail false positive
2bc4ed725 moved the unified metrics sync sites to WriteBatchBounded but
left the three source guardrails pinning the literal WriteBatchSync
call, so they failed. The guardrails' intent is that pipeline writes go
through the canonical batched ingestion path, which WriteBatchBounded
is; pin the new name.
Contract-Neutral: test-only: guardrail pins follow the WriteBatchBounded pipeline rename from 2bc4ed725
TestSeedMockMetricsHistory_SeedsVMwareMetricsStore and the TrueNAS
variant compared seeded storage values against the package-level
mock.SampleMetric, which resolves resource roles from the global
registry that only other tests populate. The assertions therefore
passed or failed depending on which tests ran earlier in the process:
isolated runs failed deterministically, and today's CI reshard flipped
the rest-0 shard red for commits that never touched the mock layer.
Both tests now build the same graph-aware sampler the seeder uses, so
the expectation is self-contained and order-independent.
Contract-Neutral: test-only: seed assertions sample via the seeder's graph sampler, removes cross-test registry dependence
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