Commit graph

766 commits

Author SHA1 Message Date
rcourtman
a39150ba4c Make qualification profiles statistically passable 2026-07-15 17:34:57 +01:00
rcourtman
d307fe8869 Preserve Patrol investigation evidence continuity 2026-07-15 15:43:18 +01:00
rcourtman
b6ed899ad5 Add branch-coverage tests for provider context and tool-choice helpers
New table-driven tests raise branch coverage on ContextWindowTokens,
extractModelName, isDigits, rateLimitInfo, normalizeOpenAICompatibleChatURL,
stop-reason normalization and the OpenAI, Anthropic and Gemini tool-choice
converters, covering date-suffix stripping, malformed URLs and default arms.
Test-only, no source changes.
2026-07-15 15:08:59 +01:00
rcourtman
c775eed739 Add branch-coverage tests for qualification scorer and report helpers
New table-driven tests raise branch coverage on applyGates, ApplyProTrackGates,
findFault, bestFindingMatch, validatePredicates, ApplyQualificationGates,
canonicalToolInput, sanitizeArtifactText and allObservationsPassed, covering
previously uncovered gate arms, grounding misses, redaction and JSON edge
cases. Test-only, no source changes.
2026-07-15 15:04:26 +01:00
rcourtman
7da4890ce9 Add branch-coverage tests for AI tools command classifiers
New table-driven tests raise branch coverage on the timeout, curl/wget,
env and recovery-point canonicalization helpers in internal/ai/tools,
exercising previously uncovered flag-parsing arms, mutation-method
detection and numeric-detail type cases. Test-only, no source changes.
2026-07-15 15:02:19 +01:00
rcourtman
580093155f Resolve canonical Patrol discovery targets 2026-07-15 12:07:42 +01:00
rcourtman
87699dfff3 Align remediation qualification with advertised actions 2026-07-15 11:31:56 +01:00
rcourtman
03ae7d2b58 Score investigation facts without magic words 2026-07-15 10:56:12 +01:00
rcourtman
cdc109d408 Publish Patrol investigation limits live 2026-07-15 10:49:16 +01:00
rcourtman
a95edafcf1 Qualify model-led Patrol investigations 2026-07-15 10:32:16 +01:00
rcourtman
a717790e90 Pin Patrol qualification routes per suite 2026-07-15 09:46:53 +01:00
rcourtman
2774744b11 Preserve canonical resource IDs in Patrol queries 2026-07-15 09:16:39 +01:00
rcourtman
a8e42fc7fe Preserve coding-plan provenance in qualification 2026-07-15 00:06:56 +01:00
rcourtman
61ef640a51 Normalize subscription models before CLI execution 2026-07-14 23:45:10 +01:00
rcourtman
f03b0c01e7 Add branch-coverage tests for tools canonical query helpers
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Canonical Governance / governance (push) Waiting to run
Patrol Qualification Regression / Catalog, scorer, and replay regression (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 1/4) (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 2/4) (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 3/4) (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 4/4) (push) Waiting to run
Core E2E Tests / E2E verdict (push) Blocked by required conditions
New white-box table tests over the pure resource-resolution helpers in
internal/ai/tools/current_resource.go, taking canonicalQueryTypeForResolvedResource,
canonicalQueryIDForResolvedResource and resolvedResourceKindMatchesLocation from
partial to full branch coverage. Every kind switch arm, the provider-uid then
resource-id then alias fallback chain, and the nil guards are pinned to exact
output.

One file, tests only, no source changes. Gates green with go test, gofmt and go
vet, plus an adversarial GLM review scoring three KEEP and zero reject.
2026-07-14 23:38:09 +01:00
rcourtman
63442b7fe4 Add branch-coverage tests for patrol runtime failure classifiers
New white-box table tests over the pure error classifiers in
internal/ai/patrol_runtime_failure.go, taking ClassifyProviderConnectionFailure
from 18 percent to full coverage and closing the residual branches in
patrolRuntimeFailureFromError and summarizePatrolRuntimeFailureDetail. Every
reachable switch arm is pinned to its exact diagnostic output, and the four
grouped causes that only preflight and readiness state can set are documented
as out of reach from a plain error input rather than faked.

