Commit Graph

194 Commits

Author SHA1 Message Date
rcourtman 3580a5ed6d Clarify storage topology and recovery guards 2026-05-14 20:51:32 +01:00
rcourtman 321f563a52 Surface blocked workload inventory sources
Show workload-capable source failures on Workloads and keep matching Proxmox host agents attached to their API source when inventory collection is blocked.
2026-05-14 00:22:18 +01:00
rcourtman ab62b46c1f Fix helm chart agent.enabled by routing through main pulse image
The chart's agent.image.repository defaulted to ghcr.io/rcourtman/pulse-agent,
an image that has never been published. publish-docker.yml only pushes
rcourtman/pulse; the Dockerfile defines an agent_runtime stage that
*could* be published but it isn't, and commit da7969fb4 from earlier in
this session removed the corresponding pulse-agent attestation
expectations — a clear signal the separate agent image was intentionally
dropped without updating the chart. Customers running
`helm install pulse pulse/pulse --set agent.enabled=true` were silently
hitting ImagePullBackOff on the agent DaemonSet.

Route the chart through the main rcourtman/pulse image instead. To make
that work without per-arch chart overrides, the runtime stage in the
Dockerfile now creates an arch-resolved /usr/local/bin/pulse-agent
symlink to the right /opt/pulse/bin/pulse-agent-linux-{amd64,arm64,armv7}
binary. The chart's agent.command default is /usr/local/bin/pulse-agent,
which overrides the server ENTRYPOINT and runs the pod as a unified
agent on whichever arch the node provides. agent.yaml renders the
command via toYaml so list values pass through cleanly.

KUBERNETES.md's DaemonSet example switches from the arch-hardcoded
/opt/pulse/bin/pulse-agent-linux-amd64 to the new arch-resolved path,
restoring multi-arch portability of the docs example.
validate-release.sh asserts the symlink exists, points at one of the
three supported Linux arch binaries, and is executable in the published
image. A new TestHelmAgentRuntimePointsAtRealImage pins the chart
defaults, the template wiring, the Dockerfile symlink, and the
validate-release.sh guard so the regression class can't quietly
resurface.

Governance: extend the helm-chart-release-runtime verification policy's
exact_files to include scripts/installtests/build_release_assets_test.go
(matching its existing pin set for related deployment-installability
policies); update the subsystem_lookup_test.py fixture that pins the
exact_files list; document the agent-image and pulse-agent symlink
contract in deployment-installability.md Extension Point 7.

Verified locally: `helm lint` passes; `helm template --set agent.enabled=true`
renders a DaemonSet with image rcourtman/pulse:6.0.0,
command ["/usr/local/bin/pulse-agent"], args ["--enable-docker", "--enable-host=false"].
End-to-end image build + agent DaemonSet smoke will run via helm_smoke
on the next release once rcourtman/pulse:6.0.0 is published.
2026-05-12 16:11:56 +01:00
rcourtman 4cf16ec9cb Stabilize summary chart SLOs 2026-05-12 14:40:55 +01:00
rcourtman 7c0f654253 Wire install.sh smoke gate into create-release.yml release pipeline
The smoke gate workflow exists from commit 065ebdb27 but until it is
called from create-release.yml it does not actually protect any release.
That is exactly the regression class that let rc.1 → rc.5 ship with a
broken install.sh: nothing in the release pipeline exercised the
documented secure-install flow against the published GitHub Release URL.

Wire install-sh-smoke.yml as a downstream workflow_call after
validate_release_assets succeeds. Gated on
historical_asset_backfill_only != 'true' since asset-backfill flows
re-upload to an already-published release and the smoke would just
re-confirm what hasn't changed.

Pre-install structural checks were verified locally against rc.5 — the
gate correctly fires the banner / agent-banner / --version handler
assertions against the broken release. The end-to-end container portion
(privileged systemd boot, install.sh execution, /api/health, /api/version
match) will run for the first time on the next release that publishes
through this workflow; existing retry loops on systemd readiness,
service activation, and health endpoint absorb transient runner flakes.

Add install-sh-smoke.yml to the deployment-installability canonical files
and to the release-promotion proof policy's match_files, and add
scripts/installtests/build_release_assets_test.go to that policy's
exact_files (matching the existing pin set for related policies in the
deployment-installability subsystem). Update subsystem_lookup_test.py
fixtures that pinned the exact_files list literally.

Pinned the create-release.yml wiring in build_release_assets_test.go
alongside the validate-release-assets wiring so the smoke step cannot
silently be unwired.

Document the gate's contract responsibilities in
deployment-installability Extension Point 2.
2026-05-12 11:44:04 +01:00
rcourtman b69c8c8007 Wire PULSE_RELAY_ENABLED and PULSE_RELAY_SERVER as real env overrides
These two env vars were documented as relay overrides in v6 docs since
March 18 (CONFIGURATION.md, RELAY.md, and the frontend-served doc copy)
but no code ever read them. Operators trying to bootstrap relay headlessly
saw no effect.

