diff --git a/docs/release-control/v6/internal/subsystems/agent-lifecycle.md b/docs/release-control/v6/internal/subsystems/agent-lifecycle.md index 43ac9b1ed2..6b97e33194 100644 --- a/docs/release-control/v6/internal/subsystems/agent-lifecycle.md +++ b/docs/release-control/v6/internal/subsystems/agent-lifecycle.md @@ -3813,10 +3813,8 @@ approval/identity checks, output bounds and fresh config admission. `TestCommandClientGuestOutcomeContract` covers status/output projection, truncation, ambiguity and independent subsequent admission. -`TestGuestExecRealServerAgentDiscoveryAdmission` must carry decoded healthy -evidence, exclude failed guest output, and resume on an explicit healthy scan -over the real registered server/agent WebSocket boundary. Fake provider/config -fixtures do not establish native PVE/HAOS safety or delivered behaviour. +Command-result source controls do not establish native PVE/HAOS safety or +delivered behaviour. ### Docker update readback is not mutation history @@ -4292,10 +4290,8 @@ overlap, thaw, writes, liveness and resumption are verified. Do not unlock, thaw or automatically restart from this guard. Raw host-shell commands and typed VM lifecycle operations are not relabelled as guarded guest reads. -`TestCommandClientGuestExecutionAdmissionContract` pins no unverified handoff; -`TestGuestExecRealServerAgentDiscoveryAdmission` connects real registration, -server/agent WebSockets and VM/nested-Docker Discovery with fake config/provider -boundaries. `TestVMGuestExecCapabilityBoundToRegisteredSession` pins old/unknown +`TestCommandClientGuestExecutionAdmissionContract` pins no unverified handoff. +`TestVMGuestExecCapabilityBoundToRegisteredSession` pins old/unknown agent rejection and retained deferral. Config ambiguity, cancellation, serialization/capacity and explicit-resumption controls are source proofs, not native PVE/HAOS-QGA, thaw, installed-agent or release acceptance. @@ -7205,9 +7201,10 @@ identifier before executing any `PolicyRequireApproval` command so a missed control-plane gate cannot silently turn into host-level RCE. The single exception is commands marked `Trusted` in the wire payload: those originate from a vetted Pulse-internal subsystem whose command catalog is hardcoded -in Pulse source (today only the servicediscovery deep scanner, which wraps -read-only inspections in `docker exec`). `PolicyBlock` still applies to -trusted payloads. The `Trusted` field must never be set by a code path that +in Pulse source. The Proxmox guest Docker checker and inventory collector use +the fixed read-only catalog in `internal/monitoring/docker_detection.go`, wired +through the authenticated executor in `internal/api/router.go`. +`PolicyBlock` still applies to trusted payloads. The `Trusted` field must never be set by a code path that deserialises user input or accepts a caller-supplied command string. That same copied install transport must also normalize canonical base URLs before composing installer asset paths: when operators enter a trailing-slash @@ -8323,17 +8320,9 @@ workload liveness or containment in installed software. ### Per-tenant resource stores are released on offboarding and shutdown -`ResourceHandlers.getStore` opens a SQLite handle per org and caches it for the -process lifetime. `CloseTenantStore` releases and evicts one org's handle and is -called from `Router.CleanupTenant` alongside the other per-tenant teardown; -`CloseStores`, exposed as `Router.ShutdownResourceStores`, releases all of them. -Without this an offboarded tenant kept its file descriptors and its -`unified_resources.db-wal`/`-shm` files alive and its directory could not be -fully removed. Closed stores are evicted from the cache so a later request opens -a fresh handle rather than using a closed one -(`TestResourceHandlers_CloseTenantStoreReleasesTheHandle`), and both entry points -are idempotent and nil-safe -(`TestResourceHandlers_CloseIsIdempotentAndNilSafe`). +Tenant offboarding and process shutdown use the [API store-lifecycle contract](api-contracts.md#per-tenant-resource-stores-are-released-on-offboarding-and-shutdown), +including its source controls and qualification limits. + ### Server upgrades nudge agent self-update within one report cycle The unified-agent report ack now carries the server's version @@ -9244,14 +9233,8 @@ sampling only, not report schemas, identity, enrollment or command authority. ### Asymmetric bridge evidence regression coverage -`TestApplyHostReportBridgeIdentity` verifies two consecutive reports through -host ingestion and checks both host-to-node and reciprocal node-to-agent links. -Custom management bridges, private IPv4 and ULA addresses retain association -when names differ and the provider endpoint is DNS-based. A Docker or generated -bridge on either side alone must not supply inferred identity: testing only -symmetric bridges would miss removal of filtering from one inventory. -This proof does not establish safety for arbitrarily renamed Docker bridges -or repair persisted links, and is not reporter or installed-release validation. +Host report ingestion preserves the [monitoring bridge-evidence controls](monitoring.md#asymmetric-bridge-evidence-regression-coverage), +including its source controls and qualification limits. ### Durable host/node association intent (6 September 2026) @@ -9299,20 +9282,8 @@ the alert manager and canonical resource timeline. ### Node setup action v7 compatibility -Workflow consumers pin `actions/setup-node` to -`820762786026740c76f36085b0efc47a31fe5020` (v7.0.0). The action manifest -retains the Node 24 execution runtime, setup/cache-save entry points and existing -inputs. Its internal ESM/toolkit upgrade does not change the requested Node 24 -application toolchain. Consumers do not supply `registry-url` or depend on the -removed dummy `NODE_AUTH_TOKEN` export. Explicit npm lockfile caching for test -jobs and disabled automatic package-manager caching for privileged release jobs -remain unchanged; no permission, dispatch input or signing backend changes. - -`test_setup_node_upgrade_preserves_consumer_contract` in the existing workflow -trust suite verifies every consumer pin, absence of the affected auth assumptions, -workflow trust controls and the retained native Windows command/lifecycle proof -steps. Native Windows execution remains a hosted check, not a local Linux claim. -This upgrade is independent of the grouped signing/Docker/Tailscale updates. +Workflow consumers and their trust controls follow the [deployment toolchain contract](deployment-installability.md#node-setup-action-v7-compatibility), +including its source controls and qualification limits. ### Command-channel registration frame ordering @@ -9339,20 +9310,8 @@ an explicit timeout, and the original server still fails the ordering assertion. ### Physical-disk provider identity round trip -The monitor's disk readback preserves the Proxmox source ID separately from -its canonical resource ID. Skipped physical-disk polls may refresh SMART data -but must not feed canonical hashes into source inventory, changing identity at -each subsequent projection. Views without Proxmox source metadata retain the -legacy ID fallback. This does not relax cross-host/device correlation, migrate -old duplicates, change agent authority, or redefine serial-less disk matching. - -`TestPhysicalDiskSkippedPollPreservesSourceIdentity` in -`internal/monitoring/physical_disk_roundtrip_test.go` drives eight real skipped -polls and adapter rebuilds for both path-shaped and bare device names, checking -provider keys, canonical IDs, JSON projection, temperature/size/cadence, separate -nodes/controller members, and confirmed inventory removal. -`TestPhysicalDiskReadbackSourceIDFallback` covers missing source metadata. -This is synthetic runtime evidence, not USB hardware or reporter acceptance. +Disk ingest and readback follow the [unified source-identity contract](unified-resources.md#physical-disk-provider-identity-round-trip), +including its source controls and qualification limits. ### Coalesced host readings follow configured source freshness @@ -9668,16 +9627,6 @@ registration, enrolment, install, update or removal path changed. ### Mock-mode read views fold linked fixture agents -`internal/monitoring/monitor.go` changed only so the mock-mode unified view -applies the operator's manual links (unified-resources contract, "Mock-mode -unified view applies operator links"). A fixture agent the operator linked -into a guest now folds into that guest in mock read views, as a linked agent -already does in live mode, so host snapshots built from them -(`HostsSnapshot`) stop listing it while the guest carries its facet. Agent -registration, enrolment, report admission, removal, continuity and the -fixture agent set itself are unchanged, and the view writes nothing to the -resource store. - ### Demo write guard ignores websocket upgrade headers `internal/api/demo_middleware.go` changed only so a `POST`, `PUT`, `PATCH` or @@ -9728,39 +9677,13 @@ continuity are unchanged. ### Windows installer acceptance engine and absence (8 October 2026) -Native installer parsing, service-removal failure controls and actual lifecycle -execution use Windows PowerShell 5.1, never a PowerShell 7 substitute. A missing -or mismatched engine on Windows fails rather than skips. The dedicated runner -rejects pre-existing or unknown service/state instead of deleting it before the -proof. Both first and repeated uninstall require independent SCM, binary, state -and listener absence; only the exact SCM not-found identity/category proves -absence. Failed listener enumeration remains a failure. This changes validation, -not installer authority, transport, enrolment or host containment. - -`TestWindowsAgentLifecycleRequiresExactEngineAndIndependentAbsence` rejects the -complete supplied parent and fourteen removed/changed controls. Native -`TestWindowsAgentLifecycleObservationRuntime` executes the actual harness -functions with fourteen no-mutation absence/failure/repeated-uninstall/owned-cleanup controls; -the existing real lifecycle job then uses real SCM. Linux skips are explicit and -do not establish a Windows parser, native runtime, reboot or installed result. - -Clean-runner admission checks service, binary, state and listener absence before -machine-environment mutation. A rejected admission cannot clear a pre-existing -machine setting. Cleanup restores only the captured prior setting, even when -owned server teardown fails; an unconfirmed stop fails and retains the handle -rather than reporting clean teardown. Real Windows execution and full terminal -cleanup evidence still have to be returned by the existing native CI job. +Installer lifecycle qualification follows the [deployment Windows acceptance contract](deployment-installability.md#windows-installer-acceptance-engine-and-absence-8-october-2026), +including its source controls and qualification limits. ### Reconciled node-agent relink fold bookkeeping -A declared node-agent join can consume one split row before its newer -operator relink is applied. The relink records that side's ID and source in -the current holder-bound `ManualLinkFold` index, so identity-pin succession -keeps the operator decision and the resources API seed retains the same fold -for report-merge. No synthetic telemetry, identity key, enrollment or service -link is added. `TestOperatorSplitOverridesProxmoxNodeAgentLink` checks that -the monitor and its re-ingested API seed retain the fold across all split -shapes, then survive pin persistence and a repeated split. +Relink consumers preserve the [unified fold-bookkeeping contract](unified-resources.md#reconciled-node-agent-relink-fold-bookkeeping), +including its source controls and qualification limits. ### Mock-mode metrics-target lookups ride the fixture structure revision diff --git a/docs/release-control/v6/internal/subsystems/ai-runtime.md b/docs/release-control/v6/internal/subsystems/ai-runtime.md index c9e6b62930..247231aafc 100644 --- a/docs/release-control/v6/internal/subsystems/ai-runtime.md +++ b/docs/release-control/v6/internal/subsystems/ai-runtime.md @@ -2201,7 +2201,7 @@ tool-result payloads must project through `OrchestratorToolResultInfo.ProviderToolResult` so the public investigation handoff contract inherits the same `agentcapabilities` input-map, thought-signature, and provider-result normalization as Assistant and MCP — -`TestOrchestratorAndChatAdaptersMapTheSameMessageFields` enforces it. +`TestOrchestratorAndChatAdaptersMapTheirMessageContracts` enforces it. Assistant frontend presentation changes under `frontend-modern/src/components/AI/Chat/` must keep live tool activity aligned @@ -8647,11 +8647,9 @@ recompute digest counts from run history, findings, or cost events, and must not call the endpoint through any other client. Proof: `frontend-modern/src/api/__tests__/patrol.test.ts`. -The explicit issue explanation journey is qualified separately from provider -reasoning and real remediation in -`docs/qualification/PATROL_ASSISTANT_CUSTOMER_JOURNEY.md`. The repeatable browser -proof is `scripts/check-patrol-assistant-journey.mjs`. A passing scripted -response does not establish a useful customer outcome or model qualification. +Issue explanation follows the [customer-journey qualification boundary](../../../../qualification/PATROL_ASSISTANT_CUSTOMER_JOURNEY.md#real-outcome-qualification-still-required), +which separates scripted interaction proof from provider reasoning, remediation +and repeatable customer outcomes. ### Subscription routing content boundary diff --git a/docs/release-control/v6/internal/subsystems/alerts.md b/docs/release-control/v6/internal/subsystems/alerts.md index 758ab96fcc..d2bc715848 100644 --- a/docs/release-control/v6/internal/subsystems/alerts.md +++ b/docs/release-control/v6/internal/subsystems/alerts.md @@ -4337,11 +4337,9 @@ populated inventory and checks incident access on desktop and the 390px mobile rail. Enabled acknowledgement controls prove access only, not persisted acknowledgement or external notification receipt. -The explicit issue explanation journey is qualified separately from provider -reasoning and real remediation in -`docs/qualification/PATROL_ASSISTANT_CUSTOMER_JOURNEY.md`. The repeatable browser -proof is `scripts/check-patrol-assistant-journey.mjs`. A passing scripted -response does not establish a useful customer outcome or model qualification. +Issue explanation follows the [customer-journey qualification boundary](../../../../qualification/PATROL_ASSISTANT_CUSTOMER_JOURNEY.md#real-outcome-qualification-still-required), +which separates scripted interaction proof from provider reasoning, remediation +and repeatable customer outcomes. ### Delivery health requests have latest-started ownership @@ -4570,10 +4568,6 @@ Unknown values still fall back to all. The email adapter round-trip matrix and webhook edit/save regression cover issue #2069 without altering delivery filters or sending provider notifications. Component proof is not installed delivery. -Formatting-only follow-up retains this warning-level contract. The production-component -browser matrix was rerun after formatting at desktop and narrow widths, including -all/critical/warning save/reload, cancel, and warning webhook creation. - ### SMTP rate-limit preference persistence The existing SMTP editor's rate limit is included by diff --git a/docs/release-control/v6/internal/subsystems/api-contracts.md b/docs/release-control/v6/internal/subsystems/api-contracts.md index 4ed0d4b673..dfab6e4712 100644 --- a/docs/release-control/v6/internal/subsystems/api-contracts.md +++ b/docs/release-control/v6/internal/subsystems/api-contracts.md @@ -284,22 +284,6 @@ warming consumers. The connected browser fixture verifies actual History components/CSS on desktop Chromium and phone WebKit, not native identity, appliance history, workload safety or released availability. -### Discovery detail reads preserve final access status - -`getDiscovery` retains final HTTP401/403 in a typed client error before any -response-body read. The fixed message exposes no denied body. This applies to -the typed resource detail, agent collection and resolved agent detail paths. -A body or transport message claiming an access status is not that status, and -ordinary transient failures retain their existing error behaviour. Successful -absent-record semantics (detail HTTP404 or an empty agent list) are unchanged. -Retained query consumers can therefore withdraw a denied service/endpoint -rather than treating it as a transient read or a successful empty discovery. -No endpoint, server permission, wire schema or mutation policy changes. -`src/api/__tests__/discovery.test.ts` exercises all three paths with actual -Response status/body objects, denied-body non-read and a misleading 503 body. -The production guest browser fixture verifies the connected final HTTP403 -withdrawal, pending retry, transient retention and successful HTTP404 recovery. - ### TrueNAS saved probes do not rewrite runtime evidence — issue #2382 The saved connection test uses stored server-owned secrets, or merges an edited @@ -11407,9 +11391,9 @@ fields. ### Per-tenant resource stores are released on offboarding and shutdown -`ResourceHandlers.getStore` opens a SQLite handle per org and caches it for the -process lifetime. `CloseTenantStore` releases and evicts one org's handle and is -called from `Router.CleanupTenant` alongside the other per-tenant teardown; +The API `resourceapi.QueryService` owns and caches SQLite handles per org. +`ResourceHandlers.getStore` delegates to that owner. `CloseTenantStore` releases +and evicts one org's handle and is called from `Router.CleanupTenant` alongside the other per-tenant teardown; `CloseStores`, exposed as `Router.ShutdownResourceStores`, releases all of them. Without this an offboarded tenant kept its file descriptors and its `unified_resources.db-wal`/`-shm` files alive and its directory could not be @@ -11970,11 +11954,9 @@ disk. The advanced-reporting entitlement gates both kinds. Proofs: `internal/api/report_schedules_test.go`, `internal/api/patrol_digest_email_test.go`, `internal/api/ai_handlers_more_test.go`. -The explicit issue explanation journey is qualified separately from provider -reasoning and real remediation in -`docs/qualification/PATROL_ASSISTANT_CUSTOMER_JOURNEY.md`. The repeatable browser -proof is `scripts/check-patrol-assistant-journey.mjs`. A passing scripted -response does not establish a useful customer outcome or model qualification. +Issue explanation follows the [customer-journey qualification boundary](../../../../qualification/PATROL_ASSISTANT_CUSTOMER_JOURNEY.md#real-outcome-qualification-still-required), +which separates scripted interaction proof from provider reasoning, remediation +and repeatable customer outcomes. ### Report email shares the canonical SMTP retry verdict @@ -12024,10 +12006,6 @@ repairs a dropped supported value without introducing a new wire enum or changin backend routing. The notification adapter save/reload matrix verifies each supported severity in frontend-modern/src/api/__tests__/notifications.test.ts. -Formatting-only follow-up retains this warning-level contract. The production-component -browser matrix was rerun after formatting at desktop and narrow widths, including -all/critical/warning save/reload, cancel, and warning webhook creation. - ### Quick security setup preserves unrelated settings Authenticated force setup in `internal/api/security_setup_fix.go` retains the diff --git a/docs/release-control/v6/internal/subsystems/frontend-primitives.md b/docs/release-control/v6/internal/subsystems/frontend-primitives.md index a3f641d6e4..6faa009c10 100644 --- a/docs/release-control/v6/internal/subsystems/frontend-primitives.md +++ b/docs/release-control/v6/internal/subsystems/frontend-primitives.md @@ -392,41 +392,8 @@ thaw, safe writes, installed acceptance or a containing published release. ### Backup inventory ownership is source-scoped and unambiguous -The existing Backups Coverage and By date views do not select a workload from -an arbitrary substring, display label or first matching row when VMIDs repeat. -PVE files, guest snapshots and task evidence use the supplied connection scope -before native node names or aliases. One VMID inside a matching PVE connection -stays associated after node migration; a known conflicting connection cannot be -rescued by a reused node name or a singleton fallback. With no connection scope, -an exact native node/alias must identify one candidate; wholly unscoped singleton -observations retain their existing compatibility behaviour. - -PBS instance and datastore identify a repository, not a PVE workload. A PBS -namespace disambiguates repeated VMIDs only with a unique exact native node, -alias or PVE connection label. Unique type/VMID PBS inventory retains the -existing root-namespace association. This bounded presentation fix does not -implement the runtime PBS source learner or alter server-owned protection policy. - -Unresolved artifacts remain listed once and keep complete, collision-safe source -keys (PVE connection/node or PBS instance/datastore/namespace), including host -backup labels. Equal VMIDs, repository labels or host names cannot pool them -across unproven sources. Untyped PVE tasks may join only PVE-scoped rows, not a -PBS-only unresolved row with a lookalike namespace. The existing collapsed group -and count say **unmatched**, not that the guest necessarily ceased to exist; -its explanation wraps on phones. These rows remain **not evaluated**, separate -from canonical provider-owned protection posture and live workload counts. - -Verification: `proxmoxBackupRecoveryModel.identity.test.ts` reproduces prefix -and reused-node collisions, order independence, migration/alias controls, -conflicting scope, ambiguous type/namespace and separated unresolved sources. -Mounted `ProxmoxBackupsTable.test.tsx` backup-identity cases cover both views, -artifact preservation, reorder/display rename, expansion identity and no extra -inventory read. `browser-tests/backup-identity.cjs` uses production tables, -router, inventory readers and CSS with synthetic responses on desktop Chromium -and touch WebKit at 390px/320px, including keyboard/touch disclosure, ambiguity, -readable unmatched explanation and same-resource recovery. No native backup -identity, restore, guest thaw or containing-release acceptance follows from -these source/render observations. +Both Backups views follow the [storage source-association contract](storage-recovery.md#backup-inventory-ownership-is-source-scoped-and-unambiguous), +including its source controls and qualification limits. ### Diagnostics are live checks; downloads require a privacy review @@ -8829,11 +8796,9 @@ App.architecture.test.ts protects the CSS scope and scroll ownership; non-scrolling wrapper. Browser receipts do not establish physical Android touch behaviour or every asynchronous update state. -The explicit issue explanation journey is qualified separately from provider -reasoning and real remediation in -`docs/qualification/PATROL_ASSISTANT_CUSTOMER_JOURNEY.md`. The repeatable browser -proof is `scripts/check-patrol-assistant-journey.mjs`. A passing scripted -response does not establish a useful customer outcome or model qualification. +Issue explanation follows the [customer-journey qualification boundary](../../../../qualification/PATROL_ASSISTANT_CUSTOMER_JOURNEY.md#real-outcome-qualification-still-required), +which separates scripted interaction proof from provider reasoning, remediation +and repeatable customer outcomes. ### Alert health attention preserves asynchronous ownership @@ -8849,20 +8814,8 @@ queue-action responses, without claiming backend notification delivery. ### Alert status distinguishes dispatch from destination evidence -The active alert card renders a valid diagnosis `lastNotified` timestamp as -“Dispatch requested”, never “Notified”: the alert manager records this field -before invoking delivery callbacks. A cooldown's `nextEligibleAt` is labelled -“next eligible”, not a promised send time. Neither field proves destination -acceptance or recipient receipt; that evidence must not be inferred from the -muted presentation tone. Missing or invalid timestamps retain the existing -pending/cooldown fallback; acknowledged alerts retain their badge without a -second status line. No API field, notification policy or shared primitive changes. - -The existing wrapping status text must remain readable at desktop and phone -widths despite the longer labels. The presentation and Overview delivery-status -tests cover the evidence boundary; `scripts/check-alert-dispatch-copy.mjs` -qualifies the real Overview with scripted API data in Chromium, not installed -notification delivery. +Shared presentation preserves the [alerts dispatch-evidence contract](alerts.md#alert-status-distinguishes-dispatch-from-destination-evidence), +including its source controls and qualification limits. ### Resource incident reads retain lifecycle ownership diff --git a/docs/release-control/v6/internal/subsystems/monitoring.md b/docs/release-control/v6/internal/subsystems/monitoring.md index 33a6c791e1..2679af1246 100644 --- a/docs/release-control/v6/internal/subsystems/monitoring.md +++ b/docs/release-control/v6/internal/subsystems/monitoring.md @@ -1520,23 +1520,6 @@ live/collapsed/expanded/History acceptance. -**Availability backfill preserves concurrent discovery changes (7 September 2026)** - -The backfill List snapshot is a work list, not an authoritative record to save. -Read the current discovery, derive a missing suggestion from its current identity, -and persist under one store write lock. State-provider reads stay outside that -lock. Preserve newer identity, URL, engine version, user notes and existing -(including dismissed) proposals; never resurrect a discovery deleted after List. -A failed persistence attempt remains an error without installing the proposed -change in cache. `TestService_BackfillPreservesConcurrentManualRepair` in `service_test.go` -deterministically pauses SetReadState -backfill after List, completes manual ESPHome repair, then resumes backfill and -checks both cache and encrypted restart. -`TestStore_BackfillAvailabilitySuggestionUsesCurrentRecord` in `store_test.go` -covers current-identity -inference, dismissal, deletion, unsupported identity and persistence failure. -This is discovery state-integrity proof, not incident or notification acceptance. - **Correlated VM memory fallback — issue #1962 (7 September 2026)** The next Proxmox guest poll indexes live agent memory embedded in VM read views, @@ -2790,10 +2773,9 @@ alerts, 5 vSphere incidents and 137 backup-age alerts in live mode, and counted a mock-mode observation toward a live connection's three-observation confirmation. `TestLeavingMockModeWaitsForAnInFlightEvaluation` holds an evaluation in its CPU window read, outside the alert manager's lock, and fails -if the switch returns first; `TestLiveRefreshIgnoresARegistryRepublishedFromMockMode` -lets a mock-mode rebuild republish while a live refresh is held before reading -the registry back, then checks the next live refresh evaluates live records. -Each of those two fails against a fence without its wait or its overlap check. +if the switch returns first; `TestLiveRefreshRejectsCollectedRecordsFromMockMode` +holds collected fixture records across a mode switch and checks that a live +refresh publishes and evaluates live provider records without fixture leakage. `TestDockerPruneIgnoresTheRegistryMockModeLeft` raises a live Docker alert before any live rebuild and fails if pruning reads the fixture registry, and `TestPreviousStateCarryIgnoresTheRegistryMockModeLeft` fails if the @@ -3509,26 +3491,9 @@ service-history reads plus denial/recovery without fabricated samples. `internal/monitoring/monitor_host_agents_test.go` and `pkg/agents/host/proxmox_lxc_test.go` must prove JSON wire-report ingestion through `ApplyHostReport`, partial/complete-empty recovery, contradictory IDs, unchanged node/agent/name/TTL protection, and no invalid-list-to-healthy-empty conversion. Omitted telemetry is never zero. Source proofs are distinct from native PVE and released availability. -### Discovery accepts successful command evidence only - -Only stdout from a successful result with zero exit status and no error enters -Discovery analysis or saved observations. Stderr, failed/partial output, a nil -result and contradictory success/status cannot identify a service. Independent -healthy output survives optional probe failures. When an attempted scan has -failures and no successful stdout evidence, return a fixed no-evidence error -and truthful terminal progress; manual metadata fallback and background -enhancement must not replace saved results, notes or observation times. An -explicit later healthy scan resumes normally; no failed command is replayed. - -`TestDiscoveryFailedCommandEvidenceContract` covers VM/nested-Docker/LXC/host/ -Docker output admission, optional partial evidence, saved manual/background -results and explicit recovery. Registered server/agent controls cover actual -guest result propagation, with fake config/provider boundaries. This is source -truthfulness, not native thaw, containing-release or workload acceptance. - 1. Update this contract when monitoring truth ownership changes 2. Tighten guardrails when `GetState()`-centric paths are removed -3. Keep discovery-provider, host-agent ingest, guest-memory trust, metrics-history, storage-risk, Docker/Podman container collection, Docker report/model payloads, Proxmox Ceph and ZFS compatibility, Docker Swarm collection, mock runtime fixtures, and container bootstrap proof routes explicit in `registry.json` +3. Keep network-discovery, host-agent ingest, guest-memory trust, metrics-history, storage-risk, Docker/Podman container collection, Docker report/model payloads, Proxmox Ceph and ZFS compatibility, Docker Swarm collection, mock runtime fixtures, and container bootstrap proof routes explicit in `registry.json` 4. Update related read-state or monitor tests when new collector paths land 5. Keep platform ingestion semantics aligned with `docs/release-control/v6/internal/PLATFORM_SUPPORT_MODEL.md`: hybrid is a @@ -3753,41 +3718,6 @@ existing reader behaviour and the real authenticated/scoped Pulse route. V2 partial inventories preserve usable filesystem readings while leaving typed-helper health degraded. Global inventory failure still yields no inventory. No host-network exception, guest mutation, database/retention change or temperature substitution accompanies this repair. -### Discovery observes VM guest execution pauses - -Verified VM results describe the guest's terminal status and decoded output, -not successful CLI delivery. Discovery admits only successful stdout as command -evidence for every resource type; stderr and failed/partial output are not -observations. An attempted scan with failures but no successful stdout returns -an error without replacing saved results or invoking analysis. Normal empty -successful probes and independent healthy output alongside optional failures -retain their existing semantics. - -Manual, automatic and nested-Docker VM scans use the existing agent execution -boundary; they cannot infer safety from the Web drawer's snapshot. VM routing -requires an exact connected agent ID or a unique owning-node hostname, never a -sole unrelated agent or guest-name hint. The agent independently requires its -current local VM config and checks the operation lock. Discovery runs VM probes -serially and stops on any explicit guest safety deferral, including optional -probes. Deferred in-flight output is not fresh discovery evidence; progress -retains an error and actual partial completion rather than 100% success. - -A manual deferral is returned as an error without replacing saved discoveries, -notes or raw observations with metadata fallback. Background enhancement keeps -its existing evidence rather than analysing partial deferred output. Clearing -a pause triggers no scan or retry by itself; an existing normal trigger or -explicit request starts a new, guarded attempt. Healthy catalogue commands, -non-VM parallelism, permissions, feature gates and saved-result access remain. - -`TestDiscoveryGuestSafetyStopsAndPreservesSavedEvidence` covers both VM/nested -Docker scans, first/later optional-command deferral, manual error and automatic -saved-evidence preservation. Node ambiguity controls exclude misrouting. These -source-connected controls and the agent protocol guard do not reserve QGA -against PVE backup start, establish native thaw, or satisfy the existing native -overlap/covered-write/liveness/resumption dependency. Preserve the monitoring -and alert outage precaution until that operational outcome is verified. - - ### Mock-mode unified view applies operator links The mock branch of currentUnifiedStateView serves the fixture graph to the @@ -5345,12 +5275,12 @@ temperature, so a retained standby or silent-agent reading never reappears as a point at the current time. The SMART history writers in `internal/monitoring/monitor.go` and `monitor_agents.go` call that helper rather than a private copy of the rule, -and `GetPhysicalDiskTemperatureCharts` pads a short disk temperature series out -to now only with a collected reading: with a retained one the stored samples -stay as they are, and a disk with none gets no series. Mock mode can still -substitute its generic demo series for that disk ID before this step; that -series is not derived from the disk's reading. Proof: -`TestDiskTemperatureChartsPadOnlyWithCollectedReading` in +and `GetPhysicalDiskTemperatureCharts` returns observed history samples without +padding a short series to now, even when the current reading was collected. +Retained readings never manufacture history. A live disk with no history keeps +its metadata without a fabricated series. Mock mode may use its seeded demo +history, which is separate from a disk reading. Proof: +`TestDiskTemperatureChartsRetainOnlyObservedSamples` in `internal/monitoring/monitor_metrics_slo_test.go`. Unified-resource physical-disk round trips must retain named `StorageGroup` membership rather than degrading it to the generic `Used` @@ -6890,20 +6820,8 @@ that already admitted or provider-accepted deliveries can be recalled. ### Physical-disk provider identity round trip -The monitor's disk readback preserves the Proxmox source ID separately from -its canonical resource ID. Skipped physical-disk polls may refresh SMART data -but must not feed canonical hashes into source inventory, changing identity at -each subsequent projection. Views without Proxmox source metadata retain the -legacy ID fallback. This does not relax cross-host/device correlation, migrate -old duplicates, change agent authority, or redefine serial-less disk matching. - -`TestPhysicalDiskSkippedPollPreservesSourceIdentity` in -`internal/monitoring/physical_disk_roundtrip_test.go` drives eight real skipped -polls and adapter rebuilds for both path-shaped and bare device names, checking -provider keys, canonical IDs, JSON projection, temperature/size/cadence, separate -nodes/controller members, and confirmed inventory removal. -`TestPhysicalDiskReadbackSourceIDFallback` covers missing source metadata. -This is synthetic runtime evidence, not USB hardware or reporter acceptance. +Disk ingest and readback follow the [unified source-identity contract](unified-resources.md#physical-disk-provider-identity-round-trip), +including its source controls and qualification limits. ### Unified metric replay guard bounds registry-rebuild writes @@ -7186,14 +7104,7 @@ for a mock-style view. ### Reconciled node-agent relink fold bookkeeping -A declared node-agent join can consume one split row before its newer -operator relink is applied. The relink records that side's ID and source in -the current holder-bound `ManualLinkFold` index, so identity-pin succession -keeps the operator decision and the resources API seed retains the same fold -for report-merge. No synthetic telemetry, identity key, enrollment or service -link is added. `TestOperatorSplitOverridesProxmoxNodeAgentLink` checks that -the monitor and its re-ingested API seed retain the fold across all split -shapes, then survive pin persistence and a repeated split. +Relink consumers preserve the [unified fold-bookkeeping contract](unified-resources.md#reconciled-node-agent-relink-fold-bookkeeping). Mock-link lifecycle validation drives the owning ingest/rebuild boundary after unlink and relink: read hydration intentionally reuses a registry diff --git a/docs/release-control/v6/internal/subsystems/notifications.md b/docs/release-control/v6/internal/subsystems/notifications.md index c5484e2158..24e0f774a0 100644 --- a/docs/release-control/v6/internal/subsystems/notifications.md +++ b/docs/release-control/v6/internal/subsystems/notifications.md @@ -1335,10 +1335,6 @@ normalization. Existing backend severity admission and delivery queues remain unchanged. The notification API adapter round trips and WebhookConfig edit/save regression establish frontend control preservation, not provider delivery. -Formatting-only follow-up retains this warning-level contract. The production-component -browser matrix was rerun after formatting at desktop and narrow widths, including -all/critical/warning save/reload, cancel, and warning webhook creation. - ### Resolution cancellation is occurrence-qualified The monitor's delayed recovery path calls `CancelResolvedAlert` with the diff --git a/docs/release-control/v6/internal/subsystems/patrol-intelligence.md b/docs/release-control/v6/internal/subsystems/patrol-intelligence.md index cd20b09b83..68eeb1fb91 100644 --- a/docs/release-control/v6/internal/subsystems/patrol-intelligence.md +++ b/docs/release-control/v6/internal/subsystems/patrol-intelligence.md @@ -2889,11 +2889,9 @@ is unavailable rather than showing zeros. Proofs: `frontend-modern/src/pages/__tests__/AIIntelligence.test.tsx` (card ordering), and the browser receipt in `frontend-modern/browser-verification.json`. -The explicit issue explanation journey is qualified separately from provider -reasoning and real remediation in -`docs/qualification/PATROL_ASSISTANT_CUSTOMER_JOURNEY.md`. The repeatable browser -proof is `scripts/check-patrol-assistant-journey.mjs`. A passing scripted -response does not establish a useful customer outcome or model qualification. +Issue explanation follows the [customer-journey qualification boundary](../../../../qualification/PATROL_ASSISTANT_CUSTOMER_JOURNEY.md#real-outcome-qualification-still-required), +which separates scripted interaction proof from provider reasoning, remediation +and repeatable customer outcomes. ### Expired action continuity (2026-09-07) diff --git a/docs/release-control/v6/internal/subsystems/performance-and-scalability.md b/docs/release-control/v6/internal/subsystems/performance-and-scalability.md index bc6ea8e360..24fa10a6fd 100644 --- a/docs/release-control/v6/internal/subsystems/performance-and-scalability.md +++ b/docs/release-control/v6/internal/subsystems/performance-and-scalability.md @@ -366,22 +366,8 @@ metric tracks at narrow width; this is readability, not a throughput claim. ### Bounded confidence/priority work in broadcast grouping — issue #2199 -The general identity matcher retains every confidence, reason, ordering and -review flag. Top-level grouping requests only its existing high-confidence -floor (0.90), so hostname-only and IP-only peer sets are not built when no -eligible composite signal exists. High-confidence results are identical to -filtering the full general matcher; machine ID, UUID and hostname+MAC still -keep their existing precedence. Host/IP fallback still requires exactly one -strictly better-priority owner. Equal/worse-priority peers are discarded before -allocating/sorting fallback candidates, and a best-priority group has no possible -attachment target. No identity, ambiguity, count, group ID or explanation rule -changes, and no cached output hides live transitions. - -Independent pre-repair matching/grouping oracles, candidate-floor differential -cases/fuzzing, a discarded-peer allocation bound, mixed grouping records and the -complete existing identity/topology suites protect these constraints. The -residual synthetic broadcast profile identified discarded matching/grouping as -the dominant cost; it is not a profile of the reporter's installed agent fleet. +Broadcast performance work preserves the [unified grouping semantics and allocation bounds](unified-resources.md#bounded-confidencepriority-work-in-broadcast-grouping--issue-2199), +including its source controls and qualification limits. ### Connected-dashboard snapshot ownership — issue #2199 @@ -3601,17 +3587,9 @@ nothing at all when workload rows are present. ### Per-tenant resource stores are released on offboarding and shutdown -`ResourceHandlers.getStore` opens a SQLite handle per org and caches it for the -process lifetime. `CloseTenantStore` releases and evicts one org's handle and is -called from `Router.CleanupTenant` alongside the other per-tenant teardown; -`CloseStores`, exposed as `Router.ShutdownResourceStores`, releases all of them. -Without this an offboarded tenant kept its file descriptors and its -`unified_resources.db-wal`/`-shm` files alive and its directory could not be -fully removed. Closed stores are evicted from the cache so a later request opens -a fresh handle rather than using a closed one -(`TestResourceHandlers_CloseTenantStoreReleasesTheHandle`), and both entry points -are idempotent and nil-safe -(`TestResourceHandlers_CloseIsIdempotentAndNilSafe`). +Tenant offboarding and process shutdown use the [API store-lifecycle contract](api-contracts.md#per-tenant-resource-stores-are-released-on-offboarding-and-shutdown), +including its source controls and qualification limits. + ### Report-ack version echo adds no steady-state work The `serverVersion` field on unified-agent report acks is a constant string diff --git a/docs/release-control/v6/internal/subsystems/security-privacy.md b/docs/release-control/v6/internal/subsystems/security-privacy.md index 8ff01c7161..1b78e8953e 100644 --- a/docs/release-control/v6/internal/subsystems/security-privacy.md +++ b/docs/release-control/v6/internal/subsystems/security-privacy.md @@ -2759,26 +2759,20 @@ capability is not treated as the authorization boundary. and image normalization. ### Licensed-feature adoption telemetry stays count-only -Schema v6 of the outbound usage payload adds nine licensed-feature adoption -signals so Pro feature usage is measurable at all: `alert_ai_enabled`, -`rbac_custom_roles`, `rbac_user_assignments`, `audit_logging_persistent`, -`audit_events_30d`, `report_schedules`, `report_schedules_enabled`, -`report_schedules_run_30d`, and `agent_profiles`. Every one is a count or a -coarse boolean. Role names, permission sets, usernames, schedule names, -delivery recipients, report scope and contents, profile names, and every audit -event field (type, actor, target, outcome, detail) stay on the install. -`audit_logging_persistent` reports only that a persistent store is active -rather than console logging, and `audit_events_30d` is a retained-row count -inside the same 30-day window used by the other counters, so it cannot be -linked to one pseudonymous identifier indefinitely. Config-sourced signals are -read in `applyLicensedFeatureConfigSnapshot` -(`pkg/server/telemetry_licensed_features.go`); RBAC and audit are read behind -the router in `Router.ApplyLicensedFeatureTelemetrySnapshot` -(`internal/api/telemetry_licensed_features.go`). Both are disclosed in -`docs/PRIVACY.md` and its `frontend-modern/public/docs/` copy, pinned by -`TestAllTelemetryFieldsAreDisclosed`, and the counts are pinned by +Licensed-feature adoption telemetry exports only the coarse counts and booleans +declared in `internal/telemetry/licensed_feature_fields.go`. Role names, +permission sets, usernames, schedule names, delivery recipients, report scope +and contents, profile names, and every audit event field stay on the install. +Config signals come from `pkg/server/telemetry_licensed_features.go`; RBAC counts +come from `internal/api/telemetry_licensed_features.go`, and licensed audit-read +activity follows the gated recorder below. + +`docs/PRIVACY.md` and its shipped copy disclose the current fields. +`TestAllTelemetryFieldsAreDisclosed`, `TestApplyLicensedFeatureConfigSnapshot_CountsScheduledReportingAndProfiles` -and `TestApplyLicensedFeatureTelemetrySnapshot_CountsOnlyOperatorAuthoredRBAC`. +and `TestApplyLicensedFeatureTelemetrySnapshot_CountsOnlyOperatorAuthoredRBAC` +pin disclosure and count semantics. Audit-store presence and background write +volume are not adoption signals. ### Telemetry RBAC reads never provision an RBAC store @@ -2791,17 +2785,11 @@ side effect of a background read. A store reporting a migration failure is skipped rather than counted, so a degraded store cannot silently understate adoption. `TestTenantRBACProvider_PeekManagerDoesNotProvision` and `TestTenantRBACProvider_PeekManagerNilProviderIsSafe` in -`internal/api/rbac_tenant_provider_test.go` pin both properties, and -`TestApplyLicensedFeatureTelemetrySnapshot_DoesNotCreateRBACStores` pins it -through the router boundary. +`internal/api/rbac_tenant_provider_test.go` pin both properties. +`ApplyLicensedFeatureTelemetrySnapshot` uses that cached-only read boundary. ### Audit adoption telemetry counts gated reads, never store presence -Schema v7 replaced `audit_logging_persistent` and `audit_events_30d` with -`audit_reads_30d`. The first two did not discriminate: `pkg/server` installs the -SQLite audit logger on every install for defense in depth and gates only the -read and export endpoints, so the boolean was true on every install that -reported it and the event count measured background write volume, saturating -the receiver clamp on unlicensed community installs. `audit_reads_30d` counts +`audit_reads_30d` counts requests that cleared `RequireLicenseFeature(featureAuditLoggingValue, ...)` on an audit read or export surface, which requires a human action and so cannot settle into a constant. The recorder in @@ -2937,17 +2925,9 @@ because it looks like data in the fleet aggregate. names. ### Per-tenant resource stores are released on offboarding and shutdown -`ResourceHandlers.getStore` opens a SQLite handle per org and caches it for the -process lifetime. `CloseTenantStore` releases and evicts one org's handle and is -called from `Router.CleanupTenant` alongside the other per-tenant teardown; -`CloseStores`, exposed as `Router.ShutdownResourceStores`, releases all of them. -Without this an offboarded tenant kept its file descriptors and its -`unified_resources.db-wal`/`-shm` files alive and its directory could not be -fully removed. Closed stores are evicted from the cache so a later request opens -a fresh handle rather than using a closed one -(`TestResourceHandlers_CloseTenantStoreReleasesTheHandle`), and both entry points -are idempotent and nil-safe -(`TestResourceHandlers_CloseIsIdempotentAndNilSafe`). +Tenant offboarding and process shutdown use the [API store-lifecycle contract](api-contracts.md#per-tenant-resource-stores-are-released-on-offboarding-and-shutdown), +including its source controls and qualification limits. + ### Report-ack server versions cannot steer agents beyond one validated check The unified-agent report ack's `serverVersion` echo gives acks a version @@ -3218,20 +3198,8 @@ a CSRF-checked `POST`. No authentication, scope or session rule changed. ### Node setup action v7 compatibility -Workflow consumers pin `actions/setup-node` to -`820762786026740c76f36085b0efc47a31fe5020` (v7.0.0). The action manifest -retains the Node 24 execution runtime, setup/cache-save entry points and existing -inputs. Its internal ESM/toolkit upgrade does not change the requested Node 24 -application toolchain. Consumers do not supply `registry-url` or depend on the -removed dummy `NODE_AUTH_TOKEN` export. Explicit npm lockfile caching for test -jobs and disabled automatic package-manager caching for privileged release jobs -remain unchanged; no permission, dispatch input or signing backend changes. - -`test_setup_node_upgrade_preserves_consumer_contract` in the existing workflow -trust suite verifies every consumer pin, absence of the affected auth assumptions, -workflow trust controls and the retained native Windows command/lifecycle proof -steps. Native Windows execution remains a hosted check, not a local Linux claim. -This upgrade is independent of the grouped signing/Docker/Tailscale updates. +Workflow consumers and their trust controls follow the [deployment toolchain contract](deployment-installability.md#node-setup-action-v7-compatibility), +including its source controls and qualification limits. ### Updates settings copy rename diff --git a/docs/release-control/v6/internal/subsystems/storage-recovery.md b/docs/release-control/v6/internal/subsystems/storage-recovery.md index 2bc191cb6e..e621be5a19 100644 --- a/docs/release-control/v6/internal/subsystems/storage-recovery.md +++ b/docs/release-control/v6/internal/subsystems/storage-recovery.md @@ -6084,17 +6084,8 @@ than drifting into "has ever used" ### Per-tenant resource stores are released on offboarding and shutdown -`ResourceHandlers.getStore` opens a SQLite handle per org and caches it for the -process lifetime. `CloseTenantStore` releases and evicts one org's handle and is -called from `Router.CleanupTenant` alongside the other per-tenant teardown; -`CloseStores`, exposed as `Router.ShutdownResourceStores`, releases all of them. -Without this an offboarded tenant kept its file descriptors and its -`unified_resources.db-wal`/`-shm` files alive and its directory could not be -fully removed. Closed stores are evicted from the cache so a later request opens -a fresh handle rather than using a closed one -(`TestResourceHandlers_CloseTenantStoreReleasesTheHandle`), and both entry points -are idempotent and nil-safe -(`TestResourceHandlers_CloseIsIdempotentAndNilSafe`). +Tenant offboarding and process shutdown use the [API store-lifecycle contract](api-contracts.md#per-tenant-resource-stores-are-released-on-offboarding-and-shutdown), +including its source controls and qualification limits. ### Report-ack version echo persists nothing diff --git a/docs/release-control/v6/internal/subsystems/unified-resources.md b/docs/release-control/v6/internal/subsystems/unified-resources.md index 7e2bfbdd76..e203605503 100644 --- a/docs/release-control/v6/internal/subsystems/unified-resources.md +++ b/docs/release-control/v6/internal/subsystems/unified-resources.md @@ -2989,7 +2989,7 @@ application resource-provider or WebSocket lifecycle. become a per-row store pattern. Regression coverage: `TestSQLiteStoreActionAuditOriginRoundTrip`, - `TestSQLiteActionAuditOriginOperationalRecordReader`, and the matching + `TestActionAuditOriginReaderReturnsLatestTransition`, and the matching memory/batch reader tests in `internal/unifiedresources/store_test.go`. Incident next-step fallback follows the same canonical resource boundary: storage guidance is reserved for storage, physical-disk, network-share,