Commit Graph

11709 Commits

Author SHA1 Message Date
pulse-triage[bot] 41bee3d475 Integrate PBS mixed-source History repair
Change-source: pulse-maintainer
2026-09-29 17:54:16 +01:00
pulse-triage[bot] 5e7c6bb7d9 Restore PBS History for mixed Agent and PVE sources
Preserve the registry-corroborated PBS-to-Agent link on the service row while selecting the Agent host metrics target in the Backups drawer. Reject PVE-only name collisions and retain the target through a transient missing host row. Recompose the unchanged #1723 runtime repair on current main with fresh desktop and phone browser proof.

Change-source: pulse-maintainer
2026-09-29 17:43:53 +01:00
pulse-triage[bot] d7baa07dad Compose scoped Proxmox repair with protected main frontier
Retain the verified #2321 source and its original receipt while incorporating upstream release and browser range validation.

Change-source: pulse-maintainer
2026-09-29 17:36:27 +01:00
pulse-triage[bot] b12dca9cd8 Integrate scoped Proxmox tab evidence on current main
Preserve the browser-verified #2321 repair and current protected Relay changes in separate ancestry. Resolve the shared receipt to the current main version; both proofs remain in their original non-merge commits.

Change-source: pulse-maintainer
2026-09-29 17:35:52 +01:00
rcourtman ac62e114b2 Validate merged integration ranges against in-range browser receipts (#2330)
The maintainer coordinator merges reviewed candidates onto a main that
keeps moving and then ran the browser verification guard once over the
whole range with the merge tip as the commit. No lane can produce a
receipt bound to that merge's parent and covering upstream frontend work
too, so 13 of 13 coordinator browser-guard rollbacks since 28 September
failed on base_sha. This adds a range mode where every changed frontend
file's final content must match a valid receipt from a non-merge commit
inside the range, each validated against its own commit. Merge-authored
receipts never count, and the per-commit and staged modes are unchanged.
2026-09-29 17:34:19 +01:00
rcourtman bbbb7da60d Let the RC attester read the lab's root-owned evidence (#2329)
Follow-up to #2328. With the canary fixed, v6.4.5-rc.4 passed the
systemd and rootful Docker lab in run 36594651903, then attestation
failed reading receipt.json because the privileged lab writes it as root
into the bind-mounted evidence directory. This chowns that directory to
the runner user after a passing lab and before attestation, and pins the
ordering in the workflow test.
2026-09-29 17:31:01 +01:00
courtmanr@gmail.com ded4e91d1f Validate merged integration ranges against in-range browser receipts
The maintainer coordinator integrates reviewed candidates by merge onto a
main that keeps moving, then ran this guard once over before..after with
--commit after. That demands one tip receipt whose base_sha is the tip's
parent and whose paths and digests cover the whole cumulative delta. The
tip is a merge and the range carries the candidate plus upstream work that
was verified on its own, so no lane could ever produce that receipt. 13 of
13 coordinator browser-guard rollbacks since 28 September failed on
base_sha for this reason.

Add --base <range-base> for range mode. Every changed user-visible
frontend file's content at the tip must equal a digest recorded by a valid
receipt in a non-merge commit inside the range, and each receipt is
validated as the per-commit guard validates it at its own commit, bound to
that commit's parent and tree. Merge-authored receipts are never evidence,
so a conflict resolution or a later correction that changes frontend
source still needs fresh proof for the final content. Replaying the three
rolled-back 29 September batches from the host passes, and the existing
per-commit and staged modes are unchanged.
2026-09-29 17:15:10 +01:00
pulse-triage[bot] 498e2b12a2 Merge protected Pulse main with reviewed publication range
Preserve upstream browser verification for the newer Relay retirement surface; earlier action recovery proof remains in reviewed ancestry. Include current CI sharding and qualification canary without rewriting accepted commits.

Change-source: pulse-maintainer
2026-09-29 17:12:31 +01:00
courtmanr@gmail.com c9915434d8 Let the RC attester read the lab's root-owned evidence
With the host-interface canary in place, v6.4.5-rc.4 passed the
schema-v7 systemd and rootful Docker lab (run 36594651903), but the
attestation step then failed with Permission denied on receipt.json,
which the privileged lab writes as root into the bind-mounted evidence
directory. Hand that directory to the runner user after a passing lab
and before attestation, without touching its content.
2026-09-29 17:12:27 +01:00
rcourtman 9e8dc122be Give RC qualification a local host-interface canary (#2328)
Split out of #2323. The v6.4.5-rc.4 installed-acceptance run
(36547091547) failed before the lab because the no-network qualification
container had no non-loopback IPv4 canary. This carries only the
qualification and demo-resolver workflow fixes, their
deployment-installability contract text and the workflow tests, so
promotion isn't waiting on #2323's conflicting UI changes.
2026-09-29 17:01:13 +01:00
courtmanr@gmail.com eafd48d197 Give RC qualification a local host-interface canary
The immutable RC systemd lab failed before installed acceptance because
its --network none container had no non-loopback IPv4 address to prove
the helper's private network cannot reach. Add a veth canary wholly
inside that namespace and assert no default route before the lab runs.

Also check out the repository in the demo resolver before it calls
scripts/write_github_output.py, so verification-only dry runs reach
their demo checks.

Split out of #2323 so the v6.4.5 promotion is not held behind the
unrelated action-review UI work in that PR.
2026-09-29 16:42:35 +01:00
rcourtman b4c5723213 Calibrate internal/api shard weights to CI and record per-test seconds (#2326)
The weights from #2324 came from one local run and left the api shards
at
4.5, 8.8, 17.1 and 12.5 minutes on CI. Most of the 17.1 was not test
time.
That shard ran `-run . -skip <1231 names>`, and the test binary caches
only
its last compiled pattern, so alternating the two recompiled the 62 KB
skip
regex for every test and subtest (about 50 ms each under -race locally,
30s
against 1.3s for 300 trivial tests). Two runs put that shard at 887s and
875s against roughly 450s of tests. The skip path now passes -skip
alone.

Every api shard now runs go test -json through
.github/scripts/record-internal-api-test-seconds.py. It prints what
plain go
test would (package lines and the output of failing or unfinished
tests),
exits non-zero on any failure behind pipefail, and writes each top-level
test's seconds to an internal-api-test-seconds-N artifact that is
uploaded
even when the shard fails.
.github/scripts/refresh-internal-api-test-seconds.py
rebuilds the weights file from those artifacts (gh run download, median
across runs, DEFAULT_WEIGHT set to the mean of the unlisted tests, which
the
selector now reads from the file).

Until those artifacts exist, the weights are a local -race -json run
with
each region of go test's order scaled to what CI reported for it.
Equal-count quarters averaged 107, 437, 100 and 787s over four runs, and
the
weighted cut gave 131s for the first 1187 tests, 350s for the next 23
and
608s for the last 21 over two. The last quarter and the last 21 tests
disagree on how the tail splits, so the tail takes the midpoint of an
exact
fit and a pooled factor.

With these weights four shards still predict a slowest shard near 10
minutes, and a 20% slower runner on the tail would take it past the 11
minutes of Frontend and rest-1. Five shards predict about 131, 325,
280-340,
330-355 and 330-365s of tests, or 4.5 to 8.5 minutes a job with about
2.3
minutes of setup, so API_SHARD_COUNT goes to 5. Every test still runs
exactly once in contiguous go test order, and all five slices passed
locally
from their new starting points. The required Backend tests (api) verdict
keeps its name.
2026-09-29 16:25:18 +01:00
courtmanr@gmail.com 341e8a7eb4 Calibrate internal/api shard weights to CI and record per-test seconds
The weights from #2324 came from one local run and left the api shards at
4.5, 8.8, 17.1 and 12.5 minutes on CI. Most of the 17.1 was not test time.
That shard ran `-run . -skip <1231 names>`, and the test binary caches only
its last compiled pattern, so alternating the two recompiled the 62 KB skip
regex for every test and subtest (about 50 ms each under -race locally, 30s
against 1.3s for 300 trivial tests). Two runs put that shard at 887s and
875s against roughly 450s of tests. The skip path now passes -skip alone.

Every api shard now runs go test -json through
.github/scripts/record-internal-api-test-seconds.py. It prints what plain go
test would (package lines and the output of failing or unfinished tests),
exits non-zero on any failure behind pipefail, and writes each top-level
test's seconds to an internal-api-test-seconds-N artifact that is uploaded
even when the shard fails. .github/scripts/refresh-internal-api-test-seconds.py
rebuilds the weights file from those artifacts (gh run download, median
across runs, DEFAULT_WEIGHT set to the mean of the unlisted tests, which the
selector now reads from the file).

Until those artifacts exist, the weights are a local -race -json run with
each region of go test's order scaled to what CI reported for it.
Equal-count quarters averaged 107, 437, 100 and 787s over four runs, and the
weighted cut gave 131s for the first 1187 tests, 350s for the next 23 and
608s for the last 21 over two. The last quarter and the last 21 tests
disagree on how the tail splits, so the tail takes the midpoint of an exact
fit and a pooled factor.

With these weights four shards still predict a slowest shard near 10
minutes, and a 20% slower runner on the tail would take it past the 11
minutes of Frontend and rest-1. Five shards predict about 131, 325, 280-340,
330-355 and 330-365s of tests, or 4.5 to 8.5 minutes a job with about 2.3
minutes of setup, so API_SHARD_COUNT goes to 5. Every test still runs
exactly once in contiguous go test order, and all five slices passed locally
from their new starting points. The required Backend tests (api) verdict
keeps its name.
2026-09-29 15:27:08 +01:00
rcourtman a76f1de3db Retire Relay labels and upsells inside Pulse (#2325)
Relay left public checkout on 2026-09-29: it only ever connected the
Pulse Mobile app, which retires on 31 March 2027, and existing Relay
subscribers now carry Pro entitlements. The app still sold it. Every
Community install saw a "Get alerts on your phone ... Available with
Relay and Pro plans" upgrade panel on Alerts destinations, the plan
screen offered a Relay card with "Remote web access via Relay", and the
settings section was called Remote Access although Relay never reached
the web UI.

The Alerts push panel now renders only on instances that have the relay
feature, with no upsell. The settings section, nav, header and locale
catalogs say Pulse Mobile and carry the retirement date. Community sees
only the Pro comparison card and Relay-tier licenses see none; gated
mobile features name Pro as their minimum plan. The relay feature is
labelled "Pulse Relay (Mobile Connection)" in the catalog, plan copy no
longer claims remote web access, the backend pairing diagnostics point
at Settings > Pulse Mobile, and the user docs, including PRIVACY.md,
state that Relay does not provide remote web UI access.
2026-09-29 15:04:36 +01:00
pulse-triage[bot] b129b5a40c Use source-filtered facets for Proxmox tab evidence
Prevent unrelated estate-wide VM and storage counts from advertising Proxmox sections, while retaining direct-link hydration and the PBS-only Backups path. Revalidate the compact facet request when an all-resources cache supplies rows without scoped counts; cover mixed-source counts in component and browser proof and update both subsystem contracts.

Change-source: pulse-maintainer
2026-09-29 14:57:59 +01:00
rcourtman 9755c85b47 Balance internal/api race shards by measured run time (#2324)
The four Backend tests (api-N) shards took equal-count quarters of go
test's list, which left them at 4.0, 10.6, 4.0 and 16.8 minutes on the
first PR run, and at 1.9, 8.0, 1.5 and 10.3 minutes of go test time on
the following main push (run 36560070496). Almost all of it sits in a
few tests. One contract mock chart test runs about six minutes on the
runner, and the 28 integration server tests at the end of the list take
about twenty seconds each, so the fourth quarter held nearly half the
package.

Shards are still contiguous runs of go test's own order, since some
tests depend on package state from their neighbours, but the cut points
now come from estimated seconds.
.github/scripts/select-internal-api-shard.sh weighs each test from
.github/scripts/internal-api-test-seconds.txt (the 199 tests at 0.5s or
more, seeded from a local -race -json run scaled to that main run's
shard totals, with a 0.05s default for anything unlisted), binary
searches the smallest per-shard budget that fits the list into four
slices, and fills up to it. The weights only move cut points. Every test
is assigned exactly one shard in a single pass, so a stale file can
unbalance shards but never drop or repeat a test, and no shard is ever
empty.

With today's list the slices hold 1187, 23, 2556 and 21 tests, estimated
at 1.9, 6.9, 6.5 and 6.7 minutes of tests, or about 9.5 minutes per job
with the roughly 2.6 minutes of setup and race compile. The 2556-test
slice would need a 124 KB -run pattern, so a shard passes -skip of the
other shards' tests whenever that is shorter, which runs the same tests
in the same order.
2026-09-29 14:49:51 +01:00
pulse-triage[bot] 20c99e2e67 Preserve community decomposition decisions in issue label sync
An empty form field or unrelated edit cannot prove comment-raised topics were dispositioned. Only label newly declared topics, leaving removal to whole-thread triage and respecting a completed manual disposition.

Change-source: pulse-maintainer
2026-09-29 14:45:33 +01:00
rcourtman 72c0190e01 Pin the corrected Relay wording in the privacy docs test
The script smoke test still required "Pulse Mobile pairing for handoff"
in PRIVACY.md, the wording the previous commit replaced when it removed
the unbacked "secure remote web access" claim. Pin the new description
and forbid the remote web access wording in both copies.
2026-09-29 14:44:48 +01:00
pulse-triage[bot] 2e346e050f Integrate Delivery bundle budget adjustment
Change-source: pulse-maintainer
2026-09-29 14:36:43 +01:00
pulse-triage[bot] 1d286c8690 Account for guarded action recovery in its bundle budget
The #1891 pending-receipt recovery adds explicit resource-state confirmation, an inconclusive audit result, and a fresh server read to ActionReviewDialog. Exact-head PR #2323 built and passed frontend tests but found this one chunk at 8.25 KiB against the August 6.89 KiB baseline and 7.93 KiB ceiling; all other chunks and totals passed. Raise only this chunk baseline to the upper byte bound of that rounded observation (8453 bytes), retaining the 15 percent growth guard and all recovery safety checks. The post-change exact-source build and protected CI remain qualification gates.

Change-source: pulse-maintainer
2026-09-29 14:27:21 +01:00
pulse-triage[bot] 968e7c5a27 Make bug evidence intake truthful for non-container installs
Ask for the failing running version and a container image only where one exists. Accept symptom-appropriate screenshots or logs without forcing irrelevant log text, and state the matching triage rule.

Change-source: pulse-maintainer
2026-09-29 14:21:28 +01:00
pulse-triage[bot] efd04b11c9 Compose Proxmox capability tab repair on current main
Carry the validated #2321 web candidate across the protected main frontier without changing its runtime or browser contract. Change-source: pulse-maintainer

Change-source: pulse-maintainer
2026-09-29 14:19:06 +01:00
pulse-triage[bot] ffc295b8a7 Merge protected Pulse main at batch frontier
Change-source: pulse-maintainer
2026-09-29 14:02:16 +01:00
rcourtman 97f894b009 Retire Relay labels and upsells inside Pulse
Relay left public checkout on 2026-09-29: it only ever connected the
Pulse Mobile app, which retires on 31 March 2027, and existing Relay
subscribers now carry Pro entitlements. The app still sold it. Every
Community install saw a "Get alerts on your phone ... Available with
Relay and Pro plans" upgrade panel on Alerts destinations, the plan
screen offered a Relay card with "Remote web access via Relay", and the
settings section was called Remote Access although Relay never reached
the web UI.

The Alerts push panel now renders only on instances that have the relay
feature, with no upsell. The settings section, nav, header and locale
catalogs say Pulse Mobile and carry the retirement date. Community sees
only the Pro comparison card and Relay-tier licenses see none; gated
mobile features name Pro as their minimum plan. The relay feature is
labelled "Pulse Relay (Mobile Connection)" in the catalog, plan copy no
longer claims remote web access, the backend pairing diagnostics point
at Settings > Pulse Mobile, and the user docs, including PRIVACY.md,
state that Relay does not provide remote web UI access.
2026-09-29 13:19:54 +01:00
courtmanr@gmail.com 06d78b66d3 Balance internal/api race shards by measured run time
The four Backend tests (api-N) shards took equal-count quarters of go
test's list, which left them at 4.0, 10.6, 4.0 and 16.8 minutes on the
first PR run, and at 1.9, 8.0, 1.5 and 10.3 minutes of go test time on
the following main push (run 36560070496). Almost all of it sits in a
few tests. One contract mock chart test runs about six minutes on the
runner, and the 28 integration server tests at the end of the list take
about twenty seconds each, so the fourth quarter held nearly half the
package.

Shards are still contiguous runs of go test's own order, since some
tests depend on package state from their neighbours, but the cut points
now come from estimated seconds.
.github/scripts/select-internal-api-shard.sh weighs each test from
.github/scripts/internal-api-test-seconds.txt (the 199 tests at 0.5s or
more, seeded from a local -race -json run scaled to that main run's
shard totals, with a 0.05s default for anything unlisted), binary
searches the smallest per-shard budget that fits the list into four
slices, and fills up to it. The weights only move cut points. Every test
is assigned exactly one shard in a single pass, so a stale file can
unbalance shards but never drop or repeat a test, and no shard is ever
empty.

With today's list the slices hold 1187, 23, 2556 and 21 tests, estimated
at 1.9, 6.9, 6.5 and 6.7 minutes of tests, or about 9.5 minutes per job
with the roughly 2.6 minutes of setup and race compile. The 2556-test
slice would need a 124 KB -run pattern, so a shard passes -skip of the
other shards' tests whenever that is shorter, which runs the same tests
in the same order.
2026-09-29 13:14:27 +01:00
pulse-triage[bot] 3a061d66c4 Gate Proxmox tabs on observed capabilities
Avoid showing unsupported Replication, Ceph and Mail Gateway sections while Proxmox resource counts are unknown, while preserving bookmarked-route hydration and legitimate PBS navigation. Cover count transitions in component tests and synthetic production-page desktop/phone browser verification; update the affected subsystem contracts and receipt.

Change-source: pulse-maintainer
2026-09-29 12:25:29 +01:00
rcourtman fcbb7e58ad Shard internal/api race tests and drop probation E2E from PRs (#2322)
Across the last 25 bot PRs the median open to merge time was about 33
minutes for one PR and about 45 when three opened together. The critical
path was the required Backend tests (api) check, where one go test -race
./internal/api step took about 27 of its 31 minutes. Every other
required
check finishes within about 12 minutes.

internal/api now runs as four Backend tests (api-N) shards. Each shard
lists the package's tests with go test -race -list from the commit under
test and runs one contiguous quarter of that list in go test's own
order,
so every test, including ones added later, runs in exactly one shard,
and
a shard that resolves no tests fails. The split is contiguous rather
than
interleaved by name because some internal/api tests depend on package
state left by the tests just before them. A round-robin split by sorted
name failed dozens of tests locally (admin bypass and session store
globals), while the four contiguous slices and the full run all pass. A
Backend tests (api) verdict job keeps the required check name and fails
unless every shard succeeded. Backend tests (rest-0) and (rest-1) keep
their names and package split. Local non-race timings put the heaviest
slice at about 42 percent of the package, so the api check should drop
from about 31 minutes to roughly 14.

Core E2E no longer runs the non-gating probation tier on pull requests.
It could not gate a PR and the promotion rule counts only main runs, so
on a PR it only held each of the eight shard runners about eight minutes
longer, which fed the runner queueing seen with concurrent PRs. Push and
manual runs still execute it.

Go test steps still run for frontend-only changes. Go tests read
frontend sources directly (internal/api contract tests,
internal/unifiedresources walking frontend-modern/src, and the
internal/telemetry repository-wide wording scan), so skipping them by
path would drop real coverage.
2026-09-29 12:10:10 +01:00
courtmanr@gmail.com 46fd0b713e Shard internal/api race tests and drop probation E2E from PRs
Across the last 25 bot PRs the median open to merge time was about 33
minutes for one PR and about 45 when three opened together. The critical
path was the required Backend tests (api) check, where one go test -race
./internal/api step took about 27 of its 31 minutes. Every other required
check finishes within about 12 minutes.

internal/api now runs as four Backend tests (api-N) shards. Each shard
lists the package's tests with go test -race -list from the commit under
test and runs one contiguous quarter of that list in go test's own order,
so every test, including ones added later, runs in exactly one shard, and
a shard that resolves no tests fails. The split is contiguous rather than
interleaved by name because some internal/api tests depend on package
state left by the tests just before them. A round-robin split by sorted
name failed dozens of tests locally (admin bypass and session store
globals), while the four contiguous slices and the full run all pass. A
Backend tests (api) verdict job keeps the required check name and fails
unless every shard succeeded. Backend tests (rest-0) and (rest-1) keep
their names and package split. Local non-race timings put the heaviest
slice at about 42 percent of the package, so the api check should drop
from about 31 minutes to roughly 14.

Core E2E no longer runs the non-gating probation tier on pull requests.
It could not gate a PR and the promotion rule counts only main runs, so
on a PR it only held each of the eight shard runners about eight minutes
longer, which fed the runner queueing seen with concurrent PRs. Push and
manual runs still execute it.

Go test steps still run for frontend-only changes. Go tests read
frontend sources directly (internal/api contract tests,
internal/unifiedresources walking frontend-modern/src, and the
internal/telemetry repository-wide wording scan), so skipping them by
path would drop real coverage.
2026-09-29 11:43:57 +01:00
pulse-triage[bot] c54d361acf Keep same-RC secure-runtime canary inside isolated lab
Create the non-loopback veth canary only inside the no-network disposable systemd container before running the immutable release lab. Preserve packet authentication and fail closed when the local interface or no-default-route assertion is absent. Bind the workflow, source contract and installtests guard in one reviewed candidate.

Change-source: pulse-maintainer
2026-09-29 10:37:15 +01:00
pulse-triage[bot] 70acab1703 Checkout demo workflow before resolving output
The scheduled release dry run reached its reusable demo resolver before checkout, so the output helper was absent and the no-mutation demo check failed. Move the credential-free checkout ahead of resolution, guard the ordering in install tests, and record that precondition in the deployment-installability contract.

Change-source: pulse-maintainer
2026-09-29 09:10:22 +01:00
pulse-triage[bot] 0684be8d70 Offer guarded recovery for aged action receipt waits
Expose the existing admin audit escape hatch in the shared Actions review with direct-state confirmation, fresh re-read, and inconclusive outcome presentation. Keep server authorization and transport truth unchanged. Record affected canonical contracts and fresh desktop/phone browser verification in the same candidate.

Change-source: pulse-maintainer
2026-09-29 07:56:08 +01:00
pulse-triage[bot] 8619ab2ec8 Verify AI-off navigation and clearer setup guidance (#2316)
## What and why
Record the composed browser verification for AI-off navigation, plain
Actions empty-state guidance, first-source setup guidance, and the
Updates label. These changes address the AI-off/Actions usability work
tracked in Pulse #905 and the setup guidance repairs already merged to
main. This proposal updates the verification receipt only; it does not
introduce another UI implementation or change the frozen v6.4.5 RC.4.

## Included source

`72d8ae6f426fc4870570e983a43cef782e6f6178..496b3047e72e92ad8987994c0bfe9fe90345bfa2`
(commits `2606c9d36a`, `388770a974`, and additive merges `360e15c10d`,
`496b3047e7`). The net file change is
`frontend-modern/browser-verification.json`.

## Validation and limits
The retained offline Chromium desktop/phone browser exercise inspected
Actions, navigation, command palette, shortcuts, setup completion and
Updates with mocked authenticated API responses. This gate confirmed the
receipt's 15 source hashes still match the composed head, its verified
parent remains in ancestry, and `git diff --check` passes. Existing
protected frontend and E2E checks passed for the implementation already
on main. The mock-backed receipt is not live-backend, installed-release
or field acceptance; this proposal still needs exact-head CI.


[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-09-29 03:36:08 +00:00
pulse-triage[bot] 496b3047e7 Merge protected Pulse main into local integration
Change-source: pulse-maintainer
2026-09-29 02:16:25 +01:00
pulse-triage[bot] 72d8ae6f42 Restore same-RC release verification and fix Synology temperature and PBS backup age (#2315)
## What and why

- Correct structured PBS comment matching so a CT's current backup is
not shown as stale when its name is encoded as `node.VMID.name` (#2292).
- Read identified ARM sysfs temperatures when lm-sensors does not
provide a usable CPU reading, while preserving other sensor values and
collision handling, for the Synology DS216j report (#2311).
- Correct the same-RC secure-runtime qualification control needed to
verify the already-published v6.4.5-rc.4 before stable promotion. This
is control-path work, not a change to that frozen RC or evidence that
installed qualification passed.
- Align the first-source setup E2E assertion with the already-reviewed
guidance (#2309).

This proposal contains reviewed local range
`762aa6fe1a423f03138e8e7e533381f3e086e3c1..9822c2b060cf8cf4af431a41da6b21f090fbb5f6`,
with additive protected-main merge
`d20d3bd9dacaf8ad8a7bb3f95ff03af9d312a64f` (upstream
`f5651f3eb90a8f43d7e4ca7fe0c1518f719f7d3a`). The reviewed commits and
their authors are unchanged. No source from the frozen RC.4 was recut.

## Validation

The reviewed combined candidate passed focused offline race/source proof
`source-65j5yh6s` for the PBS and sensor repairs; the secure-runtime
control passed focused offline proof `source-w7kjnood`. Protected main
`f5651f3e` passed its Build and Test and E2E workflows before this
additive merge. Provenance and clean-diff checks passed on this proposal
head. A further combined source-proof request was queued behind another
job and cancelled rather than represented as a pass. Exact-head PR CI
and administrative review remain required; the same-RC hosted
installation/rollback proof and release soak remain separate gates.


[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-09-28 23:44:59 +00:00
pulse-triage[bot] 360e15c10d Merge commit '388770a9744e8f489e6bce437589f69f644befbb'
Change-source: pulse-maintainer
2026-09-29 00:20:19 +01:00
pulse-triage[bot] d20d3bd9da Merge protected Pulse main before publication
Change-source: pulse-maintainer
2026-09-29 00:10:44 +01:00
pulse-triage[bot] 388770a974 Bind composed UI browser proof to verified merge parent
Record fresh offline Chromium evidence for the exact merged web source at 2606c9d36a. The per-commit browser guard requires that verified parent, not the earlier assigned candidate base. Preserve the original protected merges and setup assertion without replaying the UI proof.

Change-source: pulse-maintainer
2026-09-28 23:34:49 +01:00
pulse-triage[bot] 2606c9d36a Integrate AI-off navigation and Actions copy with main repairs
Compose protected Pulse PRs #2312 and #2313 with the reviewed main candidate so first-source setup guidance, the corrected E2E assertion, and later repairs can be verified together. Browser proof for the composed source follows in a separate receipt commit.

Change-source: pulse-maintainer
2026-09-28 23:04:42 +01:00
rcourtman f5651f3eb9 Match setup handoff E2E to the corrected first-source copy (#2314)
#2309 reworded the empty setup-complete next step so it no longer
promises temperatures and SMART on every Proxmox host, but the
stable-tier E2E spec `30-setup-platform-connections-handoff` still
waited for the old sentence. Core E2E has failed on main since that
merge. This expects the current English copy; every other string the
spec asserts is present in source.
2026-09-28 23:03:53 +01:00
rcourtman 3ec7c578de Stop describing Patrol modes on Actions while AI is off (#2313)
With AI switched off the empty Actions inbox still said "Patrol runs in
Watch only mode" and pitched Pulse Pro modes, because the autonomy
setting reads as monitor even when Patrol is not running at all. That
tells an AI-off user something untrue and turns an empty page into an
upsell for a feature they turned off (issue #905).

The guidance now requires the same assistantEnabled session capability
that gates the Assistant launcher and the Patrol navigation, and falls
back to the plain empty-state copy otherwise.

Stacked on #2312; once that lands only this commit remains.
2026-09-28 22:53:32 +01:00
rcourtman 9c2da9db9f Hide Patrol navigation when AI is off and rename Updates (#2312)
Issue #905 asked for every AI entry point to disappear when AI is
switched off, and the Assistant launcher still honours that through the
assistantEnabled session capability. Patrol did not: v6 added it as a
permanent top-level tab, mobile bottom-bar slot, g r shortcut and
command-palette entry, and the palette also kept offering Assistant
commands. Patrol cannot run without a configured provider, so an AI-off
install carried a tab that only led to an "off" page.

Gate all of those on the same capability as the Assistant launcher.
Settings keeps its Patrol and Assistant items and /patrol stays
reachable, so the path back to turning AI on is unchanged.

Also rename the System settings item "Pulse server updates" to
"Updates" and drop "runtime" from its description. The item already sits
in the System group, and the description still sends agent updates to
Infrastructure, which was the reason for the longer name.
2026-09-28 22:35:09 +01:00
rcourtman 45491819f9 Match setup handoff E2E to the corrected first-source copy
#2309 reworded the empty setup-complete next step so it no longer
promises temperatures and SMART on every Proxmox host, but the stable
tier E2E spec still waited for the old sentence. Core E2E has failed on
main since that merge. Expect the current English copy.

Contract-Neutral: Test copy follows #2309; no runtime change
2026-09-28 22:24:10 +01:00
rcourtman 1461f6486e Stop describing Patrol modes on Actions while AI is off
With AI switched off the empty Actions inbox still said "Patrol runs in
Watch only mode" and pitched Pulse Pro modes, because the autonomy
setting reads as monitor even when Patrol is not running at all. That
tells an AI-off user something untrue and turns an empty page into an
upsell for a feature they turned off (issue #905).

The guidance now requires the same assistantEnabled session capability
that gates the Assistant launcher and the Patrol navigation, and falls
back to the plain empty-state copy otherwise.
2026-09-28 22:19:35 +01:00
rcourtman a866b27f2a Hide Patrol navigation when AI is off and rename Updates
Issue #905 asked for every AI entry point to disappear when AI is
switched off, and the Assistant launcher still honours that through the
assistantEnabled session capability. Patrol did not: v6 added it as a
permanent top-level tab, mobile bottom-bar slot, g r shortcut and
command-palette entry, and the palette also kept offering Assistant
commands. Patrol cannot run without a configured provider, so an AI-off
install carried a tab that only led to an "off" page.

Gate all of those on the same capability as the Assistant launcher.
Settings keeps its Patrol and Assistant items and /patrol stays
reachable, so the path back to turning AI on is unchanged.

Also rename the System settings item "Pulse server updates" to
"Updates" and drop "runtime" from its description. The item already sits
in the System group, and the description still sends agent updates to
Infrastructure, which was the reason for the longer name.
2026-09-28 22:05:02 +01:00
pulse-triage[bot] 9822c2b060 Integrate Synology CPU sensor collision fix
Retain existing lm-sensors chip data while adding identified sysfs CPU temperature for Pulse #2311.

Change-source: pulse-maintainer
2026-09-28 21:53:41 +01:00
pulse-triage[bot] 78d1effbe3 Integrate secure-runtime RC qualification control
Change-source: pulse-maintainer
2026-09-28 21:43:04 +01:00
pulse-triage[bot] e4dbbcde8a Preserve sensor chip on sysfs fallback name collision
An existing cpu_thermal chip with an unusable CPU value can still carry valid fan readings. Use a free synthetic CPU-chip key instead of replacing that entry when supplementing Pulse #2311, and cover the collision with a regression test.

Change-source: pulse-maintainer
2026-09-28 21:42:58 +01:00
pulse-triage[bot] e9f057c187 Run secure-runtime RC qualification from reviewed control
Dispatch the post-publication check from protected main while binding its packet to the immutable RC tag. Accept only canonical Pulse checkout origins before normalising the spelling required by the attester, and document the deployment contract and source guard together.

Change-source: pulse-maintainer
2026-09-28 21:34:44 +01:00
pulse-triage[bot] b5360c1e5a Supplement unusable CPU sensor output from sysfs
A named CPU chip with no valid CPU temperature must not suppress an identified SoC thermal reading. Preserve other lm-sensors readings and existing valid CPU precedence.

Change-source: pulse-maintainer
2026-09-28 21:17:04 +01:00
pulse-triage[bot] 2eff4c9954 Supplement non-CPU sensor output with identified sysfs temperature
When lm-sensors returns disk or other readings without a CPU chip, retain those readings and add a bounded, identified SoC temperature from sysfs. Preserve existing CPU output and ignore unusable optional sysfs data. Cover combined and precedence paths for Pulse #2311.

Change-source: pulse-maintainer
2026-09-28 21:02:38 +01:00