Files
pulse/docs/release-control
rcourtman 537a32d8ad Point Patrol trigger contracts at the Patrol settings page (#2691)
## What

27ba85ddc6 removed the Patrol page's "Configure Patrol" popover.
Schedule, trigger and model settings moved to **Settings > Pulse
Intelligence > Patrol** (`PatrolSettingsContent` in `AISettings.tsx`,
saved through `useAISettingsState.ts`). Several contract clauses still
described the popover. This PR rewrites them to say where the controls
live and how they save.

| Contract | Old claim | Source today |
|---|---|---|
| patrol-intelligence (alert-trigger policy) | The selector sits in the
Patrol control panel and persists through its own `AIAPI.updateSettings`
call with optimistic state and revert-on-error | It is a field in the
settings form. Nothing is written until `Save Patrol settings`. The
severity goes in the page's single payload only when it changed. A
rejected save keeps the edit, and a successful save reloads the form
from the response |
| frontend-primitives (severity selector) | Lives under
`features/patrol/` in an "advanced Patrol settings disclosure" |
`FormSelect` in the settings page's Triggers section, rendered only
while alert triggers are on |
| frontend-primitives (toggles) | Toggles are named through
`ariaLabelledBy` | They carry explicit `ariaLabel` strings that contain
the visible label (`Enable alert-triggered Patrols`) |
| patrol-intelligence, api-contracts, frontend-primitives #61 | A header
"Schedule & model" drawer, a header settings surface with trigger
toggles, and a Patrol mode dialog | The header has a `Settings` link
(hidden while setup blocks), a conditional trigger-status line, and the
mode selector inside its `Mode and automation` disclosure |

Clauses owned by sibling PRs are left alone: the frontend-primitives
"Patrol schedule and model drawer" block, the patrol-intelligence
"advanced Patrol settings drawer" paragraph, and the patrol-intelligence
"header and configuration dialog" sentence (being folded into #2687).
Merge-tree against #2682, #2686, #2677 and the unpushed sibling heads is
clean.

## Tests

Three new cases in `AISettings.test.tsx` pin the rewritten claims:

- The severity selector is hidden while alert triggers are off, keeps
its value across off/on, and writes nothing before Save.
- A rejected save leaves the edit in the form for a retry. A successful
save reloads the form from the response and does not resend an unchanged
severity.
- Each Patrol trigger toggle's accessible name contains its visible
label.

Each assertion fails against a deliberately broken build: selector
always rendered, autosave on change, form reset on error, no reload
after success, severity always sent, and a divergent toggle `ariaLabel`.
`contract_audit.py`, `registry_audit.py` and `status_audit.py` report no
errors. The test-only frontend change needs no browser receipt; the
guard skips it.
2026-10-08 07:51:55 +01:00
..