One file, tests only, no source changes. Gates green with go test, gofmt and
go vet, plus an adversarial GLM review scoring two KEEP, one WEAK and zero
reject.
2026-07-14 23:23:14 +01:00
rcourtman
89a7b88093 Distinguish subscription allowances from API spend 2026-07-14 23:12:37 +01:00
rcourtman
99615c18e3 Support Patrol streaming on subscription routes 2026-07-14 23:05:28 +01:00
rcourtman
917a9e5421 Add local subscription model routes 2026-07-14 22:57:38 +01:00
rcourtman
d0d8426cb9 Add branch-coverage tests for qualification contribution helpers
New white-box table tests over the pure validators, predicates and readme
renderer in internal/ai/qualification/contribution.go, covering
ValidateContributionChallenge, validateContributionIdentity,
everyRunChallengeBound, observationsPassedOrEmpty, reportPhasePassed,
ContributionBundle.Validate and renderContributionReadme.

One file, tests only, no source changes. Gates green with go test, gofmt
and go vet, plus an adversarial GLM review scoring seven KEEP and zero
reject.
2026-07-14 22:50:13 +01:00
rcourtman
280a44ef08 Add branch-coverage tests for AI patrol, qualification, tools and agentcapability helpers
New white-box table tests over previously-untested pure functions in
internal/ai (patrol run recency, patrol findings JSON validation),
internal/ai/tools (read-only violation hints, VM config parsing, node
target matching), internal/ai/qualification (compare predicate,
percentile and model summary, runner helpers), internal/ai/chat
(investigation run error, session compaction formatting) and
internal/agentcapabilities (path parameter substitution, markdown
helpers).

Twelve files, tests only, no source changes. All gates green with go
test, gofmt and go vet, plus an adversarial GLM review scoring twelve
KEEP and zero reject.
2026-07-14 22:33:40 +01:00
rcourtman
538c1baaef Add community Patrol qualification exports 2026-07-14 22:08:32 +01:00
rcourtman
b540025ef1 Reserve Patrol final finding decision turn 2026-07-14 21:07:49 +01:00
rcourtman
3487b9a98e Require collected negative control convergence 2026-07-14 20:14:35 +01:00
rcourtman
960e9f5e89 Bound Patrol finding verbosity 2026-07-14 19:58:03 +01:00
rcourtman
12f317364a Separate Watch restart detection from investigation 2026-07-14 19:51:53 +01:00
rcourtman
3f94a8f302 Preserve restart evidence in Patrol scope 2026-07-14 19:47:16 +01:00
rcourtman
6e71bcb151 Preserve resolved provider in qualification scoring 2026-07-14 19:38:25 +01:00
rcourtman
739b0c92d4 Align Patrol quiet-run tool contracts 2026-07-14 19:30:45 +01:00
rcourtman
9ea8cb2aa1 Clarify Patrol scope identities and finding reads 2026-07-14 19:23:36 +01:00
rcourtman
e008343b7a Align Docker host query schema and executor 2026-07-14 19:13:11 +01:00
rcourtman
3b1bc65b43 Separate Watch symptoms from injected fault targets 2026-07-14 19:02:32 +01:00
rcourtman
aa0f9ea5a7 Require collected fault convergence before Patrol 2026-07-14 18:56:06 +01:00
rcourtman
2b271e3e20 Repair disposable dependency qualification fixtures 2026-07-14 18:49:25 +01:00
rcourtman
44d8614330 Bound Patrol finding summary turns 2026-07-14 18:35:17 +01:00
rcourtman
d1e8aece7d Price reviewed OpenRouter qualification routes 2026-07-14 18:24:33 +01:00
rcourtman
090e6fde64 Separate finding writes from infrastructure verification 2026-07-14 18:19:03 +01:00
rcourtman
ee9d4b1071 Reserve Patrol reporting turn for confirmed symptoms 2026-07-14 18:10:00 +01:00
rcourtman
f6a289f72d Make Patrol report confirmed health failures 2026-07-14 18:04:09 +01:00
rcourtman
728d09769c Preserve qualification artifacts for bounded transcripts 2026-07-14 17:31:05 +01:00
rcourtman
7deaf60b37 Harden Patrol provider streams and runtime scoring 2026-07-14 17:20:56 +01:00
rcourtman
84eff17578 Preserve Patrol evidence on provider errors 2026-07-14 16:34:19 +01:00
rcourtman
3f45953866 Complete Patrol autonomous qualification loop 2026-07-14 15:35:48 +01:00
rcourtman
7a1e41bcf9 Let flowing AI streams outlive the configured request timeout
Thinking models served through OpenAI-compatible endpoints (qwen3 via
Ollama >=0.31, DeepSeek) spend most of a turn streaming per-token
reasoning deltas before any content. The stream reader wrapped the whole
turn in a wall-clock deadline at the configured request timeout, so a
live, visibly-thinking stream was killed mid-thought with 'AI response
timed out before completion' (#1576, second symptom).

