The complete installer suite exposed a stale assertion requiring a beta.1 comparison after the reviewed changelog correctly named its actual v6.5.0 base. Keep the existing packet, signing, installer, rollback and compatibility checks, and require both the truthful stable-based introduction and matching changelog heading.
Contract-Neutral: Test-only correction for the unchanged, already-recorded beta.2 changelog range; no release or runtime contract changes.
Change-source: pulse-maintainer
Bind removal guidance to checked NAS quiescence and boot retirement instead of retired installation markers. Model DSM hard-link semantics through real exclusive link syscalls so macOS contract jobs no longer depend on GNU ln, retaining raced-directory adverse controls and every existing manager/recovery assertion.
Contract-Neutral: Tests only; production removal, documentation and teardown contracts are unchanged.
Change-source: pulse-maintainer
Rebind its old next-platform sentinel and include the production NAS selector. The fixture otherwise reaches unrelated runtime cleanup and correctly refuses a non-fixture path. Keep that filesystem guard and every existing DSM safety assertion unchanged.
Change-source: pulse-maintainer
Require the actual NAS quiescence/retirement caller rather than the removed best-effort autorun cleanup. Preserve Upstart exclusion from SysV while requiring the NAS exclusion too. No manager or process safety control is removed.
Change-source: pulse-maintainer
The closed signal and server doubles record the current boot/process state without changing outcomes. Require exact boot absence before both signals and complete quiescence at the server boundary, so a future ordering regression cannot pass on final state alone.
Change-source: pulse-maintainer
A go shell can hold later launches in memory after its boot file changes. Treat that live mixed-purpose owner as unknown rather than signalling it or inferring quiescence from the edited file. Require the actual-caller refusal control alongside the existing NAS suite.
Change-source: pulse-maintainer
The renderer heredoc contains nested shell functions. Extract through its own EOF and outer closing brace so the real private process control executes the complete producer; retain renderer diagnostics on failure.
Change-source: pulse-maintainer
Retire only exact Unraid and QNAP boot entries before checked watchdog-first process termination and same-instance server removal. Preserve unrelated boot owners and refuse unknown, partial or concurrent state without erasing credentials or restarting. Exercise the complete uninstall caller and generated private watchdogs.
Change-source: pulse-maintainer
A missing SCRIPT path or empty COMMAND target cannot establish that a task is unrelated or absent. Retain recovery before any task or service mutation when those fields are unavailable. Add three actual-caller adverse controls to the mandatory sixteen-method hook and both owning contracts.
Change-source: pulse-maintainer
Disable and independently verify every exact owned middleware activation task before systemd stop and server removal. Close task, unit and process state after the full stop and after task deletion, retaining recovery on refusals or concurrent changes without restarting. Ordinary Linux state directories are not appliance identity. Register all fifteen actual-function/full-caller controls and update both owning contracts in this coherent candidate.
Change-source: pulse-maintainer
The first beta's release workflow failed twice in backend_tests:
TestHostAgentCredentialFileHandoff, added on 2026-10-11 and so new to
every release job, compiles pulse-agent itself and was killed at exactly
180s with "build agent from this source: signal: killed".
The release runner starts each API shard with a small pinned GOMAXPROCS,
and the test's child compiler inherits it. A cold agent build is about
250 CPU-seconds, so under the pin it serializes past the test's fixed
three-minute limit. The release job also has no Go build cache, and the
race-enabled test binary the runner compiles does not warm this plain
build. Pull request jobs keep a warm cache, which is why the test passed
there.
Reproduced on pulse-dev with the shard's conditions, a prebuilt test
binary, GOMAXPROCS=1 and an empty cache: the test fails at 180.02s with
the identical message. With the agent built once beforehand, unpinned, in
99s, the same pinned run passes in 16s.
Build the agent once in the runner, after compiling the test binary and
before any shard starts, with the full CPU count. The runner test pins
that order so the warm-up cannot drift after the shards, and the contract
records why. Against the previous runner the pin fails with the expected
message. The release preflight and policy suites pass.
Contract-Neutral: Release test runner ordering only; no published artifact, tag, signing, install or customer contract changes.
Inline and command-double changes did not establish cleanup on the retained race refusal. Register only the non-credential manual temporary with the existing installer trap and execute that exact trap in the confined caller controls. Never register the credential-bearing staged job backup for automatic deletion. All retention, no-clobber, refusal and native obligations remain intact.
Change-source: pulse-maintainer
The retained race refusals still left manual temporary files after the command-double change. Check write, permission and atomic link operations individually rather than relying on the grouped chain to reach cleanup. Keep concurrent files/directories and all credentials intact; the same mandatory race assertions remain. Matching Go1.26.9 is now actually observed and the complete installer suite remains required.
Change-source: pulse-maintainer
The two race controls retained private manual temporary files because the command double exited before the production failure handler. Exact confined traces show that exit boundary. Capture and return the real external ln exit explicitly, preserving production cleanup and every file/directory race assertion. No product code, safety assertion, method count or deadline changes.
Contract-Neutral: Faithful closed-model external exit observation only; no runtime or contract delta.
Change-source: pulse-maintainer
The retained fourth proof stopped at a test-double argument refusal before the intended prior-source race. Execute both legitimate ln argv forms unchanged inside the private fixture; current file/directory preservation still requires exact-target non-clobbering semantics. No product change, safety assertion, method count or deadline is weakened.
Contract-Neutral: Transparent closed-model command arguments only; no runtime or contract delta.
Change-source: pulse-maintainer
Extend the existing no-clobber method with file and directory creation at restoration, not only before its initial path check. The real private-file operations must retain the original staged inode and every credential, never overwrite or write inside a concurrent target. Product code, method count, deadlines and native obligations are unchanged.
Contract-Neutral: Closed-model race coverage only; no runtime or contract delta.
Change-source: pulse-maintainer
A pathname absence check followed by mv could overwrite a concurrent root-created job. Use exact-target non-replacement links for override creation and config restoration; directory races also refuse without creating nested artifacts. Confined concurrent-file/directory controls are mandatory. Partial activation is never restarted and conflicting staged recovery is never discarded.
Change-source: pulse-maintainer
The first exact proof retained two fixture failures: timeout executes an external initctl rather than a shell function, and the source-order assertion unintentionally included later install code. Remove the actual model binary for its missing-tool control and bound the assertion to uninstall. Add an explicit concurrent-config/no-clobber recovery verdict; product code and safety deadlines are unchanged.
Change-source: pulse-maintainer
Treat DSM6 Upstart and stale DSM7 jobs through their actual manager, not SysV or late best-effort cleanup. Keep trusted job state and credentials on refused, unknown or partial observations; require effective manual activation and observed stopped/absent processes before remote removal and local erasure. Stage the original config until absence is confirmed, restore without restart on failure, and preserve non-clobbering recovery. Mandatory production-function/caller controls retain every refusal and timeout boundary. This is confined source repair, not native Linux/Windows or whole-issue acceptance.
Change-source: pulse-maintainer
The second beta's preparation pull request failed Backend tests
(TestCurrentPrereleasePacketTracksInstallMetadata): the changelog the
release metadata tool wrote said it describes the changes since
v6.6.0-beta.1, and the test expected v6.5.0. previousPrereleaseVersion
only understood -rc.N, so for beta.2 it reported no predecessor and the
test fell back to the previous stable. The tool names the predecessor in
the pre-release's own stage, alpha, beta or rc, N-1.
Do the same in the helper: rc.2 follows rc.1 and beta.2 follows beta.1,
while the first of a stage has no predecessor even when an earlier stage
shipped. Pin it with a table test, because beta.1 passed without ever
exercising the second-beta case.
Run against the beta.2 preparation snapshot with this change, the whole
installer test package and the release policy suite pass.
Contract-Neutral: Test helper only; no release, install or customer contract changes.
The first beta's release workflow failed in create_release at "Locate
existing release". That step reads up to 100 releases with every asset,
about 25 MB, in one call, and GitHub answered it with an HTTP 504. The
step has no pipefail, so the failed read reached jq as empty input and
the job ended with exit code 5. Timing the call from a workstation, one
of three tries returned an error body, so this is not rare.
Retry the read up to five times with the same backoff the asset upload
uses, and accept only a complete listing of valid pages. A failed or
truncated read must never look like "no existing release": that answer
would stage a duplicate draft for a tag that already has one. Exhausting
the attempts fails the job with an explicit error. The listing call and
the downstream handling of an existing draft are unchanged.
Run the real step script in the release policy test against doubles for
gh and sleep: two 504s then a complete listing finds the draft after
backoff of 15s and 30s; a read that exits 0 but is truncated every time
fails after five attempts, with the capped backoff and no outputs; and a
complete listing without the tag still means no existing release. Against
the previous step the test fails with the production symptom, exit 5 and
the 504 message. The create-release pin list and the contract record the
retry.
Contract-Neutral: Release workflow reliability only; no published artifact, tag, signing, install or customer contract changes.
The retained validation ended with an empty model record, not a product erasure verdict. Use atomic replacement for closed model updates so command interruption cannot truncate the state used to judge actual recovery files; production deadlines and safety assertions are unchanged.
Contract-Neutral: Closed fixture observation writes only; no product runtime or contract change.
Change-source: pulse-maintainer
Compose upstream bed5052eb5 without replacing reviewed history. Keep the accepted one complete stdout/stderr observation and blank-line refusal instead of upstream second-sample replacement. Retain upstream real-systemctl fresh-host assertions and its platform-availability decorator alongside every reviewed failure-retention control. No release, installed recovery or LXC stop-cause claim.
Change-source: pulse-maintainer
An owned activation link may already be disabled before a later observation fails; assert exact service/PID/credential retention without re-enabling it. Require the old installed-script PID-erasure adverse control, keeping that runtime observation distinct from credential erasure and new renderer behaviour.
Contract-Neutral: Verification and precise contract documentation only; the production installer is unchanged.
Change-source: pulse-maintainer
The renderer contains nested functions inside its heredoc; extracting at the first closing brace never exercises its stop function. Bind its full top-level body and inject missing sysrc in the executable model reached by timeout.
Contract-Neutral: Confined test extraction and missing-tool modelling only; no installer or contract behaviour changes.
Change-source: pulse-maintainer
Retain recovery before unknown or unavailable timeout/sysrc observations, require bounded PID records, and align the existing daemon-supervisor assertion with checked signal delivery rather than ignored errors. Every source control remains mandatory.
Change-source: pulse-maintainer
Continue #1099: stop and disable the actual legacy manager before remote deregistration or local erasure, recheck after confirmation, and retain PID/service/credential material on refusal or unknown state. Check collector and supervisor absence, exact runlevel ownership and rendered signal failures with confined production-function controls. Appliance bootstrap and native acceptance remain separate.
Change-source: pulse-maintainer
The previous commit inserted a new real-systemctl test above the old one
and took over its skipUnless decorator, so on macOS, which has no
systemctl, the new test skipped and the old one ran unprotected and
failed. Restore the decorator on the old test.
The installer proof required the real-systemctl control to have passed.
Where systemctl does not exist it must instead report skipped, so the
proof now checks for ok on a host with systemctl and for skipped on one
without, and still fails if the control is absent from the output.
Refs: #2785
The 2026-10-10 server service discovery change lists the two historical
unit names with one pattern read and refuses to continue when that read
exits non-zero. systemctl list-unit-files exits 1, printing nothing on
stdout or stderr, when none of the named unit files exist. That is every
fresh host, so install.sh refused with "Cannot identify the Pulse systemd
service: unit inventory failed" before it did any work. The first beta's
install.sh smoke test caught it on a clean Debian 12 container; no
release carries it, and v6.5.0 listed the whole inventory and grepped it.
The tests could not see it. Their systemctl double reports "no units" as
exit 0, and test_partial_failed_inventory_is_not_absence asserted that an
empty inventory with exit 1 must be refused, which is the defect itself.
Add one inventory read shared by the installer and the unattended
updater, and use it for the auto-update mask check, which had the same
hazard. It accepts exactly the silent exit 1 as an empty inventory, and
only after a second read confirms there is still no output and no
message. A timeout, a signal, any other status, or an exit 1 that carries
output or a message stays a failed inventory, so a real failure still
cannot pass as absence.
Make the doubles model systemd: a failure now prints its message, silent
exit 1 is absence, and a new test runs real systemctl --root over an
empty unit root for both scripts. Run against the unfixed scripts, the
four new fresh-host tests fail; the rest of the suite is unchanged.
The registered runtime proofs for install.sh and the unattended updater,
which drive this suite, now require the fresh-host controls to have run
and passed, so they cannot be skipped or deleted unnoticed.
Refs: #2785
Read optional intake precautions at their expandable report fields, bind OpenShift Secret tests to the validated private file, and target helper workflow negative controls by step. Preserve the prepared GNU timeout in the private teardown probe on macOS and keep the actual security migration boundaries mandatory. Production guidance, installer behaviour and platform coverage are unchanged.
Contract-Neutral: Fixture-only integration repair; no product, installer, workflow, deployment or safety contract delta.
Change-source: pulse-maintainer
Require bounded diagnostic-free service and all-runlevel readback before server removal or local mutation, and reconcile again after remote confirmation while recovery state still exists. Refused stops, disable failures, unknown reads and unexpected init paths retain local material; absent and repeated removal need independent manager/process absence. Add executable confined refusal, ordering, custom-runlevel and timeout-child controls to the registered installer hook and owning contracts. Native OpenRC, Windows, other-manager and installed acceptance remain separate.
Change-source: pulse-maintainer
Run the accepted Unix teardown functions on fresh public Linux x64 and ARM64 CI, with real stop refusal, socket activation, batch reactivation and independent process/file readback. Retain bounded source-bound phase and owned-cleanup receipts; keep synthetic revocation separate from installed TLS, signed-agent and Windows acceptance.
Change-source: pulse-maintainer
Load the production quiescence helpers in the existing failed-revocation fixture and provide complete closed systemd observations. Continue testing the actual revocation refusal after verified stop/disable rather than replacing or bypassing the new safety boundary.
Change-source: pulse-maintainer
Replace ignored stop and disable failures with bounded complete state observations and independent inactive/non-enabled readback. Reconcile helper socket and service together, and quiesce the full uninstall activation set before remote or local mutation. Preserve failed runner revocation material and existing saved-state, token, trust and platform boundaries. Add executable production-shell refusal, reactivation, timeout and owned-cleanup controls.
Change-source: pulse-maintainer
Non-interactive token-file reading currently erases the supplied credential before permission checks and authenticated removal, including when removal is refused or its result is unknown. Treat token-file ingress as read-only: callers own their bootstrap cleanup, and confirmed removal still deletes only authorised runtime state. Keep token validation, TLS policy, exact record confirmation and credential-free local removal unchanged.
Extend the existing portable removal fixture through the actual parser and token ingress, root refusal and post-confirmation owned cleanup. Parent proof records thirty premature-erasure failures; a separate no-TTY harness control remains distinct. Update both owning contracts and the registered Go inventory hook together. Native Windows, compiled TLS and installed whole-job acceptance remain separate.
Change-source: pulse-maintainer
Adapt rcourtman’s Pulse PR2855 (aef53d0d3e), which diagnosed systemd’s silent exit-one absence. The original contributor commit is unchanged and explicitly credited, not imported, amended or re-parented in this maintainer candidate.
One bounded stdout/stderr observation accepts genuine absence but retains failed first reads, other statuses and blank-line output. Include the existing registered installer/updater verification hooks, real-empty-root controls and missing-unit recovery double in this same source commit. This replaces the rejected foreign-history composition with a normal maintainer-reviewed implementation; no provenance policy, credential or host installation changes.
Source-attribution: rcourtman, https://github.com/rcourtman/Pulse/pull/2855, aef53d0d3e
Change-source: pulse-maintainer
Credential-bearing removal currently short-circuits its confirmation gate when connection recovery leaves no URL, allowing local teardown without durably removing the server record. Check credential presence first and stop with same-instance recovery guidance before any process, service or state teardown. Keep credential-free local-only removal and existing exact-record/path authority intact.
Execute the real admission and initial teardown with private transport/service doubles, including every saved credential form, refusal, unknown response, identity mismatch and authorised cleanup. Register the portable Python controls in the installer inventory and describe the boundary in both owning contracts. Native Windows/TLS and whole installed lifecycle acceptance remain separate.
Change-source: pulse-maintainer
Compose the exact observed upstream additively without rewriting reviewed tip 805ea6d712 or any accepted ancestry. The new Go 1.26.9 and x/net graph need matching final-source evidence before this batch can be proposed.
Change-source: pulse-maintainer
govulncheck on the pinned 1.26.8 toolchain reports twelve reachable
standard library vulnerabilities in Pulse (net/http, crypto/tls,
html/template, os, net/textproto), published on 2026-10-08 and fixed in
Go 1.26.9. golang.org/x/net v0.58.0 carries further advisories fixed in
v0.60.0. With 1.26.9 and x/net v0.60.0 the scan reports no affecting
vulnerabilities under both govulncheck v1.1.4 and v1.7.0.
Pulse's own govulncheck job last ran on 2026-10-05, so nothing flagged
this. The private Enterprise build and test job notices it: once the scan
finds reachable advisories it needs more than the 4 GiB CI VM holds, the
guest kernel kills govulncheck, and the job is cancelled. That has failed
every Enterprise pair check since 2026-10-08, including the first
beta's.
Move every release builder and local toolchain guard together, as 1.26.8
did, so no candidate artifact keeps an older compiler: go.mod, the
builder image digests (index digest for 1.26.9-alpine), the release and
dev scripts, the devcontainer, and the root pair diagnostic. Only x/net
is raised in the module graph; go mod tidy is deliberately not run, so
unrelated indirect requirements stay as they were.
Contract-Neutral: Toolchain and indirect dependency patch update that clears reported advisories; no product or runtime contract changed.
Preserve Delivery tip 00680c9c5a exactly in merge ancestry. Resolve the overlapping startup helper to the candidate implementation and retain the canonical diagnostic controls and existing documentation. Frontend test formatting is already present; no runtime UI or workflow changes.
Change-source: pulse-maintainer
Completed PR2825 CI reports Windows Unix-type compilation failures and three Prettier fixture failures. Compile the existing Linux-only MSP daemon fixture only on Linux and format the unchanged frontend assertions. Separate successful CLI stdout from retained stderr diagnostics so Compose warnings cannot corrupt container identities, ports or bootstrap facts; add three executable controls without changing deadlines or acceptance gates.
Change-source: pulse-maintainer
The release train now cuts a beta every two days before the release
candidate. Its first beta, v6.6.0-beta.1, failed its preparation checks
twice: the governance test that maps VERSION to its release packet only
matched -rc.N, and two tests required the release index to say "current
v6 release candidate packet" while the metadata tool writes "current v6
beta packet" for a beta.
Accept -beta.N where the packet paths are derived and derive the expected
index wording from the version. Release candidates and stable releases
are checked exactly as before.
Contract-Neutral: Release metadata tests only; no runtime, API, install or customer contract change.
The refreshed proposal compiles the Linux-only control-plane startup fixture during Windows installer tests, failing on Unix-only dependencies before lifecycle assertions run. Exclude the fixture and its controls at compile time outside Linux, check Go file selection, and preserve required native Windows/macOS execution. Format only the three test files rejected by the exact containing CI, with Prettier AST-equivalence checks; no assertion, timeout, production source or workflow gate changes.
Change-source: pulse-maintainer
The exact-head hosted startup check reaches Docker exec with readback taken from CombinedOutput. Separate stdout from successful stderr warnings for identities, endpoints, mount hashes, bootstrap facts and cleanup, while retaining warnings and both failed-command streams. Add real-child-process controls and the matching deployment acceptance contract; hosted Compose acceptance remains required.
Change-source: pulse-maintainer
The native Unix inventory tests the root installer, unattended updater and their Python service/readback fixtures, but the workflow's event filters omit those inputs. Include each on push and pull_request, preserving all jobs, tools and deadlines. Decode both events in regression controls and reject removal or exclusion of each input.
Contract-Neutral: Native CI admission coverage only; installer/updater behaviour, agent and Windows lifecycle, service authority and recovery contracts are unchanged.
Change-source: pulse-maintainer
Use a counted-NUL shell logger double instead of starting Python for every installer line. Keep production log(), complete pipe draining, all eight first/later/final-error recovery cases and the existing 45-second bound. Require exact argument-frame and failure-sequence controls in the Go acceptance wrapper.
Change-source: pulse-maintainer
Contract-Neutral: Confined installer test fixture optimisation only; production updater, signing, native oracle, recovery matrix and safety deadlines are unchanged.