Commit graph

146 commits

Author SHA1 Message Date
rcourtman
76ced45c3a Harden demo SSH setup for private deploy hosts
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Canonical Governance / governance (push) Waiting to run
Helm CI / Lint and Render Chart (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 1/4) (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 2/4) (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 3/4) (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 4/4) (push) Waiting to run
Core E2E Tests / E2E verdict (push) Blocked by required conditions
2026-07-09 16:51:38 +01:00
rcourtman
fbddd91fcb Add install-script regression tests for the piped and version fixes
Cover the two installer bugs fixed in c98acb9e8 so they cannot regress:

- TestRootInstallScriptSourceGuardSurvivesPipedExecution runs the source guard
  through stdin the way curl ... | bash does and asserts it reaches the
  installer body instead of aborting on BASH_SOURCE[0] unbound. (#1526)

- TestInstallSHAgentVersionMismatchIgnoresVPrefix drives the version check and
  asserts v6.0.4 vs 6.0.4 does not warn while a real 6.0.3 vs 6.0.4 does, plus
  content assertions pinning the normalization in scripts/install.sh. (#1527)

Refs #1526 #1527
2026-07-09 12:04:41 +01:00
rcourtman
6999ca0119 Prepare 6.0.5 release 2026-07-09 11:52:28 +01:00
rcourtman
93bccaff18 Update the Pro binary in-app from the license server download broker
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Canonical Governance / governance (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 1/4) (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 2/4) (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 3/4) (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 4/4) (push) Waiting to run
Core E2E Tests / E2E verdict (push) Blocked by required conditions
The in-app updater and the unattended timer both target the public
rcourtman/Pulse community assets, so a Pro install that used them was
silently downgraded to community. Guard 2 (983a89326) blocked in-app
apply on the Pro edition, which stopped the downgrade but left Pro
installs with no update path except manual portal downloads. That
friction is a plausible driver of the runtime split: as of 2026-07-08
only 10 of 66 active paid licenses have any Pro-runtime install.

Root fix: the compiled Pro binary now checks and applies updates
through the license server download broker (GET /v1/downloads/pulse-pro
with the installation token and instance fingerprint). The check
compares against the broker's pinned private release instead of GitHub,
respecting the stable/rc channel guard. Apply re-resolves fresh signed
R2 URLs at apply time, verifies the archive against the same pinned
pulse-installer SSHSIG key plus the broker manifest sha256, and refuses
GitHub-shaped download URLs outright. An unactivated Pro binary still
refuses with the portal fallback. The community edition path is
unchanged.

The update banner restores in-app apply for auto-updatable Pro
deployments and keeps the portal instructions for deployments the
updater cannot drive (Docker). scripts/pulse-auto-update.sh now skips
when the installed binary reports Pulse Pro so the unattended timer can
never reinstall community over Pro.

Note: internal/updates/pro_update.go and manager_pro_update_test.go for
this change landed one commit early inside 313552deb via a parallel
session committing a shared staged index; this commit completes the
wiring they belong to.
2026-07-08 23:39:37 +01:00
rcourtman
313552debc Pin the OAuth Tailscale path in the update-demo workflow test
TestUpdateDemoWorkflowUsesGovernedNetworkPath still asserted the retired
authkey: TS_AUTHKEY line; 0a9a29d63 moved update-demo-server.yml to the
OAuth client (TS_OAUTH_CLIENT_ID / TS_OAUTH_SECRET, tag:infra), so the
test now pins those lines instead.
2026-07-08 23:23:20 +01:00
rcourtman
0d787a4b1f Prepare v6.0.5 RC4 release packet
Refs #1535
2026-07-08 13:10:06 +01:00
rcourtman
c7dcd90b83 Surface agent auth failures and staleness instead of a silent 401 loop
Refs #1515

When an upgraded or restored Pulse server no longer recognises an agent's
API token, the report endpoint returns 401. The agent buffered and retried
that report forever with only a generic warning, and the server kept the
node green at its last known agent version because a Proxmox node stays
online via the PVE API poll even after its agent dies.

- Agent: special-case 401 on /api/agents/agent/report. Drop the report
  instead of buffering it and log a throttled, actionable error pointing the
  operator at the install command to mint a fresh token.
- Installer: verify_agent_server_registration now tells a rejected token
  (401/403) apart from "agent has not reported yet" and prints the recovery
  steps at install time instead of a vague soft warning.
- Status layer: resourceFromHost flags a stale agent (its host marked
  offline by the staleness evaluator) and carries the agent's own last
  report time. Coalescing keeps a node online via the PVE source but the
  dead agent stays flagged, so its version is no longer presented as current.
  The Machines table renders such versions as "(stale)".
2026-07-08 08:35:46 +01:00
rcourtman
8113f3e8c3 Ensure Helm Pages publishes release chart 2026-07-07 19:21:48 +01:00
rcourtman
0ff922ca16 Prepare v6.0.5 RC3 release packet
Refs #1535
2026-07-07 16:48:12 +01:00
rcourtman
e1cddca2d1 Prepare v6.0.5 RC2 release packet
Refs #1470

Refs #1471

Refs #1476

Refs #1483

Refs #1511

Refs #1515

Refs #1516

Refs #1524

Refs #1533

Refs #1534
2026-07-07 10:50:49 +01:00
rcourtman
3dd2ecd198 Add Proxmox token smoke diagnostics
Refs #1476
2026-07-07 10:10:16 +01:00
rcourtman
d52231855d Fix Proxmox token preservation regressions
Refs #1470, #1476, #1511
2026-07-07 09:49:26 +01:00
rcourtman
b503ee6fd3 Fix legacy agent update token recovery
Refs #1515
2026-07-07 09:31:21 +01:00
rcourtman
dded079297 Prepare v6.0.5 RC1 release packet
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Canonical Governance / governance (push) Waiting to run
Helm CI / Lint and Render Chart (push) Waiting to run
Core E2E Tests / Playwright Core E2E (push) Waiting to run
Refs #1530

Refs #1531

Refs #1471
2026-07-07 00:12:09 +01:00
rcourtman
4b669ad9b5 Fix SAT SMART temperature collection
Refs #1471
2026-07-06 23:42:00 +01:00
rcourtman
41a99c1a03 Prepare v6.0.5 patch release
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Canonical Governance / governance (push) Waiting to run
Helm CI / Lint and Render Chart (push) Waiting to run
Core E2E Tests / Playwright Core E2E (push) Waiting to run
Refs #1530

Refs #1531
2026-07-06 23:29:17 +01:00
rcourtman
1d7fa6c4bf Prepare v6.0.4 release 2026-07-06 16:50:59 +01:00
rcourtman
926c6bd433 Fix legacy agent update recovery
Refs #1515
2026-07-06 14:01:26 +01:00
rcourtman
44af57b8fc Prepare v6.0.4-rc.2 support build
Some checks failed
Canonical Governance / governance (push) Waiting to run
Helm CI / Lint and Render Chart (push) Waiting to run
Build and Test / Secret Scan (push) Has been cancelled
Build and Test / Frontend & Backend (push) Has been cancelled
Package the audit timestamp compatibility fix for private Pro support validation.
2026-07-06 09:22:44 +01:00
rcourtman
6212eecf12 Align Docker defaults with v6.0.4-rc.1
Some checks failed
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Canonical Governance / governance (push) Waiting to run
Helm CI / Lint and Render Chart (push) Waiting to run
Core E2E Tests / Playwright Core E2E (push) Waiting to run
Update Integration Tests / Update Flow Integration Tests (push) Has been cancelled
Pin Docker install defaults and Helm metadata to the support prerelease version.
2026-07-05 21:10:47 +01:00
rcourtman
c384d5e0c8 Prepare v6.0.3 patch release
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
2026-07-05 11:07:27 +01:00
rcourtman
314429b879 Fix v5 agent update recovery
Issue: #1515
2026-07-05 10:08:19 +01:00
rcourtman
1ba7bb06a0 Verify public Helm chart publication 2026-07-05 09:40:20 +01:00
rcourtman
c0ae794dc9 Prepare v6.0.2 release
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
2026-07-04 23:19:42 +01:00
rcourtman
d029e4dc42 Fix demo fixture entitlement recovery
Seed the hidden demo fixture entitlement during stable demo updates so release builds can enable governed mock resources after runtime configuration is restored.

Keep the deployment contract and release policy checks aligned with the release-build entitlement gate.
2026-07-04 22:44:43 +01:00
rcourtman
cd6b250ae6 Fix demo verification and agent update recovery
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Refs #1515

- restore demo runtime env and verify mock fixtures even when the target version is already installed
- require recovered agent update state to include both URL and token before reporting success
2026-07-04 22:30:58 +01:00
rcourtman
84ad973540 Prepare v6.0.1 patch release
- bump release, Docker, and Helm metadata to 6.0.1

- add committed v6.0.1 patch release notes and changelog

- allow stable patch hotfix releases without a fabricated same-version prerelease tag
2026-07-04 19:32:01 +01:00
rcourtman
64d58fd161 Fix legacy agent update state recovery
Refs #1515
2026-07-04 17:22:29 +01:00
rcourtman
de0c5ff5c1 Retire v6 preview demo target after GA 2026-07-04 16:16:57 +01:00
rcourtman
72c8d9677a Prune nested demo runtime stores 2026-07-04 15:47:00 +01:00
rcourtman
d2ab2b793d Prune demo volatile stores for release deploy 2026-07-04 15:39:35 +01:00
rcourtman
d8487b568a Tighten demo backup cleanup headroom 2026-07-04 15:34:08 +01:00
rcourtman
dc5f0a35c0 Harden installer and demo backup handling 2026-07-04 15:28:42 +01:00
rcourtman
e3dba105a7 Build control-plane image with embedded frontend assets 2026-07-04 14:46:53 +01:00
rcourtman
28cee7c467 Prefer PVE 9 guest-agent privileges in setup
Refs #1466
2026-07-03 11:15:51 +01:00
rcourtman
bf96c9cb08 Bump version to 6.0.0
- set release version for v6 GA publication
- align Docker defaults and promotion proof with the stable cut
2026-07-02 22:05:56 +01:00
rcourtman
d796928969 Install signature verifier dependencies 2026-06-28 03:26:13 +01:00
rcourtman
55204cde9b Align RC7 Docker install defaults 2026-06-27 10:18:40 +01:00
rcourtman
ee8a24e14a backend and governance: MCP contract, agent capabilities, API, and release-control
Manifest-backed MCP tools, prompts, and resources with surface affordance contracts; agent capability manifest and governance projection; API contract tests and capability route projection; operations-loop and intelligence-funnel telemetry; release-control subsystem documentation, registry, and tooling; licensing and configuration.
2026-06-23 17:26:15 +01:00
rcourtman
c04ac2f7cf Make private Pro publication block v6 releases
Some checks failed
Build and Test / Secret Scan (push) Has been cancelled
Build and Test / Frontend & Backend (push) Has been cancelled
2026-06-15 15:37:13 +01:00
rcourtman
6178bcbdc7 Update workflow pin installtests 2026-06-14 19:56:33 +01:00
rcourtman
48e1efece7 Use patched Go toolchain for v6 release 2026-06-14 18:22:26 +01:00
rcourtman
b179b1782c Stabilize Proxmox guest Docker inventory 2026-06-12 12:10:54 +01:00
rcourtman
841100caa7 Clarify Proxmox LXC Docker install path 2026-06-12 09:57:58 +01:00
rcourtman
5e78825f54 fix(install): make unattended auto-updates actually run after install and upgrade
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Two GA-blocking bugs in the auto-update install path:

The pulse-update.service unit was rendered through an unquoted heredoc
containing $${PULSE_SERVICE_NAME}, which bash expands to the installer's
PID, so the unit shipped with ExecCondition checking a service like
"24757{PULSE_SERVICE_NAME}". The condition always failed and systemd
silently skipped every scheduled run, for fresh installs and upgrades
alike. The heredoc now renders the detected service name directly:
ExecCondition=/bin/sh -c 'systemctl is-active --quiet pulse'.

Upgrades also never refreshed the updater assets: a v5 box with
auto-updates enabled keeps pulse-update.timer and autoUpdateEnabled=true,
so the update/reinstall flows never re-ran setup_auto_updates and the
v5.1-pinned /usr/local/bin/pulse-auto-update.sh stayed in place, logging
"Already running latest version" forever instead of selecting v6
releases. The asset-install half of setup_auto_updates is now a shared
install_auto_update_assets(), and a new refresh_auto_updates() rewrites
the helper script and units unconditionally whenever the timer already
exists, without touching system.json or the timer's enabled state. All
five install flows (update, reinstall, --version, --source, fresh) are
wired.

Tests now render the real unit and execute the rendered ExecCondition
against a recording systemctl stub instead of asserting source-text
fragments, pin refresh_auto_updates behavior (stale helper replaced,
system.json and enablement untouched), and pin the call-site wiring.
The deployment-installability contract records both invariants.

Note: rewritten message only — the original local commit carried a
parallel agent's licensing commit message due to a shared-index race;
the tree is byte-identical to the hook-verified original.
2026-06-10 22:43:08 +01:00
rcourtman
a17882458a Rename CP_TRIAL_ACTIVATION_PRIVATE_KEY to CP_ENTITLEMENT_SIGNING_PRIVATE_KEY in the provider MSP bundle
The variable signs hosted entitlement leases; the trial-activation name is
left over from the retired trial era and reads as trial machinery to an
operator generating their licensing root key. The provider MSP bundle has
no installed base yet, so the canonical rename is free today and frozen
the moment the first design partner installs.

- Control plane reads CP_ENTITLEMENT_SIGNING_PRIVATE_KEY first and falls
  back to CP_TRIAL_ACTIVATION_PRIVATE_KEY, so existing Pulse-hosted cloud
  deployments (deploy/cloud, hibernated snapshot) keep working unchanged.
- deploy/provider-msp (.env.example, compose, setup.sh), MSP.md, and the
  install-test pins use the canonical name; error messages name it too.
- deploy/cloud intentionally keeps the legacy name: that stack historically
  signed hosted trial activations, and its snapshot predates the rename.
2026-06-10 14:08:52 +01:00
rcourtman
b707512e38 Clear all errcheck and gofmt violations so make lint gates on real findings
golangci-lint run ./... failed on ~190 pre-existing errcheck violations and
5 unformatted files, burying any new regression in noise. Fix all of them:

- Test files that hand-rolled mock-mode set/restore (vmware, truenas, and
  friends) now use the canonical setMockModeForTest/testutil.SetMockMode
  helper instead of drift copies that ignored SetEnabled errors.
- internal/mock and internal/monitoring tests get package-local
  mustSetEnabled/mustSetMockEnabled/mustSetMonitorMockMode helpers that
  fail the test on toggle errors.
- pkg/auth/sqlite_manager.go, pkg/metrics/store.go, pkg/server/server.go:
  rollbacks in defers use the explicit-discard idiom, migration renames and
  rollup commits log failures, the hosted reaper goroutine logs an error
  exit, shutdown mock-disable logs failures.
- Remaining test sites check errors with t.Fatalf/t.Errorf or explicitly
  discard best-effort calls (restore-chmods, handler-closure unmarshals)
  per existing repo style.
- gofmt: internal/api/maintenance_verification.go, internal/ai/demo.go and
  three findings test files.

Only dupl findings remain (44 pre-existing production-code duplication
pairs) — those need real refactors, not mechanical fixes.

Full test suites pass for every touched package.
2026-06-09 21:42:21 +01:00
rcourtman
16f791a656 Harden install-time PVE token extraction with JSON-first parsing (#44/#1312)
The install-time auto-register path (auto_register_pve_node) parsed the API
token secret out of pveum's box-drawing table output with a fragile awk
column-split. The web-setup render path was already hardened to request
'pveum ... --output-format json' first and parse the value field, but this
secondary install.sh path was never ported.

auto_register_pve_node now requests --output-format json first (falling back
to the bare --privsep 1 form only when an older pveum rejects the JSON flag,
which keeps the secure-installer contract pin on that form satisfied) and
extracts the secret via a new extract_pve_token_value helper: JSON value-field
parse first, then a locale-independent box-drawing table fallback (normalizes
the column separator to a plain pipe byte-wise before splitting, so it works
regardless of host locale). This mirrors the hardened render path and removes
the silent-failure / mis-parse risk when pveum table formatting drifts.

Functional + contract tests in root_install_sh_test.go; deployment-installability
contract documents the deterministic extraction. The host-agent path
(internal/hostagent/proxmox_setup.go setupPVEToken) carries an agent-lifecycle
token-permission proof obligation and is left for a governed lane.
2026-06-09 15:47:12 +01:00
rcourtman
2ff2b18c74 Wire legacy sensor-proxy cleanup into install.sh --uninstall (#34)
A Proxmox host upgraded from v5 may still carry the legacy pulse-sensor-proxy
footprint (binary, systemd units, runtime/state dirs, dedicated service user,
and managed SSH keys in root's authorized_keys). install.sh --uninstall removed
everything for the Pulse server itself but left that legacy footprint behind,
so a 'complete uninstall' was not complete -- most notably it left SSH key
entries in /root/.ssh/authorized_keys.

uninstall_pulse now calls cleanup_local_sensor_proxy, which removes the LOCAL
footprint only: stop/disable the units, remove the binary/units/runtime/state
dirs, strip the '# pulse-managed-key' / '# pulse-proxy-key' entries, and remove
the service user/group. It is presence-gated (silent no-op when no proxy was
installed). The aggressive cluster-wide authorized_keys removal and
pulse-monitor@pam API-user deletion stay behind the explicit standalone
scripts/uninstall-sensor-proxy.sh, which we print a pointer to.

Functional + contract tests in scripts/installtests/root_install_sh_test.go;
deployment-installability contract documents the new uninstall removal scope.
2026-06-09 15:25:08 +01:00
rcourtman
bd6f77e093 Prepare v6.0.0 release candidate
Tighten v5-to-v6 upgrade safety, release installability, provider MSP mode handling, AI cost accounting, metrics flushing, and frontend guardrails for the v6.0.0 GA candidate.
2026-06-04 14:07:14 +01:00