Commit Graph

9474 Commits

Author SHA1 Message Date
rcourtman dc129cd3a4 Improve Proxmox node search coverage
Contract-Neutral: Behavioral search fix; no public subsystem contract delta
2026-08-23 17:01:49 +01:00
rcourtman d8fe2a9358 Stabilize large-estate workload scrolling 2026-08-23 16:32:53 +01:00
rcourtman 4040a79f4f Fix workload virtualization scroll ownership 2026-08-23 15:51:40 +01:00
rcourtman 3bc613c915 Scale large-estate workload and Proxmox demo performance 2026-08-23 15:09:32 +01:00
rcourtman 6869612c66 Isolate PC compilation from SignPath workflow 2026-08-23 15:02:33 +01:00
rcourtman 32d7b22996 Use trusted PC for release compilation 2026-08-23 14:41:11 +01:00
rcourtman c7c42f87e4 Add a weekly scheduled dependency vulnerability scan
Build and Test audits npm dependencies on every push, but nothing scans the
Go module for known vulnerabilities and neither surface is re-checked when
no pushes happen — which is exactly when a newly disclosed advisory against
unchanged code goes unnoticed. Run govulncheck and both npm audits weekly on
a schedule so a failed run emails the maintainer.
2026-08-23 14:40:01 +01:00
rcourtman a7f87471f4 Stop returning the stored Apprise API key from the notifications API
GET /api/notifications/apprise and the PUT echo returned the saved API key
verbatim, so any settings:read token could exfiltrate a write-capable
secret while the sibling email handler blanks the SMTP password under the
same scope. Responses now drop the key and report hasApiKey instead, the
update and test-send paths fall back to the saved key when the request
leaves it blank (matching the email password contract), and the settings
form tells the user a saved key is kept when the field stays empty.
2026-08-23 14:39:07 +01:00
rcourtman aba7cec747 Fix Proxmox guest table layout and virtualization
Contract-Neutral: Behavioral UI and scroll-container fix; no canonical subsystem contract changed
2026-08-23 14:24:27 +01:00
rcourtman 567eca2572 Harden stable release convergence 2026-08-23 14:21:09 +01:00
rcourtman 2f3d224997 Use hosted container qualification for stable releases v6.3.1 helm-chart-6.3.1 2026-08-23 12:43:18 +01:00
rcourtman 0f369a4b0d Use hosted compilation for stable releases 2026-08-23 12:16:14 +01:00
rcourtman c1d0aaa0d5 Approve v6.3.1 unsigned Windows exception 2026-08-23 12:02:53 +01:00
rcourtman 34ae5c98f9 Fix SignPath release provenance 2026-08-23 11:39:21 +01:00
rcourtman e51618a9ce Prepare v6.3.1 stable patch release 2026-08-23 10:38:19 +01:00
rcourtman ddf081a55a Bound Docker storage inventory collection 2026-08-23 09:34:40 +01:00
rcourtman 66eb537522 Fix local subscription CLI service setup 2026-08-23 09:28:44 +01:00
rcourtman 3a9dffa850 Fix Docker command recovery after token rotation 2026-08-23 09:18:44 +01:00
rcourtman bce5564025 fix notification terminal failure recovery 2026-08-23 09:05:54 +01:00
rcourtman 434e1448ff Restore Docker update preflight through unified agent 2026-08-23 08:35:26 +01:00
rcourtman ea5c105ff2 Log refused actions and name the missed command-agent lookup
A refused action plan, decision, or execution returned its 409 to the
client and left no trace in the server journal, so every remote report
of "Docker / Podman command agent is not connected" stalled on greps
that could never match anything. Refusals now log one warn line with
the resource, capability, and reason code, and the Docker command-agent
resolver reports which lookup missed (stale enrollment token binding vs
agent-id/hostname session), carried as an optional diagnostic detail on
the readiness contract and in the refusal envelope.

