Pulse/scripts
courtmanr@gmail.com 5c1c89a363 Guard auto-update asset staging and migrate stale update units
Adversarial review of 9db25ba60 found four residual defects in the
auto-update asset install, plus a doc line it left contradicting itself.

- install_auto_update_assets copied the bundled helper into the staged
  mktemp file with an unchecked cp, and both call sites invoke the
  function under `if !`, which suppresses errexit for its whole body. A
  failed copy (ENOSPC, EIO) fell through to
  configure_auto_update_script_repo, whose awk emits a lone GITHUB_REPO=
  line for empty input, so a shebang-less one-line stub replaced the
  working helper with a "script" that only ever exits 0 - silently
  disabling unattended updates. Check the cp, and refuse the swap unless
  the staged helper is non-empty and starts with #!.
- Both units were rendered with a bare truncating `cat > "$unit"` whose
  status was never checked, and the function's last statement is
  safe_systemctl daemon-reload, which returns 0 by design. A failing
  write truncated a working unit and still reported success. Render each
  unit to ${path}.tmp and commit it with a checked rename, so a failure
  leaves the installed unit byte-identical.
- The widened ReadWritePaths could not reach deployed boxes: the unit
  that grants the write access is itself the file that has to be
  rewritten, and on an existing install the sandbox running the
  installer excludes /etc/systemd/system and /usr/local/bin (EROFS). The
  Go update pipeline cannot carry it either - pulse.service runs as
  User=pulse with its own ProtectSystem=strict over the install and
  config dirs only. So probe each destination directory up front and,
  when one is blocked, re-exec this already-signature-verified installer
  through systemd-run with a new internal --repair-auto-update-units
  entry point: PID 1 forks the transient unit, so it starts in the host
  mount namespace instead of inheriting the sandbox. The installer is
  copied into the install dir first because the calling unit's
  PrivateTmp=yes hides its /tmp copy from PID 1. The escape needs root
  and systemd-run, and never recurses.
- Keep the ReadWritePaths entries as directory grants: every write now
  commits with a rename from a sibling staging file, and rename needs
  write access on the containing directory, so the file-level entries
  systemd would otherwise accept cannot work. Document the tradeoff in
  the unit and the subsystem contract instead.

