--- id: STATE-WP-0048 type: workplan title: "UI State Change Reconciliation" domain: custodian repo: state-hub status: finished owner: codex topic_slug: custodian planning_priority: high planning_order: 48 created: "2026-05-23" updated: "2026-05-23" state_hub_workstream_id: "8cb9d9d3-ec8f-4690-bb22-b9b0b52b4125" --- # STATE-WP-0048 - UI State Change Reconciliation ## Goal Make State Hub UI state changes safe in an ADR-001 world: if a human changes a workstream or task state in the dashboard, the file-backed workplan must either be updated, queued for reconciliation, or explicitly marked as requiring human follow-up. ## Context State Hub is a live coordination surface, but workplan files remain the origin of truth. Today a dashboard user can push a workstream back to `backlog` in the DB while the repository file remains unchanged. The same mismatch can happen for other workstream and task state transitions. This workplan defines the reconciliation path between UI actions, DB state, repo files, and scheduled cleanup. ## Reconciliation Classes | Class | Meaning | Default follow-up | |-------|---------|-------------------| | `write_through` | The change can be represented directly in the workplan file. | Patch the file first, then sync the DB from file state. | | `deferred` | The change cannot safely touch the file immediately. | Create a visible reconciliation record or task. | | `human_confirmation` | The change may hide work, require a blocker reason, or move archived context. | Ask for confirmation or gather missing intent before writing. | ## Initial Transition Classification | Target | Safe write-through | Deferred | Human confirmation | |--------|--------------------|----------|--------------------| | Workstream status | Open, file-backed transitions among `proposed`, `ready`, `active`, and `backlog`; `finished` only when known tasks are terminal. | Non-file-backed workstreams, unsupported statuses, unavailable file links. | Archived files, `blocked` without explicit blocker/dependency context, `finished` with open/unknown tasks, `archived`. | | Task status | Linked task blocks in active workplan files for `todo`, `in_progress`, `done`, `cancelled`, and `blocked` with a blocking reason. | Non-file-backed workstreams or DB tasks without a linked task block. | Archived files and `blocked` task changes without a blocking reason. | ## T01 - Classify UI State Changes ```task id: STATE-WP-0048-T01 status: done priority: high state_hub_task_id: "0332be96-ebc7-4a7b-97c6-bbe6ae3a66ac" ``` Define which dashboard state changes are safe to write through immediately to repo files, which require a queued reconciliation task, and which require human confirmation. Done when each workstream/task transition has a reconciliation class and a reason. Result 2026-05-23: added the initial classification matrix and `api.services.reconciliation` helpers for workstream/task status changes. Tests pin the write-through, deferred, and human-confirmation decisions. ## T02 - Add Reconciliation API Contract ```task id: STATE-WP-0048-T02 status: done priority: high state_hub_task_id: "50c20ddf-f039-418b-a763-7a8f581be5b0" ``` Design and implement an API contract for UI-originated state changes that captures intent, actor, target state, file-backed status, write-through result, and follow-up action. Done when dashboard actions no longer perform ambiguous direct status patches without reconciliation metadata. Progress 2026-05-23: added a classify-only `POST /reconciliation/state-change` API contract. It returns actor, intent, current/target status, file-backed flags, reconciliation class, reason, follow-up action, and `write_through_result: not_attempted`. Dashboard wiring and write-through execution remain for the next slice. Result 2026-05-23: the API contract now also supports `apply: true` for safe write-through changes. Unsafe classifications return `not_applicable` instead of mutating files or DB state. ## T03 - Implement File Write-Through For Safe Changes ```task id: STATE-WP-0048-T03 status: done priority: high state_hub_task_id: "c0a4e976-81fb-4fe3-a8a9-b8262e2c1c85" ``` For safe transitions, update the relevant workplan frontmatter or task block in the repo file, then sync the DB. Preserve formatting and existing `state_hub_*_id` links. Done when common dashboard transitions such as `active -> backlog` or task status updates can update the file representation deterministically. Result 2026-05-23: added workplan-file helpers and write-through support for file-backed workstream status and linked task status changes. The endpoint patches the workplan file first, then updates the DB status, and returns the relative workplan path plus `write_through_result: applied`. ## T04 - Queue Reconciliation For Deferred Changes ```task id: STATE-WP-0048-T04 status: done priority: high state_hub_task_id: "2ed06c09-7b92-4b82-bcd3-090a1e320a88" ``` For changes that cannot be written immediately, create a reconciliation record, message, or task that makes the pending file update visible and schedulable. Done when UI changes that cannot write through are never silent DB-only drift. Result 2026-05-23: attempted `apply: true` changes that classify as deferred or human-confirmation now create an unread message for `state-hub` with actor, intent, target id, current/target status, reason, follow-up, and workplan path when known. ## T05 - Surface Reconciliation State In Dashboard ```task id: STATE-WP-0048-T05 status: done priority: medium state_hub_task_id: "04025e9f-b1cc-4b73-b95a-2a53bad6b360" ``` Show whether a workstream/task is file-synced, pending write-through, blocked on human review, or out of sync. Done when a dashboard user can tell whether their state change has reached the repo file or still needs reconciliation. Result 2026-05-23: dashboard status controls now submit state changes through `POST /reconciliation/state-change` with `apply: true` instead of direct DB patches. The control reports `synced` when the repo file and cached DB state were updated, `queued` for deferred reconciliation, and `needs review` for human-confirmation cases. ## T06 - Add Conflict Handling ```task id: STATE-WP-0048-T06 status: done priority: high state_hub_task_id: "b1769ce0-de21-4faf-9db4-75ebc8506044" ``` Handle cases where the repo file changed after the UI loaded, the workplan is missing, the workplan is archived, or the State Hub host path is unavailable. Done when reconciliation failures produce clear, actionable records instead of partially applied state. Result 2026-05-23: apply-mode reconciliation now blocks stale UI requests, repo file/cache drift, missing host-path access, and failed file patch attempts before DB mutation. These cases create reconciliation messages with actionable reasons and return `conflict: true` for dashboard display. ## T07 - Tests And Consistency Integration ```task id: STATE-WP-0048-T07 status: done priority: high state_hub_task_id: "7d7e36e8-783d-494f-9691-5213e35c7539" ``` Add API, dashboard, and consistency tests for UI-originated state changes and deferred reconciliation. Done when UI state changes are covered as first-class ADR-001 workflows. Progress 2026-05-23: added API tests for classify-only responses, safe write-through, missing-file deferral, and human-confirmation message creation. Progress 2026-05-23: routed dashboard status controls through the reconciliation API so UI-originated changes exercise the same write-through and deferred-record path as API clients. Result 2026-05-23: added API coverage for stale expected status, workplan file/cache drift, and unavailable host paths. Added a dependency-free dashboard component test that verifies status controls post the reconciliation contract, include `expected_current_status`, keep local state on conflicts, and surface `out of sync` to the user. ## Acceptance Criteria - Dashboard state changes never create silent DB/file divergence. - Safe changes write through to workplan files and then sync to the DB. - Deferred changes become visible reconciliation work. - Conflicts and host-path failures are explicit and recoverable.