The broader release-policy check still expected the removed shell configuration step. Assert its real transaction entry and runtime profile/entitlement preservation while keeping activation, exact stable tag, network and public browser checks unchanged.
Contract-Neutral: Align verification with the already implemented demo transaction; no runtime or authority change.
Change-source: pulse-maintainer
Current operational source exposes healthz and takes the shared deployment lock. Pin that route and make the disposable service return 404 for unknown paths so native acceptance cannot manufacture a healthy cohost observation.
Change-source: pulse-maintainer
Exercise actual systemd and Caddy with a changed executable, distinct persistent data, delayed synthetic failure, observer loss and TERM during full rollback. Keep 300-second clocks, exact-source and cleanup receipts; no production credential or worker system privilege is added. Update the connected recovery contract and policy assertions, and retain bounded service identity observations.
Change-source: pulse-maintainer
Assert the existing file-level verification receipt so the new routing control exercises real ownership instead of assuming an unavailable summary field.
Contract-Neutral: Test-only assertion of existing subsystem lookup output; no runtime or authority change.
Change-source: pulse-maintainer
Keep new source paths on their own connected proof policy after the full lookup suite exposed six broadened metadata expectations. Preserve terminal no-op cancellation evidence and the runtime file owner.
Contract-Neutral: Correct connected observation and verification routing within the existing demo operations and authority.
Change-source: pulse-maintainer
Compose the existing signed stable demo paths with the Relay host lock, durable systemd ownership, full persistent estate capture and five-minute forward and recovery watches. Preserve uncertain attempts and failed rollback, refuse destructive headroom pruning, and keep native installed acceptance separate from connected source controls.
Change-source: pulse-maintainer
Preserve existing polling evidence before a connection test updates its ledger. Explain freshness, optional telemetry and session turnover using the read-only projection, correct the 60-second default, and keep diagnostic steps free of credentials and destructive reproductions.
Contract-Neutral: Documentation and existing-guide checks only; no runtime, API, transport, identity, access or retention change.
Change-source: pulse-maintainer
Retain both History/storage and Reporting contracts; keep the upstream browser receipt unchanged. Earlier accepted receipts remain in history, with runtime blobs preserved.
Change-source: pulse-maintainer
The `patrol_digest` report schedule kind has been on main since early
September, but only the API could create one: the Settings > Reporting
form had no way to choose it, so the weekly "what Patrol did" email
never reached the customers it was built for, the ones who have stopped
opening Pulse.
The schedule form now has a Report type choice between the performance
report and the Patrol weekly summary. The choice shows only while the
session reports Patrol can run (AI on with a provider configured), and
an existing summary schedule keeps showing its type so it stays editable
after AI is switched off. Choosing the summary reduces the form to a
name, weekday, time, timezone and optional recipients: cadence is pinned
to weekly and delivery to email, and the format, resource picker, tag
filter, retention, attach and save-copy controls are hidden because the
server fixes those values. The save path no longer demands a resource
scope for this kind, and the schedules table describes a summary as
"Patrol activity, last 7 days".
Verification: model, hook and panel tests cover the gating, the pinned
fields and the saved payload; the browser receipt records a Pro-licensed
pass of `/settings/support/reporting` at 1280 and 375 pixels, including
create, save, edit, and a run without an email destination that surfaces
the server's message naming the missing setting. Design note updated in
`docs/PATROL_WEEKLY_DIGEST.md`; demand ledger entry "Patrol weekly
digest (what Patrol did for you)" in pulse-pro.
Recognise matching notify_unsubscribed events before and after acknowledgement, preserve unrelated streams and clean log completion, and retain only numeric errno with fixed diagnostics. Keep nonempty Apps inventory and poll-ledger progress while rejected stats recover on the next ordinary poll. The reporter supplied a source-derived envelope, not a retained capture; native acceptance and delivery remain separate.
Change-source: pulse-maintainer
The patrol_digest report schedule kind has been on main since early
September, but only the API could create one: the Settings > Reporting
form had no way to choose it, so the weekly "what Patrol did" email never
reached the customers it was built for, the ones who have stopped opening
Pulse. The schedule form now has a Report type choice between the
performance report and the Patrol weekly summary. The choice shows only
while the session reports Patrol can run (AI on with a provider), and an
existing summary schedule keeps showing its type so it stays editable
after AI is switched off.
Choosing the summary reduces the form to a name, weekday, time, timezone
and optional recipients. Cadence is pinned to weekly and delivery to
email, and the format, resource picker, tag filter, retention, attach and
save-copy controls are hidden because the server fixes those values; the
save path no longer demands a resource scope for this kind. The schedules
table describes a summary as "Patrol activity, last 7 days". Model, hook
and panel tests cover the gating, the pinned fields and the saved
payload, and the browser receipt records a Pro-licensed pass at 1280 and
375 pixels, including a run without an email destination that surfaces
the server's message naming the missing setting.
The existing drawer fetches all metrics without a metric query field. Explain metrics-object and single-metric points responses so readers do not wait for an absent CPU request or mistake missing CPU and measured zero for the same result.
Contract-Neutral: Clarify existing History diagnostics and protect mirrored documentation; no runtime, API, identity, access, retention or response-shape change.
Change-source: pulse-maintainer
## What changed and why
Reduce configuration-fetch audit overhead without hiding access events
(#2320). The suppression tracker now remembers at most 4,096
organisation/agent pairs and uses an expiry index instead of repeated
full-map scans. Existing agents keep daily suppression; unremembered
agents at capacity are conservatively audited on every fetch.
Token/configuration changes and every failure remain audited. No audit
history is deleted.
The Apprise confidentiality test now observes the autonomous queue
dispatcher instead of starting a competing manual batch. Its lifecycle,
retry, configuration and confidentiality assertions remain intact.
Preserve the exact 6.4.6 release-line mapping for the already-published
packet. The fallback to main incorrectly rejected its immutable source
during convergence. This maps that version only, not future patches, and
changes no candidate product source.
## Included source and upstream reconciliation
Complete new publication range:
`e6540da45da4de4bcb954463373d8ea9f196eb56..35d8c7c13d3665b2ffe2fe4fd61e8952c46e21b1`.
- Reviewed Delivery correction:
`3578b0044740087e7589f19bca450245f610aced`.
- Reviewed Core changes: `e225bf2abcb4189dcedd457292248e72a945dc74` and
`6ab5383412f156f286c38623f9b86f2b0d3151f0`, integrated by
`94ce8496b7d79e9b77d43493adc432c954d5e8b7`.
- Additive upstream merge: `35d8c7c13d3665b2ffe2fe4fd61e8952c46e21b1`,
incorporating published Proxmox table repairs at
`e6540da45da4de4bcb954463373d8ea9f196eb56`.
Every reviewed commit identity and ancestry is preserved. No upstream
frontend source or dependency manifest changes in this proposal.
## Validation and limits
Recorded independent-review evidence: Core returned four complete
source-proof receipts covering connected
configuration-fetch/authorization tests, five race repeats,
notifications correctness/races and ten queue-fixture repeats,
vet/builds, 135 governance tests, 23 docs-sync tests and frontend
production build/budgets. Its fixed controls retained a maximum of 4,096
keys versus 12,288 in the predecessor; saturated in-memory lookup
measurements are not installed write-rate or CPU acceptance.
Delivery returned a complete offline source proof of 947 release-control
tests (8 skipped), with guest shutdown. The exact-version tests reject
unrelated versions. These are reviewed owner returns, not new
qualification executions by this publication gate.
On the combined committed source, provenance, whitespace, ancestry,
canonical completion, browser-verification scope, control-plane audit,
all 62 shipped-document mirrors and the 211-file public-document check
pass. Core runtime and Go manifests are byte-identical to the reviewed
Core candidate; release-control source/policy is byte-identical to the
reviewed Delivery candidate; frontend runtime and graph are
byte-identical to current upstream. Sufficient heavy/browser evidence
was therefore not replayed.
Core used Go 1.26.7 rather than declared 1.26.8, with an explicit
backend embed fixture and a separately proved frontend build. Required
exact-head CI remains necessary before landing. This proposal does not
establish installed outcomes, release readiness, successful convergence
or stable delivery, and does not replace or recut the published v6.4.6
candidate.
[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
Accept exact candidate 34f73590bb with retained source and browser proof. Resolve only the shared receipt pointer; runtime content remains exact to its non-merge proof commits.
Change-source: pulse-maintainer
The Workload Controllers table printed Job and CronJob timestamps
exactly as the agent reports them, so at 1440px the Detail cell read
"Last success: 2026-10-02T19:59:14.523639+01:00" in a 119px column
and was cut off before the time. A user could not tell when the job
last ran.
The cell now says "Last success 31m ago" or "Completed 2h ago" through
the shared platform relative-time formatter, with the absolute local
time on hover, matching how the Events table shows its observed time.
The Detail column takes 12% instead of 9% so every label the column
can produce fits whole, taken from the Kind, Current and Available
columns which hold short values. The Detail span truncates to the cell
with an ellipsis instead of being cut at the cell edge.
Contract-Neutral: presentation of existing Kubernetes controller time
fields only; owning unified-resources clause updated; no
frontend-primitives clause, primitive, or API change
Repeated device paths and UnRAID group names must not attach foreign SMART, temperatures or topology counts to a pool. Preserve canonical children, require host or scoped native ownership for inferred membership, and compare exact device identifiers. Cover live target changes and real desktop/phone presentations.
Change-source: pulse-maintainer
Avoid a needless subscription when Apps has no inventory, preserve second-attempt stream cleanup and bounded log-tail completion, and record only classified local socket-close causes without private wire data. This repairs the empty-inventory path in #2396; the exact rejection envelope and the cause of #2400 remain unconfirmed.
Change-source: pulse-maintainer
The mock generator stamped each job's last and next sync once at
startup, with the last sync up to an hour old on a 15-minute schedule.
Most jobs therefore started out overdue, and on a long-running demo
every job read as hours overdue in red while still reporting Healthy.
The demo's Replication tab looked broken to anyone evaluating Pulse.
Replication timing now follows the fixture clock. Each job keeps a
stable phase inside its schedule window, so a healthy job last synced
less than one interval ago and is next due in the future, and a
failing job's last good sync falls behind by its failure count.
The target node was picked by index and could equal the source, which
showed a job replicating pve1 to pve1. The source is no longer a
candidate, and an estate without a second node gets no jobs.
Preserve candidate 7c48430d5a and its exact runtime bytes alongside the reviewed main frontier. Resolve only the shared browser receipt file to the candidate receipt; original non-merge receipts remain the integration evidence.
Change-source: pulse-maintainer
Preserve the reviewed local tip and incorporate current upstream additively. The frontend/table changes are disjoint from the audit, Apprise fixture and exact-version release mapping corrections.
Change-source: pulse-maintainer
The Workload Controllers table printed Job and CronJob timestamps
exactly as the agent reports them, so at 1440px the Detail cell read
"Last success: 2026-10-02T19:59:14.523639+01:00" in a 119px column
and was cut off before the time. A user could not tell when the job
last ran.
The cell now says "Last success 31m ago" or "Completed 2h ago" through
the shared platform relative-time formatter, with the absolute local
time on hover, matching how the Events table shows its observed time.
The Detail column takes 12% instead of 9% so every label the column
can produce fits whole, taken from the Kind, Current and Available
columns which hold short values. The Detail span truncates to the cell
with an ellipsis instead of being cut at the cell edge.
Contract-Neutral: presentation of existing Kubernetes controller time fields only; owning unified-resources clause updated; no frontend-primitives clause, primitive, or API change
On a 1440px screen the Mail Gateway table showed a spam count as "3…"
and the Ceph table showed its Services column as "mon…". Both tables
use fixed layout and sized only their always-on columns, so the
optional ones split the few percent left over. Every visible column
now takes a weighted share through the shared platform helper.
Replication hid the reason a job failed. The error column had 8% of
the row and clipped mid-word, mid-width layouts dropped the column,
and the phone expansion omitted it. Rows now expand at every width to
the full job record with the whole error first, the error column is
wider, and search matches error text.
Backups sortable headers rendered in sentence case beside uppercase
plain headers because a button resets text-transform. Coverage rows
truncated node and workload names while short cells sat half empty,
and empty evidence cells repeated their header ("No PVE backup file")
until they truncated too. They now read "None" with the long form on
hover.
On phones the Ceph row clipped every value and the pool usage bar
clipped "50.1%" to "0.1%". The phone projection keeps five values
that fit whole. The FSID column, which never fit, leaves the row and
stays searchable and whole in the expansion.
Contract-Neutral: presentation sizing and labels only; owning
unified-resources clause updated; no storage-recovery or
frontend-primitives clause, API or primitive change
Preserve exact Core candidate commits after independent diff and retained-proof review. Bound suppression state without evicting recent agents or hiding audit events; retain the real-worker confidentiality assertions.
Change-source: pulse-maintainer
Real Chromium and WebKit first taps selected the latest reading instead of the tapped observation. Select and retain the actual sample across compatibility focus and mouse events, shared-chart focus transfer and matching refreshes. Reject pan, cancellation and multiple contacts without preventing native scrolling. Preserve mouse and keyboard inspection, source ownership, units and access.
Change-source: pulse-maintainer
The mock generator stamped each job's last and next sync once at
startup, with the last sync up to an hour old on a 15-minute schedule.
Most jobs therefore started out overdue, and on a long-running demo
every job read as hours overdue in red while still reporting Healthy.
The demo's Replication tab looked broken to anyone evaluating Pulse.
Replication timing now follows the fixture clock. Each job keeps a
stable phase inside its schedule window, so a healthy job last synced
less than one interval ago and is next due in the future, and a
failing job's last good sync falls behind by its failure count.
The target node was picked by index and could equal the source, which
showed a job replicating pve1 to pve1. The source is no longer a
candidate, and an estate without a second node gets no jobs.
On a 1440px screen the Mail Gateway table showed a spam count as "3…"
and the Ceph table showed its Services column as "mon…". Both tables
use fixed layout and sized only their always-on columns, so the
optional ones split the few percent left over. Every visible column
now takes a weighted share through the shared platform helper.
Replication hid the reason a job failed. The error column had 8% of
the row and clipped mid-word, mid-width layouts dropped the column,
and the phone expansion omitted it. Rows now expand at every width to
the full job record with the whole error first, the error column is
wider, and search matches error text.
Backups sortable headers rendered in sentence case beside uppercase
plain headers because a button resets text-transform. Coverage rows
truncated node and workload names while short cells sat half empty,
and empty evidence cells repeated their header ("No PVE backup file")
until they truncated too. They now read "None" with the long form on
hover.
On phones the Ceph row clipped every value and the pool usage bar
clipped "50.1%" to "0.1%". The phone projection keeps five values
that fit whole. The FSID column, which never fit, leaves the row and
stays searchable and whole in the expansion.
Contract-Neutral: presentation sizing and labels only; owning unified-resources clause updated; no storage-recovery or frontend-primitives clause, API or primitive change
Keep at most 4096 remembered org/agent pairs and use an expiry index instead of repeated full-map scans. Audit unremembered overflow deliveries conservatively, preserving daily suppression for established agents, changed-config/token events and every failed fetch. Cover capacity, expiry, concurrency and the real handler contract.
Change-source: pulse-maintainer
Convergence used main's unmapped fallback and rejected the immutable 6.4.6-rc.1 source. Retain its exact-version release/v6.4 policy for artifact convergence and promotion without mapping future patches or accepting unrelated source.
Change-source: pulse-maintainer
## What changed and why
A History chart with one stored reading now shows a visible marker and
its actual timestamp, including a measured zero. Pointer and keyboard
inspection use the same real timestamp instead of an invented
one-millisecond window. Multiple readings, empty results, request
ownership and existing keyboard access remain intact.
Inspection of the existing production chart reproduced a blank series
for a real one-point response. This repairs an existing History surface;
it adds no collection, polling, access or new product surface, and does
not establish resolution of every PBS or TrueNAS symptom.
## Included source
- Reviewed Web candidate `20261002T182804Z-web-product`:
`b112524cd237602f9a9cab3bdeb3026bc6e3c91e`, based on
`ad7f7a1063d45e26f77faf35bacbca6877f41cac`.
- Complete unpublished range:
`761f714af8f0409c7efff0e95da9f1adc7e3b104..34257d19f64d9bf44e666c1af1663293c0aa19f9`,
including additive integration
`34257d19f64d9bf44e666c1af1663293c0aa19f9`.
- Reviewed commit identities are preserved. Final frontend source and
dependency manifests exactly match the reviewed candidate. The only
candidate-to-integration differences are the signing-preflight workflow
and its README, already present on current published main.
## Validation and limits
- Recorded reviewed proof `source-sph989yd`: 21,709 tests passed, three
skipped; typecheck, lint, production/embedded builds and budgets passed.
The recorded outcome establishes complete hash-matched output and guest
shutdown.
- Recorded Chromium and WebKit predecessor controls reproduce the
missing series; final desktop/phone checks pass 12 states covering
visible pixels, singleton/zero, pointer and keyboard inspection,
multiple readings, empty response and restored singleton. Representative
screenshots were inspected during review.
- Publication provenance, range whitespace and the full-range
browser-verification guard passed. Final runtime hashes match the
committed browser receipt and reviewed candidate. Sufficient
heavy/browser evidence was not replayed solely for publication.
- Required exact-head CI remains a landing gate. Native panels,
installed acceptance and containing release qualification remain
separate. This PR does not change the frozen v6.4.6 packet or publish a
release.
[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
v6.4.6-rc.1 failed notarization today because the Apple developer
agreement had lapsed, and nothing noticed until a release hit it. This
adds a workflow_dispatch-only check on the hosted macOS runner that
imports the Developer ID certificate into a throwaway keychain, checks
the identity and that the cert has 30 days left, signs and verifies a
throwaway probe binary, and calls notarytool history, which fails while
an agreement is unsigned. It builds, uploads and publishes nothing, has
contents read only, and never runs on pull requests. The maintainer's
nightly release rehearsal dispatches it.
A one-point stored History response drew no visible series and pointer inspection mapped it into a fictional one-millisecond window. Show a centred marker and one real timestamp, including measured zero, and share timestamp geometry with pointer inspection. Preserve multi-point rendering, keyboard access, empty states and request ownership.
Chromium and WebKit reproduce the predecessor defect. Twelve final desktop and phone states verify real canvas pixels, pointer and keyboard inspection, and sparse-to-empty refreshes. Synthetic presentation proof does not establish native collection or release availability.
Change-source: pulse-maintainer
On 2 Oct 2026 v6.4.6-rc.1 failed notarization because the Apple developer
agreement was unsigned, about an hour into the release. The maintainer's
nightly release rehearsal now dispatches release-signing-preflight.yml from
main on a hosted macos-15 runner. It imports the Developer ID certificate
into a throwaway keychain, requires the identity to be valid and at least 30
days from expiry, signs and verifies a probe binary with a secure timestamp,
and reads the notary submission history with the release key, which Apple
refuses while an agreement is unsigned or the key is revoked. The four
checks are independent and each reports one titled outcome, so one night
names every broken credential. It builds, uploads and publishes nothing.
## What changed and why
Disk Overview now displays a valid reported temperature even when
extended SMART attributes are missing or empty. Previously an early
return hid that independent reading. Units and configured thresholds are
preserved; invalid readings do not create cards, and the existing
unavailable-details message returns when no details remain. This repairs
the existing storage presentation, without changing collection or adding
a new surface.
## Included source
- Reviewed Web candidate `20261002T163042Z-web-product`:
`442717f4099e80c5386130e542eb91bd691e6a24`.
- Complete unpublished range:
`005eb08cb9bce5a8ab8a07379f2a2414c92596b4..68272db93bfba4819438b35171d9b34478bc7a9b`
(candidate plus additive integration commits
`d69aae63470bbbdb14f7c264f716cf60e47d6155` and
`68272db93bfba4819438b35171d9b34478bc7a9b`).
- The proposal tree exactly matches the reviewed candidate and validated
source `547c255612`; reconciliation retained all reviewed commit
identities. Current upstream main is incorporated unchanged.
## Validation
- Recorded source proof `source-17es3j79`: 2,869 tests across 182 files,
typecheck, lint, production/embedded build and budgets passed, with
complete output and guest shutdown.
- Predecessor Chromium/WebKit controls reproduce the hidden temperature.
Final browser checks passed ten desktop/phone states covering standalone
temperature, critical thresholds, Fahrenheit, missing readings and full
SMART data; screenshots were inspected in the reviewed evidence.
- Publication provenance and range whitespace checks passed. Exact tree
equality makes repeating these checks unnecessary.
- Exact-head PR checks must pass before landing. Synthetic presentation
proof does not establish native appliance collection, whole PBS/TrueNAS
issue resolution, installed acceptance or release availability. This
does not alter the frozen v6.4.6 candidate.
[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
## What changed
History now distinguishes a successful empty response from a failed
background refresh. Empty charts no longer promise that collection is
running. If a refresh fails, the chart keeps its last successful
readings and source visible, with an accessible warning until recovery
or a target change. Initial load failures remain distinct.
This addresses two misleading states found while improving the existing
Storage/PBS History surface; it does not claim to repair native
collection or resolve every symptom in #1723.
## Included source
- Range:
`1a41c8f0e0c84ac9c9465df2918c88e6b11b48f7..6e410d8430c3aa4db26904005d9e4b61b75935f7`.
- Runtime candidate `c6edeee869a11f9206390e855fc63da744fb394a`;
assertion and browser-evidence correction
`df18123e7da3b682eed811c0e01c94a44dc2c29c`.
- Additive integration `6e410d8430c3aa4db26904005d9e4b61b75935f7`
preserves those commits and incorporates published main. Its complete
tree equals the validated candidate tree.
## Validation
- Recorded offline source proof: 2,814 tests across 181 files,
typecheck, lint, production/embedded build and budgets passed, with
complete output and guest shutdown.
- Recorded Chromium desktop and WebKit phone checks cover 16 states,
including predecessor reproduction, failed/pending refresh, recovery,
target change and initial failure; screenshots were inspected by the
source owner.
- Publication checks: provenance, complete-range browser receipt/content
coverage, canonical contract guard, tree equality and whitespace checks
passed.
- Earlier obsolete-copy assertion, browser selector and timestamp
failures remain recorded; corrected proofs followed them.
These are synthetic source/presentation checks, not native PBS
acceptance or release qualification. Exact-head PR checks and review
remain required before landing. Release placement is separate.
[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
Preserve exact reviewed History commits and their browser receipts while incorporating the published frontier present at batch start.
Change-source: pulse-maintainer
## Outcome
Keep Storage History readings tied to the selected target, and make
individual readings usable without a mouse.
Late responses and polling from a previous target could replace the
selected target's data. The reviewed repair invalidates superseded
requests and clears stale readings while retaining pointer inspection
during matching live refreshes. Keyboard focus, arrows, Home/End and
Escape now inspect actual samples; polite announcements and a taller
tooltip keep timestamp/value readings usable. This improves the existing
History surface, not a new feature.
## Included source
Base `1ecb0d6e490abb7a915ba498957bd622b9deab2f` → proposed
`65a36dd4e7a83e682b9dadc4bb624d79fcb10546`.
- Target ownership candidate `9dc6bd0ffe..1177e4d143`, integrated by
`cf5d6cdf06`.
- Keyboard/tooltip candidate `0be430813f..65a36dd4e7`, including
corrected geometry and empty-announcement regression assertions.
All reviewed commit identities and ancestry are retained.
## Validation
Recorded exact-source proof `source-haln3xw5`: 1,405 tests, typecheck,
lint, production/embedded builds and budgets passed with complete output
and guest stop. Recorded Chromium/WebKit parent/final browser controls
cover 14 keyboard navigation states plus linked/empty charts and focus
exit; target-selection regressions cover delayed responses and refresh
ownership. Initial browser setup and assertion failures remain recorded
with their corrections.
Publication checks: provenance, whitespace, aggregate completion guard
and committed-range browser receipt validation passed. Existing
sufficient proofs were not replayed. Required exact-head CI and
independent review still apply. Synthetic browser/DOM checks are not
screen-reader or native PBS acceptance, and this PR does not establish
release availability or whole-issue resolution.
[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
A fresh two-engine browser pass verifies the unchanged runtime source. Update the cross-surface empty-state assertions to the truthful copy.
Contract-Neutral: Verification and receipt corrections only; runtime source and subsystem contracts are unchanged.
Change-source: pulse-maintainer