Files
pulse/docs
rcourtman 3c813bf793 Stop pin succession erasing an operator split (#2810)
## What

An operator split of a reporter from a sibling that reports the same
machine could be erased by pin succession. A source the operator split
(unlink or report-merge records the exclusion `(sibling's ID, source's
source-specific ID)`) pins the shared machine key on its own
source-specific ID while the sibling is present. With the sibling
absent, the source mints the sibling's ID, and pin succession read the
source's pin as that ID's earlier era. Applying the pair rewrote the
exclusion into one of the ID from itself, so the sibling's return merged
the two.

Unforced rebuild sequence {agent + Docker host, Docker host only, agent
+ Docker host}: 2, 1, 1 agents in 37 of 40 trials on `main`, 2, 1, 2 in
40 of 40 with this change.

## Change

`PersistIdentityPins` (`internal/unifiedresources/canonical_id_pins.go`)
now:

- refuses a succession whose retired ID the operator excluded from its
successor (the registry owns the check, beside the observed-ID check, so
a rebuild that could not read its decisions guards the split from the
exclusions it carried);
- drops the successions of one batch that would retire two IDs the
operator split from each other onto one successor
(`withoutSplitFanInLocked`; only each predecessor's first declaration
counts, as in both stores).

A split that pairs the retired ID with a third resource still follows
the succession. The stores are unchanged; the reporter-era skip from
#2800 and record-declared eras are unchanged.

## Boundary

With the sibling absent the split source is listed under the sibling's
ID, and an operator lock set on its candidate ID does not cover it until
the sibling returns. Before this change the lock was carried onto the
sibling's ID and the split erased; in the other pin-holder state the gap
already existed, and the reporter-era skip in #2800 accepts the same
boundary. The unified-resources contract records it, with the limits of
the check (chains through stale carried decisions, a split recorded
after the registry read its decisions, an already-recorded predecessor
counting toward a fan-in). Keeping a split reporter on its candidate ID
in the sibling's absence would close the gap but renames every currently
split reporter whose sibling is absent; that is a separate decision.

## Proof

`TestPinSuccessionKeepsASplitSourceApart` (both stores): key held by the
split source or by the sibling, a rebuild that cannot read its decisions
(with a control that records the succession through the same store), the
fan-in batch with controls (no split; a stored self-pair exclusion), the
narrowness control (a split of a superseded ID paired with a third
resource still follows), and the filter's own table. Mutation controls
run on pulse-dev: pair check removed, blanket rule, wrong pair, previous
exclusions not carried, fan-in filter not applied, self pair counted,
suppression when decisions were unreadable (with and without an
exclusion), later declarations weighed, whole group dropped, every batch
dropped. Each fails its intended subtests. Full
`internal/unifiedresources` and `internal/monitoring` suites pass on
pulse-dev on the rebased tree, `internal/alerts` on the tree before the
last rebase. `internal/api` there had two failures that are not this
change: `TestServerInfoEndpointReportsDevelopment` (the rsynced tree has
no `.git`) and `TestContainerBootstrapFailuresStopAndClean/hangup` (a
load flake: 5 of 5 alone, and the `configapi` package 2 of 2).
2026-10-10 15:54:14 +01:00
..
…
2026-10-05 21:53:41 +01:00
…
…
2026-10-05 21:53:41 +01:00
2026-10-05 21:53:41 +01:00

Pulse documentation

Start here for installation, platform setup, security, operations, and Pulse Intelligence. Commands, configuration keys, image names, API fields, and product identifiers remain untranslated in localized guides.

Start here

  • Install Pulse — signed Proxmox/Linux installation, Docker, Docker Compose, Kubernetes, and first-run setup.
  • Production deployment and security — least-privilege Proxmox setup, root-agent boundaries, discovery, supply-chain verification, plan limits, scale evidence, and a rollout checklist.
  • Upgrade from Pulse v5 — migration prerequisites, rollback, agent continuity, and post-upgrade checks.
  • Releases and update channels: choosing Stable or Preview, beta and RC expectations, and how releases are tested and promoted.
  • Configure Pulse — authentication, notifications, discovery, retention, and system settings.
  • Deployment models — data locations, lifecycle, and differences between supported deployment paths.
  • Troubleshooting and FAQ — common failures, diagnostics, and operator questions.

Localized getting started guides: Deutsch · Español

Platforms and agents

VMware vSphere support is early access. Current builds expose dedicated vSphere inventory and recovery context, but operators should validate the integration against their own vCenter before production use.

Monitoring and operations

Pulse Intelligence

Patrol watch-only analysis is available on Community with a local model or the operator's own provider. Investigation and governed fixes require the relevant Pulse Pro capabilities.

Security, privacy, and access

Plans and managed access

Pulse Cloud is not generally available. Ordinary self-hosted Pulse remains the primary installation path; MSP and Enterprise access are explicit commercial paths rather than defaults in self-hosted setup.

Development and reference

Detailed design notes and dated migration specifications may remain in this directory for maintainers, but they are not operator setup guides unless they are linked from the sections above.

Previous versions and migrations

Found a bug? Use the issue forms. For setup questions, use GitHub Discussions.