Document integrated update and navigation contracts

This commit is contained in:
pulse-triage[bot] 2026-08-29 21:31:37 +01:00
parent 5cfa0f26b6
commit d8f8f78c2c
10 changed files with 159 additions and 23 deletions

View file

@ -6828,3 +6828,17 @@ authority state. Agent lifecycle remains the sole owner of the relationship;
alerts receives only a bounded presentation identity after that relationship
has already been established. The reciprocal and fail-open cases are pinned in
`internal/monitoring/monitor_host_agents_test.go`.
### Proxmox package evidence does not create agent authority
The PVE API poll may publish a node's bounded package-update evidence through
the shared node model whether or not a Unified Agent is linked to that node.
`pendingUpdates`, its last successful check time, and the fixed evidence status
and reason describe only the Proxmox package source. They cannot enroll, link,
command, update, revoke, remove, or re-enroll an agent, and a linked agent does
not become an alternative authority for the package count.
The node drawer may use `Node.LinkedAgentID` to label Pulse coverage, but that
presentation does not combine agent lifecycle with package evidence. The
polling states are pinned independently in
`internal/monitoring/node_pending_updates_evidence_test.go`.

View file

@ -7774,3 +7774,17 @@ leaves page content visible and interactive below the backdrop while the
Assistant is open, which is a modal-containment defect rather than a cosmetic
one. The bar owns that value; see the frontend-primitives contract. Proofs live
in `frontend-modern/src/components/AI/Chat/__tests__/AIChat.test.tsx`.
### Mobile destination links do not expand AI authority
`AppLayout` supplies the same remembered primary route to desktop and mobile
anchors. Converting the Patrol destination from a button to an anchor changes
browser navigation semantics only: native modified activation may open the
existing Patrol route in another browsing context, while plain activation uses
the existing shell callback. It does not start an investigation, approve an
action, invoke a tool, or create mutation authority.
Menu-opening controls remain buttons, and the mobile bar continues to own
`--pulse-mobile-nav-height`; Assistant overlay containment and action approval
boundaries are unchanged. Mobile navigation and AppLayout tests pin the route
and focus behavior.

View file

@ -10154,3 +10154,20 @@ sharing mutable pointers; the frontend API type mirrors the optional wire
shape exactly. `internal/alerts/correlation_test.go` and
`frontend-modern/src/features/alerts/__tests__/useAlertOverviewState.test.tsx`
are the focused transport-consumer proofs.
### Proxmox package-update evidence is additive and closed
Proxmox node payloads retain the numeric `pendingUpdates` field and may add
`pendingUpdatesCheckedAt`, `pendingUpdatesStatus`, and
`pendingUpdatesReason`. Status is the closed set `checked`, `stale`,
`unavailable`, or `not_checked`; reason, when present, is the closed set
`permission_denied`, `source_unavailable`, `check_failed`, or `node_offline`.
A checked zero is authoritative evidence rather than an absent capability.
The reason is a server-owned diagnostic category and must never contain the
provider error text, endpoint, credential, or response body. Older clients may
ignore the additive fields, while newer clients retain legacy positive counts
that predate explicit status. Model, resource, and presentation contracts are
pinned by `internal/monitoring/node_pending_updates_evidence_test.go`,
`internal/unifiedresources/proxmox_update_evidence_test.go`, and
`frontend-modern/src/utils/__tests__/proxmoxUpdateEvidence.test.ts`.

View file

@ -3440,3 +3440,12 @@ bootstrap group beside runtime branding, after authentication and organization
context resolve. Hosted-mode, organization, license, entitlement, and
presentation-policy behavior are unchanged. `reduceProUpsellNoise` remains a
compatibility display flag; it does not grant or derive commercial capability.
### Shell links do not bypass commercial capability checks
The shared mobile shell now exposes destination `href` values, including for
native modified and context-menu navigation. Those links resolve only routes;
they do not enable a platform, grant an entitlement, select an organization,
change hosted mode, or bypass a server capability check. An unconfigured
platform still resolves to infrastructure settings, and paid destinations
continue to render and authorize from the existing runtime entitlement state.

View file