Refs #1728
2026-08-23 06:33:30 +01:00
rcourtman c313a80daa Prevent disabled PBS offline alert dispatch (#1759)
Resolve PBS alert overrides once per observation and reuse that snapshot during offline lifecycle evaluation. Add canonical-ID coverage for disabled eligibility and dispatch, enabled alerts and recovery, unrelated metrics, and concurrent configuration updates.

Contract-Neutral: Narrows internal PBS offline alert eligibility without changing external APIs or release artifacts.

Co-authored-by: rcourtman <rcourtman@users.noreply.github.com>
2026-08-22 15:52:27 +01:00
rcourtman 73c4147d5e Restore owner risk acceptance wording (#1760)
Co-authored-by: rcourtman <rcourtman@users.noreply.github.com>
2026-08-22 14:05:29 +01:00
rcourtman 124a2806ca Record v6.3.0 publication proof 2026-08-22 12:20:22 +01:00
rcourtman ca311323e9 Join every release compilation task v6.3.0 helm-chart-6.3.0 2026-08-22 11:07:26 +01:00
rcourtman b88e05d1ce Prepare v6.3.0 stable release 2026-08-22 10:35:27 +01:00
rcourtman 53ba9786c5 Stop same-short-name hosts collapsing across estates
Presentation host coalescing buckets agent rows by short hostname and
PVE node names are short, so a pve01 in one estate merged with a pve01
in another, re-parenting both estates workloads onto one row and
cross-wiring reachability. Veto the merge when the rows carry proof of
distinct machines, a disjoint machine ID set, differing DMI UUIDs, or
differing Proxmox cluster names, while equal cluster names still merge
so the same cluster added under two connections keeps its single row.
Apply the same cluster discrimination to agent-node link inference,
whose short endpoint alias keys and short-hostname corroboration
fallback could hand one estate agent to the other estate node.

Refs #1753

Contract-Neutral: behavioral bugfix in unified resources presentation coalescing and node link inference; no API shape or subsystem contract change
2026-08-22 07:58:43 +01:00
rcourtman 3de30d75fd Pin the pre-commit golangci-lint step to the go.mod toolchain
GOTOOLCHAIN=auto never downgrades, so once the system Go moved to
go1.27.0 the go command wrote version-4 export data that golangci-lint
v1.64.8 (built with go1.26, older vendored x/tools) cannot decode.
Every Go commit then failed with "export data version 4 is greater
than maximum supported version 2" and a cascade of bogus "type X has
no field" typecheck errors. Rebuilding the linter with go1.27 does not
help; its vendored x/tools is still too old for the new export data.

Derive GOTOOLCHAIN from the root go.mod (toolchain directive, falling
back to the go directive, else auto) and export it for both the root
and nested-module lint invocations, so lint always runs under the
toolchain the module actually ships with. The single root pin also
covers nested modules, whose go directives must stay at or below it.
GOLANGCI_LINT_GOTOOLCHAIN overrides the derivation.
2026-08-22 07:33:29 +01:00
rcourtman b92893351d Make release dry-run diagnostics fail closed (#1758)
* Make release dry-run diagnostics fail closed

Select the installed Chromium project with retries disabled, replace the unconditional pass with fail-closed API and rendered-UI readiness assertions, retain actionable runtime evidence, and guard the release workflow contract against regression.

Contract-Neutral: Release diagnostic and workflow verification hardening only; no product runtime contract changes.

* Expose stable E2E failure identities

Project Playwright JUnit failures into bounded GitHub annotations so repeated stable-tier failures can be diagnosed without rerunning or weakening the gate. Keep the full reports and runtime logs as the forensic record, and cover annotation parsing and escaping with deterministic tests.

Contract-Neutral: This changes CI failure observability only and does not alter product runtime behavior, stable-tier membership, retries, or verdict semantics.

---------

Co-authored-by: rcourtman <rcourtman@users.noreply.github.com>
2026-08-22 07:28:29 +01:00
rcourtman 022db18ef7 Let a per-resource severity override re-enable disabled offline alerts
applyThresholdOverride only ever copied DisableConnectivity=true from an
override, so once the global default disabled connectivity alerts no
override could turn them back on. A guest row set to Warning or Critical
saved its severity, showed as Custom, and never fired, while the
frontend already encodes re-enablement by pairing an explicit severity
with the row offline control (off stores DisableConnectivity=true).
Treat an override that carries an explicit powered-off severity as that
row offline control set to warning or critical and clear the inherited
disable, matching the Docker container state path which already works
this way.

Refs #1738

Contract-Neutral: Refs #1738: behavioral bugfix in alerts override merge, no API or contract shape change
2026-08-22 06:24:04 +01:00
rcourtman 9aa095a3b5 Reapply release qualification corrections (#1756)
Reapply the still-applicable exact-candidate tool setup hardening and its workflow contract assertions on current main. Current main already contains the native-path Docker and host fixtures plus the prescribed resource guardrail source path.

Contract-Neutral: Release-workflow hardening and test-fixture portability do not change the product runtime contract.

Co-authored-by: rcourtman <rcourtman@users.noreply.github.com>
2026-08-21 23:36:03 +01:00
rcourtman ebb08e0de2 Make native-agent test fixtures path-portable on Windows
The dockeragent credential-store tests keyed their fake filesystem and
path-bearing env seams on POSIX literals, while dockerConfigCredentials
builds candidate config paths with filepath.Join. On Windows every lookup
therefore missed the fixture and the nine credential-expecting
TestDockerConfigCredentials_* cases failed with a nil credential; the
hostagent PULSE_PCT_PATH override test likewise asserted a POSIX path that
is not absolute on Windows. Map fixture keys and env values through
filepath.FromSlash and anchor the override on t.TempDir().

Taken from PR #1755 (ff96aed8c) so the correction lands on main instead of
a parked agent branch. The unified-agent-native Windows x64 job has been
red on every push run since these tests landed on 2026-08-13; the
intervening green runs were pull_request events exercising that PR's own
corrected fixtures.

Contract-Neutral: test fixtures only, no production runtime change.
2026-08-21 22:36:52 +01:00
rcourtman a0770b87bb Ground backend shard admission in measured worker headroom
The three-shard backend gate landed with a 16 GiB admission requirement
that exceeded the 8-vCPU PVE worker's own idle availability (measured
16.1-16.7 GiB, and 14.1-14.9 GiB beside the sibling release compilers),
so the next release would have hard-failed at admission before running a
single test. Direct probes on the worker measured the complete gate at a
~6-7.5 GiB footprint (8.9 GiB MemAvailable floor from a 16.4 GiB start,
zero swap), so admission now requires 10 GiB for three shards and 8 GiB
for two, and degrades the shard count instead of failing the release
when the bounded wait expires without headroom.

Shard CPU is now weighted by planned test volume from the plan manifest.
Top-level tests execute serially per test-binary process, so width mainly
buys runtime, GC, and race-detector headroom for the 3595-test prefix
shard; the ~15-test wait-bound tails cannot use it. Probes measured the
prefix shard at 569s with 2 procs versus 484s with 4, with total
allocation still equal to the worker's vCPU count.

Validated by three direct runs of the canonical script on the worker:
the full gate passed in 8m10s wall (auto-admitted three shards, procs
4/2/2, shard walls 484s/331s/224s) against the 12m09s two-shard release
job measured in run 32514803052. One rig run also proved the gate fails
closed: a stale contract pin failed the non-API graph and the harness
terminated every descendant shard process.
2026-08-21 22:16:33 +01:00
rcourtman f38e95eb72 feat(telemetry): export the Patrol blocked cause at schema v10
An enabled Patrol that can never run and one that runs and finds nothing
were indistinguishable in the fleet: both presented as high run counts
with zero AI calls and zero findings. The install that motivated this
sat blocked for over a month because provider initialisation failed once
at boot and was never retried; the self-heal landed separately, but
telemetry still cannot see which blocked cause dominates in the field.

Schema v10 exports the fixed machine cause code (for example
provider_not_configured) only while Patrol is in the blocked runtime
state. The cause rides the router-owned Pulse Intelligence snapshot into
the outbound ping. Blocked-reason text, provider endpoints, model names,
and configuration stay on the install; an untyped blocked reason exports
nothing rather than free text, and a disabled, active, or mid-run Patrol
exports an empty value even when a stale cause is still recorded.
2026-08-21 21:43:54 +01:00
rcourtman 7c37a85cb2 Surface and self-heal Patrol's provider-unavailable state
Field telemetry showed installs with Patrol enabled recording weeks of
empty error runs (runs_30d=122, ai_calls=0, findings=0): provider
initialization failed once at boot (model resolution can need the
provider's live catalog, so Pulse racing a booting Ollama server loses)
and was never retried, while the run loop kept recording "Patrol
provider not configured" errors that told operators who had configured
a provider to configure one.

- Retry provider initialization on every scheduled run, so a boot-time
  race strands Patrol for at most one interval instead of until the
  next settings save. LoadConfig records the redacted init failure.
- Name the real failure in the blocked reason and run record when the
  configured provider failed to initialize, instead of claiming no
  provider is configured.
- Raise the deduped Patrol runtime finding when scheduled runs are
  skipped by a persistent readiness blocker or missing provider, so the
  state reaches the findings surfaces and alert notification channels
  once, instead of living only on the Patrol page banner. Transient
  circuit-breaker blocks stay finding-free; the attempts that opened
  the breaker already raised their own.
- Resolve the runtime finding when Patrol is turned off; opting out is
  a resolution, not a state to keep nagging about.
- Record the extended runtime-failure surface in the ai-runtime
  subsystem contract.
2026-08-21 21:05:54 +01:00
rcourtman 9ef94418e8 Accelerate release convergence on PVE 2026-08-21 20:41:04 +01:00
rcourtman 779f9a10bc Follow extracted resource service in frontend guard v6.3.0-rc.6 helm-chart-6.3.0-rc.6 2026-08-21 19:38:28 +01:00
rcourtman 5c26022d65 Join frontend before embedded server builds 2026-08-21 19:16:47 +01:00
rcourtman 89eba99bb4 Build frontend for Pro packaging profile 2026-08-21 19:04:23 +01:00
rcourtman 0cd70edd90 Prepare v6.3.0-rc.6 release 2026-08-21 18:56:45 +01:00
rcourtman 910c05355e Align extracted resource governance fixtures 2026-08-21 18:55:29 +01:00
rcourtman fa156e0bb1 Record chart and resource qualification 2026-08-21 18:53:27 +01:00
rcourtman 08827bb887 Extract chart and resource query services 2026-08-21 18:36:21 +01:00
rcourtman dca06991c2 Parallelize exact-version Docker publication 2026-08-21 18:25:26 +01:00
rcourtman 00157de00a Require two-shard backend memory admission 2026-08-21 18:14:33 +01:00
rcourtman e5389e2130 Parallelize inert release artifact staging 2026-08-21 18:08:22 +01:00
rcourtman 0027c82f84 Record rc.5 release convergence evidence 2026-08-21 17:56:23 +01:00
rcourtman 8869753b1e Require tailnet access for every paid runtime proof 2026-08-21 17:52:19 +01:00
rcourtman b16b8e5242 Bind Helm convergence to the release repository 2026-08-21 17:46:55 +01:00
rcourtman 1ef8797d28 Repair release activation recovery contracts 2026-08-21 17:43:01 +01:00