Commit graph

105 commits

Author SHA1 Message Date
rcourtman
255c7c23d4 Modernize Unified Agent lifecycle and platform support 2026-07-09 23:20:35 +01:00
rcourtman
c0ac0762da Fix security scan findings
Harden proxy-auth admin role checks, metrics listener exposure, Teams webhook escaping, and dependency lockfiles.
2026-07-01 09:55:35 +01:00
rcourtman
dd5d6b9ad1 Use product language for Patrol control telemetry disclosure 2026-06-27 09:47:39 +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
d341f79a94 Fix hot-dev Vite dependency optimization 2026-06-15 09:08:54 +01:00
rcourtman
566c5b9da4 Add lab-agent hot-dev mode 2026-06-14 09:55:56 +01:00
rcourtman
47dfb6c171 Add localized public docs entry points 2026-06-13 08:07:46 +01:00
rcourtman
11464b4df8 Clarify agent upgrade and notification docs
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
2026-06-12 19:26:26 +01:00
rcourtman
b179b1782c Stabilize Proxmox guest Docker inventory 2026-06-12 12:10:54 +01:00
rcourtman
55db13fc06 Fix CI test drift and SSE idle race
Refs Build and Test failures on pulse/v6-release.
2026-06-11 15:48:00 +01:00
rcourtman
1a42011724 Verify Pulse restarts after an interactive update; don't leave it silently stopped (#1323)
Finishes the deferred half of the v5->v6 parity fix for #1323 (the
pulse-auto-update.sh half landed in 672e81985). The interactive install.sh
update/reinstall flow stopped a running Pulse then called start_pulse, which
tolerates a silent start failure (common on unprivileged LXC) by printing a note
and returning 0 — leaving Pulse stopped under an "installation completed!" message.

- stop_pulse_for_update records whether Pulse was running before the update.
- start_pulse, only when Pulse was running before (PULSE_WAS_ACTIVE), no longer
  accepts a silent start failure: it verifies the service became active
  (wait_for_service_active, 20s), retries one explicit start, and surfaces a clear
  error + diagnostics if it still will not come up. Fresh installs are unchanged
  (the flag stays false, so the reassuring container note is kept).
- Wired into all three update/reinstall sites; added a BASH_SOURCE guard so the
  installer's functions can be unit-tested without running the installer.

Scope: fixes the #1323 'restart silently failed' case. Does NOT add a binary
rollback (download_pulse deletes bin/pulse.old right after the swap) — a
bad-release rollback is a separate concern.

