Commit graph

1517 commits

Author SHA1 Message Date
rcourtman
917a9e5421 Add local subscription model routes 2026-07-14 22:57:38 +01:00
rcourtman
ae4162f8f2 Enforce installation-scoped license invalidation 2026-07-14 16:18:21 +01:00
rcourtman
3f45953866 Complete Patrol autonomous qualification loop 2026-07-14 15:35:48 +01:00
rcourtman
acd5637485 Drive executing-action restart recovery at startup and agent registration
RecoverExecutingActions existed with full test coverage but had no
production caller, so any typed action mid-dispatch across a server
restart (container update, start/stop/restart, host update, storage
cleanup) stayed in the executing state forever and sat in the Actions
inbox as live work, even after the agent persisted its terminal durable
receipt. Reproduced live on the dev instance with a Docker container
update (act_bf77dfe860ad3d8e4e0a91dc8eb83b44).

The router now runs a bounded, serialized recovery pass per organization
from a startup background worker, and again whenever an agent
(re)registers on the agentexec command server via a new registration
notifier, because a receipt-pending attempt can only be reconciled while
the owning agent is connected. Both triggers reuse the existing
query-only reconciliation semantics; nothing gains a resend authority.

Task 07 owns this residual; the api-contracts and agent-lifecycle
subsystem contracts now record the production trigger. The
rg-07-durable-delivery gate suite stays green, and a new router-level
test pins that a receipt-pending executing action completes from the
agent receipt without a second dispatch.
2026-07-14 14:19:19 +01:00
rcourtman
1a2215c9b4 Refresh the action-plan contract snapshot for identity-hashed resource versions
098ba4eaa changed plan resource versions to hash relationship identity
instead of observation stamps, and updated the planner unit tests, but
missed the pinned API contract snapshot: its fixture carries a vm-to-node
relationship, so the resourceVersion (and the actionId, decisionId, and
planHash derived from it) legitimately changed. TestContract_ActionPlanJSONSnapshot
has been red on main since that commit; this re-pins the snapshot to the
deterministic values the new hashing produces.
2026-07-14 14:15:52 +01:00
rcourtman
3c778e2b26 Restore one-click Docker container updates through the typed action plane
v6.1.0-rc.1 retired the legacy update endpoints before a replacement
existed, so the UI's Update button failed with an internal-jargon 410
(issue #1564). This lands the replacement end to end: update_container
is a typed agentexec operation with its own strict codec, durable
receipts, and a request digest bound to the image digest the plan
observed; the unified agent bridges execution to the Docker module's
existing pull/backup/recreate/verify/rollback implementation (which now
reports rollback attempt and outcome); and the container action
executor plans, dispatches, and reconciles the operation with declared
backup/rollback compensation truth. Containers advertise an
admin-approval update capability while an image update with a stated
current digest is detected. The legacy endpoints stay retired but
return actionable copy.

Proven live against a Colima daemon: single-container update, the
issue-1564 shared-network-namespace update, and the full UI journey
(Update button, governed review, approve, run) all completed with the
namespace preserved and the backup retained.
2026-07-14 12:19:04 +01:00
rcourtman
848b4d5038 Preserve customer data across plan downgrades 2026-07-14 11:47:25 +01:00
rcourtman
b3ae6f72b6 Recognize OIDC sessions that carry no refresh token
A provider that issues no refresh token (offline_access not requested,
e.g. default Authelia) left session.OIDCIssuer unset, so
/api/security/status reported an empty ssoSessionUsername and
X-Auth-Method fell back to plain session. The frontend then skipped the
SSO fast path, and the pre-auth bootstrap short-circuit pinned the user
to the login page after ?oidc=success before the /api/state probe could
run (issue #1574). Stamp issuer/client on every OIDC session (refresh
stays gated on the token being present) and let a completed SSO
callback bypass the bootstrap short-circuit.
2026-07-14 09:42:27 +01:00
rcourtman
d746731c75 Dispatch relay proxy requests to the local API in-process
The relay client's HTTP proxy dialed http://127.0.0.1:<FrontendPort> for
every proxied mobile request. With HTTPS_ENABLED the main listener serves
TLS on that port, so Go answered each plaintext dial with a bare
"Client sent an HTTP request to an HTTPS server" 400 - breaking Remote
Access backlog sync (alerts/approvals) on every HTTPS-enabled instance.
A non-loopback BIND_ADDRESS broke the same dial outright.

Route proxied requests through the router's own handler chain in-process
instead, via a streaming-capable RoundTripper (pipe-backed, SSE flush,
panic recovery, loopback RemoteAddr for address-keyed middleware). The
listener's scheme and bind address no longer matter, and the request
traverses exactly the middleware the real listener serves.

Reported by Johannes Strasser (Remote Access thread, 2026-07-14).
2026-07-14 09:26:41 +01:00
rcourtman
71a3b6ebcd Restore release-blocking backend contracts 2026-07-13 21:51:33 +01:00
rcourtman
a393744894 Add in-app release highlights 2026-07-13 18:30:29 +01:00
rcourtman
66dc5fd7df Polish Actions layout and review details 2026-07-13 17:00:36 +01:00
rcourtman
4c073d6b17 Add mock action lifecycle data 2026-07-13 16:24:06 +01:00
rcourtman
9286422263 Bind mobile actions to reviewed plans 2026-07-13 15:27:39 +01:00
rcourtman
a10f309c95 Add Proxmox lifecycle Patrol detectors 2026-07-13 14:34:27 +01:00
rcourtman
f095da2fdb Wire production Proxmox action verification 2026-07-13 11:04:09 +01:00
rcourtman
5cde383b98 Adopt a member agent's connection address on cluster re-registration
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
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
The v6.0.5 host-adoption fix (f85009913) only applies when a
re-registering agent matches a top-level instance host, so an agent on a
non-primary cluster member never benefited: its registration created a
standalone instance that ConsolidatePVEInstances folded back into the
cluster, and the fill-empty endpoint merge silently discarded the agent's
fresh address. The member row kept showing the corosync short-DNS host
rebuilt on every re-discovery (the "Install issues with V6" support
thread; a reinstall on v6.0.5 still showed the stale name).

Canonical auto-register now matches cluster member endpoints directly:
address identity against the agent's candidate list first, then an
unambiguous corosync node-name match. The Pulse-verified selected host is
adopted as the member's IPOverride, the durable field re-discovery
preserves and polling prefers, plus the fingerprint captured from that
address. An admin-managed override absent from the candidate list is
preserved, mirroring shouldPreserveExistingAutoRegisterHost. Credential
writes stay restricted to a same-token-identity secret refresh (reinstall
rotates the agent's token in place, so the stored secret is already
invalid) and full promotion onto a credential-less cluster; a member's
distinct per-node token never replaces working cluster credentials, and
no standalone instance is created for consolidation to discard.
2026-07-13 09:59:18 +01:00
rcourtman
a63b3eae2b Require independent evidence for verified findings 2026-07-12 23:15:54 +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
rcourtman
8676e5d5b9 Keep RG09 cache fixture across restart 2026-07-12 22:31:29 +01:00
rcourtman
329039354d Use Development SSD for RG09 Go cache 2026-07-12 22:13:04 +01:00
rcourtman
373b491484 Fix durable APT drift receipts 2026-07-12 21:53:52 +01:00
rcourtman
1ff4c29cf7 Add Debian and Ubuntu APT certification 2026-07-12 21:25:48 +01:00
rcourtman
60ce8924bb feat(assistant): retry re-runs the turn in place and the last answer gains regenerate
Retrying a failed turn re-sent the prompt without removing the persisted
turn, so session history double-recorded the prompt. Session undo now
accepts an expected-prompt guard (a stale retry can never remove a
different turn); retry drops the replaced turn server-side before
re-sending. The latest settled assistant answer gains a hover-revealed
Regenerate button that reuses the same path.
2026-07-12 20:58:20 +01:00
rcourtman
b8df758ede Preserve RG06 evidence trust boundaries 2026-07-12 20:49:18 +01:00
rcourtman
8b2eef10b4 Normalize bounded APT agent clock skew 2026-07-12 20:44:21 +01:00
rcourtman
9981e370bb Align RG06 operator lock reason 2026-07-12 20:39:14 +01:00
rcourtman
399745fde5 Plan RG06 stale barrier explicitly 2026-07-12 20:35:47 +01:00
rcourtman
03cb85d85a Measure RG06 stale plan at dispatch 2026-07-12 20:30:28 +01:00
rcourtman
43accc722e Project RG06 resource staleness fully 2026-07-12 20:26:19 +01:00
rcourtman
4334535291 Invalidate RG06 registry on staleness 2026-07-12 20:22:53 +01:00
rcourtman
912f131cd0 Measure RG06 barriers before teardown 2026-07-12 20:19:03 +01:00
rcourtman
1ad813c2e7 Align RG06 emergency barrier reason 2026-07-12 20:15:25 +01:00
rcourtman
322f4fc50d Bind RG06 agent and host identity 2026-07-12 20:12:00 +01:00
rcourtman
d518e7d33d Use canonical default tenant in RG06 2026-07-12 20:08:10 +01:00
rcourtman
fedc77ef62 Route RG06 through canonical registry 2026-07-12 20:04:40 +01:00
rcourtman
06dcd59121 Bind RG06 report projection identity 2026-07-12 19:59:35 +01:00
rcourtman
e0e6842cb5 Fix RG06 ext4 pressure fixture 2026-07-12 19:56:47 +01:00
rcourtman
7fd7e2b160 fix(frontend): key drawer guest web-interface URLs by the canonical workload id
The infrastructure resource drawer saved guest metadata (web interface
URLs) under the unified resource hash or the discovery resource id, a
keyspace no workloads table reads: the tables and the workloads drawer
resolve metadata by the canonical id (instance:node:vmid for PVE guests,
resource id otherwise), which is also the key v5 upgrades carry over in
guest_metadata.json. A URL saved from that drawer was stranded where
only the same drawer could read it back.

Route the drawer's guest metadata id through
getCanonicalWorkloadIdForResource, and canonicalize the resource type
inside that helper so lxc/oci-container/qemu spellings build the same
node-scoped id the workloads surfaces use.

Refs #1556
2026-07-12 19:52:21 +01:00
rcourtman
99aa2bd6eb Add Colima autonomy release proof 2026-07-12 19:47:56 +01:00
rcourtman
90edcfe017 Fix strict APT lifecycle fixture 2026-07-12 13:00:02 +01:00
rcourtman
0062128414 Add durable Docker restart lifecycle proof 2026-07-12 12:11:16 +01:00
rcourtman
d6838d3a25 Complete durable APT workflow continuity 2026-07-12 05:23:02 +01:00
rcourtman
4aac79dc72 Add durable agent operation receipts 2026-07-12 04:16:22 +01:00
rcourtman
e77ab9518d Add safe APT workflow foundations 2026-07-12 02:53:01 +01:00
rcourtman
82c7c52727 Expose server-authored action policy provenance 2026-07-12 00:18:43 +01:00
rcourtman
76f1084c9b Enforce server-owned Patrol Autopilot acknowledgement 2026-07-11 23:12:00 +01:00
rcourtman
b7b897651b Add canonical action result truth 2026-07-11 21:27:00 +01:00
rcourtman
cd7886aa44 Enforce server-owned action approval authority 2026-07-11 19:49:17 +01:00
rcourtman
a23a8fad9a Addresses #1558 2026-07-11 19:02:14 +01:00