# Phase 4 — Backlog reconciliation

**Depends on:** Phase 0, Phase 3 (and consumes Phase 2's drift list) · **Blocks:** Phase 5 · **Size:** 1–2 sessions

## Goal

Turn **five unreconciled ledgers plus 50+ scattered "follow-ups" sections** into one triaged backlog
where every open item is real, deduplicated, and carries its origin.

This is the "remaining works from plans, dev, refine and ui phases should be well documented"
deliverable. Today the honest answer to "what's left?" is *nobody knows* — the hardening ledger has
18 items with **zero ticked**, written before three more chains ran on top of it.

---

## Inputs

| Source | Volume | Note |
| --- | --- | --- |
| [dev/post-phase/hardening/issues.md](../../dev/post-phase/hardening/issues.md) | 18 items, **all unticked** | Written 2026-07-16. UI phases 0–13 and the deploy commits ran after. **Every item must be re-verified against current code.** |
| [dev/shared-working-context/frontend/requests/for-backend.md](../../dev/shared-working-context/frontend/requests/for-backend.md) | 67 REQs, 1,115 lines | Most delivered in refinement-phase-3; some `partially delivered`; REQ-066/067 blocked on a privacy sign-off |
| `dev/shared-working-context/reports/*.md` | 50 files | Each has a "Follow-ups for later phases" / "Deferred" section |
| `dev/shared-working-context/backend/STATUS.md` + `frontend/STATUS.md` | 86 KB | Deferrals recorded with explicit **pull-triggers** (e.g. Elasticsearch `INurseSearch`, SMS/push dispatcher, analytics, holiday feed, 8 unbuilt product tables) |
| [dev/manual-testing/iteration-1/](../../dev/manual-testing/iteration-1/) + [iteration-2/](../../dev/manual-testing/iteration-2/) | 2 raw notes + screenshots | Your own most recent feedback. Some applied in `baa3cc6` / `e6a8f93`; **which parts landed is unknown** |
| [product/notes/open-questions.md](../../product/notes/open-questions.md) | build backlog + research questions | |
| Phase 2's output | drift list | `phantom` and `drifted` endpoints |
| Phase 3's output | gap list | everything found while verifying flows |
| Root [CLAUDE.md](../../CLAUDE.md) §6 | | credential rotation before real users — a real pre-launch item |

## Outputs

```
docs/status/
  index.md            where the project is, in one page
  implemented.md      the product/business overlay: 14 areas -> build state
  backlog.md          BL-### — every open item, triaged
  backlog-closed.md   items confirmed done, with what closed them
  decisions.md        the distilled decision log
```

---

## Steps

### 1. Harvest everything into one raw list

One row per candidate item, with its **origin id** (`H-01`, `REQ-042`, `ui-phase-9 follow-up`,
`iteration-2`, `deferral: elasticsearch`, `phase-3 finding`, `phase-2 drift`). Expect 150–250 raw
rows before dedup. Do not filter while harvesting.

### 2. Verify each item's current state

This is the phase's real work, and the reason it comes after Phase 3.

- **The 18 hardening items**: re-locate each in the code. The file itself warns that line numbers
  drifted. Several are likely fixed by the UI chain — e.g. **H-01** (the auth gate never running,
  traced to a stray `pnpm-lock.yaml` and the `middleware.ts` → `proxy.ts` question) overlaps directly
  with what ui-phase-13 did to the root route and matcher. Verify; don't assume either way.
- **The 67 REQs**: classify `delivered` / `partially delivered — what's left` / `open` / `obsolete`.
  The ones marked `partially delivered in refinement-phase-3` need the residue spelled out. Once
  Phase 2 folded delivered REQs into the domain docs, a delivered REQ is *closed*, not an item.
- **Iterations 1 & 2**: walk each bullet against the code. The clearest testable one:
  *"replace all forms with more than 1 field with react-hook-form"* — 28 files import it today;
  find the forms that still use raw state and file the residue.
- **Deferrals**: these are not bugs; they are *decisions with pull-triggers*. Keep them as
  `deferred`, carry the trigger, and hand them to Phase 5's `roadmap/deferred.md`.

### 3. Dedup and assign `BL-###`

Many items appear in three ledgers. Merge them into one `BL-###` carrying **all** origin ids.
Old ids stay greppable — never rewrite the archived sources.

### 4. Write `backlog.md`

```markdown
> Last verified: <date> against <commit>

| ID | Area | Sev | Item | Origin | Status | Blocks |
|----|------|-----|------|--------|--------|--------|
| BL-001 | client | blocker | … | H-01 | open | flow: auth-login-otp |
```

- **Area**: `client` · `server` · `contract` · `ops` · `product` · `docs`
- **Sev**: `blocker` (product is wrong or unusable) · `major` · `minor` · `deferred`
- **Status**: `open` · `in-progress` · `blocked (on what)` · `deferred (trigger)`
- **Blocks**: the flow(s) from `docs/flows/` it degrades — this is what connects the backlog to
  something a user can feel

Sort by severity, then area. Anything closed goes to `backlog-closed.md` with *what* closed it
(commit or phase), so the count of open items is honest at a glance.

### 5. Write `implemented.md` — the product overlay

The agreed alternative to touching `product/`. One row per business area:

| Business area | Doc | State | Flows | Gaps |
| --- | --- | --- | --- | --- |
| 08 Payments & escrow | [product/business/08-…](../../product/business/08-payments-and-escrow.md) | built | checkout-and-payment, cancellation-and-refunds | BL-023 |

States: `built` · `partial` · `mocked` · `not started` · `deferred`. Add the reverse link from each
`docs/flows/*.md` back to its business area. This gives the two-way mapping without editing a single
`product/` file.

Do the same, briefly, for the data model: the STATUS logs mention **8 product tables that were never
built** — name them here rather than leaving them in a status log.

### 6. Write `decisions.md`

The distilled decision log — the highest-value thing buried in 3 MB of reports. Extract every
**non-obvious decision with a reason** and write it as a short ADR-style entry: *what was decided,
when, why, and where it binds*. Candidates already visible in the STATUS logs and memory:

- Commission 0.15 / VAT 0.10 **on commission only** (the canonical fee model, refinement-phase-3)
- `district_id = NULL` means whole-city — in both directions
- Verification `status` is the source of truth; `is_verified` is a guarded flip
- Booking status is forward-only; the three-amount split has a CHECK constraint
- The two-stage clinical-disclosure gate; EVV is **advisory**, never a block
- Webhook idempotency is upsert-first; ledger postings must balance
- Reviews recompute from source; nurse care records are append-only
- `is_internal` ticket messages never appear in user-facing types
- One payout per booking (UNIQUE); whole-clawback greedy netting
- Escrow released after a confirmed check-out; weekly payout generation automatic, processing manual
- Config in files, not a secret store — deliberate pre-launch trade
- Error state is never an empty state (the client convention)
- Root `/` forks by auth via middleware **rewrite**, never redirect

Each entry: 3–6 lines. Where a decision is already stated in `product/`, link rather than restate —
`product/` wins for business rules; `decisions.md` is for *engineering* decisions and for business
decisions that were made **during** the build and never made it back into `product/`. Anything in the
second category should also get a note in `product/notes/` so the business truth stays complete.

### 7. Write `index.md`

One page: how many flows are built/partial/mocked, how many backlog items are open by severity, the
top five things standing between here and a usable product, and links to everything. This is the page
you open when you come back after two weeks away.

---

## Verification

- [ ] Every one of the 18 hardening items has a verdict backed by a code check — none carried over
      unexamined.
- [ ] Every REQ-001…067 is classified; the count of `open` is explicit.
- [ ] Every "Follow-ups for later phases" section across the 50 reports was read and harvested.
- [ ] Both iteration notes are fully accounted for, bullet by bullet.
- [ ] No `BL-###` duplicates another; every one names its origin id(s).
- [ ] Every `blocker` names the flow it blocks.
- [ ] `implemented.md` covers all 14 business areas and all 23 flows.

## Definition of done

"What's left?" is answered by one file, and every number in it was checked rather than inherited.

## Handoff

_(filled in by the agent that runs this phase — item counts by severity, and anything that turned out
to be worse than the old ledgers claimed)_