The timeout's job is stall detection, not turn budgeting. It now bounds
only how long Pulse waits for the stream to start: the response-header
wait (Ollama holds headers while a cold model loads) and the first-chunk
wait both honor the configured timeout, completing what 1c0648451
started. Once deltas flow, the 12s inter-chunk stall bound and caller
cancellation are the only limits, matching the native Ollama provider's
long-standing design.

Verified live against Ollama 0.31.1 / qwen3:8b: with a 15s configured
timeout, a turn streaming 10k chars of reasoning over 4m17s completes
and delivers the answer; previously it died at the timeout.
2026-07-14 11:57:26 +01:00
rcourtman
52469f5cbc Surface native Ollama thinking tokens instead of silently dropping them
Ollama's /api/chat returns reasoning in message.thinking, but the native
provider had no field for it: thinking models like qwen3 (the quickstart
default) showed dead air in the Assistant drawer for the whole reasoning
phase. Decode the field, stream it as thinking events (matching the
OpenAI provider's reasoning handling), carry it on the non-streaming
response as ReasoningContent, round-trip prior-turn reasoning on
assistant history messages, and make SupportsThinking tell the truth.

Verified live against Ollama 0.31.1 with qwen3:8b: first stream event is
now thinking (1137 thinking chunks before content), and non-streaming
Chat returns the reasoning text.
2026-07-14 11:50:01 +01:00
rcourtman
1c06484512 Honor the configured AI timeout while waiting for the first stream chunk
The OpenAI-compatible stream reader bounded every chunk wait at 12s.
Local backends (LM Studio, llama.cpp) legitimately spend minutes on
prompt processing before the first SSE chunk, so raising the provider
timeout in Settings changed nothing and Pulse dropped the stream with
'AI response timed out' (discussion #1571). The wait for first bytes now
uses the configured request timeout; the 12s bound still applies to
inter-chunk gaps once the stream is flowing.
2026-07-14 09:44:22 +01:00
rcourtman
71a3b6ebcd Restore release-blocking backend contracts 2026-07-13 21:51:33 +01:00
rcourtman
2e9520da81 Bind governed action intent across Patrol and web 2026-07-13 16:05:44 +01:00
rcourtman
a10f309c95 Add Proxmox lifecycle Patrol detectors 2026-07-13 14:34:27 +01:00
rcourtman
7d772acff3 feat(assistant): mid-turn steering of the running response
Some checks are pending
Core E2E Tests / Playwright Core E2E (shard 1/4) (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 2/4) (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 4/4) (push) Waiting to run
Core E2E Tests / E2E verdict (push) Blocked by required conditions
Unified Agent Native Verification / Linux ARM64 (push) Waiting to run
Unified Agent Native Verification / Linux x64 (push) Waiting to run
Unified Agent Native Verification / Windows x64 (push) Waiting to run
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Canonical Governance / governance (push) Waiting to run
Helm CI / Lint and Render Chart (push) Waiting to run
Core E2E Tests / Playwright Core E2E (shard 3/4) (push) Waiting to run
Unified Agent Native Verification / FreeBSD cross-build contract (push) Waiting to run
Unified Agent Native Verification / macOS ARM64 (push) Waiting to run
Unified Agent Native Verification / macOS Intel (push) Waiting to run
A follow-up sent during an active run now offers itself to the running
agentic loop via POST /api/ai/sessions/{id}/steer. Accepted steers join
the loop at its next turn boundary (the abort-check site) as plain user
messages, are announced with a steer_applied stream event so the drawer
settles the pending row, and persist through the end-of-run save. A
steer carries prompt text only: no route, control-level, or autonomy
changes, no turn-budget extension, system sessions rejected, and the
per-session inbox is bounded (steer_backlog overflow). Delivery is not
guaranteed by acceptance: a run that ends first discards the inbox and
the row drains as an ordinary queued turn, so pre-steering queue
semantics remain the fallback. Steering rows lose edit/remove once
accepted.
2026-07-12 23:01:40 +01:00