Pulse/internal
courtmanr@gmail.com c3fb35c8f8 Harden Patrol readiness streaming transport (#1640)
Follow-up to 8d0d74e35. The keepalive mechanism was right, the edges
were not.

1. The evaluation ran on a bare goroutine with no recover, so a panic in
   provider streaming or validation took the whole Pulse process down.
   Before that commit the same panic was on the request goroutine and the
   recovery middleware turned it into a logged 500. The goroutine now
   recovers, logs the panic with its stack, and answers with an ordinary
   readiness result carrying the new internal_error cause and every
   dimension reported as not assessed. A Pulse defect is not a model
   verdict.

2. Headers were only Set, never committed, despite the comment, the
   commit message, and api-contracts.md all claiming otherwise. The
   status line went out with the first keepalive at +10s, so a proxy
   with a sub-10s time-to-first-byte budget still severed the request.
   The transport now writes and flushes WriteHeader(200) before the
   ticker starts, matching the pattern the file already uses for SSE.

3. The flusher was resolved with a discarded ok, so a writer that is not
   an http.Flusher silently buffered the keepalives and degraded back to
   the original bug. It is now checked and logged; the response still
   completes, so a warning is the right level here rather than the hard
   failure the SSE handlers use.

4. TestIssue1640HandlerUsesKeepaliveTransport grepped the handler source
   for substrings, which proves nothing about behaviour. Replaced with a
   real httptest.NewServer test that runs a 300ms evaluation and asserts
   the client sees the 200 and a body byte before the evaluation
   completes, and that the padded body still parses as the expected JSON.
   Added coverage for the panic path and the non-flushable writer, and
   fixed the eager body[:1] that would panic when a transport regression
   left the body empty.

5. The settings readiness banner had no not_assessed branch, so an
   interrupted run still rendered the red "Patrol model not verified"
   headline: the exact blame-the-model presentation the backend fix
   removed. Tone and headline are now exported pure functions with a
   neutral treatment for not_assessed and interrupted results, and an
   interrupted run cannot claim verification from a max_verified_mode
   recorded before the cancellation.

6. createAPIErrorFromResponse let a short plain-text body override an
   explicit caller fallbackMessage. A caller passing a fallback knows
   which operation it was performing; an intermediary writing the body
   does not. Precedence is now canonical JSON, then caller fallback,
   then body, with the HTML and oversize suppression unchanged.

7. patrolRunCancelled classified on the raw "context canceled" substring
   as its first switch case. Ollama embeds that phrase in its own error
   body when it aborts an upstream request, so a genuine provider
   failure on a healthy run was classified interrupted and finish()
   persisted it as not_assessed. Cancellation is now established from
   the run itself (errors.Is(err, context.Canceled), or a cancelled run
   context), never from error wording, and the readiness paths classify
   through a context-aware entry point. context.DeadlineExceeded keeps
   its provider-path timeout classification.

The readiness gate in HandlePatrolModelReadiness keying off ToolProtocol
alone is untouched, as agreed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 12:17:25 +01:00
..
actionlifecycle Fix backend release gate failures 2026-07-23 14:03:44 +01:00
actionplanner Cover the alert read-model, guest identity and action-planner validators 2026-07-25 06:34:48 +01:00
agentcapabilities Refuse dispatch when action readiness is lost 2026-07-20 21:44:59 +01:00
agentcontext Add Go branch-coverage tests for pure helpers across six packages 2026-07-19 15:11:02 +01:00
agentexec Fix agent command channel admission 2026-07-24 13:00:03 +01:00
agenttarget Add report-only Unified Agent observer destinations 2026-07-19 15:30:34 +01:00
agenttls Modernize Unified Agent lifecycle and platform support 2026-07-09 23:20:35 +01:00
agentupdate Prepare v6.1.2 stable patch release 2026-07-26 20:38:42 +01:00
ai Harden Patrol readiness streaming transport (#1640) 2026-07-28 12:17:25 +01:00
alerts Fix PBS backup attribution for VMIDs shared across clusters 2026-07-28 11:24:01 +01:00
api Harden Patrol readiness streaming transport (#1640) 2026-07-28 12:17:25 +01:00
availabilityprobe Extract availability probe execution into a shared package 2026-07-27 11:13:04 +01:00
bootstrap
cloudcp Bump postcss to 8.5.23 in both frontend lockfiles 2026-07-27 09:46:28 +01:00
config Remove dead autoUpdateCheckInterval and autoUpdateTime settings 2026-07-28 11:13:37 +01:00
crypto Harden secure local key file handling 2026-04-22 05:13:01 +01:00
deploy Remove monitored-system volume caps 2026-05-05 12:59:59 +01:00
discovery
dockeragent Fix Docker agent test timer race 2026-07-26 21:32:35 +01:00
fleethealth Add Agent Doctor fleet diagnostics workflow 2026-07-20 19:53:34 +01:00
hostagent Fix Proxmox registration for host-token installs 2026-07-28 11:21:14 +01:00
hosted Remove 198 unreachable Go functions 2026-06-03 12:29:37 +01:00
hostmetrics Clarify disk exclusion behavior 2026-07-24 09:20:26 +01:00
kubernetesagent Cover agent policy, alias normalization and agent report helpers 2026-07-23 06:44:33 +01:00
license Register the external_probe Pro entitlement 2026-07-27 11:13:04 +01:00
logging Harden native Windows agent lifecycle 2026-07-10 19:16:23 +01:00
maintenancesentinel Record maintenance evidence in resource timelines 2026-05-13 14:19:59 +01:00
metrics Coordinate incident recorder async persistence 2026-07-04 13:13:41 +01:00
mock Align the service availability fixture test with the check-row contract 2026-07-24 23:31:50 +01:00
mockmode Simulate Patrol end to end in demo/mock mode 2026-07-11 11:25:52 +01:00
mockmodel Add Go branch-coverage tests for canonical trust and recovery helpers 2026-07-19 15:11:01 +01:00
mockruntime Add Go branch-coverage tests for unified-resource pure helpers and platform fixtures 2026-07-20 10:49:11 +01:00
models Harden PBS backup attribution against shared sources (#1639) 2026-07-28 12:02:46 +01:00
monitoring Route discovery policy DNS through the cached resolver (#1638) 2026-07-28 12:08:10 +01:00
mutationregistry Restore one-click Docker container updates through the typed action plane 2026-07-14 12:19:04 +01:00
notifications Cover the alert-spec matchers and the audit, email and update guards 2026-07-25 02:17:36 +01:00
operationaltrust Harden Operational Trust rollout contracts 2026-07-19 15:11:02 +01:00
operationreceipt style(operationreceipt): goimports the sqlite blank import 2026-07-17 17:24:57 +01:00
platformsupport Fix agent update triage and durable action recovery 2026-07-23 11:19:50 +01:00
proxmoxidentity Harden PBS backup attribution against shared sources (#1639) 2026-07-28 12:02:46 +01:00
recovery Harden PBS backup attribution against shared sources (#1639) 2026-07-28 12:02:46 +01:00
relay Enforce Pulse Mobile compatibility from the core contract 2026-07-22 13:41:09 +01:00
remoteconfig Add an explicit operator override for plaintext HTTP to non-local Pulse hosts 2026-07-14 16:42:02 +01:00
repoctl Fix Proxmox registration for host-token installs 2026-07-28 11:21:14 +01:00
securityutil Add Go branch-coverage tests for pure config and helper packages 2026-07-16 10:19:51 +01:00
sensors Remove 198 unreachable Go functions 2026-06-03 12:29:37 +01:00
servicediscovery Cover the missing arms of the SSRF, clone and classifier guards 2026-07-25 00:39:15 +01:00
ssh/knownhosts
storagehealth Cover the missing arms of the SSRF, clone and classifier guards 2026-07-25 00:39:15 +01:00
system Remove 198 unreachable Go functions 2026-06-03 12:29:37 +01:00
telemetry Document external probes and count adoption in telemetry 2026-07-27 11:13:04 +01:00
testutil Stabilize rc1 mock mode and metrics history 2026-04-11 16:47:37 +01:00
truenas Backfill monitoring contract for the TrueNAS handshake-redirect upgrade 2026-07-27 13:16:52 +01:00
unifiedresources Remove dead cache-aware RRD fields from the guest RRD path 2026-07-27 18:36:50 +01:00
updates Cover the Unraid merge, setup classifier and retry helpers left untested 2026-07-22 08:06:56 +01:00
updatesignature Add Go branch-coverage tests for canonical trust and recovery helpers 2026-07-19 15:11:01 +01:00
utils Clear all errcheck and gofmt violations so make lint gates on real findings 2026-06-09 21:42:21 +01:00
vmware Fix VMware connection test degradation handling 2026-07-23 22:06:57 +01:00
websocket Document websocket lifecycle synchronization 2026-07-26 22:02:22 +01:00