Test: scripts/tests/test-install-update-resilience.sh (sources install.sh, stubs
systemctl, asserts was-active capture + retry + clear error). Go installtests +
bash -n confirm the guard does not change installer execution.
2026-06-09 15:05:08 +01:00
rcourtman
672e819850 Verify service restart in unattended auto-update; roll back if down (#1323)
Back-port the pulse-auto-update.sh half of v5 fix 0f2982ce3 to v6. After a
verified update, if Pulse was running beforehand, wait_for_service_active
polls up to 20s, tries one explicit start, and if it still does not come
back up restores the backup binary/VERSION, restarts, and returns failure
instead of leaving Pulse stopped (common on unprivileged LXC where the
installer's restart silently fails). Adds a BASH_SOURCE guard so the
script can be sourced, plus scripts/tests/test-pulse-auto-update.sh.

Note: the install.sh start_pulse STOPPED_PULSE_SERVICE guard (interactive
installer path) still needs the stop-tracking infrastructure wired into
v6's update flow; tracked as a follow-up.
2026-06-04 09:07:24 +01:00
rcourtman
5afe1845cf Report target RC telemetry signal coverage 2026-06-01 17:59:28 +01:00
rcourtman
c61bd1c554 Show telemetry deep-signal sources by version 2026-06-01 17:50:22 +01:00
rcourtman
a13218a39a Recover managed mock-mode restart handoffs
Adopt replacement managed hot-dev supervisors during listener waits and let mock-mode toggles continue only when the browser entrypoint proves the requested runtime state after a non-clean restart.
2026-06-01 08:33:18 +01:00
rcourtman
82ce72f20b Stabilize script smoke checks 2026-05-28 12:55:33 +01:00
rcourtman
226f0bdf72 Report restricted hot-dev probes as unavailable
Render managed runtime status probes as unavailable instead of 000 when a restricted shell can see loopback listeners but cannot run local HTTP probes. Refs architecture post-RC canonicalization follow-up.
2026-05-21 15:51:40 +01:00
rcourtman
a77420e88a Make hot-dev local-only by default
Keep the managed dev runtime on loopback unless PULSE_DEV_LAN=true is set, so installed LAN agents cannot accidentally attach to a developer session. Harden managed status checks for restricted local shells. Refs architecture post-RC canonicalization follow-up.
2026-05-21 15:26:53 +01:00
rcourtman
bc2adac8b5 Stabilize dev runtime and complete PMG read-state migration
Refs architecture post-RC canonicalization follow-up.
2026-05-21 15:15:23 +01:00
rcourtman
bce500732a Stabilize managed dev runtime recovery 2026-05-21 13:36:36 +01:00
rcourtman
9ef4e588b7 Add TrueNAS services and stabilize dev startup 2026-05-21 12:08:25 +01:00
rcourtman
391cea1b13 Fix managed hot-dev LAN browser binding 2026-05-19 09:08:32 +01:00
rcourtman
484d9aab87 Fix dev backend binding for local agent reports
Ensure hot-dev reconciles loopback BIND_ADDRESS when local agent URLs point at this machine.
2026-05-17 14:20:17 +01:00
rcourtman
702fc5aeb5 Stabilize hot-dev backend startup recovery 2026-05-17 09:54:11 +01:00
rcourtman
7938f28de4 platforms: scale K8s clusters to 3 + fix VMware storage source matching
Two specific platform-page quality issues from the audit:

1. **/kubernetes/overview only had 1 cluster.** Bumping the K8s cluster
   count past 1 had been deferred because the prior
   monitor-broadcast equivalence test compared the raw snapshot count
   to the broadcast count exactly, and broadcast's
   `coalesceBroadcastResources` + second-pass coalesce inside
   `convertResourcesForBroadcast` legitimately drops merge candidates
   that the raw snapshot keeps. Switch the test to compare against
   the canonical snapshot count within a ±5% tolerance so future
   fixture bumps stay green without loosening any of the test's
   exact-name and exact-identity assertions. With that in place, bump
   `K8sClusterCount` 1 → 3 in `internal/mock/generator.go`,
   `scripts/toggle-mock.sh`, and the matching
   `scripts/tests/test-toggle-mock.sh` so the canonical mock estate
   ships with production + staging + edge clusters end-to-end.

   Live mock survey: k8s-cluster: 3, k8s-deployment: 42, pod: 120,
   plus 15 K8s nodes merged onto their agent hosts.

2. **/vmware/storage looked empty under platform-page chrome.**
   `resolveStorageSourceKey` was reading only `storage.type` (the
   on-disk technology like `vsan`, `vmfs`, `nfs41`, `zfs-pool`) and
   never consulted `storage.platform` (the canonical platform key
   like `vmware-vsphere` or `truenas`). Source filter chip options
   were therefore generated as `vsan`, `vmfs`, `nfs41`, etc., and
   `forcedSourceFilter='vmware-vsphere'` had nothing to match.
   Prefer the canonical `storage.platform` tag when set, so VMware
   datastores group under `vmware-vsphere`, TrueNAS pools group under
   `truenas`, PBS datastores under `proxmox-pbs`, etc., for both the
   chip options and the embedded platform-page filter.

Browser verification (Playwright, chromium, live mock-mode dev runtime):
- 9 tests pass.

Targeted vitest:
- `src/features/storageBackups` + `src/utils/__tests__/sourcePlatforms.test.ts` +
  `src/components/Storage/__tests__/storageSourceOptions.test.ts` (31
  files / 141 tests) green.

Go tests:
- `go test ./internal/mock/... ./internal/monitoring/... ./internal/vmware/...`
  all green.

Contracts updated:
- `monitoring.md` Shared Boundaries: new K8s multi-cluster default,
  ±5% tolerance for the broadcast equivalence assertion.
- `deployment-installability.md` Shared Boundaries: toggle-mock.sh /
  DefaultConfig parity updated for the K8sClusterCount=3 baseline.
2026-05-16 11:43:41 +01:00
rcourtman
cef057943a mock(fixtures): scale default fixture sizes to a mature SMB homelab
Mock pages were sparse: 3 Proxmox nodes × 3 VMs × 3 LXCs, 2 Docker
hosts × 5 containers, 1 K8s cluster × 3 nodes × 10 pods × 4
deployments. That populated platform pages with handfuls of rows
rather than table density that exercises sorting, grouping, drawers,
and responsive layout.

Bump `internal/mock/generator.go::DefaultConfig` to target a mature
small-to-mid homelab / SMB environment:

- NodeCount: 3 → 5 (matches the curated demo scenario's pve1..pve5
  regional naming)
- VMsPerNode: 3 → 6
- LXCsPerNode: 3 → 8
- DockerHostCount: 2 → 5
- DockerContainersPerHost: 5 → 14
- GenericHostCount: 2 → 4
- K8sClusterCount: 1 (unchanged; the curated demo and broadcast
  coalesce tests assume a single cluster identity)
- K8sNodesPerCluster: 3 → 5
- K8sPodsPerCluster: 10 → 40
- K8sDeploymentsPerCluster: 4 → 14

Resource survey under the new defaults (live mock backend):

- TOTAL 307 unique resources (was ~50-100)
- app-container: 75, storage: 55, system-container: 44, pod: 40,
  vm: 31, physical_disk: 19, agent: 15, k8s-deployment: 14,
  docker-host: 5, network-endpoint: 5, pmg: 2, pbs: 1, k8s-cluster: 1

Platform pages now feel populated under mock mode:
- /docker/overview: 5 hosts (was 2)
- /docker/containers: 75 containers (was 13)
- /kubernetes/nodes: 5 (was 3)
- /kubernetes/pods: 40 (was 10)
- /kubernetes/deployments: 14 (was 4)

`internal/mock/demo_scenarios.go` extended to season `local`,
`local-zfs`, and per-node iso/service-pool storage names for pve6 and
beyond, so future NodeCount bumps don't regress the curated demo into
generic "service-pool" labels (a test guard explicitly forbids that
alias). A new `TestDemoScenarioStorageNamingHandlesScaledNodeCount`
covers the scaled-NodeCount path.

`internal/monitoring/monitor_unified_state_test.go` updated to compare
the broadcast count against the coalesced snapshot count rather than
the raw snapshot count — the broadcast path merges resources that
share a canonical host key (K8s nodes onto linked agent hosts), so
larger fixture sizes legitimately produce more merge candidates, and
the prior raw-equality assertion would have broken on any future
fixture growth too. The test still asserts every canonical name and
mock identity it checked before.

`scripts/toggle-mock.sh` (`mock_default_entries`) and the matching
`scripts/tests/test-toggle-mock.sh` assertions are aligned with the
new defaults so `npm run mock:edit` and per-dev `.env` seeding match
the canonical baseline.

Contracts updated:
- `monitoring.md` Shared Boundaries: records the new DefaultConfig
  target sizes and the requirement that demo-scenario seasoning stay
  aligned with NodeCount changes.
- `deployment-installability.md` Shared Boundaries: records that
  `mock_default_entries()` in toggle-mock.sh must stay aligned with
  `internal/mock.DefaultConfig` so CLI/toggle/runtime mock densities
  never drift apart.

Targeted Go tests:
- `go test ./internal/mock/...` green
- `go test ./internal/monitoring/...` green

Playwright (chromium, live mock-mode dev runtime):
- 9 tests, all pass; populated assertions now hit dense tables (5
  hosts, 14+ containers, 40 pods, etc.).

Known remaining fixture gaps (canonical adapter, not config):
- VMware fixture inventory in `internal/vmware/fixtures.go` is
  hardcoded at 4 hosts / 6 VMs / 4 datastores; not scaled in this
  commit.
- TrueNAS fixture inventory in `internal/truenas/fixtures.go` is
  similarly hardcoded; not scaled in this commit.
2026-05-16 08:16:00 +01:00
rcourtman
fbcb77d635 Stabilize managed hot-dev startup 2026-05-14 21:40:07 +01:00
rcourtman
8554754f3e Harden managed dev backend recovery
Fix the local hot-dev backend monitor so a missing Pulse process is counted safely under pipefail, keep backend launch stderr in the debug log, and govern the new runtime helper with focused smoke coverage.
2026-05-14 09:19:12 +01:00
rcourtman
ec72977d3e Skip runtime-defaults raw-node TS imports when integration node_modules absent 2026-05-12 01:14:41 +01:00
rcourtman
8e49e68393 Pre-check integration node_modules before root-playwright wrapper assertion 2026-05-12 01:05:54 +01:00
rcourtman
216b3cae38 Skip root-playwright wrapper check on any tsx/playwright eval failure 2026-05-12 00:57:24 +01:00
rcourtman
86f9159bae Skip root-playwright wrapper check when @playwright/test isn't installed 2026-05-12 00:49:21 +01:00
rcourtman
659018ed28 Skip acceptance-doc wording-pin when the working-draft doc isn't checked out 2026-05-12 00:40:05 +01:00
rcourtman
96660e7586 Switch script-reference integrity test from rg to git grep for portable CI 2026-05-12 00:30:43 +01:00
rcourtman
cd2abe879e Fix mock mode legacy sidecar drift 2026-05-05 15:12:31 +01:00
rcourtman
c7164c2906 Clarify Relay mobile handoff paid copy 2026-04-30 13:18:04 +01:00
rcourtman
99e65d7e68 Rename retired trial acquisition proof assets 2026-04-28 18:38:10 +01:00
rcourtman
0b52968cd0 Retire self-hosted trial start route 2026-04-28 15:05:58 +01:00
rcourtman
c51708000f Tighten unified agent hardening proof 2026-04-23 23:37:25 +01:00
rcourtman
88683cc32f Add Pulse Cloud public signup smoke 2026-04-23 23:09:10 +01:00
rcourtman
a442eb6bda Normalize hot-dev auth defaults 2026-04-22 16:28:52 +01:00
rcourtman
b666d131b0 Migrate Docker integrations to maintained Moby modules 2026-04-18 11:40:38 +01:00
rcourtman
35429774b4 Probe /api/health in hot-dev backend monitor
The supervisor's backend health monitor in scripts/hot-dev.sh only
checked whether a `./pulse` process existed via pgrep. If the Go binary
hung, panicked into recovery without exiting, or failed to bind :7655
while the process stayed alive, the monitor saw a healthy process count
and never restarted, leaving the dev frontend talking to a dead listener.
Hit that twice in one session.

Add an HTTP probe of /api/health on the dev port. After two consecutive
5s polls where the process exists but /api/health is unreachable, kill
the process and restart the same way the dead/duplicate branches do.
Cut the poll interval from 10s to 5s so the worst-case unresponsive
window is ~10s instead of ~30s. Bring deployment-installability into
line by naming alive-but-unresponsive recovery as part of the dev-runtime
orchestration boundary, and cover the new branch with static-source
assertions in scripts/tests/test-hot-dev-bg.sh.
2026-04-18 10:56:33 +01:00
rcourtman
ba9589f091 Fix hot-dev mock mode env contract 2026-04-17 20:49:36 +01:00
rcourtman
be3c1535c6 Harden telemetry privacy reporting contract 2026-04-14 15:06:37 +01:00
rcourtman
53bf37a8b2 Add windowed telemetry adoption snapshots 2026-04-14 11:16:11 +01:00
rcourtman
58e67c7b19 Canonicalize usage-data telemetry reporting 2026-04-14 11:05:10 +01:00
rcourtman
12294b587e Keep embedded demo assets in sync 2026-04-12 14:33:02 +01:00
rcourtman
d92ce0c54b Anchor trial retry-after UI proof 2026-04-10 23:58:54 +01:00
rcourtman
c54b245bed Tighten hosted trial contract anchors 2026-04-10 22:46:02 +01:00