Implement them rather than remove the documentation. Headless and
container deployments now have a real path to enable relay and point it
at a private endpoint without going through Settings → Relay.

internal/relay/config_env.go:
  - ApplyEnvOverrides(*Config) mutates relay.Config in place.
  - PULSE_RELAY_ENABLED accepts true/false/yes/no/1/0/on/off (case-
    insensitive). Unrecognized values log a warning and leave the file
    value untouched — important so "unset" reads differently from
    "explicit false."
  - PULSE_RELAY_SERVER goes through the existing validateRelayServerURL
    check; invalid URLs log a warning and fall through.

internal/config/persistence_relay.go:
  LoadRelayConfig calls ApplyEnvOverrides after the file load and after
  the default-fallback when relay.enc is absent, so the env override
  applies on every load.

Tests cover unset / true / false / garbage-bool / valid-URL / invalid-URL
/ both-together / nil-config paths in the relay package, plus two
end-to-end tests in internal/config that prove the override flows through
LoadRelayConfig against a real persisted file and against the
missing-file default branch.

Restore the env-var docs with the correct default URL (the full
wss://relay.pulserelay.pro/ws/instance, not the bare hostname the
original aspirational table claimed) and add an explicit precedence note:
saving from the UI after an env override persists the env-effective state
to disk, so clearing the env alone does not revert.

Add internal/relay/config_env_test.go to the relay-runtime registry's
desktop-relay-runtime exact_files so the new code surface is proof-tracked.
Update the matching pin in subsystem_lookup_test.py. Extend the
relay-runtime contract Extension Point 3 to document the override
semantics LoadRelayConfig must satisfy.
2026-05-12 11:18:31 +01:00
rcourtman e38332de86 Keep Patrol evidence aligned with live findings 2026-05-08 11:08:53 +01:00
rcourtman b56428e8cf Promote Pulse Intelligence governed lane 2026-05-08 02:54:48 +01:00
rcourtman d2625c4dfb Persist Patrol settings with readiness handoff
Refs #1463
2026-05-07 19:26:00 +01:00
rcourtman d7b17a6a2d Add paid runtime attribution release gate 2026-05-07 18:58:05 +01:00
rcourtman 9d1fabef03 Gate Patrol readiness across runtime entrypoints
Refs #1463
2026-05-07 18:24:47 +01:00
rcourtman 371ce99694 Add Patrol runtime readiness contract
Refs #1463
2026-05-07 17:51:40 +01:00
rcourtman 9cbd3dcbc6 Fail closed malformed approval expiry state 2026-05-07 16:56:47 +01:00
rcourtman 812c86692d Route Assistant handoffs through model context 2026-05-07 03:00:58 +01:00
rcourtman 990f9fbc21 Show live approval state in Assistant handoff 2026-05-07 00:23:27 +01:00
rcourtman 75e3cb76fd Add structured Patrol investigation records 2026-05-06 16:31:51 +01:00
rcourtman 2f5aa20122 Add mock availability endpoint fixtures
Refs #1460
2026-05-06 14:08:03 +01:00
rcourtman d6ca8b12e6 Add agentless availability targets
Refs #1460
2026-05-06 10:35:34 +01:00
rcourtman e3c1dad256 Hide public demo admin reads 2026-05-04 09:14:09 +01:00
rcourtman c436e1a2a2 Add CLI fleet connection reads 2026-05-04 08:40:34 +01:00
rcourtman 5fbe723ad9 Add CLI action planning adapter 2026-05-04 00:05:21 +01:00
rcourtman b11f57ed62 Add API-first action planning endpoint 2026-05-03 23:51:54 +01:00
rcourtman d994a7a60d Resolve agent-ready operations target scope 2026-05-03 23:27:49 +01:00
rcourtman 4e2b62e89b Retire legacy Storage and Workloads filter helpers after FilterBar migration
Deletes files that no runtime path imports after the migration to
chip-based FilterBar:

  Storage's three-layer filter indirection:
  - StorageFilter.tsx (legacy filter shell)
  - StorageControls.tsx (subtab + filter pass-through wrapper)
  - useStorageFilterToolbarModel.ts (legacy active-filter / reset hook)
  - useStoragePageControlsModel.ts (sortDisabled + groupBy gating)
  - useStorageControlsModel.ts (subtab + node-filter wiring)
  - their tests

  Workloads filter state hook:
  - useWorkloadsFilterState.ts (replaced by inline FilterBar wiring;
    countActiveWorkloadsFilters / hasActiveWorkloadsFilters stay in
    workloadsFilterModel.ts)
  - its test

