Commit Graph

12251 Commits

Author SHA1 Message Date
pulse-triage[bot] d77f56bee4 Integrate reviewed fully cached Patrol budget and projection accounting
Retain cache-only success and partial usage using the shared four-bucket rule. Exact-source parent/final race evidence source-m_se_bxv covers result, ledger, next-run budget and history boundaries; broad readiness failures remain adverse operational evidence, not product-test results.

Change-source: pulse-maintainer
2026-10-04 03:57:17 +01:00
pulse-triage[bot] d5e0b4a19a Incorporate published main frontier for cached Patrol review
Preserve published commit identity alongside already reviewed local guest provenance changes; published merge adds no new content.

Change-source: pulse-maintainer
2026-10-04 03:57:07 +01:00
pulse-triage[bot] e7c2b37cf6 Keep fully cached Patrol usage in budgets and cost projections
Follow up #2118/#2350: ordinary input can be zero while cache writes or reads remain billable. Preserve cache-only successful and partial results, record them in the usage ledger, and include them in the history median and triggered-spend rate. Keep genuinely empty/expired history excluded and retain the existing five-minute prices and budget semantics.

Change-source: pulse-maintainer
2026-10-04 03:25:57 +01:00
pulse-triage[bot] 614d68a55e Report advancing Podman CPU and keep TrueNAS probe results separate from polling (#2454)
## What changed and why

- Podman one-shot stats can report a zero percentage while CPU counters
advance. The collector now retains a baseline on every sample and uses
valid CPU-time/wall-clock intervals when the compatibility percentage is
zero, absent or invalid. Positive native percentages keep their existing
units; container restarts rebaseline and duplicate/backward samples
cannot manufacture spikes. Docker calculations remain unchanged.
- A saved TrueNAS connection test reads system information through a
separate client, not the scheduled inventory poller. Its success or
failure now stays in the probe response rather than clearing runtime
errors, advancing freshness/readiness or postponing inventory polling.
Real runtime polling still owns those state changes. Stored-secret and
tenant boundaries remain intact.
- Matching subsystem contracts and regression fixtures distinguish a
successful connection probe from actual inventory collection.

Related to #2447.

Related to #2382.

These changes address demonstrated source mechanisms. Native Podman
payload, graph/alert acceptance and the original TrueNAS
appliance/session failure remain unverified. The probe conflation also
existed in 6.4.1 and is not attribution of the reported 6.4.5
regression; the other TrueNAS session reports remain separate.

## Included source

Base `7fa6d164628588ac65872fb4e67a15aa3f92e2c8` → reviewed tip
`e382a5cd458f72e72235cb363121acc6f2f23ad5`.

Core candidate `ac51a2d37847d2bdc639ce81908d66161ae62a03` comprises:
- `ab978b6cfc4a27749e653f975d729609c8d53f52`: Podman interval CPU.
- `9677b5cd60758f01fd9f3dd9eeeeb58e82ae3ed7`: probe/runtime evidence
separation.
- `afd6cf975744836a2b5e461890563e2e1c3ce33f` and
`ac51a2d37847d2bdc639ce81908d66161ae62a03`: legacy-key and API contract
fixture reconciliation.

Integration `e382a5cd` preserves all reviewed commit identities and
published main ancestry.

## Validation and limits

Core's completed candidate proofs `source-ogv54f5k` / `source-r72b93x8`
report 5,942 top-level passes, 12,059 passing case events and 24
explicit native/load/SLO skips, including all 3,803 API tests across
five disjoint shards, races, vet and release/agent/helper builds. Its
frontend proof `source-3yj9h19f` covers that candidate's unchanged
frontend; intervening frontend changes are already published, not newly
claimed by this proposal.

Canonical-head offline proof `source-cfgfywcu` additionally passes
focused race checks in `internal/dockeragent`, `internal/monitoring` and
`internal/api` at exact head `e382a5cd458f72e72235cb363121acc6f2f23ad5`,
with complete output and stopped guest. It uses the standard dummy
frontend test assets, not a release build. It covers CPU
decoding/collection, TrueNAS runtime summaries and
saved-probe/list/contract controls. Relevant collector/poller/handler
implementation bytes match the validated Core candidate.

Provenance, whitespace and all four per-commit canonical completion
guards pass. Browser verification correctly skips this backend-only
range. Earlier adverse attempts remain retained in Core's outcome; none
is relabelled a pass. Exact-head protected CI and independent review
remain landing gates. Source publication does not establish reporter
resolution, native fleet relief, deployment or release readiness.


[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-04 02:21:37 +00:00
pulse-triage[bot] da49bcdf8c Integrate reviewed guest filesystem provenance and phone value visibility
Change-source: pulse-maintainer
2026-10-04 03:13:42 +01:00
pulse-triage[bot] e382a5cd45 Integrate reviewed Podman CPU and TrueNAS probe evidence repairs
Change-source: pulse-maintainer
2026-10-04 03:00:48 +01:00
pulse-triage[bot] 031de38ec1 Narrow filesystem provenance reads to the VM source type
The final-source controls passed 342 tests but type-check reported TS2339: WorkloadGuest also includes containers without diskStatusReason. Read the existing VM-only field after the local guest passes its type guard, preserving reactive identity and presentation. Record a fresh inspected browser pass on the corrected bytes; the earlier failed proof remains retained.

Change-source: pulse-maintainer
Contract-Neutral: Type-only correction to the existing VM-only provenance memo; no surface, contract or safety semantics change.
2026-10-04 02:59:44 +01:00
pulse-triage[bot] 7fa6d16462 Open guest details on the first tap and clarify container-update recovery (#2453)
## Outcome and why

- **Guest details open on the first phone tap.** Give VM and container
rows the same native click eligibility as shared table rows while
preserving delegated actions, keyboard disclosure and nested-link
isolation. The observed touch-browser failure hid existing backup and
disk safety details.
- **Container-update help states the real recovery limits.** Put
independent application-data backups before updates. Explain shared
mounts, five-minute old-container removal, best-effort rollback and
limited readiness checks; distinguish image-update suppression from
command authority. The preceding guide promised recovery guarantees the
agent does not provide.
- **Promotion controls preserve billing state.** Strengthen the existing
read-only entitlement and integrity assertions after an obsolete
assertion blocked the preceding reviewed batch. No production billing or
release authority changes.

Related to #1891. Its installed failed-update and durable recovery
outcomes remain unfinished. Related to #2439. Opening safety details is
not native guest thaw or a demonstrated fix for that report. No issue is
intentionally closed.

## Reviewed range and reconciliation

Complete range:
`dd00f9fccd6a7e66eb8841d230cb82d0d3b46cf1..5311a7c6febc5dfd7fcd81b10ca188d925e34527`.

Includes:
- Delivery candidate `c5bd6f1d99eecd49b5907c3091197dcbf55a6511`,
integrated at `a131e4be7dd83c323af9d3613f1b4b5e95624bbd` with the union
of overlapping test assertions.
- Container-help candidate
`c211bfe5229b2823975a708a6fa5c11435396b3d..1b97f2d94b3f4600ac0be45b31e16f4283c2c6f9`,
integrated at `4c3d6f10c4a979d1ed02d82229eeeb2f78acdbed`.
- Guest-row repairs `d856689f5b3b200c942db4151a0b657cfdacf1c4` and
`826eaf2a1275b59dfc22f372958665223a0ebbe8`, qualified together at
`116211d7f2585481b79f28c7c441aa6efbb879a1` and integrated at the final
head.
- Additive upstream composition
`6de9771e76340d83d53730ebb2acbe78ae253487` retains the current published
main and every reviewed identity. No accepted history was rewritten;
dependency manifests are unchanged.

## Validation and limits

Retained owning proof `source-vrim01em` passes 137 GuestRow tests, full
types, focused lint/format, copy and row accessibility audits,
production frontend/embed build and budgets. Original own-parent browser
receipts cover the exact unchanged final row bytes: six
guest/full-drawer cases plus four shared-row controls, desktop Chromium
and phone WebKit, first/repeated taps, keyboard disclosure and
propagation isolation. This is emulated browser evidence, not a physical
phone or native backup operation.

Retained help proof `source-34vo9thj` passes 59 rendered-doc controls,
types, focused lint/format/copy, production build/budgets and mirrors.
Its inspected desktop Chromium and phone WebKit witness covers help
rendering, keyboard navigation and overflow, not an actual container
update or rollback. Retained Delivery proof `source-o60c8bal` passes 60
promotion controls, 58 connected demo-transaction controls and two
install contracts. Earlier setup failures and corrected intermediate
lint/theme observations remain adverse history, not passes.

Final-range provenance, whitespace, canonical completion, exact guide
mirror and cumulative two-file browser coverage pass. The final-source
promotion suite passes all 60 controls. An additional combined frontend
check could not start within the isolated executor capacity window
(`proof-worker-busy`, client exit 2); it is not counted as a pass. The
checked row source/fixtures and guide/witness are byte-identical to
their respective owning proofs, the two changes are disjoint, and
manifests and shared renderer code are unchanged. Those sufficient
build/browser checks are reused; exact-head CI must still complete.

Independent review and required exact-head CI still govern landing. This
proposes source improvements only; containing release, installed
recovery, native thaw and customer acceptance remain separate outcomes.


[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-04 01:48:44 +00:00
pulse-triage[bot] 10f181b500 Keep guest filesystem provenance visible in every display mode
Show retained or unavailable read context beside filesystem values across bars, sparklines and history lenses, with the full safe reason available to assistive readers and the existing drawer. Announce retained chart values as last known, and let narrow chart plots yield width to the numeric value without growing dense rows. Include fixed-reason regressions, subsystem obligations and inspected final-content Chromium/WebKit proof.

Change-source: pulse-maintainer
2026-10-04 02:23:36 +01:00
pulse-triage[bot] 5311a7c6fe Integrate reviewed first-tap guest disclosure repair
Preserve the exact reviewed guest touch commits and own-parent browser receipts. Retained final-source proof covers the small native eligibility repair; native thaw, installed recovery and release delivery remain separate.

Change-source: pulse-maintainer
2026-10-04 01:53:58 +01:00
pulse-triage[bot] 4c3d6f10c4 Integrate reviewed monitored-container recovery guidance
Accept exact Product Intelligence candidate 1b97f2d94b. Existing help now states shared-data, five-minute old-container cleanup, best-effort rollback and separate command-authority limits. Retain owning final-source and rendered-help proof; no native update or release delivery is claimed.

Change-source: pulse-maintainer
2026-10-04 01:38:41 +01:00
pulse-triage[bot] 6de9771e76 Integrate batch-start published main without dropping reviewed identities
Retain the published batch-start frontier and locally reviewed billing-safe governance integration by exact ancestry. No source reconciliation beyond the batch-start frontier.

Change-source: pulse-maintainer
2026-10-04 01:38:00 +01:00
pulse-triage[bot] 116211d7f2 Compose retained guest touch repair for final source qualification
Preserve d856689f and 826eaf2a and their own-parent browser receipts on the supplied current base. Complete the unexecuted final-binding source checks and production embed build without changing the repair or dropping Recovery and release-governance maintenance.

Change-source: pulse-maintainer
2026-10-04 01:27:37 +01:00
pulse-triage[bot] dd00f9fccd Make monitoring, notification results and recovery guidance safer and more truthful (#2429)
## Outcome and why

Make existing monitoring evidence, notification results and recovery
guidance safer and more truthful.

- **Guest-agent reads respect backup activity.** Coordinate guest reads,
defer them around backup locks and incomplete responses, and show
freshness/deferral rather than presenting retained readings as current.
The VM diagnostic helper stays off the guest-agent channel. The serious
frozen-VM report in #2439 motivates this source mitigation; it is not a
reproduced freeze cause or native thaw proof. Advice remains to stop
Pulse before the backup and restart only after independently verified
thaw, with the monitoring/alert outage explained.
- **Current, permission-scoped monitoring details.** Keep drawers on the
current resource snapshot; retain stored disk History independently of
current collection; withdraw History and fallback readings on access
denial; scope fetched History to the active organisation. Improve honest
PBS/NAS, Docker, Kubernetes and guest disk rows, units, wrapping and
unknown/pending states. These address the existing #1723/#2077 panel
concerns without claiming every appliance symptom resolved.
- **Fewer false metadata changes, honest notification results.** Sort
deduplicated label-derived tags while retaining real metadata edits and
clears, addressing #2441's narrow cause and one contributor to #2199.
Keep delayed firing/recovery, pending groups and repeat cooldowns tied
to their alert occurrence. Preserve SMTP final-DATA acceptance despite
cleanup failure and reject interrupted ntfy responses rather than
reporting delivery success. Failed notification-evidence reads remain
visible, not empty success.
- **Safer existing help and recovery.** Explain the actual configuration
archive and its omissions, key/stopped-state requirements, retargeting
and partial-import risks. Keep backup versus snapshot evidence and
rollback consent separate. Use private credential-header files, bounded
failure-aware diagnostics, bootstrap installation authentication and
non-destructive login recovery. Updated instructions cover scheduler,
webhook freshness, deployment, platform navigation and bounded write/CPU
evidence (#1966/#2199); they do not establish runtime performance
relief.
- **Evidence-preserving demo update/recovery.** Route owned signed
runtime transactions through captured baselines, sustained observations
and guarded forward/reverse restoration, including restoration when
receipt writing fails. Add a separate native acceptance workflow without
claiming it has run or that an installed transaction has passed.
Release-note title guards are aligned with the existing signed-runtime
recovery model. No release is selected or published here.

## Reviewed source and upstream reconciliation

The complete current unpublished range is
`8e14b4a63e954c52cf30f0c533b213020abc9397..e597bb2a4beba8679782a453e0653bf53d3f743d`:
**138 commits, 86 non-merge source/proof commits**. Every previously
reviewed identity and ancestor is retained, including starting local tip
`3c0fdcc74255d3ea6192475206326ee176ddaa7c`.

Earlier publication updated PR2429 from
`7a5635b2c0b76e13f510cc7a27b7ca0cd55091ba`; its failures and additive
remedies are retained history. Failed logs identify the VM-diagnostics
fixture lacking authoritative configuration (Build run `37143637085`),
the Deferred badge substring also matching the unreadable-evidence
warning (E2E run `37143637132`), macOS temporary-path aliases (Native
run `37143637054`), and clear-text billing-state rewriting (CodeQL check
`111263223348`). Reviewed additive repairs `091f9877`, `d9a2c786`,
`cd20663a`, and `7d739698` address those paths. Re-running that old head
would not incorporate these repairs.

Later reviewed work is included now because the old batch cannot land
independently:

- Web candidate `0f480d23aff50bd33236d125aafbfd67b1a65fd9` preserves
`c54aa9e3` backup-response validation: unreadable/malformed responses
are not empty success, and one source's failure does not hide another
source's readable inventory. It composes measured disk labels with
paused-read provenance and same-VM resumption.
- Recovery help `2201fd59` distinguishes completed-backup evidence from
safe restore; proxy help `c381995d` keeps navigation aligned with the
forwarded-header trust boundary; independent bounded guest-write witness
`ee069f21` records writes/liveness without issuing guest-agent commands.
None proves native thaw or installed recovery.
- Billing-safe demo profile repair `7d739698` requires an already
admitted demo capability and leaves billing/key material untouched;
canonical encrypted/legacy/HMAC controls remain with the application.
Diagnostic and delivery fixtures assert the real admission/evidence
boundaries without weakening them.
- Core candidate `509c12f1ae7c27fd004890c4db9e6d12312c874c` isolates
strict zero-allocation checks from unrelated background fixture workers.
Current upstream independently adds a related isolation helper at
`8e14b4a6`. Additive merge `49e37ddd` reconciles the upstream entry
point with the reviewed bounded child launcher, measurement witness,
escaping result sink and background-allocation control. No production
normalisation or allocation threshold changes.

Startup-fetched upstream `8e14b4a63e954c52cf30f0c533b213020abc9397` was
merged by full identity. No reviewed commits were rebased, amended or
recreated. No stopped upstream-refresh attempt was replayed or
retrospectively cleared. Final frontend runtime and fixture bytes match
the owning Web candidate; additional upstream receipts are preserved
unchanged.

### Current proposal decision

PR2429 at `49e37dddfcf3ed03f5c47cdcca10a367969da9b5` has completed
validation, not a running batch to preserve. All functional backend/API
shards, frontend, eight E2E shards/verdict, native and CodeQL checks
succeeded. Required governance run `37161775883` failed because its
source assertion still demanded the billing-integrity removal and
entitlement rewrite that reviewed security repair `7d739698`
deliberately removed. Additive correction `e597bb2a` instead requires
read-only admission of an existing demo capability and rejects those
former unsafe writes. Production paths and thresholds are unchanged.
This batch cannot land independently until that required defect is
repaired, so the newer reviewed Recovery link work is included rather
than repeatedly advancing a checking head.

Product Intelligence candidate
`2a9e4183a6ff670d2f08dab3f67f4b95b27f6c1c`, source `48dc32d1`, is
retained by integration `3c0fdcc7`. Both Recovery mirrors now navigate
to the actual rendered safe-evidence heading. Its renderer regression
and Chromium/phone WebKit keyboard-focus controls pass at the owning
exact source; the initial missing dependency and fixture-only full-shell
API500 remain separate adverse setup results. Retained `source-3ytpvq_m`
passes 58 docs controls, types, focused lint/copy, production
build/budgets and mirrors. No released or native recovery claim follows.

Advisory Benchmarks in completed Build/Test run `37161775840` reports
`HandleMetricsHistory_MemoryFallback/single-metric-4` **+15.59%**,
117.0us to 135.3us, p=0.035, n=10. That result is not a pass, diagnosed
noise or release approval. No measurement or workflow was replayed;
Delivery receives the exact head/run/evidence for its existing
performance follow-through. The test-only correction does not remedy
this performance observation. New exact-head CI must run normally.

## Validation and remaining limits

Current lightweight final-source fixture proof via
`pulse-maintainer-proof` at `e597bb2a` passes all **60 release-promotion
policy controls and 58 demo transaction fixture controls** (complete
output; exit 0). The disposable source-proof request remained queued for
capacity at the last observation and has no terminal receipt; it is not
counted as a pass. No new production bytes require repeating already
sufficient heavy functional evidence. A first dirty-source proof
admission was refused before execution, and the initial correction
commit was refused for noncontiguous trailers; the clean committed
correction fixes that metadata, with no accepted commit rewritten.
Current provenance, whitespace, the three added source/proof commits'
own-parent/history guards, 34-path final browser coverage,
contract/registry audits and shipped-doc/public-doc checks pass. Earlier
83-commit governance and unchanged functional evidence are retained, not
claimed as new execution.

Retained reviewed evidence is reused where final bytes are unchanged:

- Earlier Web `source-iad0hwfi` / `source-e56ectzj`: 21,916 frontend
passes / three skips, types/lint/format, real production embed/build and
inspected desktop/phone fixture families. Migration `source-uawz1_yy`
and `source-eb0vj05m` retain types, focused tests, production
build/budgets and inspected combined help/dialog rendering.
- Core `source-s1fokff6` / `source-ect7ogdd`: consumer/tag/API/race
controls and real embed/application build. Earlier cleanup and
performance/native limitations remain adverse evidence, not cleared
acceptance.
- Composed fixes `source-00eqpxhc`: 140 frontend tests,
types/build/budgets; `source-zfh88hkq`: diagnostic/billing controls and
58 demo methods. These are retained reviewed proofs at their recorded
source, not a new execution here.
- Final owning Web: unchanged 580-case `source-fi8xj80e`; 467 combined
tests and types completed in `source-9ua5hue8`, which then failed test
formatting; the separate committed correction `source-jq0lly7u` passes.
Chromium/WebKit rendering, eight inspected settled screenshots and
own-parent receipts cover the combined reader/disk content. Trusted
phone row/name taps did not activate the drawer; mouse-click rendering
is not touch acceptance. That unresolved input observation remains with
Web.
- Core allocation candidate: `source-g3lk4tyh` passes connected
controls, full required API shard under races, vet and real application
build; `source-720fc09_` supplies actual frontend assets;
`source-ya9bup8h` passes release-tagged embed/allocation consumers.
Skipped native/load/SLO controls remain explicit.

Previously recorded provenance, whitespace, **all 83**
own-parent/history governance checks, final-content browser coverage for
**34 frontend source files**, 62 shipped-doc mirrors, 211 public
Markdown documents, workflow trust and 16-subsystem contract/registry
audits pass.

Retained exact-source `source-bh_gki5e` at `49e37ddd` passes
normaliser/allocation/background-worker and VM-diagnostic admission
checks, followed by normaliser/allocation race checks: 311 passing case
events, no skips; complete 44,002-byte output is hash-matched and the
guest stop completed. This uses the repository's explicit synthetic
test-assets setup, not a new real production embed or full API-suite
acceptance. The first all-API attempt `source-d2rcrw3i` failed at
compile setup because the clean offline VM lacked generated frontend
assets; no test ran. That failed attempt and an earlier dirty-source
admission failure remain recorded separately. Unchanged
frontend/real-build evidence above is reused, not replaced by the
synthetic test index.

Independent review and required exact-head GitHub checks still govern
landing; old failed checks are not a pass. Source publication
establishes neither a release nor native backup thaw, fleet performance,
installed update/recovery, appliance/panel acceptance or reporter
confirmation. The frozen release candidate is unchanged; containing
all-main release and native follow-through remain separate work. No
issue is intentionally closed by this partial maintenance batch.

<details>
<summary>Complete unpublished non-merge source/proof inventory</summary>

```text
e597bb2a4b Keep release governance aligned with billing-safe demo profiles
2a9e4183a6 Keep the safe-reporting browser check on the Docs fixture
48dc32d1a3 Fix Recovery safe-reporting navigation
0f480d23af Verify composed disk labels without losing paused-read context
c54aa9e3e7 Reject unreadable backup responses before publishing inventory
509c12f1ae Isolate route allocation checks from API fixture workers
d203eeb17a Bind backup read tests to cancellation and independent settlement
d9292ef38c Keep backup inventory failures source-local
2201fd59b4 Make recovery help distinguish backup evidence from safe restore
5355a41c08 Record final browser proof for composed disk and backup presentation
7d73969882 Keep demo runtime profile changes out of signed billing state
091f987798 Exercise authoritative guest-lock admission in VM diagnostics fixtures
d9a2c78612 Assert held delivery rows separately from unreadable evidence
c381995d24 Keep proxy-auth help navigation independent of emoji fragments
cd20663a7e Keep demo recovery fixtures portable across temporary path aliases
ee069f2144 Add independent bounded guest-write evidence for backup thaw
bbf839a261 Keep completed guest backup evidence visible during activity
d36dba5dff Verify trusted-peer proxy help in the shipped Docs viewer
cbbed83add Make reverse-proxy help match the forwarded-header trust boundary
971d4e9f77 Keep auth context tests independent of tenant runtime writers
76484e4e8c Verify combined migration warnings and guides on Tailwind 4
b8eaed71c8 Record final-content browser proof for the composed frontend
1e9c2bdae6 Bind migration browser checks to the composed source graph
e5986b2edc Remove trailing whitespace from migration browser harness
11c7f32dba Format the combined Swarm wrapping regression assertion
26c64634f0 Verify configuration scope without outbound-network assumptions
9a05a5d477 Keep connected metadata controls independent of tag ordering
4e57511d1e Stabilise label-derived tags without hiding metadata changes
73d2c64e0f Make configuration migration warnings match the actual backup
6725576c7e Allow full-width guest freshness explanations in drawer ownership guard
a355525d57 Keep fresh drawer test bytes consistent with its percentage
b22d3b4490 Explain deferred guest reads without unsafe backup advice
3c57c2d207 Defer guest commands after incomplete HTTP error responses
6ec491bdf3 Keep VM disk diagnostics off the guest-agent channel
98e2a5ef69 Keep release guards aligned with signed runtime recovery
a090a67756 Keep guest-agent admission single-attempt for password sessions
577e40edf3 Keep guest-agent continuity guard aligned with backup deferral
41457c8a82 Make copied webhook verification freshness-aware
35914abab7 Validate release notes by their exact first title
2df28d5877 Defer and coordinate Proxmox guest-agent reads around backup locks
ec5c96a290 Keep scheduler diagnostics private and failure-aware
9df89142d3 Keep notification activity truthful when evidence reads fail
3a98883de1 Preserve notification verdicts through SMTP cleanup and ntfy diagnostics
43b81bbb2b Exercise curl header removal and explicit empty roles separately
2789a15fe5 Keep authentication diagnostics private and permission-aware
9c3d79ba6a Scope Swarm browser check to the current-state evidence
2839333474 Make operator-row browser fixture self-contained
480be08288 Preserve REST operator evidence and readable platform rows
462cdfb170 Recover local logins without deleting authentication state
200ce831a8 Keep installation quick starts on bootstrap authentication
aefbb2b6c4 Verify private-auth help through production rendering
f273e86189 Keep Docker setup credentials private across help languages
e899ecb0cf Keep backup evidence and rollback consent truthful on narrow screens
45835634ea Qualify rollback help by updater and backup scope
6e5acd9c02 Keep denied resource evidence out of drawer fallbacks
d16e665e6c Route deployment updates through evidence-preserving procedures
2dda2e6653 Scope fetched History to the active organisation
227657b1b0 Retain the attempted terminal phase on writer failure
5cf724b4e7 Keep recovery independent of its phase writer interface
f827f7150f Restore owned demo runtime despite receipt I/O failure
ae427e6afe Respect the Docs heading inset in recovery visual checks
c71bdbbda7 Capture the recovery procedure after theme and scroll settle
4fbb69a7dd Make server update and rollback help evidence-preserving
a23029a80c Keep demo installation proof aligned with signed runtime operation
ac995ef565 Keep pending notification groups occurrence-qualified
a2fc29b70b Limit guarded demo updates to owned signed runtime files
6f5bf96370 Withdraw History readings when access is denied
63b24757d6 Accept readable wrapped help tables as well as local scrolling
0027f7c9d9 Verify help table cells with the production style configuration
661d7c7b2e Activate paired firing work in the receipt-ordering fixture
1a1b59072b Point monitoring help at the current platform navigation
0dcd592ef2 Keep notification cooldowns ordered by alert occurrence
ee451f8c8c Restore canonical ordering for demo registry entries
7ec246381f Check retained demo profile inside its owning transaction
360721cc91 Bind demo cohost observation to the real Relay health route
c9a0f0bf6a Keep stored disk History independent of current collection
d0d621a7c2 Exercise detector admission in partial-delivery recovery proof
4df3e8974e Add disposable native acceptance for owned demo recovery
1c9440546a Use destination receipts for delayed partial-delivery recovery
2c57a54ec4 Preserve sending-row crash recovery in the occurrence fixture
8f42497b8f Keep delayed alert recovery scoped to its resolved occurrence
b3937a4803 Use the actual lookup receipt shape in demo ownership proof
751fb67523 Bind demo controls without broadening unrelated release proof
f56e28e6af Own demo update and recovery through sustained host observation
286c8a1f51 Make write and CPU troubleshooting bounded and evidence-preserving
0d8d5beb5f Keep open resource details on current snapshots
```
</details>


[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)


[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-04 00:24:56 +00:00
pulse-triage[bot] a131e4be7d Integrate reviewed billing-safe promotion controls
Merge exact Delivery candidate c5bd6f1d99. Resolve the overlapping test-only repair by retaining the union of existing and candidate read-only admission and billing-write prohibitions. No runtime or frontend changes.

Contract-Neutral: Test-only integration preserves production behaviour and release authority.
Change-source: pulse-maintainer
2026-10-04 01:20:15 +01:00
pulse-triage[bot] e597bb2a4b Keep release governance aligned with billing-safe demo profiles
PR2429 governance run 37161775883 still required the superseded entitlement rewrite after reviewed repair 7d739698 made profile admission read-only. Require the existing demo capability and reject the former integrity removal and billing rewrite instead. Retain runtime-setting, release and recovery guards unchanged.

Contract-Neutral: Test-only integration reconciliation; production billing and release admission are unchanged.
Change-source: pulse-maintainer
2026-10-04 01:04:36 +01:00
pulse-triage[bot] ac51a2d378 Keep saved TrueNAS probe contract independent of runtime polling
Update the legacy contract assertion exposed by the full API suite. A successful system-info-only probe remains successful but must not invent a runtime attempt, success or observed inventory. The real poll and failure-preservation controls remain unchanged.

Change-source: pulse-maintainer
2026-10-04 00:57:19 +01:00
pulse-triage[bot] 1b97f2d94b Capture Docker safety help after theme transitions settle
Wait for the Docs fixture theme transition before retaining phone screenshots. This changes the visual witness only, not rendering, container actions or the guide.

Contract-Neutral: Browser validation only; no runtime or public contract change.
Change-source: pulse-maintainer
2026-10-04 00:56:41 +01:00
pulse-triage[bot] c5bd6f1d99 Align promotion controls with billing-safe demo profiles
PR2429 governance run 37161775883 still requires the removed demo entitlement rewrite and integrity clearing. Require the existing read-only capability gate instead, and reject billing writes or integrity removal. Keep all runtime profile, protected publication and exact-RC controls.

Contract-Neutral: Test-only alignment with the reviewed billing-preserving demo transaction; no runtime, API, deployment authority or release policy delta.
Change-source: pulse-maintainer
2026-10-04 00:56:16 +01:00
pulse-triage[bot] c211bfe522 Make monitored-container update help truthful about recovery
Replace a claimed 15-minute backup and guaranteed rollback with the implemented five-minute cleanup, shared-data and best-effort limits. Put independent backups and deployment-manager recovery before the action, preserve current-state checks, and distinguish image-update suppression from command authority.

Contract-Neutral: Documentation and validation only; no container runtime, command authority or API changes.
Change-source: pulse-maintainer
2026-10-04 00:50:18 +01:00
pulse-triage[bot] 826eaf2a12 Forward native and delegated guest row handlers through typed props
Match the existing shared TableRow splitProps pattern so the JSX lint check recognises distinct native eligibility and delegated action handlers. Preserve the same callback ordering, conditional removal, identity and keyboard controls; repeat the production guest/full-drawer browser pass for the final binding.

Change-source: pulse-maintainer
Contract-Neutral: Typed handler forwarding preserves the already-contracted touch eligibility, actions, child isolation, accessibility, row identity and state; no contract delta.
2026-10-04 00:47:28 +01:00
pulse-triage[bot] afd6cf9757 Keep legacy-key probe controls independent of poll success
The connected proof passed both probe/poll evidence cases but found one older fixture still expecting a successful stored-key probe to manufacture poll success. Keep its stored-secret, HTTPS and missing-ID controls while requiring untouched runtime timestamps and observations. Retain the adverse proof separately.

Change-source: pulse-maintainer
2026-10-04 00:32:36 +01:00
pulse-triage[bot] d856689f5b Restore first-tap guest details on touch browsers
Reuse the shared non-activating native row marker without moving actions out of delegated event ordering. Preserve nested controls, keyboard disclosure, row identity and conditional action removal. Cover guest/full-drawer touch input and safe backup guidance with exact browser proof and source regressions.

Change-source: pulse-maintainer
2026-10-04 00:31:00 +01:00
pulse-triage[bot] 3c0fdcc742 Integrate reviewed Recovery safe-reporting navigation
Preserve exact Product Intelligence commits 48dc32d1a3 and 2a9e4183a6. Correct the existing Recovery link in both shipped mirrors and retain its renderer and desktop/phone keyboard-navigation controls. Reviewed source-3ytpvq_m and content-bound browser evidence remain adequate; no native recovery or released availability is claimed.

Contract-Neutral: Existing help-link repair and regression controls only; no runtime or API contract changes.
Change-source: pulse-maintainer
2026-10-04 00:30:56 +01:00
pulse-triage[bot] 49e37dddfc Compose current upstream allocation guard with reviewed maintenance repairs
Preserve reviewed tip 888d918ba1 and startup-fetched upstream 8e14b4a63e unchanged in history. Resolve the allocation-test conflict by retaining the upstream boolean entry point with the reviewed bounded child launcher, strict measurement witness, escaping root sink and background-allocation control. No runtime or threshold changes; no stopped refresh replay.

Contract-Neutral: Test-only additive reconciliation of allocation-isolation repairs; runtime contracts unchanged.
Change-source: pulse-maintainer
2026-10-04 00:15:28 +01:00
rcourtman 8e14b4a63e Measure route-normaliser allocations in an isolated child (#2451)
`TestNormalizeRoute_RootFastPathDoesNotAllocate` failed in the api-2
shard of #2445 (a frontend-only change) with `normalizeRoute("/")
allocated 419 times per call, want 0`. A rerun passed.

`testing.AllocsPerRun` diffs the process-wide `MemStats.Mallocs`, so it
also counts allocations by parallel tests and by goroutines that earlier
tests left running. Any of them that the scheduler lets in during the
measurement inflates the count. `TestNormalizeSegment_DoesNotAllocate`
has the same exposure.

Both tests now re-run themselves in a child process of the same test
binary (`-test.run=^Name$`), where nothing else allocates. The parent
fails if the child fails or does not report a PASS for the test. The
zero-allocation assertion is unchanged.

Evidence:
- With a leaked allocating goroutine and 30 concurrent processes
(`-count=40` each), the old tests failed in 30 of 30 processes (204
failing checks, for example `normalizeSegment("resources") allocated
8808 times per call`). The new tests passed in 30 of 30.
- Removing the `/` fast path via `-overlay` still fails:
`normalizeRoute("/") allocated 1 times per call, want 0`.
- `go test ./internal/api -run TestNormalizeRoute -count=200` passes on
the Mac and on pulse-dev. `-run DoesNotAllocate -count=200 -race` passes
on pulse-dev.
2026-10-04 00:02:36 +01:00
pulse-triage[bot] 888d918ba1 Integrate batch-start upstream frontier without dropping reviewed repairs
Merge exact upstream 99927467f5. Resolve only the agent-lifecycle contract append conflict by retaining both monitor recovery ownership and AI usage export clauses. Frontend auto-merges preserve reviewed final bytes; no runtime conflict correction or browser receipt rebinding.

Change-source: pulse-maintainer
2026-10-04 00:00:18 +01:00
pulse-triage[bot] 8a2e18a20f Integrate reviewed backup response validation and composed disk-label proof
Preserve exact Web candidate 0f480d23af and its own-parent browser receipts; retained source and browser evidence covers the final reader and deferred-read label content.

Change-source: pulse-maintainer
2026-10-03 23:59:47 +01:00
pulse-triage[bot] 9677b5cd60 Separate TrueNAS probes from runtime poll and readiness evidence
A saved connection test reads system.info on a separate client. Keep both probe results out of runtime timestamps, failures, retry cadence and inventory readiness. Preserve stored-secret and tenant boundaries, and validate the existing API evidence through real local client/poller/handler controls. Update the matching API, monitoring, lifecycle and recovery contracts together. This repairs the diagnostic gap in #2382; its native polling/session cause remains unverified.

Change-source: pulse-maintainer
2026-10-03 23:58:11 +01:00
pulse-triage[bot] ab978b6cfc Keep Podman CPU interval evidence when one-shot percentages are zero
Retain a baseline on every response and fall back to interval counters for zero, absent or invalid compatibility percentages. Preserve positive native units and Docker calculations, rebaseline on restarts and reject out-of-order intervals. Add connected collector controls and the matching monitoring and agent contracts. Addresses the source gap reported in #2447; native payload and reporter acceptance remain unverified.

Change-source: pulse-maintainer
2026-10-03 23:57:05 +01:00
pulse-triage[bot] 0f480d23af Verify composed disk labels without losing paused-read context
Add owning-Web browser proof for the exact combined model after preserving the reviewed backup-reader and original upstream commits. Exercise measured label fit, independent provenance and settled same-VM resumption in Chromium and phone WebKit, while explicitly retaining failed trusted row-tap evidence. Correct only Prettier layout in the additive test resolution; do not repeat the unchanged backup suite or claim native acceptance.

Change-source: pulse-maintainer
Contract-Neutral: Browser fixtures and own-parent receipt for already composed runtime; Prettier-only assertion layout, with no new contract behaviour.
2026-10-03 23:42:25 +01:00
pulse-triage[bot] a30758c33a Integrate reviewed isolated API allocation guards
Change-source: pulse-maintainer
2026-10-03 23:33:43 +01:00
pulse-triage[bot] 2a9e4183a6 Keep the safe-reporting browser check on the Docs fixture
The navigation check uses the production Docs component and real shipped assets. Reloading its route instead loaded the full application shell, which needs an unavailable backend; retain that adverse run and keep this check on the changed link.

Contract-Neutral: Browser-test scope correction only; product and documentation bytes are unchanged.
Change-source: pulse-maintainer
2026-10-03 23:32:14 +01:00
rcourtman 06ddc47e22 Measure route-normaliser allocations in an isolated child
TestNormalizeRoute_RootFastPathDoesNotAllocate failed in the api-2 shard
of PR 2445 with normalizeRoute("/") reporting 419 allocations per call,
though the fast path only returns a constant. testing.AllocsPerRun diffs
the process-wide malloc counter, so it also counts allocations made by
parallel tests and by goroutines earlier tests leave running whenever the
scheduler lets one in during the measurement. Under CPU contention with a
leaked allocating goroutine, the old checks failed in 30 of 30 runs.

Both zero-allocation tests (normalizeRoute's root fast path and
normalizeSegment) now re-run themselves in a child of the same test
binary, limited to that one test, where nothing else allocates. The
assertion is unchanged: removing the fast path still fails with
normalizeRoute("/") allocated 1 times per call. The same contended
stress passes 30 of 30, and -count=200 passes locally and on pulse-dev,
with and without -race.
2026-10-03 23:28:38 +01:00
pulse-triage[bot] 48dc32d1a3 Fix Recovery safe-reporting navigation
Resolve the shipped Recovery link to the actual Troubleshooting heading and bind it to rendered Markdown. Exercise keyboard and reload fragment navigation in desktop Chromium and phone WebKit.

Contract-Neutral: Correct an existing help link and add regression controls; no API or subsystem contract changes.
Change-source: pulse-maintainer
2026-10-03 23:24:02 +01:00
pulse-triage[bot] ffac59b6dc Compose exact upstream storage and workload presentation
Preserve reviewed backup-reader and canonical deferred-read status guidance with upstream measured-width disk labels. Resolve only additive test assertions, keeping lifecycle refusal, PMG replacement, phone projection and word-wrapping controls. The combined disk model matches the previously diagnosed 9f50f630 content and requires fresh owning-lane browser proof.

Change-source: pulse-maintainer
2026-10-03 23:20:52 +01:00
pulse-triage[bot] 0c827e7dd7 Compose reviewed backup response validation
Preserve reviewed c54aa9e3 unchanged alongside canonical recovery help and storage presentation. Retain its exact-source proof; obtain owning-lane proof for the remaining combined upstream model.

Change-source: pulse-maintainer
2026-10-03 23:19:47 +01:00
rcourtman 99927467f5 Record a browser pass for the merged stacked disk bar model (#2450)
PRs #2438 and #2449 each verified their own edit to
`stackedDiskBarModel.ts`. The file that ended up on main combines both
edits and had no receipt, so the Canonical Governance push run for #2449
failed range validation.

This adds only a receipt for that combined content. It was verified on a
mock stack built from main, at 1440, 1280, 900 and 390px (plus dark at
1440): multi-disk nodes show their fullest-disk percentage beside the
micro-bars, single-disk nodes keep their used/total label, and no
disk-cell text clips.
2026-10-03 23:05:06 +01:00
rcourtman 4cf935d4cc Record a browser pass for the merged stacked disk bar model
PRs 2438 and 2449 each verified their own edit to stackedDiskBarModel.ts, but the file main now holds combines both and had no receipt, so the main push run for 2449 failed range validation. This records a pass of the combined content on a mock stack built from main.
2026-10-03 22:44:00 +01:00
rcourtman 06a68dbff3 Warn on inherited npm advisories when the lockfile is unchanged (#2442)
Since 3 October the required Frontend check has failed on every open
pull request, including Go-only ones, because of GHSA-vfj7-8cjw-p6xm
(`braces` <= 3.0.3, high, no patched release). `braces` reaches the
frontend graph only through dev-only `tailwindcss` 3 and `jscpd` 4. `npm
audit --omit=dev` is clean, so the shipped bundle is not affected.

A pull request that leaves `package.json` and `package-lock.json`
untouched has the same dependency graph as its base commit. It can
neither add a finding nor remove one, so failing it blocks every fix
without making anything safer.

## What changes

`scripts/npm-audit-retry.sh` now treats findings the same way it already
treated an unreachable advisory endpoint:

- **The change moves the dependency graph, or edits the runner**
(`NPM_AUDIT_REQUIRE_RESULT=true`): any finding at any severity fails, as
before. A missing answer also fails.
- **The graph is the base commit's** (`NPM_AUDIT_REQUIRE_RESULT=false`):
the run warns instead, still naming every finding. A missing answer also
only warns, as before.
- **Only an explicit `false` relaxes the verdict.** An empty or
unrecognised value stays strict. This also tightens the outage path,
which previously relaxed on any value other than `true`.

The scheduled `npm-audit` scan and the daily dependency advisory watch
keep the strict default. An inherited advisory therefore still fails
once a day until the graph is fixed; `test_dependency_advisory_watch.py`
now proves this. No severity threshold, allowlist or suppression is
added.

## Landing

This change edits the runner, so its own Frontend audit runs in strict
mode and fails on this same advisory. It cannot pass the required
checks, so it lands only by an explicit maintainer merge. That is
intentional: the policy is relaxed by a human decision, never by a
change passing its own check.

Removing `braces` for real means migrating to Tailwind 4 and jscpd
5.4.0; that is tracked separately. Dependency PRs (#2352, #2278) stay
blocked until that lands.

## Verification

- `scripts/tests/test-npm-audit-retry.sh`: 19 cases pass.
- `test_npm_audit_retry.py` and `test_dependency_advisory_watch.py`
pass.
- `TestFrontendDependencySecurityAuditsAreRequired` passes.
- `check_workflow_trust.py` passes.
- The real runner against main's lockfile exits 0 with the warning and
all 7 findings named when `NPM_AUDIT_REQUIRE_RESULT=false`, and exits 1
with `::error::` when it is `true`.
2026-10-03 22:41:14 +01:00
rcourtman 5ef76a0bbd Show the last backup in Proxmox coverage and keep its tables whole on phones (#2448)
Supersedes #2435, whose branch conflicted with the Tailwind 4 move
(#2443) in `proxmoxHostTableModel.test.ts`. Same change, rebuilt as one
commit on current main with a fresh browser pass and receipt.

- **Coverage:** the Restore column is now Last backup, meaning the
newest completed PBS snapshot or PVE backup file. Guest snapshots no
longer count, matching the posture engine.
- **Phones:** the node, backup server, coverage and By date tables keep
their values whole on phones.
- **By date Details:** shows the archive format (`vma.zst`, `tar.zst`)
with the full volid on hover and in search.

Verified on a private mock stack at 1440, 560, 440 and 390px, in light
and dark. On phones, only identity strings clip.

A second commit restores two `storage-recovery.md` notes from main,
covering History touch inspection and pool-to-disk ownership. The
original branch had dropped them with a stale copy of the file.
2026-10-03 22:33:52 +01:00
rcourtman eaa4b965da Account Anthropic prompt-cache usage instead of dropping it (#2431)
Fixes #2350 (from #2118).

The Anthropic client logged `cache_creation_input_tokens` and
`cache_read_input_tokens` and then returned only `input_tokens` and
`output_tokens`, so every cached Patrol run reached the usage ledger,
the cost preview, the budget check and the weekly digest with its cache
buckets missing. #2350 reproduced the loss on both the `Chat` and
`ChatStream` paths.

Both response paths now carry the two buckets as fields disjoint from
`InputTokens` (streaming assigns them from `message_start` and the final
cumulative `message_delta` rather than summing). The agentic loops,
Patrol responses and run records sum them beside the ordinary totals,
the usage ledger and its persisted copies keep them, and
`cost.EstimateUsageUSD` prices each bucket at Anthropic's published
cache rates (5-minute write 1.25x, read 0.1x of the input rate), falling
back to the input rate for providers without a known cache price. Spend
summaries, the digest spend, the cost projection medians and the usage
export expose the buckets and price them the same way. `InputTokens`
keeps its meaning everywhere, so the telemetry token buckets are
unchanged.

Proof: `anthropic_test.go` (both response paths keep the buckets; the
final delta does not double them), `pricing_anthropic_test.go`,
`store_test.go`, `patrol_digest_test.go`,
`patrol_cost_projection_test.go`, `cost_persistence_test.go`, and
`ai_handlers_more_test.go` for the export in both formats. This repairs
lost accounting data; it is not a measured provider bill or a claim of
savings across six-hourly runs.
2026-10-03 22:30:26 +01:00
rcourtman a53f43b2b5 Proxmox and Docker page passes: storage words, first paint, table fits (#2449)
Supersedes #2432, whose branch conflicted with the Tailwind 4 move
(#2443) in `StackedDiskBar.tsx` and `DockerTasksTable.tsx`. Same eight
fixes, rebuilt as one commit on current main. The conflict resolution
keeps both this change and main's class renames (`rounded-sm` to
`rounded-xs`). A fresh browser pass and receipt are included.

Proxmox
- PBS datastores read Online in the storage vocabulary instead of
Unknown.
- The mock estate carries shared PBS storage as one cluster row.
- Storage types read LVM-Thin and NFS, and cluster-merged storage reads
"Shared · N nodes".
- REST-mapped resources carry PMG metadata, so the Mail Gateway table no
longer paints dashes on fresh loads.
- In Bars mode, multi-disk hosts show their fullest disk's percentage.
- REST rows carry source status, action readiness and technology.

Docker
- The containers table fits at laptop and phone widths.
- Swarm states read as words, and task times show as ages.
- Demo container names are unique per host.

Verified on a private mock stack built from this tree at 1440, 1280 and
390px, in light and dark.
2026-10-03 22:23:22 +01:00
rcourtman bab3530214 Carry Kubernetes job times into the controller row expansion (#2434)
## Why

The Workload Controllers table hides its Detail column below a 76rem
container, and that column was the only place a Job's completion time
and a CronJob's last success or last run were shown. The row expansion
rendered only the generic Observed state, Last seen, Identity and
Aliases, so a phone or a half-width pane had no way to read when a job
finished. At 390px the 15 percent Kind track also clipped "DaemonSet",
"StatefulSet" and "CronJob", and the Target track clipped "1
completions".

## What

- The drawer's Kubernetes model builds a per-kind controller section
(Job, CronJob, DaemonSet, StatefulSet, ReplicaSet) that the
always-visible summary tables render in the same slot as the Docker
container section, so the facts are one tap away at every width and on
the Infrastructure drawer too. Job rows lead with Started, Completed and
Duration; CronJob rows with Schedule, Last run and Last success; each
timestamp is the absolute time with its age in parentheses and wraps in
a phone-width cell. Target, counts, the StatefulSet service name,
Namespace and Cluster follow.
- The phone projection keeps Controller, Kind, Ready and Issues and
demotes Target with `platform-table-phone-hidden`, widening Kind to 25
percent so every kind label fits whole.
- The Target count pluralizes through `getPlatformResourceCountNoun`, so
a single completion reads "1 completion" in the row as it does in the
expansion.

## Verification

Playwright clip sweep (scrollWidth over clientWidth on every th/td and
their children) at 1440, 1280, 900 and 390px against a private mock-mode
stack, with each CronJob, Job, DaemonSet and StatefulSet row expanded at
every width:

- 390px: the Kind track is 90px and no kind label or target value clips;
only the four long controller names truncate with an ellipsis. The
wrapped timestamp values in the expansion no longer clip (a single-line
value had needed 169px in a 142px cell).
- 1440px: no new clipped cell; the StatefulSet service name, which the
Detail column truncates, now reads whole in the expansion.
- No viewport scrolls horizontally.

Unit tests cover the controller section per kind and the table's phone
classes and expansion content.
`frontend-modern/browser-verification.json` carries the receipt.

Builds on #2411. Supersedes #2417, which conflicted with main on the
shared browser-verification receipt.
2026-10-03 22:22:16 +01:00
rcourtman 68df09104b Fit metric bar labels by measured glyph widths, not character count (#2438)
## What was wrong

The metric, stacked memory and stacked disk bars choose between `60%`
and `60% (265 GB/440 GB)` by estimating the label's width. The estimate
was 5.5px per character plus 8. At the label's 10px type a digit is
6.7px wide and a full stop 3px, so the estimate was off by -7px to +5px
on real labels.

In the Kubernetes clusters table at a 560px viewport the memory bar is
113px wide, the estimate came to 112.5px, the label needs 118px, and it
rendered with an ellipsis. A sweep of the platform tables found 24 such
bars on `main`, all stacked memory bars: 3 on Kubernetes clusters at
560px, 4 on Proxmox overview at 900px, 16 on Docker overview and 1 on
Kubernetes nodes at 1440px.

## The fix

`estimateTextWidth` sums per-glyph advances instead of multiplying a
character count.

- It reads the advances once per page from a hidden probe that carries
the label's type classes, so the estimate follows whichever system font
the browser renders. The advances measured for the macOS system font
stand in where there is no layout (unit tests).
- The value is measured semibold and the detail after it at normal
weight.
- Each model adds the padding its own label sits in (4px in the metric
and disk bars, 8px in the memory bar's chip) instead of sharing one
constant.

Two more gaps in the same decision are closed:

- The stacked memory and disk bars now count the anomaly marker that
shares the label's line.
- The inline per-disk slots are sized after the gap between them. A
two-disk Proxmox node at 900px clipped `backup 80%` by 2px.

A flat safety margin was not enough: the error depends on which glyphs
the label holds, so a margin that stops the clipping also hides labels
that fit. Measuring each label in the DOM would add a layout read per
bar on the Workloads hot path.

## Verification

Playwright sweep of every table on 32 platform routes at 1440, 900, 700,
560 and 390px (160 loads, 2,579 bars), on this branch and on `main`
against the same mock backend:

| | `main` | this branch |
| --- | --- | --- |
| Bars whose chosen label does not fit | 24 | 0 |
| Clipped inline disk labels | 3 | 0 |
| Bars showing the long label | 567 | 550 |

Of the 17 fewer long labels, 24 are the clipped ones, 14 Proxmox guest
disk bars at 900px gained the long form, and 7 memory bars dropped it: 5
that had 1.0px to 2.8px to spare and 2 that overflowed by under 0.5px.

With every glyph forced to Verdana (10% wider) no bar clips; with Arial
(7% narrower) no bar clips and 237 more show the long label. WebKit
matches Chromium.

The probe is the estimator's only layout read: 1.7ms on the 429-bar
Proxmox overview, about 110ns per estimate afterwards. Bar widths still
come from the resize observer alone.

## Not changed here

The storage usage bar on Proxmox > Storage still clips at 390px (72
rows) and by up to 2.3px at 700px (19 rows). It is a different component
that always renders the long label and does not use the estimator; #2418
reworks it.
2026-10-03 22:11:05 +01:00
pulse-triage[bot] c54aa9e3e7 Reject unreadable backup responses before publishing inventory
Validate backup envelopes, source collections and consumed row fields without coercing completion flags, dropping bad rows or treating missing data as empty. Preserve independent evidence and explicit nil PVE collections, keep format errors private and retry only the failed source. Include parser and mounted regressions, subsystem contracts and inspected Chromium/WebKit final-content proof.

Change-source: pulse-maintainer
2026-10-03 22:03:13 +01:00
pulse-triage[bot] 4b1849bc6e Integrate reviewed recovery help safety and API guidance
Change-source: pulse-maintainer
2026-10-03 21:57:14 +01:00
pulse-triage[bot] 5ce364a83f Integrate batch-start upstream storage presentation
Upstream storage presentation is already composed in canonical history. Preserve exact reviewed canonical files, including later phone padding, Tailwind 4 wrapping and stable disk History catalog fixes; retain upstream identity and its additive receipt without inventing a combined frontend content.

Change-source: pulse-maintainer
2026-10-03 21:57:14 +01:00
rcourtman 9abde5e8f8 Fit storage table values on phones and move reasons to the drawer (#2433)
Supersedes #2418 and #2421, rebuilt as one commit on main after the
table padding fix (#2427) landed, re-measured on that tree.

On a 390px phone the shared Storage table clipped nearly every value:
pool names, hosts (60px for 97px of text), the usage bar's "59% (1.18
TB/2.00 TB)" label on every row, and on Physical Disks the TEMP header,
every temperature and every size.

**Pools**
- Usage bar shows only its percentage below the shared 34rem container
query; the used/total sublabel stays in the tooltip and in wider
containers.
- Compact/operational boundary moves 560px -> 544px so the column set
and the label change together; operational usage grows to 25% so the
full label fits from the first operational width.
- Widths resolve through `getPlatformTableWeightedColumnWidthStyle`;
full-mode weights unchanged, so desktop is identical.
- Narrow/compact rows use the 4px gutter their headers already have
(4-11px of slack per value at 390).
- zpool states are titleized ("DEGRADED" -> "Degraded").

**Physical Disks**
- Phone weights rebalanced from measured values; with #2427 the cells
need no padding override.
- "Needs Attention" / "Replace Now" render as "Attention" / "Replace" in
the phone projection.
- The row shows the verdict word whole with the reason as its title; the
drawer header now carries the verdict and the reason spelled out (it
showed no health state before).

**Protection badge**
- A resilvering/scrubbing ZFS pool shows the activity word (with
percentage when reported) derived from the pool's scan state; the
backend sentence stays as the title. Non-ZFS rebuild labels are
untouched.

**Verification** (mock stack, Playwright th/td
scrollWidth-over-clientWidth sweep at 360/390/420/600/700/900/1280/1440
including expanded drawers): 1440 reports nothing in either table; 390
only long identity strings (two pool names, three disk models). The mock
did not emit its random ZFS-issue scenario during the final pass, so the
scan badge is pinned by unit tests. storageBackups + Storage suites,
Table primitive tests, the resource-type boundary test and the
shared-primitives guardrails pass (89 files, 1603 tests). Receipt in
`frontend-modern/browser-verification.json`.
2026-10-03 21:54:52 +01:00
pulse-triage[bot] 509c12f1ae Isolate route allocation checks from API fixture workers
AllocsPerRun observes process-wide allocations even with GOMAXPROCS=1. Run both zero-allocation checks in the same instrumented test binary with only the selected measurement enabled, bound execution to its marker and retain strict failure propagation. A synchronised background-allocation control demonstrates the old attribution error while the child checks still demand zero. Root results now escape as real metric labels do. Production normalisation and thresholds are unchanged.

Contract-Neutral: Test-process isolation and connected allocation controls only; no runtime, API or performance contract delta.
Change-source: pulse-maintainer
2026-10-03 21:53:22 +01:00