@ -6819,3 +6819,23 @@ The labels retain singular/plural behavior, use the existing responsive button
primitives, and introduce no parallel group component. Localization and
presentation proofs live in `frontend-modern/src/i18n/__tests__/i18n.test.ts`
and `frontend-modern/src/utils/__tests__/alertOverviewPresentation.test.ts`.
### Mobile destinations are links and update evidence stays explicit
Fixed mobile destinations and menu destinations that navigate are anchors with
real `href` values. Plain primary activation remains in the SPA so route
warming and per-platform route memory continue to apply; modified activation,
middle-click, and context-menu actions remain native browser behavior.
Platform and overflow controls that open menus remain buttons. Disabled
platform anchors resolve to infrastructure setup, and menu focus, Escape
return, active state, badges, and narrow-layout containment remain unchanged.
`MobileNavBar.test.tsx`, `mobileNavBarModel.branchcov0712.test.ts`, and
`AppLayout.test.tsx` pin those distinctions.
The Proxmox node drawer presents checked zero, current positive, stale,
unavailable, and not-checked package evidence as a labelled detail row with
bounded copy and checked time. The compact table badge remains reserved for a
current positive observation. Provider errors are never rendered. Component
and browser evidence covers both 1440px and 390px layouts in
`NodeDrawerOverview.updateEvidence.test.tsx`, `ProxmoxNodesTable.test.tsx`, and
`frontend-modern/browser-verification.json`.

View file

@ -3476,3 +3476,19 @@ owns the correlation wire type and presentation semantics; monitoring owns the
identity evidence that permits the host signal to join that system.
`internal/monitoring/alert_correlation_test.go` pins reciprocal-link admission
and every fail-open case.
### Proxmox update polling preserves evidence quality
The 30-minute node package poll treats one successful response, including an
empty package list, as `checked` and records its completion time. A failed read
must remain an error through the cluster-client fallback boundary. Monitoring
maps it to a fixed privacy-safe reason and reports `unavailable` when no prior
success exists or `stale` with the last successful count and timestamp when a
cache entry exists. An offline node is `not_checked` with `node_offline`.
Failures never refresh the successful timestamp or convert permission and
reachability errors into zero. Cached successful observations remain checked
until their normal refresh boundary, and a failed refresh is retried without
discarding the cache. `node_pending_updates_evidence_test.go` and the cluster
client pending-update tests pin zero, permission, reachability, stale-cache,
and offline behavior.

View file

@ -2908,3 +2908,12 @@ rebuilding the estate. `internal/mock/alert_incidents_test.go` proves bounded
resource results and defensive-copy isolation, while
`internal/api/alerting/alerts_test.go` proves that mock transport does not need
the production incident store.
### Update evidence reuses the bounded node observation
Package evidence adds only one bounded status, one bounded reason, and the
existing count and timestamp to each Proxmox node facet. It introduces no new
poll loop, websocket channel, history series, or per-render scan: collection
retains the existing 30-minute cache and frontend projection/presentation is
constant work per rendered node. Failed refreshes reuse the single cached
successful observation rather than accumulating attempts or provider errors.

View file

@ -5742,3 +5742,13 @@ inventory, a recovery point, restore evidence, retention state, or durable
storage metadata. Mock notes must not be written to the production incident
store or survive a fixture-graph rebuild, and real-mode incident persistence
remains unchanged. The mock API and fixture tests pin that isolation.
### Package-update evidence is not recovery state
The Proxmox fields projected through `useUnifiedResources` and
`ResourceProxmoxMeta` describe the latest package-list observation only. A
count, checked time, stale marker, or failure category is not backup inventory,
a recovery point, retention evidence, restore authority, or permission to
install packages. Canonical merging may replace an older count with a checked
zero or clear inherited check metadata for unavailable evidence, but it must
not mutate storage or initiate remediation.

View file

@ -4868,3 +4868,19 @@ that agent view once instead of duplicating the PVE inventory.
`frontend-modern/src/utils/__tests__/resourceStateAdapters.test.ts`
pin collection continuity, canonical projection, and both unified and
Proxmox-page drawer presentation.
### Proxmox update evidence merges as one authoritative observation
The Proxmox node facet carries `pendingUpdates`, `pendingUpdatesCheckedAt`,
`pendingUpdatesStatus`, and `pendingUpdatesReason` through adapters, registry
cloning, typed views, and frontend state adapters. When explicit status is
present, the incoming observation is authoritative as a unit: a checked zero
clears an older positive count, and unavailable or not-checked evidence cannot
inherit an older checked timestamp or status. Legacy status-less positive
counts remain compatible.
Consumers must not infer a successful zero from absent fields. The node drawer
uses the explicit state for details, while the compact node-row badge requires
current evidence. `proxmox_update_evidence_test.go`, `views_test.go`, and the
frontend evidence presentation tests pin transport, merge, and consumer
behavior.