> For the complete documentation index, see [llms.txt](https://help.resouris.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.resouris.com/job-planning/hcs-history-ui.md).

# Plan history — the UI

**Landed:** 2026-08-03. **What's new:** three admin routes, one dashboard widget, and a modal for opening a new WTE spell — all on top of the P44 data plane. The operator surfaces that v1.7.5 deliberately deferred so we could prove the data model first.

**Scope frame:** UI + one atomic write helper. Zero MIGs, zero new perms, zero new audit event kinds. Reuses `admin.job_plan_monitoring.read` for reads and `admin.staff.edit` for the open-spell write.

## Plan history

Landing at `/ui/admin/job-plans/{plan_id}/history` (linked from the workload-plan detail page).

Renders a vertical timeline with one card per revision of a plan, oldest-first. Each card shows the state at that revision, the active window, the band grade at the time, the WTE at active-from, the entitlement totals by category (DCC / SPA / ANR / ED), and a recursive link to the predecessor plan's history so you can drill up the supersedes chain by clicking.

Unknown plan or access-denied → friendly "No history recorded" card. Never 404s.

## WTE history — with a session-based fork

Landing at `/ui/admin/staff/{staff_id}/wte-history` (linked from the staff-edit page as **WTE history** for time-based contracts or **Sessions history** for session-based).

Newest spell first. The currently-open spell carries an "Open" badge. Backfilled rows (from the MIG-213 backfill at the P44 upgrade) carry a "Backfilled" badge with a tooltip flagging that the historical value is honestly unknown.

**Session-based fork.** When `staff.contract_kind = 'session_based'` (per MIG-192), the timeline renders sessions per week (= WTE × 10 per Guidelines §5.1) instead of a raw WTE decimal, and the modal input flips to a session-count field.

## Open a new WTE spell (with auto-supersede)

The "Open new spell" button on the WTE-history page opens a modal that:

1. Asks for effective-from, reason (from a 4-value dropdown: `wte_change`, `promotion`, `return_from_leave`, `correction`), the new WTE (or session count), and optional notes.
2. Shows a **red warning banner** if the target staff has an active plan — "This will supersede the active plan" — with a link to the plan's history so you see which chain you're extending.
3. On submit, atomically:
   * closes the current WTE spell at (effective\_from - 1 day);
   * inserts a new open spell with the given WTE;
   * updates the `staff.wte_fraction` current-value mirror;
   * if `supersede_active_plan` is on (default), transitions the active plan to `superseded` and inserts a new draft plan (awaiting approval) inheriting the new WTE.

All in one psycopg 3 transaction — if any step fails, the whole write rolls back.

**Why the auto-supersede?** Guidelines §5.1's SPA-min pro-rating uses the plan's WTE at `active_from`. Leaving an active plan on the old WTE while the worker's actual WTE changed is exactly the silent-drift bug P44 was built to prevent. Auto-supersede makes the plan reflect the current WTE without the operator having to remember to open a new plan manually.

**The reason `initial` is deliberately excluded** from the manual form — it's reserved for MIG-213 backfill rows so backfilled and manually-opened spells can be distinguished later.

## Cycle coverage snapshot

Landing at `/ui/admin/cycles/{cycle_id}/coverage` (linked from the cycles list + from the cycle detail page).

* **Headline**: coverage-% + progress bar + "N covered of M total". Numerator = active staff in the cycle's department with a plan linked to this cycle; denominator = all active staff in the department.
* **Missing-staff table**: one row per worker without a plan linked to this cycle, ordered by display name.

Each row has a "Has plan in another cycle" pill and an action:

* **When true**: "Supersede candidate" pill + "Open spell to supersede" link. The signal is *this worker already has a plan against a different cycle — the right action is supersede via WTE change, not fresh create*.
* **When false**: disabled "Create draft plan" stub (coming in v1.7.7).

**Empty envelopes**: unknown cycle → "Cycle not found"; all covered → success banner. Never 404s.

## Dashboard widget

New `hcs_cycle_coverage_percent` widget on the HCS Job Planning preset dashboard. One row per open cycle for the tenant, showing coverage-% + missing + total. Click-through to the per-cycle route.

Fail-open: pre-migration or per-cycle read error → the widget's no-data card renders rather than the dashboard 500ing.

## Cycles list polish

The `/ui/admin/job-plan-cycles` list gets clickable rows, a primer card explaining what a cycle is + the at-most-one-non-closed invariant, coloured state badges (5-value MIG-203 closed set), a "New cycle" CTA button, and a richer empty state — plus a "View coverage" per-row link into the new snapshot page.

## What deliberately deferred (v1.7.7+ / v1.8)

* CSV / PDF export from all three routes.
* Quick-create draft plan from the coverage table.
* Filter + pagination on large coverage tables.
* Reverse-transitions (un-supersede, re-open a closed spell).
* Cross-cycle plan continuation UX.
* Department-transfer flow.
* Trainee-grade plans under Guidelines §7.
* Working-day-aware appeal SLA.
* Band history (`staff_band_spell` temporal table). Plan history shows current `staff.band_grade` in v1.7.6 — same posture as the P44 JSON API.

## Traceability

* Plan doc: `docs/phases/v1.7.6-hcs-job-planning-history-ui-build-plan.md`.
* Predecessor: P44 / v1.7.5 (data plane). See the [Plan history + WTE temporal](/job-planning/plan-history-and-wte-temporal.md) primer for what shipped first.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://help.resouris.com/job-planning/hcs-history-ui.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
