Commit graph

168 commits

Author SHA1 Message Date
rcourtman
b9eb7c3241 Prepare v6.1.0-rc.3 release 2026-07-18 16:56:00 +01:00
rcourtman
6351fd6526 fix(updates): select releases by highest version, not GitHub list order
Production telemetry (7d, 2026-07-17) shows a persistent tail of live
installs on 6.0.0-rc.x and 6.0.3/6.0.4 while 6.0.5 has been stable since
2026-07-09. Root cause for the reachable stranding class: release
selection trusted GitHub's created_at ordering, and this repo interleaves
v5-line maintenance releases with v6 releases (v5.1.36 was created the
day before v6.0.5). Whenever a v5.1.x release is the most recently
created stable:

- stable channel (getLatestReleaseForChannel) returned the first
  non-prerelease in list order -> "no update" for every v6 install
  until the next v6 release ships
- the RSS rate-limit fallback returned the first feed entry matching the
  channel, same failure, both channels
- the unattended updater trusted /releases/latest, which GitHub defines
  as most-recently-created stable -> timer no-ops in the same window

All three now select the highest eligible version: the API path tracks
newest stable + newest prerelease in one pass (prerelease = GitHub flag
OR tag shape), the feed fallback picks the max matching the channel, and
pulse-auto-update.sh scans /releases pairing each tag with its own
draft/prerelease flags before the fail-closed shape filter, keeping
/releases/latest as fallback. helm-chart-* tags fail semver parsing and
are dropped everywhere.

Verified not broken (pinned by new tests): rc-channel installs are
offered the newer stable (6.0.0-rc.6 -> 6.0.5) and move onto the next rc
line when one opens (-> 6.1.0-rc.2); the auto-update prerelease filter
(fail-closed is_prerelease_tag, metadata-flag refusal) still refuses
prerelease targets on stable. Go tests fail on the pre-fix code
(returned 5.1.37 / "no update").

Contract: deployment-installability now pins version-max release
selection with proofs in manager_stranded_upgrade_test.go and
pulse_auto_update_test.go.
2026-07-17 23:21:49 +01:00
rcourtman
7ab605452d fix(release): fail closed on malformed release notes 2026-07-17 11:12:22 +01:00
rcourtman
a857c7e783 Prepare v6.1.0-rc.2 release 2026-07-16 23:45:31 +01:00
rcourtman
252754ee4f Refresh Pulse 6.1 RC1 mobile coordinates 2026-07-13 20:27:42 +01:00
rcourtman
310ee94b0d Refresh Pulse 6.1 RC1 mobile evidence 2026-07-13 19:41:41 +01:00
rcourtman
e2ec59a840 Prepare v6.1.0 RC1 release
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
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 / E2E verdict (push) Blocked by required conditions
Unified Agent Native Verification / Linux ARM64 (push) Waiting to run
Unified Agent Native Verification / Linux x64 (push) Waiting to run
Unified Agent Native Verification / Windows x64 (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 4/4) (push) Waiting to run
Unified Agent Native Verification / macOS ARM64 (push) Waiting to run
Unified Agent Native Verification / macOS Intel (push) Waiting to run
Unified Agent Native Verification / FreeBSD cross-build contract (push) Waiting to run
Helm CI / Lint and Render Chart (push) Has been cancelled
2026-07-13 18:35:08 +01:00
rcourtman
4c3e0756e3 Guard the allowed_signers format in the install verification docs 2026-07-13 16:27:04 +01:00
rcourtman
5a6871813f Grant CAP_NET_RAW to the installed systemd unit for ICMP probes
The installer's unit hardens with NoNewPrivileges=true, which strips the
ping binary's setuid/file capabilities, so ICMP availability probes could
never work on a systemd install. Grant the capability ambiently instead,
document the systemctl edit override for existing units, and pin the
hardening block with an install test and contract clause.

Addresses #1554 (discussion)
2026-07-11 18:15:22 +01:00
rcourtman
d5437a9353 Allow RCs while Windows signing is pending 2026-07-10 23:12:12 +01:00
rcourtman
92ea590000 Prepare v6.0.6 RC1 release packet 2026-07-10 21:39:03 +01:00
rcourtman
3bea52b1b5 Harden native Windows agent lifecycle 2026-07-10 19:16:23 +01:00
rcourtman
0e40ec07cb Make the provider MSP portal honest and self-sufficient without an email provider
Exercised the full provider portal as a pilot MSP would and fixed what
made it feel broken:

- The signed-out portal promised "a sign-in link is on the way" even when
  the control plane has no email provider (the bundle default), and team
  invitations silently sent nothing. The portal bootstrap now carries
  email_sign_in_available and provider_hosted_mode; the sign-in page shows
  the host command that actually prints a link, and the invite panel says
  invitation emails are not sent and how to hand over a link instead.
