Preserve the exact Web candidate and its own-parent browser receipt. Retained connected controls, final focused checks and desktop/phone pixel proof cover the bounded presentation delta; the readiness-failed full-suite attempt remains incomplete.
Change-source: pulse-maintainer
## What changed and why
- DSM agent removal now confirms stopped processes, disabled automatic
activation and retirement of the Upstart job before erasing recovery
state. Atomic no-clobber restoration protects concurrent configuration.
This advances the safe-removal work reported in #1099.
- Proxmox guest polls skip disk-inventory copies for unrelated or
offline host agents while preserving linked-host evidence and guest
selection. This removes unnecessary allocation from repeated polling; it
does not establish installed memory relief.
- PBS help distinguishes inventory timestamps, point verification, the
point's Protected flag and workload protection. The comparison uses
existing evidence without replaying jobs, addressing the help gap
exposed by #2864.
- VM/LXC drawer History defaults now show readings from one dated stored
observation, rather than mixing independent latest times or live
fallback. Missing siblings remain explicit dashes; empty panels retain
qualified fallback.
## Included reviewed source
Complete publication range:
`70ae4c7e0eb3d5ce2c7f3c1d7610b97f6eb8e36e..1779434f0253e3e1e6240284ada2cf6c33e37636`.
- Delivery: `a6527d9ae3..da597d34d6`, eight DSM commits, integrated by
`c253560830`.
- Core: `345ed2da6a715dd0e274c97b2817fb091cdfa7e3`, integrated by
`fc5df2a4b0`.
- Help: `3573abbf0e..422fd81c62`, three commits, integrated by
`348d2eca6d`.
- Web: `58d6e6d591..6cf9b197aa`, two commits, integrated by
`0d8ade2b3b`.
- Additive merge `1779434f02` incorporates current upstream Discovery
contract consolidation without rewriting any reviewed commit.
## Validation and limits
- Retained DSM proof `source-p77gpfj5`: 15 production-function/EXIT
controls and complete installer package on Go 1.26.9, with 524 passes
and 16 explicit native/resource skips; complete output and guest stop
retained.
- Retained Web proof `source-8gfraepz`: types, lint, 308 connected
tests, production/embed build and budgets; 48 desktop/phone browser
checks, six inspected captures and 254 matching production hashes.
Earlier full frontend evidence retained five old-default assertion
failures; the reviewed test follow-up corrects those controls, not a
claim of a full final-suite pass.
- Retained help evidence: recipe/entrypoint/link/mirror controls, 36
frontend tests and types, exact Docs consumption and inspected
desktop/phone pixels.
- Publication provenance, whitespace, per-commit canonical completion
history/guards and final-range browser verification pass. Exact-byte
comparisons preserve all candidate code/tests after the document-only
upstream merge. Public documentation (247 Markdown files) and shipped
mirrors (62 files) pass at the composed source.
- Supplementary VM checks remained queued for capacity, with no terminal
receipt available; they are not passing evidence. The retained candidate
proofs and final-source byte/guard checks are the validation used. No
browser or build replay was needed.
Native DSM/Windows removal, workload thaw/restoration, QGA
restart/OS/every-volume recovery, installed memory relief and the actual
PBS discrepancy remain separate unfinished outcomes. Source publication
is not released or installed acceptance. Exact-head hosted checks and
required review remain necessary before landing.
Related to #1099
Related to #2864
[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
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
The development protocol described blanket runtime documentation and test
diffs but omitted the existing contract-neutral declaration carried into CI.
That encouraged task receipts and unchanged boundary rules to accumulate in
current contracts.
Document the established declaration and its limits at the protocol owner.
Keep current behavior and invariants in contracts, replace superseded text,
and retain validation evidence in proof artifacts and delivery history.
Point the source-of-truth and entry README to that policy.
The completion guard, browser verification, ownership, security and release
gates remain in effect. No runtime or paid-feature behavior changes.
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
Age the existing completed-backup readout and policy tone on the shared passive clock. Show elapsed age and the validated UTC completion time without clipping; keep activity, absence and invalid times separate. Cover default and custom policy boundaries, clock changes, tab round trips and retained completion with connected controls and desktop/phone browser proof.
Change-source: pulse-maintainer
Denied update queries left users without an explanation while ordinary
monitoring still worked. Add visible guidance through the shared help
contract, preserve the read-only choice, and wrap update evidence on phones.
Keep help open through polling and contain it through resize and scrolling.
Refs #1802
Make the existing guide distinguish same-time stored observations, missing metrics, independent panel times and qualified fallback. Link it from the guest-memory workflow, separate retained data from runtime access and explain the retired Relay compatibility limit without offering a new plan. Preserve read-only evidence and guest recovery boundaries.
Contract-Neutral: Existing help, mirrors and regression/browser checks only; collectors, rendering behaviour, runtime grants, retention defaults and product routes are unchanged.
Change-source: pulse-maintainer
Current contracts repeated the Discovery retirement policy and still
described deleted scanners, drawer controls, payloads and trusted
command dispatch as active requirements.
Define the retirement boundary in its existing AI runtime owner and
replace duplicated rules with scoped references. Remove guidance for
deleted code while retaining network discovery, canonical availability
configuration, encrypted knowledge and governed action execution with
all four Patrol modes.
Validation: contract, registry, status and control-plane audits pass.
The Patrol configuration and runtime source are unchanged.
Current contracts repeated the same retirement rule and still required
deleted scanners, drawer controls, payloads and trusted execution paths.
Point dependent contracts to the AI runtime owner and remove obsolete
requirements. Retain network discovery, saved availability targets,
encrypted knowledge and governed action execution with all four Patrol
modes.
Verified contract, registry, status and control-plane audits.
Refs #2848
Preserve exact help and parent-bound desktop and phone proof. This clarifies existing evidence without claiming runtime repair or released availability.
Change-source: pulse-maintainer
Beta cut from main at 552e838749. It carries every change merged since stable v6.5.0.
Contract-Neutral: Release-only v6.6.0-beta.2 version, release notes and distribution metadata; no public install or runtime contract changes.
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.
Default grouped legends combined differently dated values and live fallbacks, despite their accessible description selecting one stored time. Show a visible latest-stored timestamp, leave missing siblings unavailable, and preserve qualified fallback only for empty panels. Retain native inspection, zero, scoped refresh and access withdrawal controls; update the shared rendering and bounded-work contracts.
Change-source: pulse-maintainer
Desktop threshold edits could save before Cancel ran, or when a resize
replaced the table with cards. Four implementations of the numeric
controls also made bounds and Off/inherit handling drift-prone.
Use one numeric editor for global defaults and resource overrides. The
row owns focus-based saving, and the responsive table transfers drafts
and metric focus between layouts. Editing fits the table, host cards
retain cluster context, and backup/snapshot defaults remain separate
from numeric thresholds. Clearing a resource override also shows
inherited Off, disables its slider, and enables once to the factory
threshold when the parent is Off. Existing saved zero, negative and
inherited values keep their meanings.
Validation: 209 targeted tests across six files, full frontend
type-check, frontend and embedded Go builds, and current-build
Playwright checks at 1920, 1280, 900 and 390px. Guest Off persistence
and TrueNAS per-type fallback also checked at 2400 and 390px, with
save/reload, keyboard focus, cancellation, both resize directions and
pixel inspection.
Explain the existing Created, State and Provider evidence fields so an older inventory, missing verification and a conflicting workload assessment are not confused. A point's Protected label hides its verification flag; Job OK is not snapshot verification. Preserve safe read-only comparison and every guest recovery boundary.
Contract-Neutral: Documentation and regression checks clarify existing evidence; collection, backup policy, API and product behaviour are unchanged.
Change-source: pulse-maintainer
Numeric threshold controls had four implementations. Desktop input blur
could save a draft before Cancel ran, and resizing could save the draft
while replacing the table with cards.
Share the numeric editor, keep focus changes within the owning row, and
transfer draft and metric focus when the active layout changes. Stack
sliders above inputs so editing fits the table. Preserve cluster context
on host cards and keep backup/snapshot configuration out of numeric
defaults. Cleared overrides resolve inherited Off for both badge and slider, and
one toggle enables a factory threshold when the parent is Off. Existing
Off, inherit and persistence contracts stay intact.
Verified with 209 targeted tests, type-checking, builds and current-build
browser checks across desktop, intermediate and phone widths.
## What changed and why
Keep Proxmox guest readings, alerts and History owned by the live
connection that collected them. A completed obsolete poll must not
republish after connection replacement, retirement or runtime shutdown.
Both enumeration routes now stage the complete guest generation and its
effects before publication. Caller detail-budget expiry still preserves
already collected inventory, without granting another read or fallback.
Make FreeBSD rc.d and SysV agent removal retain recovery material until
shutdown, process absence and disabled boot activation are confirmed.
Refused, incomplete or ambiguous observations stop removal; a partially
stopped installation is not automatically restarted. Existing
systemd/OpenRC protections remain.
Keep the guest memory explanation's agent-setup advice safe: defer
setup, restarts and live guest-agent probes during backups or an
incident. The underlying percentage, source and reading age are
unchanged.
These are bounded maintenance steps for reported workload safety,
restart recovery and safe removal, not whole-report completion. Related
to #1099, #2439, #2619, #2762 and #2822. Native recovery, independent
thaw, Windows removal and installed acceptance remain separate.
## Included source
Complete unpublished range:
`dba4b722af3f1e9a648b09ace9484a1cfc26f785..d4e89c1a1bd7892b3fc16441365a90a15139efd4`.
- Guest publication candidate:
`1ccc3651fdd611a1d5da47c5d44659fbcd4c2773` through
`08a7eaf70d8452c223e05b19ce2bd7866bbb237d`, integrated at
`ac00b9ec782b1a5964c3a9b00cdd19775293d6fc`.
- Recovery-preserving removal candidate:
`bad484550830d19569e0332c96c495e71c1694d6` through
`65f813c49758c663380ad0179e5cce3245615baf`, integrated at
`7bda196005275cd25da63776db8eadc500c0066d`.
- Memory setup precaution: `c776990b817b6a96d02abc38692960c2be578419`
and compatibility-fixture correction
`9327bc02409ffe3f07d14b8f560d6fb75d492f46`, integrated at starting
reviewed tip `020a7be6bf2a2923c291395a8409ed79ddcde336`.
- Additive upstream composition
`b523c0b6f33b6cc0ddcb36b967b05fffa7f63b4a` contains the published backup
guide unchanged. It has the same source tree as the starting reviewed
tip. Every accepted commit identity and ancestry is preserved.
- Additive correction `6281d6e0008aec029b5cc7f79820ed46159aa17a`
reconciles the canonical Docker-ingest source guard with both routes
through the ownership gate, retaining the canonical state-update
assertion and all behavioral withdrawal controls. It changes no runtime
source.
- Additive upstream composition
`a61f14c823be5ee99f20b2aa2eb3808eff83645d` incorporates the published
second-beta metadata-test repair at
`171f003a04950b53e577019398961758eb32d91c`. Its exact object was already
present; no transport or history rewrite was needed.
- Final additive composition `d4e89c1a1bd7892b3fc16441365a90a15139efd4`
incorporates published beta.2 metadata at
`dba4b722af3f1e9a648b09ace9484a1cfc26f785`. The bounded upstream refresh
completed at the requested identity with source unchanged before this
merge. It adds no new maintenance scope or release action.
## Validation and limits
Publication provenance, whitespace and all fifteen per-commit completion
guards pass. The complete-range browser guard validates the unchanged
source-bound memory precaution receipt. Recorded candidate evidence
includes 33 guest scenarios and both original 500-guest budget controls,
60 removal methods and ten targeted installer fixtures, and 40 grouped
browser checks with twelve captures recorded as inspected. Unchanged
sufficient browser evidence was not replayed merely for batching.
Earlier Go 1.26.8 results remain diagnostic rather than matching the
declared compiler.
- `source-ji6j004_` on the first composition observed Go 1.26.9 and
failed the stale direct-publication assertion. The complete failure
remains retained; later vet/installer steps were not reached.
- Corrected `source-krkur1bl` on
`6281d6e0008aec029b5cc7f79820ed46159aa17a` passes the targeted
Proxmox/guest-ownership race suite, monitoring vet, shell syntax and
twelve targeted installer/consumer tests, including fifty Python removal
controls executed through their production-function wrappers. It uses Go
1.26.9, exits zero, collects complete output and confirms guest stop.
These monitoring and agent-removal bytes are unchanged in the final
composition.
- `source-9u5ig0nx` passes 62 frontend tests, full types, changed-source
formatting/ESLint, the production/embed build and every bundle budget.
Exit zero, complete output and guest stop are recorded. The final
frontend delta from that proof is only the already-published
upgrade-guide mirror; JavaScript, styles, manifests and browser-verified
inputs are unchanged.
- `source-p3ht5oy2` verifies the reconciled canonical ingest guard and
the newly published prerelease-predecessor helper/current prerelease
metadata on `a61f14c823be5ee99f20b2aa2eb3808eff83645d`. Two
stable-packet checks correctly skip on prerelease source. Go 1.26.9,
zero exit, complete output and guest stop are recorded. The later beta.2
metadata is validated separately on the final tip.
- Exact final `source-sl4t8d7o` on
`d4e89c1a1bd7892b3fc16441365a90a15139efd4` passes shell syntax and the
prerelease-predecessor/current beta.2 install-metadata checks on Go
1.26.9. The two stable-packet checks remain explicitly skipped. Exit
zero, complete 1,485-byte output and completed guest stop are recorded.
Earlier receipts retain their reporting-line-bound flags without loss of
their complete raw output.
These checks do not establish installed restoration, native guest
safety, Docker qualification, release readiness or publication of this
maintenance. Administrative review and all required exact-head hosted
checks still govern landing; any advisory failures need an
evidence-based disposition.
[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
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
Reverts #2863 before any release ships it. No tag contains it;
v6.6.0-beta.1 predates it.
The live Pro pricing and Patrol pages, in English, German and Spanish,
sell both modes: Pro "applies safe fixes in the mode you choose (Ask
first, Safe auto-fix, or Autopilot)". Paying installs also chose them.
Shipping the retirement would have silently downgraded those installs
while the sales page still promised the modes. If the modes are retired,
that needs a dated notice: stop selling them, warn affected installs
in-app, then re-ship the change.
The companion enterprise revert (rcourtman/pulse-enterprise#114) already
landed. It is safe with either core.
The receipt #2863 landed stays in place; this adds a receipt for the
restored content.
Verification:
- Go vet is clean. config, ai, ai/qualification, telemetry,
actionlifecycle, unifiedresources, aicontracts, pkg/server and api pass
on pulse-dev. The only api failure, the server-info development check,
needs `.git` in the tree.
- Release_control Python suites, the commit guard, the status and
registry audits, and the docs mirror all pass.
- Browser, on a pulse-enterprise build of this revert with a Pro
licence:
- all four Patrol modes are offered and Safe auto-fix saves;
- the Autopilot acknowledgement dialog activates effective `full`, and
Revoke is shown;
- drawer and plan page render, and phone width is fine.
The exact composed Go 1.26.9 proof source-ji6j004_ fails because the Docker-ingest source guard still requires two direct state updates replaced by reviewed live-owner publication. Require both routes to call the ownership gate and require that gate to retain the canonical state update. No runtime or Docker behavior changes; preserve the failure and all accepted commits.
Change-source: pulse-maintainer
Reverts #2863 before any release ships it. The live Pro pricing and
Patrol pages, in English, German and Spanish, sell both modes ("applies
safe fixes in the mode you choose: Ask first, Safe auto-fix, or
Autopilot"), and paying installs chose them. Shipping the retirement
would have silently downgraded those installs while the sales page still
promised the modes.
If the modes are retired, that needs a dated notice: stop selling them
first, warn installs on those modes in-app, and then re-ship the change.
It should not arrive through an engineering cleanup.
The receipt #2863 landed stays in place; this commit adds the receipt
for the restored content.
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
Beta cut from main at 171f003a04. It carries every change merged since stable v6.5.0.
Contract-Neutral: Release-only v6.6.0-beta.2 version, release notes and distribution metadata; no public install or runtime contract changes.
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
Preserve reviewed guide commits and upstream Patrol retirement and release-registry repairs without rewriting either history.
Change-source: pulse-maintainer
The first beta's release workflow failed in publish_docker at "Verify
exact tags and signed provenance": gh attestation verify copied an image
blob from Docker Hub and got a 502 Bad Gateway. The verifier calls
docker buildx imagetools inspect and gh attestation verify against
Docker Hub and GHCR with no tolerance for a transient registry error, so
one 5xx fails the whole release, and the train can rerun it only once.
Each of those reads is now retried up to four times with doubling
backoff from 10 seconds. They are idempotent, and a moved tag or an
invalid attestation fails identically on every attempt, so a real
failure is delayed by the backoff and never masked. The script's stdout
is the step output, so each attempt's stdout is captured and only the
successful attempt's is emitted: a failed read that printed half a
manifest cannot corrupt the verified digests. VERIFY_REGISTRY_ATTEMPTS
and VERIFY_REGISTRY_WAIT_SECONDS tune it, validated as small whole
numbers so the retry stays bounded.
Tests use doubles that fail like a dropped connection: transient
attestation reads are retried and only the digest proof is emitted; a
digest read that prints a partial manifest before failing leaves no
trace in the output; an exhausted attempt budget fails with an explicit
error and no output; unbounded settings are rejected. The old assertion
that an unverifiable attestation costs exactly one read now expects the
four attempts. Against the previous script the new tests fail. The
contract records the retry.
Checked: all 9 tests in the verifier's test file pass; the script and
its test are not registered in a subsystem, so the completion guard has
no proof file to require.
Second of the release-path retries after #2862 (release listing 504).
Retain exact PI commits and source-bound guide proof. Explain existing display hours separately from alert days and preserve the v6.5.0 critical-Off caveat.
Change-source: pulse-maintainer
Patrol now has two modes: **Watch only** reports findings, and **Ask
first** investigates and proposes fixes. Every fix waits in Actions for
an operator to approve and run it. Safe auto-fix (`assisted`) and
Autopilot (`full`) are retired.
Why: schema-v17 telemetry for the week to 2026-10-11 counts 1 assisted
and 2 full installs out of 612 reporting Patrol, and 4 executed Patrol
actions in 30 days, all on one install. No GitHub issue asks for more
autonomy. Meanwhile the automatic path carried its own policy leases,
acknowledgement store, per-resource allowlist, release gate and Colima
lab. Investigation is what paid installs use, so it stays.
Behaviour
- A saved `assisted`, `full` or `autonomous` level reads as `approval`.
Both autonomy update routes refuse those levels with `400
invalid_autonomy_level`. The acknowledgement routes are gone.
- The core Patrol action broker only plans: `Plan` and `Submit` persist
the plan and return. `TestContract_PatrolActionBrokerOnlyPlans` forbids
execution calls in its source.
- Removed:
- `ExecuteUnderPolicy`, the policy authorization lease, and the policy
execution store methods;
- Autopilot acknowledgement persistence, its routes and its dialog;
- the per-resource automatic-action allowlist: type, API field and
drawer editor. The store column is written as NULL.
- Kept for compatibility:
- `GetPatrolFullModeUnlocked` stays on the extension contract and
reports false;
- historical action records keep their lease and reason codes decodable,
labelled as retired modes.
- The Patrol inbox no longer has a "continuing without a decision"
bucket: every current issue is an operator decision.
Governance
- RG-06 now proves Patrol never executes without an operator decision
(integration tier).
- RG-02/RG-04 and the RA35/RA39/RA40 proof commands point at surviving
tests. Every `-run` name was checked against `git grep '^func Test'`.
- Pro plan copy, AI docs, privacy telemetry wording and the subsystem
contracts describe the two modes.
Verification
- Go: vet is clean. config, ai, ai/qualification, telemetry,
actionlifecycle, unifiedresources, aicontracts and api pass on
pulse-dev.
- Frontend: type-check and lint are clean; 217 related test files pass.
- Governance: release_control Python suites, status/registry audits and
the docs mirror pass.
- Browser: a pulse-enterprise build of this tree with a Pro licence, run
before and after merging onto main:
- the Patrol selector has exactly two modes, and each save reads back;
- retired levels get 400, and the acknowledgement route returns 404;
- the drawer Manage tab has no allowlist editor and still saves;
- phone width is fine; the plan page shows no retired modes.
The first beta's release workflow failed in publish_docker at "Verify
exact tags and signed provenance": gh attestation verify copied an image
blob from Docker Hub and got a 502 Bad Gateway. The verifier calls
docker buildx imagetools inspect and gh attestation verify against
Docker Hub and GHCR with no tolerance for a transient registry error, so
one 5xx fails the whole release, and the train can rerun it only once.
Retry each of those reads up to four times with doubling backoff from 10
seconds. They are idempotent, and a moved tag or an invalid attestation
fails identically on every attempt, so a real failure is delayed by the
backoff and never masked. This script's stdout is the step output, so
each attempt's stdout is captured and only the successful attempt's is
emitted: a failed read that printed half a manifest cannot corrupt the
verified digests. VERIFY_REGISTRY_ATTEMPTS and VERIFY_REGISTRY_WAIT_SECONDS
tune it, validated as small whole numbers so the retry stays bounded.
Test it with doubles that fail like a dropped connection: transient
attestation reads are retried and only the digest proof is emitted; a
digest read that prints a partial manifest before failing leaves no trace
in the output; and an exhausted attempt budget fails with an explicit
error and no output. The old assertion that an unverifiable attestation
costs exactly one read now expects the four attempts. Against the previous
script the new tests fail. The contract records the retry.
Contract-Neutral: Release verification reliability only; no published artifact, tag, signing, install or customer contract changes.
The compound worktree commands still assume pulse/v6 and reserve a lease
in the source checkout that Git does not transfer to the new worktree.
They also use a second claim implementation with different renewal and
expiry rules. No callers remain outside their entrypoints, docs and tests.
Use ordinary Git tools under the current branch policy and the supported
work_claim command in the checkout where the slice runs. Remove the legacy
workflow, its private claim engine and their obsolete advertisements.
Demo fixtures used a separate resource assembly sequence that left aged
TrueNAS source sightings marked current. Fixture views now use the live
monitor adapter for source ordering, manual links, availability
projection and final freshness. Storeless generations retain explicit
links and capture metrics targets through the existing indexed API. The
duplicate public link-deferral helpers are removed.
Browser verification also reproduced a vSphere drawer reset in the
previous implementation. Group keys changed from a VM name to its
cluster when metadata arrived, remounting the same resource and losing
the selected History tab. vSphere groups now follow the canonical parent
ID while their display labels update.
Validation: complete unified-resource and mock suites, targeted
monitoring checks, 206 frontend tests and the full frontend type-check.
Negative controls reproduce the old source-freshness and manual-link
defects. A fresh embedded build was exercised in Playwright at 1280x800,
390x844 and 900x800 across platform, availability and alert routes,
including cold History selection, range changes, keyboard chart
inspection, drawer reopening, switching resources, expanded details,
empty filters, and cross-source link refresh/reload/unlink behavior. The
browser receipt binds to the final staged frontend bytes.
Fixtures still synthesize provider inputs. This change does not replace
provider collection or reproduce every poller merge/rebase, and the
existing fixture-exclusion limitation remains documented.
Patrol could run some fixes on its own in two paid modes: assisted (Safe
auto-fix) and full (Autopilot, behind a server-owned acknowledgement).
Schema-v17 telemetry for the week to 2026-10-11 counts 1 assisted and 2
full installs out of 612 reporting Patrol, 4 executed Patrol actions in
30 days, all on one install, and no GitHub request for more autonomy,
while the automatic path carried its own policy leases, acknowledgement
store, per-resource allowlist, release gate and Colima lab. Investigation
is what paid installs use, so it stays.
Patrol now has two modes. Watch only reports findings. Ask first
investigates and proposes fixes, and every fix waits in Actions for an
operator to approve and run it.
- A saved assisted, full or autonomous level reads as approval, and the
update routes refuse those levels with 400 invalid_autonomy_level.
- The core Patrol action broker only plans: Plan and Submit persist the
plan and return. ExecuteUnderPolicy, the policy authorization lease,
the policy admission store methods, the Autopilot acknowledgement
persistence, routes and dialog, and the per-resource automatic-action
allowlist (store column now written as NULL) are gone.
GetPatrolFullModeUnlocked stays on the extension contract and reports
false.
- Historical action records keep their policy lease and tenant/resource
reason codes decodable, labelled as retired modes.
- The Patrol inbox no longer splits issues into "continuing without a
decision"; every current issue is an operator decision.
- Release gate RG-06 now proves Patrol never executes without an operator
decision (integration tier) instead of limited unattended autonomy,
and RG-02/RG-04 point at the surviving human-admission proofs.
- Pro plan copy, AI docs, privacy telemetry wording and the subsystem
contracts describe the two modes.
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.
Demo fixture assembly duplicated freshness and operator-link ordering.
Reuse the live monitor builder, retain explicit in-memory links and
capture indexed metrics targets without persisting fixture identities.
vSphere group keys also changed when display metadata arrived, remounting
open drawers and discarding History selection. Keep groups on canonical
parent IDs and use explicit cluster metadata instead of a VM's own name.
Cache-inclusive memory can be benign, but that reading does not establish that changing a guest agent is safe. Put the backup and guest-incident precaution before optional VM/container setup advice, including retained and freshness-unknown observations. Preserve source selection, readings, thresholds and guest operations.
Production snapshot-mapped rows and drawers passed 40 desktop/phone checks with 12 inspected captures; current, retained, unknown, unavailable and measured-zero controls keep their meanings. Add source and reactive drawer regressions, and state the same boundary in the existing frontend contract.
Refs: #2439, #2762, #2822
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
Beta cut from main at bed5052eb5. It carries every change merged since stable v6.5.0.
Contract-Neutral: Release-only v6.6.0-beta.1 version, release notes and distribution metadata; no public install or runtime contract changes.
Change-source: pulse-maintainer
The first beta (v6.6.0-beta.1) now passes its preparation checks and
both source pairs, and its release workflow failed twice at the
install.sh smoke test: on a clean Debian 12 container install.sh stops
with "Cannot identify the Pulse systemd service: unit inventory failed".
That is a real regression on main, not a flake. v6.5.0 does not have it,
so no release carries it.
Cause: the 2026-10-10 service discovery change reads `systemctl
list-unit-files -- pulse-backend.service pulse.service` and refuses on
any non-zero exit. systemd exits 1, printing nothing on stdout or
stderr, when none of the named unit files exist, which is every fresh
host (checked on systemd 255 here and by the smoke container's systemd
252). The change's comment says a successful empty read permits a new
installation, but an empty read is not exit 0.
Why the tests missed 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 is refused.
Fix: one shared inventory read, used by the installer, the unattended
updater and the auto-update mask check (which had the same hazard). It
accepts exactly the silent exit 1 as an empty inventory, 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 real failures still refuse.
Tests: the doubles now model systemd (a failure prints its message, a
silent exit 1 is absence), the two tests that encoded the defect model a
real failure, and new tests cover a fresh host for both scripts,
including real `systemctl --root` over an empty unit root. Contract doc
updated. The registered runtime proofs for install.sh and the unattended
updater (the Go tests that drive this suite) now require the fresh-host
controls to have run and passed.
Checked on pulse-dev: against the unfixed scripts the four new
fresh-host tests fail and the rest pass; against this change all 18
discovery tests, the 2 repair tests and the 16 timer tests pass, and the
Go installer tests pass (184 s).
This replaces #2855, whose first commit lacked the registered proof
files the completion guard requires per commit.
Refs #2785