The deployment-installability contract still claimed the update sandbox
leaves "only the install dir, config dir and /tmp" writable, which the
paragraph the same file gained in 9db25ba60 contradicts; the same stale
rationale had been copied into two test comments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 11:56:52 +01:00
..
dev
eval
installtests Guard auto-update asset staging and migrate stale update units 2026-07-28 11:56:52 +01:00
intelligence_lab Document RG-06 autonomy proof runner 2026-07-13 18:32:56 +01:00
lib backend and governance: MCP contract, agent capabilities, API, and release-control 2026-06-23 17:26:15 +01:00
lint-fixer
release_control Sync guard test snapshots with newly registered proof files 2026-07-28 11:19:29 +01:00
tests Guard auto-update asset staging and migrate stale update units 2026-07-28 11:56:52 +01:00
.go-version Modernize Unified Agent lifecycle and platform support 2026-07-09 23:20:35 +01:00
audit-private-boundary.sh
backfill-release-assets.sh Add historical release asset backfill workflow 2026-04-22 17:25:58 +01:00
build-release.sh Allow RCs while Windows signing is pending 2026-07-10 23:12:12 +01:00
bundle.manifest
bundle.sh
check-bench-regression.sh
check-workflow-dispatch-inputs.py fix(release): restore release helper executable bits 2026-03-26 12:26:55 +00:00
check_telemetry_schema_parity.py Add privacy-safe telemetry lifecycle and outcome signals 2026-07-23 01:10:38 +01:00
clean-mock-alerts.sh Route mock alert cleanup through managed runtime 2026-03-24 15:49:29 +00:00
cleanup.sh
cloud-backup.sh
com.pulse.hot-dev.plist.template
conformance-smoke.sh
demo_public_browser_smoke.cjs Harden demo public browser smoke readiness 2026-04-12 17:07:50 +01:00
dev-check.sh Switch script-reference integrity test from rg to git grep for portable CI 2026-05-12 00:30:43 +01:00
dev-deploy-agent.sh Harden dev agent deploy SSH host verification 2026-04-22 11:41:50 +01:00
dev-launchd-setup.sh Prefer managed runtime controls in launchd helper 2026-03-24 16:01:14 +00:00
dev-launchd-wrapper.sh Supervise launchd dev runtime through hot-dev-bg 2026-03-24 15:39:55 +00:00
docker-build.sh
ensure_test_assets.sh
exclusive-lock.mjs
generate-pulse-intelligence-docs.go backend and governance: MCP contract, agent capabilities, API, and release-control 2026-06-23 17:26:15 +01:00
generate-release-notes.sh Add in-app release highlights 2026-07-13 18:30:29 +01:00
generate-self-hosted-feature-catalog.go Format generated self-hosted feature catalog with prettier in the generator 2026-07-27 11:58:05 +01:00
generate-types.go feat(assistant): mid-turn steering of the running response 2026-07-12 23:01:40 +01:00
hot-dev-bg.sh backend and governance: MCP contract, agent capabilities, API, and release-control 2026-06-23 17:26:15 +01:00
hot-dev.sh Build canonical Patrol attention workbench 2026-07-19 15:11:01 +01:00
install-container-agent.sh Restore Docker agents to Hosts inventory 2026-07-23 22:06:56 +01:00
install-docker.sh Prepare v6.2.0-rc.1 release 2026-07-27 14:08:29 +01:00
install-go-toolchain.sh Modernize Unified Agent lifecycle and platform support 2026-07-09 23:20:35 +01:00
install-mcp.ps1 Stop install-mcp scripts from linking to GitHub blob/main docs 2026-05-11 23:58:45 +01:00
install-mcp.sh Stop install-mcp scripts from linking to GitHub blob/main docs 2026-05-11 23:58:45 +01:00
install.ps1 Align Windows agent state with the installer 2026-07-19 19:41:57 +01:00
install.sh Fix Proxmox registration for host-token installs 2026-07-28 11:21:14 +01:00
package-helm-chart.sh
patrol_e2e_matrix.sh
pulse-auto-update.sh Fix auto-update leaving service down after installer failure 2026-07-27 09:38:37 +01:00
release_asset_common.sh Fix release key helper module path 2026-05-04 09:44:41 +01:00
release_candidate_manifest.py Build releases once and promote verified candidates 2026-07-09 22:21:34 +01:00
release_ldflags.sh Require signed unified agent release assets 2026-04-22 02:00:29 +01:00
release_update_key.go Fix v6 demo release signing key deployment 2026-05-05 21:40:14 +01:00
remerge-parallel.sh
render_installers.go Fix RC3 backend release blockers 2026-05-01 21:36:28 +01:00
repo-boundary-paid-surface.allowlist
run_cloud_public_signup_smoke.sh Add Pulse Cloud public signup smoke 2026-04-23 23:09:10 +01:00
run_demo_public_browser_smoke.sh Add public browser smoke proof to demo workflows 2026-04-11 13:50:00 +01:00
run_hosted_staging_smoke.sh Auto-select hosted staging tenant 2026-04-15 12:23:57 +01:00
session-handoff.sh
standalone.manifest
sync-production-config.sh
sync_chart_release_metadata.py fix(deploy): pin docs links to release refs 2026-03-28 21:32:11 +00:00
telemetry_adoption_report.py Measure verified telemetry outcomes 2026-07-27 10:15:48 +01:00
test-vm-disk.sh
toggle-mock.sh fix(mock): backfill the metrics store in mock mode so reports get real history 2026-06-10 21:25:02 +01:00
trigger-release-dry-run.sh Record v6.1.0 unsigned Windows exception 2026-07-22 15:37:48 +01:00
trigger-release.sh Record v6.1.0 unsigned Windows exception 2026-07-22 15:37:48 +01:00
trigger-stable-patch.sh Fix stable patch workflow dispatch input types 2026-07-23 13:31:31 +01:00
uninstall-sensor-proxy.sh Prepare v6.0.0 release candidate 2026-06-04 14:07:14 +01:00
validate-published-release.sh Publish signed release-packet SBOM assets 2026-04-22 16:49:29 +01:00
validate-release.sh Delete the unreachable adapter Execute/Rollback update path and the unused UpdateQueue 2026-07-10 01:14:40 +01:00