- New "provider-msp portal-link --email" CLI mints a one-time portal link
  for an account member or pending invitee, so teammates can sign in at
  all on email-less installs (bootstrap only covers the owner).
- Portal sessions were fixed at 12h; CP_SESSION_TTL now configures them
  and provider-hosted MSP mode defaults to 7 days.
- Creating a client past the license cap showed a generic "Failed to
  create workspace." toast: the limit error is now a JSON payload with
  current/limit, the API client no longer drops non-JSON error bodies
  (double body read), and the toast explains the license limit.
- Copy polish: provider-mode sign-in intro (no refunds/privacy register),
  least-privilege default invite role, queue tile label matches "Client
  onboarding", softer Support tab with a docs/MSP.md pointer, setup.sh
  summary now prints the bootstrap next step and day-2 sign-in commands,
  .env.example and docs/MSP.md document portal sign-in and sessions.

Contracts updated (cloud-paid, api-contracts, deployment-installability,
security-privacy) with verification pins in tenant_handlers_test,
config_test, magiclink_test, and provider_msp_deploy_test.

Verified live against a dockerless control plane: portal-link for an
invitee redeems, promotes the invitation, and sets a 7-day session;
the at-cap toast shows the license copy; portal vitest suite and
cloudcp/auth/account/installtests Go suites pass.
2026-07-10 11:22:57 +01:00
rcourtman
f356994869 Extract the transport-independent action lifecycle service
Planning, approval decisions, and execution for typed resource actions
move out of the HTTP handlers in internal/api/actions.go into a new
internal/actionlifecycle.Service owned by api-contracts. The REST
handlers become thin decode/actor/error-mapping adapters over the one
shared service, and ResourceHandlers.ActionLifecycle() exposes the same
service for in-process consumers, so a future Patrol action broker
inherits identical resource lookup, availability checks, plan hashing,
audit persistence, remediation locks, plan-drift revalidation,
execution, and terminal publication instead of loopback HTTP or a
parallel lifecycle.

Behavior is preserved: same status codes, error codes, and audit/
lifecycle persistence ordering, backed by the existing api contract
tests plus new fail-closed proofs for the service itself (unknown
resource/capability, availability refusal, unapproved execution,
remediation lock, plan drift, missing executor, missing store).

Contract text in api-contracts, agent-lifecycle, and storage-recovery
now names the service alongside actions.go and planner.go; the
subsystem registry owns internal/actionlifecycle/ under api-contracts
with a dedicated path policy; the code-standards and contract source
pins follow the moved invariants; and the subsystem_lookup line-number
pin shifts with the api-contracts canonical-files list insertion.

This is the first slice of making the typed action lifecycle the only
autonomous execution route for Patrol, Assistant, and MCP.
2026-07-10 11:06:55 +01:00
rcourtman
11bf0c9e74 Fix native agent release lifecycle verification 2026-07-10 01:49:38 +01:00
rcourtman
33d318a29e Delete the unreachable adapter Execute/Rollback update path and the unused UpdateQueue
The only production consumer of the UpdaterRegistry is the plan endpoint
(GET /api/updates/plan); every real apply runs through the in-Go pipeline
in manager.go ApplyUpdate, with concurrency held by updateMu/updateInFlight.
The InstallShAdapter Execute/Rollback path (install.sh piping, rollback
binary download, health wait) and the UpdateQueue were never called outside
tests, so fixes made there silently did nothing. Adapters are now plan
providers only: the Updater interface keeps SupportsApply, PrepareUpdate,
and GetDeploymentType, pinned by the new registry proof in
internal/api/updates_test.go.

The orphaned fetchAndVerifyReleaseSignature helper goes with it; its
fail-closed sidecar tests now exercise the manager's
downloadAndVerifyReleaseSignature directly. The deployment-installability
sshsig invariant now names the manager pipeline as the only surface that
fetches release artifacts, and api-contracts, storage-recovery, and
agent-lifecycle pin the same plan-provider-only shape at their update
transport boundaries. Stale adapter references in build-release.sh,
validate-release.sh, and the installtests comments are updated to match.
2026-07-10 01:14:40 +01:00
rcourtman
255c7c23d4 Modernize Unified Agent lifecycle and platform support 2026-07-09 23:20:35 +01:00
rcourtman
8dda0b6efa Build releases once and promote verified candidates 2026-07-09 22:21:34 +01:00
rcourtman
7897a9131e Fix FreeBSD agent update recovery
Refs #1546
2026-07-09 20:36:58 +01:00
rcourtman
f8bbae2f34 Expose demo tailnet identity diagnostics 2026-07-09 20:32:43 +01:00
rcourtman
910418c3b2 Make stable patch releases unattended 2026-07-09 20:16:13 +01:00
rcourtman
2be167331d Harden demo SSH setup for IP targets 2026-07-09 17:06:52 +01:00
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