The StorageStatusFilter and StorageGroupByFilter type aliases that
StorageFilter.tsx exported fold into the existing canonical types in
storagePageState.ts (StorageStatusFilterValue) and storageModelCore.ts
(StorageGroupKey), keeping useStorageFilterState.ts alive without the
deleted shell.

PageControls.tsx and its companion FilterToolbar primitives stay in
the tree because the alert-history filter card and the Kubernetes
deployments drawer still consume them. The canonical claim shifts:
FilterBar is the chip-based shell for catalog-driven page filters
(Infrastructure, Workloads, Storage, Recovery Protected items, Recovery
events). PageControls remains for non-migrated surfaces.

Subsystem contracts and registry updated:
- frontend-primitives.md: adds FilterBar files to Canonical Files;
  describes FilterBar as the canonical page-level filter shell for
  catalog-driven resource lists; PageControls described as the legacy
  fallback for non-migrated surfaces.
- performance-and-scalability.md: drops useWorkloadsFilterState
  references; describes Workloads' FilterBar / viewOptionsTrailing
  composition.
- storage-recovery.md: replaces "PageControls toolbar rail" prose with
  FilterBar / viewOptionsTrailing for both Storage and Recovery events;
  notes the legacy three-layer indirection retired.
- registry.json: drops deleted file paths from owned_files,
  verification.exact_files, and verification.path_policies entries.
- canonical_completion_guard_test.py + subsystem_lookup_test.py: drop
  deleted file paths from hard-coded fixtures so the governance helper
  tests track the registry.
- SharedPrimitives.guardrails.test.ts: adds regression assertions that
  StoragePageControls no longer imports the deleted shells.
2026-05-01 10:51:22 +01:00
rcourtman daf825dee6 Remove customer commercial analytics wrappers 2026-04-30 11:46:16 +01:00
rcourtman 0bbba3b818 Restrict commercial metrics reporting access 2026-04-30 10:00:35 +01:00
rcourtman 0714fec8af Guard diagnostics against internal analytics 2026-04-30 09:41:16 +01:00
rcourtman b413a56d85 Canonicalize Docker Podman infrastructure copy 2026-04-30 00:20:59 +01:00
rcourtman cbc34e7302 Canonicalize Docker and Podman token copy 2026-04-30 00:04:35 +01:00
rcourtman 72fe17a5d9 Extend paid claim proof boundary 2026-04-29 23:40:32 +01:00
rcourtman 65fe50ad5b Canonicalize remaining table shells 2026-04-29 23:15:12 +01:00
rcourtman f6bf4779be Canonicalize platform drawer table shells 2026-04-29 20:41:31 +01:00
rcourtman c743a231b8 Retire dashboard landing surface 2026-04-29 16:25:09 +01:00
rcourtman 535e623ad0 Surface resource action audit history 2026-04-29 14:48:02 +01:00
rcourtman 8fa84b7ad1 Polish dashboard problem resource wording 2026-04-26 13:15:30 +01:00
rcourtman a2c101379a Guard stable updater from prerelease tags
Refuse prerelease-shaped tags and explicit GitHub prerelease responses in the unattended stable updater before installer invocation.

Add installability tests and proof routing for the auto-update prerelease refusal guard.
2026-04-25 23:49:27 +01:00
rcourtman 9bd67fe2c1 Add fleet governance projection 2026-04-25 23:41:38 +01:00
rcourtman 97bf4af36d Add platform support floor projection 2026-04-25 23:01:01 +01:00
rcourtman acbed82d75 Add governed action audit preflight 2026-04-25 22:35:19 +01:00
rcourtman 175f8b4bf1 Add relationship-aware resource timelines 2026-04-25 22:07:57 +01:00
rcourtman c8d72cf06f Align AI data handling disclosures 2026-04-25 21:44:26 +01:00
rcourtman fc5325ab80 Add resource data handling settings surface 2026-04-25 20:23:40 +01:00
rcourtman d57987d48d Govern Pulse Cloud control plane ownership 2026-04-23 22:54:57 +01:00
rcourtman a5687cd22e Formalize v6 paid-surface classification 2026-04-23 14:53:41 +01:00
rcourtman 48e4ec818c Make self-hosted settings plan-owned 2026-04-22 19:49:50 +01:00
rcourtman dad0529a2f Domain-separate relay channel HKDF derivation 2026-04-22 15:04:09 +01:00
rcourtman c0ac251316 Require target-organization approval for org shares 2026-04-22 09:16:40 +01:00
rcourtman 70b91759d2 Harden secure local key file handling 2026-04-22 05:13:01 +01:00
rcourtman f7c1d9b629 Require accepted org invitations and stable runtime capabilities 2026-04-22 03:06:22 +01:00
rcourtman 669908acd4 Normalize workloads and recovery page headers 2026-04-21 17:51:33 +01:00