Files
2026-08-24 11:09:03 +00:00

114 lines
4.9 KiB
Markdown

---
spec: docs/specs/agents/requirements/runtime-updates.md
created: 2026-07-31
status: complete
---
# Fix Plan: Handle Same-Version Agent Runtime Updates
## Overview
The update preview already reports both the installed and upstream versions,
but the shared approval predicate checks only that the current version is
present. Render an identical target as one version with an **Up to date**
status, tighten the predicate so that preview is non-actionable, then cover the
shared desktop dialog and mobile drawer and document the no-op state.
## Confirmed root cause
`canApproveUpdate` in
`apps/web/components/settings/agent-runtime-update-control.tsx` returns true for
any successful preview with a non-empty `current_version`. It never requires a
non-empty `target_version` or compares the two values, so a preview such as
`0.64.0 → 0.64.0` both suggests a transition that does not exist and enables
**Approve update**, which can send the update POST.
## Frontend
### Shared approval predicate
Update `canApproveUpdate` so approval requires non-empty current and target
versions whose reported values differ, in addition to the existing preview,
loading, maintenance, and request-state guards. Keep the normal upgrade and
failed-job retry paths unchanged when current and target versions differ.
Update the version summary in `UpdateBody` so identical reported values render
the version once with a visible **Up to date** status and no arrow. Differing
versions continue to render the existing `current → target` transition.
### Desktop and mobile behavior
The existing desktop `Dialog` and phone `Drawer` both render `UpdateFooter`, so
the state rule remains shared rather than duplicated. This fix does not change
composition, navigation, scrolling, safe-area behavior, or touch targets. The
nearest mobile exemplar remains the shipped agent runtime update drawer in
`mobile-agent-runtime-update.spec.ts`; focused mobile Playwright coverage will
prove that the same-version preview is visible and its shared approval action
is disabled without sending a POST.
### Public documentation
Update `docs/public/agents-and-profiles.md` to say that a matching target is
shown once as **Up to date** and **Approve update** is available only when the
upstream target differs from the reported current version.
## Tests
- **What:** A successful preview with identical non-empty current and target
versions shows a single version with **Up to date** and cannot start an
update.
**File:** `apps/web/e2e/tests/settings/agent-runtime-update.spec.ts`.
**How:** Configure the existing route fixture with `0.64.0` for both values,
open the desktop dialog, assert the single-version summary, **Up to date**
status, absence of the arrow transition, disabled confirmation button, and a
zero POST count.
- **What:** Existing differing-version approval and failed-job retry behavior
stays enabled.
**File:** Existing scenarios in
`apps/web/e2e/tests/settings/agent-runtime-update.spec.ts` and
`apps/web/e2e/tests/settings/mobile-agent-runtime-update.spec.ts`.
**How:** Run both focused spec files after the predicate change.
- **What:** Public documentation remains structurally valid.
**File:** `docs/public/agents-and-profiles.md`.
**How:** Run the public-doc validators.
No new public function or API contract is introduced; the private version
resolution helper and approval predicate are covered by focused unit tests and
the rendered shared action is exercised through the mocked update boundary.
## E2E Tests
- **Desktop scenario:** **GIVEN** current and target are both `0.64.0`, **WHEN**
the operator opens the update dialog, **THEN** it shows `0.64.0` once with
**Up to date**, omits the arrow transition, disables **Approve update**, and
sends no update request.
**File:** `apps/web/e2e/tests/settings/agent-runtime-update.spec.ts`.
- **Mobile scenario:** **GIVEN** the same preview on a phone viewport, **WHEN**
the operator opens the update drawer, **THEN** it uses the same single-version
**Up to date** presentation, the shared approval action is disabled, and no
update request is sent.
**File:**
`apps/web/e2e/tests/settings/mobile-agent-runtime-update.spec.ts`.
## Implementation Wave
- [x] [Task 01: Disable same-version approval](task-01-disable-same-version-approval.md) — done
Execution is sequential in the primary conversation. No subagents are
authorized.
## Risks and out of scope
- Equality is based on the two reported preview strings. Normalizing alternate
SemVer spellings such as `v0.64.0` versus `0.64.0` is out of scope.
- The update icon remains available so operators can open a fresh read-only
preview; this change disables only the confirmation action after equality is
known.
## Stale preview guard
The backend resolves the target and then re-reads the current runtime version
before invoking the package command. If the versions now match, it completes a
successful no-op job with an explicit message and skips the update and refresh
commands.