diff --git a/_docs/02_tasks/todo/AZ-512_admin_edit_detection_class.md b/_docs/02_tasks/backlog/AZ-512_admin_edit_detection_class.md similarity index 95% rename from _docs/02_tasks/todo/AZ-512_admin_edit_detection_class.md rename to _docs/02_tasks/backlog/AZ-512_admin_edit_detection_class.md index ccc83dc..fafc5d0 100644 --- a/_docs/02_tasks/todo/AZ-512_admin_edit_detection_class.md +++ b/_docs/02_tasks/backlog/AZ-512_admin_edit_detection_class.md @@ -1,5 +1,7 @@ # Admin: edit existing detection class (inline form + PATCH wiring) +> **STATUS (2026-05-13)**: BLOCKED on cross-workspace prerequisite. The cycle 3 batch 15 BLOCKING gate (Cross-Workspace Verification below) failed: the `admin/` service exposes only `/login`, `/users*`, `/resources*`. There is no `/classes` route at all (neither the PATCH this task needs, nor the POST/DELETE that `AdminPage.tsx` already calls today). Task spec parked in `_docs/02_tasks/backlog/` until the prerequisite ticket on the `admin/` workspace lands. Re-activation steps: (1) confirm the admin/ work shipped; (2) `git mv _docs/02_tasks/backlog/AZ-512_*.md _docs/02_tasks/todo/`; (3) re-invoke `/autodev` to re-enter Step 10. See `_docs/_process_leftovers/2026-05-13_az-512-admin-classes-prereq.md` for the full prerequisite payload. + **Task**: AZ-512_admin_edit_detection_class **Name**: Admin — edit existing detection class **Description**: Re-introduce the "edit detection class" affordance the WPF→React port lost. Wire an inline edit form on each Detection Class row in the Admin page, calling `PATCH /api/admin/classes/{id}` with the editable fields, refreshing classes via the existing read endpoint. Closes Architecture Vision principle **P12** ("admin can edit existing detection classes — add + edit + delete is the full CRUD surface"). diff --git a/_docs/03_implementation/batch_15_cycle3_report.md b/_docs/03_implementation/batch_15_cycle3_report.md new file mode 100644 index 0000000..8ceaa99 --- /dev/null +++ b/_docs/03_implementation/batch_15_cycle3_report.md @@ -0,0 +1,70 @@ +# Batch 15 — AZ-512 (Admin edit detection class) — DEFERRED + +**Date**: 2026-05-13 +**Cycle**: 3 — autodev Step 10 (Implement), batch 3 of 3 (fixes-first order: AZ-510 ✓ → AZ-511 ✓ → AZ-512 deferred at gate) +**Tickets**: AZ-512 (Epic AZ-509) +**Verdict**: DEFERRED — BLOCKING gate failed; cross-workspace prerequisite missing + +--- + +## Task Results + +| Task | Status | Files Modified | Tests | AC Coverage | Issues | +|------|--------|----------------|-------|-------------|--------| +| AZ-512_admin_edit_detection_class | DEFERRED | 0 production files (verification only) | n/a — implementation never started | 0/8 ACs covered (gate stopped before implementation) | 1 (cross-workspace prerequisite missing) | + +## Why deferred + +The task spec defines a Cross-Workspace Verification BLOCKING gate that must pass before implementation begins: + +> *"Before implementing the form, the implementer MUST verify the backend endpoint exists. +> Read `../admin/` source to confirm `PATCH /api/admin/classes/{id}` is routed and accepts `{ name?, shortName?, color?, maxSizeM? }`."* + +### Verification result + +`grep -rn -E "MapPost|MapPatch|MapDelete|MapGet" /Users/.../suite/admin --include="*.cs" | grep -i class` → **no matches**. + +The `admin/` sibling service (`Azaion.AdminApi/Program.cs`) exposes `/login`, `/users*`, `/resources*` only. There are no `/classes` routes at all. + +### Choices presented (per spec) + +- **A**: File a hard-prerequisite ticket on the `admin/` workspace, pause AZ-512 until it lands. +- **B**: Implement only the UI form, MSW-stubbed in tests, mark Step 11 blocked-on-admin/PATCH, ship draft PR. +- **C**: Drop AZ-512 from cycle 3, defer to a future cycle. + +User was prompted via `AskQuestion`; user skipped the prompt. + +### Default decision (A) + +The autodev defaulted to **A** for these reasons: + +1. **Workspace boundary discipline** (`.cursor/rules/coderule.mdc`): the UI workspace cannot add routes in the `admin/` workspace. Filing a prerequisite ticket is the right cross-workspace coordination pattern. +2. **Spec invariant**: *"Do not invent a workaround that bypasses the missing endpoint."* Option B's MSW-stubbed UI is exactly that workaround once it ships, because the user-visible affordance would 404 in production. +3. **Cycle ordering rationale**: cycle 3 was deliberately ordered fixes-first (AZ-510 → AZ-511 → AZ-512) for exactly this risk — if AZ-512 hits a cross-workspace blocker, the fixes ship anyway. Option C re-validates that decision. +4. **Conservative default**: A is the minimal-progress option that preserves both correctness and the user's ability to override at the next `/autodev` invocation. + +### Side observation (pre-existing bug, not introduced by AZ-512) + +`AdminPage.tsx` already calls `POST /api/admin/classes` and `DELETE /api/admin/classes/{id}`. Neither is served by the admin service today (same gap that blocks AZ-512). The existing add+delete affordances on the Detection Classes table are therefore broken end-to-end against the live admin/ service in production. This is **pre-existing**, not introduced by AZ-510 / AZ-511 / AZ-512. Captured in the leftover record (see Section 7) for the user to track as a separate UI-workspace ticket once the admin/ work is filed. + +## Files touched + +- `_docs/02_tasks/todo/AZ-512_admin_edit_detection_class.md` → moved to `_docs/02_tasks/backlog/AZ-512_admin_edit_detection_class.md` (with a STATUS banner inserted at the top of the spec). +- `_docs/_process_leftovers/2026-05-13_az-512-admin-classes-prereq.md` (new) — full prerequisite payload + replay obligation. +- Jira AZ-512 — status remains `To Do` (no `Blocked` status exists in the project workflow); a comment was added explaining the blocker and linking to the leftover record. + +## Re-activation + +The next `/autodev` invocation will: + +1. Run the leftovers replay step from `.cursor/rules/tracker.mdc` and check this entry. +2. If the admin/ workspace's `/classes` routes now exist → move `_docs/02_tasks/backlog/AZ-512_*.md` back to `todo/`, transition the Jira ticket back to In Progress, and proceed with implementation. +3. If they still don't exist → leave the leftover as-is and surface the outstanding prerequisite to the user. + +## Cycle 3 outcome (overall) + +- **AZ-510** ✓ shipped (batch 13, commit `70fb452`) — closes Finding B3 / Vision P3 +- **AZ-511** ✓ shipped (batch 14, commit `c368f60`) — closes Finding F3 +- **AZ-512** ⏸ deferred to backlog — blocked on cross-workspace prerequisite + +Cycle 3 ships **6 of 9 planned story points** (3 + 3 = 6, with AZ-512's 3 points carried forward). Both delivered tasks were the cycle's "fixes" half — Vision P3 and F3 are now closed. The "feature" half (P12 / F10) is deferred until the cross-workspace prerequisite lands. diff --git a/_docs/03_implementation/implementation_completeness_cycle3_report.md b/_docs/03_implementation/implementation_completeness_cycle3_report.md new file mode 100644 index 0000000..80e413d --- /dev/null +++ b/_docs/03_implementation/implementation_completeness_cycle3_report.md @@ -0,0 +1,54 @@ +# Product Implementation Completeness — Cycle 3 + +**Date**: 2026-05-13 +**Cycle**: 3 +**Inputs**: `_docs/02_tasks/done/AZ-510_*.md`, `_docs/02_tasks/done/AZ-511_*.md` (the 2 completed product tasks of cycle 3); `_docs/02_document/architecture.md`; `_docs/02_document/components/02_auth/description.md`; `_docs/02_document/components/11_class-colors/description.md`; `_docs/02_document/architecture_compliance_baseline.md`; cycle 3 batch reports + reviews. + +--- + +## Per-task classification + +### AZ-510 — Auth bootstrap refresh consolidation + +**Verdict**: **PASS** + +| Promise | Implementation evidence | +|---------|------------------------| +| Bootstrap uses `POST /api/admin/auth/refresh` with `credentials:'include'` | `src/auth/AuthContext.tsx:45-48` — direct `fetch(getApiBase()+endpoints.admin.authRefresh(),{method:'POST',credentials:'include'})` | +| Chained `GET /api/admin/users/me` on success | `:51-53` — `setToken(refreshData.token)` then `api.get(endpoints.admin.usersMe())` | +| `setToken(null)` precedes `setUser(null)` on every failure path | `:59` (users/me failure) and `:87-88` (outer catch) | +| StrictMode-safe inflight guard | `:25, 70-74` — module-scoped `bootstrapInflight` promise + test-only reset hook | +| Closes Architecture Vision principle P3 + Finding B3 | Baseline `architecture_compliance_baseline.md` updated (B3 closed); `components/02_auth/description.md` updated; verification log `04_verification_log.md` B3 marked closed | + +Evidence files/symbols checked: `src/auth/AuthContext.tsx`, `src/auth/index.ts`, `src/api/endpoints.ts`, `tests/setup.ts`, `tests/msw/handlers/admin.ts`. No `placeholder`, `stub`, `TODO`, `NotImplemented`, `fake`, `deterministic`, `scaffold`, or empty-bridge markers in the changed surface. + +### AZ-511 — classColors carve-out to `src/class-colors/` + +**Verdict**: **PASS** + +| Promise | Implementation evidence | +|---------|------------------------| +| File at new location `src/class-colors/classColors.ts` | `git mv` confirmed; `find src/features/annotations -name classColors.ts` empty | +| Barrel `src/class-colors/index.ts` re-exports the 4 public symbols | File exists; re-exports `getClassColor`, `getPhotoModeSuffix`, `getClassNameFallback`, `FALLBACK_CLASS_NAMES` | +| All 4 consumers import via barrel | Verified in `src/components/DetectionClasses.tsx`, `src/features/annotations/CanvasEditor.tsx`, `src/features/annotations/AnnotationsSidebar.tsx`, `src/features/annotations/AnnotationsPage.tsx` | +| Zero STC-ARCH-01 exemptions remain | `scripts/check-arch-imports.mjs` `ARCH_IMPORTS_EXEMPT_RE = null`; `class-colors` added to `COMPONENT_DIRS` so deep imports past the new barrel are caught | +| Architecture test fixture replaced with stronger assertion | `tests/architecture_imports.test.ts` "AC-4: FAILS when a deep import bypasses the class-colors barrel" | +| 5-coupled-places carry-over fully retired | `module-layout.md` (Layout Rule #2/#3 + 4 Per-Component Mapping entries + Verification Needed #1/#3 + shared/class-colors block); `11_class-colors/description.md` (Caveats §7 + Module Inventory); `architecture_compliance_baseline.md` (F3 CLOSED + F4 carry-forward exemption note retired); `06_annotations/index.ts` (carry-over comment removed); `scripts/run-tests.sh` (description block updated); `04_verification_log.md` (#1 + #8 RESOLVED) | +| Build passes with no circular-import warnings | `bun run build` — built in 3.83s; 198 modules; only pre-existing CSS/chunk-size warnings remain | +| Closes Finding F3 | Baseline `architecture_compliance_baseline.md` F3 marked CLOSED 2026-05-13 by AZ-511 | + +Evidence files/symbols checked: `src/class-colors/`, all 4 consumer files, `scripts/check-arch-imports.mjs`, `tests/architecture_imports.test.ts`, `tests/detection_classes.test.tsx`, all 5 coupled doc/script touchpoints. No scaffold, no placeholder, no TODO. Pure file-move + barrel + import-path edits + doc updates. + +### AZ-512 — Admin edit detection class + +**Verdict**: **DEFERRED — outside this gate's scope** (cross-workspace prerequisite missing; task spec parked in `_docs/02_tasks/backlog/`; not in `done/`). The Product Implementation Completeness Gate audits completed product tasks for the cycle; deferred tasks are not classified here. See `_docs/03_implementation/batch_15_cycle3_report.md` and `_docs/_process_leftovers/2026-05-13_az-512-admin-classes-prereq.md`. + +--- + +## Verdict + +**Cycle 3 product implementation: PASS.** + +Both completed product tasks (AZ-510, AZ-511) implement the promised production behaviour with no scaffold, no placeholder, no missing named runtime dependency. AZ-512 is parked in `backlog/` with a leftover record; it is the only cycle 3 work that did not ship, and it was deferred at its spec-defined BLOCKING gate (not silently abandoned). Cycle 3 ships 6 of 9 planned story points (AZ-510 + AZ-511); the remaining 3 (AZ-512) carry forward. + +No remediation tasks needed for the completed work. The cross-workspace prerequisite for AZ-512 is captured in the leftover record for the user to action externally. diff --git a/_docs/03_implementation/implementation_report_auth_classcolors_cycle3.md b/_docs/03_implementation/implementation_report_auth_classcolors_cycle3.md new file mode 100644 index 0000000..0fcabfa --- /dev/null +++ b/_docs/03_implementation/implementation_report_auth_classcolors_cycle3.md @@ -0,0 +1,58 @@ +# Implementation Report — Cycle 3 (Auth bootstrap + classColors carve-out) + +**Date**: 2026-05-13 +**Cycle**: 3 +**Epic**: AZ-509 (UI workspace cycle 3) +**Status**: COMPLETE for AZ-510 + AZ-511; AZ-512 deferred to backlog/ at its BLOCKING gate. + +--- + +## Tasks delivered + +| Task | Title | Points | Status | Commit | Batch report | +|------|-------|--------|--------|--------|--------------| +| AZ-510 | Auth bootstrap refresh consolidation (closes Vision P3 / Finding B3) | 3 | DONE — In Testing | `70fb452` | `batch_13_cycle3_report.md` | +| AZ-511 | classColors carve-out to `src/class-colors/` (closes Finding F3) | 3 | DONE — In Testing | `c368f60` | `batch_14_cycle3_report.md` | +| AZ-512 | Admin edit detection class (P12 / F10) | 3 | DEFERRED to backlog/ — see `batch_15_cycle3_report.md` | — | `batch_15_cycle3_report.md` | + +**Shipped**: 6 of 9 planned story points. **Carried forward**: 3 points (AZ-512 awaiting cross-workspace prerequisite). + +## Code review + +| Batch | Verdict | Findings | Report | +|-------|---------|----------|--------| +| 13 (AZ-510) | PASS | 0 | `reviews/batch_13_review.md` | +| 14 (AZ-511) | PASS | 0 | `reviews/batch_14_review.md` | + +No auto-fix attempts; no escalations. Cumulative review (every K=3 batches) — not triggered this cycle (only 2 successfully completed batches). + +## Product Implementation Completeness Gate + +PASS — see `implementation_completeness_cycle3_report.md`. AZ-510 and AZ-511 both implement promised production behaviour with no scaffold or placeholder. AZ-512 is deferred (not failed), task spec parked in `backlog/` with a leftover record for replay. + +## Architecture baseline delta (cycle 3) + +| Status | Finding | Delta source | +|--------|---------|--------------| +| Resolved | B3 — Auth bootstrap missing `credentials:'include'` (Vision P3) | AZ-510 (batch 13) | +| Resolved | F3 — Physical / logical owner split for `classColors.ts` (5-coupled-places carry-over) | AZ-511 (batch 14) | +| Open | F2 (CanvasEditor cross-feature edge), F5 (mission-planner internal cycle, track-only), F6 (no `src/shared/`), F8 (Header→useAuth unannotated), F10 (P12 missing CRUD edit) | Untouched this cycle; F10 is AZ-512's target, deferred | + +## Cycle 3 leftovers + +- `_docs/_process_leftovers/2026-05-13_az-512-admin-classes-prereq.md` — cross-workspace prerequisite (POST + PATCH + DELETE `/classes` routes in `admin/Azaion.AdminApi/Program.cs`). Includes a side observation that `AdminPage.tsx`'s existing add+delete affordances are **also** broken end-to-end against the live admin/ service today (pre-existing bug, surfaced during AZ-512 verification — NOT introduced by cycle 3). + +Cycle 2 leftovers (carried forward; not actioned this cycle): +- `_docs/_process_leftovers/2026-05-12_az-498-deploy-and-key-revocations.md` — `L-AZ-498-DEPLOY` (deploy gate at Step 16); `L-AZ-499-OWM-REVOKE` and `L-AZ-501-GOOGLE-REVOKE` (manual user action at OpenWeatherMap and Google Cloud dashboards). + +## Test posture (handoff to Step 11) + +- Static profile: GREEN (all gates including STC-ARCH-01 with zero exemptions, STC-ARCH-02) +- Fast profile: GREEN (31 files / 231 passed / 13 skipped quarantines unchanged) +- Build (`bun run build`): GREEN (no circular-import warnings) + +Per `.cursor/skills/implement/SKILL.md` Step 16, the Final Test Run is **handed off to Step 11 (Run Tests)** — the next autodev step in the existing-code flow. The full-suite gate is owned by `.cursor/skills/test-run/SKILL.md` to avoid duplicate runs. + +## Next autodev step + +**Step 11 — Run Tests** (auto-chain). The test-run skill will rerun the full suite and surface any blocking failures. diff --git a/_docs/_autodev_state.md b/_docs/_autodev_state.md index f2f67c4..a6d4c0c 100644 --- a/_docs/_autodev_state.md +++ b/_docs/_autodev_state.md @@ -2,26 +2,17 @@ ## Current Step flow: existing-code -step: 10 -name: Implement -status: in_progress +step: 11 +name: Run Tests +status: not_started sub_step: - phase: 14 - name: loop - detail: "batch 3 of 3 (AZ-512 next; BLOCKING cross-workspace verification)" + phase: 0 + name: awaiting-invocation + detail: "" retry_count: 0 cycle: 3 tracker: jira ## Notes -- Cycle 3 entered via auto-loop from cycle 2 retrospective. -- Cycle 3 epic: **AZ-509** — Auth bootstrap + classColors carve-out + admin class edit. -- Cycle 3 tasks (in implementation order — fixes first per user instruction): - 1. **AZ-510** — Auth bootstrap refresh consolidation (3 pts; closes Finding B3 / Vision P3). Spec: `_docs/02_tasks/todo/AZ-510_auth_bootstrap_consolidation.md`. - 2. **AZ-511** — classColors carve-out to `src/class-colors/` (3 pts; closes Finding F3 + 5-coupled-places exemption). Spec: `_docs/02_tasks/todo/AZ-511_classcolors_carve_out.md`. - 3. **AZ-512** — Admin edit existing detection class (3 pts; closes Vision P12 / F10). BLOCKING cross-workspace verification at impl time — `admin/` must expose `PATCH /api/admin/classes/{id}`. Spec: `_docs/02_tasks/todo/AZ-512_admin_edit_detection_class.md`. -- Total cycle 3 complexity: 9 points; all PBIs at 3 pts (within 2–5 budget). -- Cycle 2 leftovers still pending (carried forward from `_docs/_process_leftovers/2026-05-12_az-498-deploy-and-key-revocations.md`): - - L-AZ-498-DEPLOY → scheduled for cycle 3 Step 16 (cross-workspace gate). - - L-AZ-499-OWM-REVOKE / L-AZ-501-GOOGLE-REVOKE → await user manual action at OWM / Google Cloud dashboards. -- Step 9 (New Task) status: **completed** for cycle 3 — 3 tasks created, epic linked, dependencies table updated. Per existing-code auto-chain rules, Step 9 is a **session boundary**: a new conversation is recommended before Step 10 (Implement). +- Cycle 3 Step 10 (Implement) shipped 6 of 9 points: AZ-510 + AZ-511 done; AZ-512 deferred to backlog/ at its BLOCKING cross-workspace verification gate (admin/ workspace lacks the prerequisite /classes routes). Leftover: `_docs/_process_leftovers/2026-05-13_az-512-admin-classes-prereq.md`. +- Cycle 2 leftovers still pending (deploy + manual key revocations). diff --git a/_docs/_process_leftovers/2026-05-13_az-512-admin-classes-prereq.md b/_docs/_process_leftovers/2026-05-13_az-512-admin-classes-prereq.md new file mode 100644 index 0000000..840a51e --- /dev/null +++ b/_docs/_process_leftovers/2026-05-13_az-512-admin-classes-prereq.md @@ -0,0 +1,71 @@ +# 2026-05-13 — AZ-512 admin classes CRUD prerequisite (cross-workspace) + +## Summary + +AZ-512 (Admin edit detection class) hit its spec-defined Cross-Workspace Verification BLOCKING gate during cycle 3 batch 15 implementation in the UI workspace. The `admin/` sibling service (Azaion.AdminApi) does not expose `/classes` routes at all. This leftover records (a) the deferred AZ-512 work in the UI, and (b) a separately-noted pre-existing bug discovered during verification. + +## Timestamp + +`2026-05-13T02:12:00+02:00` (Europe/Paris) — entry created by autodev cycle 3 batch 15 BLOCKING gate. + +## What was blocked + +1. **AZ-512 implementation (UI workspace)** — the inline edit form + `PATCH /api/admin/classes/{id}` wiring on `src/features/admin/AdminPage.tsx`. Task parked in `_docs/02_tasks/backlog/AZ-512_admin_edit_detection_class.md`. + +2. **Cross-workspace prerequisite ticket** — a NEW ticket needs to be filed on the `admin/` workspace's tracker (Jira project AZ, but linked under the admin/ module's epic) to add **POST + PATCH + DELETE `/classes` routes** to `Azaion.AdminApi/Program.cs`. This leftover does NOT itself create the ticket because the `user-atlassian-mcp` cannot reliably scope a ticket to the admin/ workspace's epic from the UI workspace's autodev session — it requires user judgment on epic linkage and ownership. + +## Prerequisite payload (for the user to file) + +**Suggested ticket summary**: `[admin/] Add /classes CRUD routes (POST + PATCH + DELETE) to Azaion.AdminApi` + +**Suggested description**: + +> The UI workspace (`ui/src/features/admin/AdminPage.tsx`) calls three /classes endpoints today, but only the read path is served (and it is served by the `annotations` service, not `admin`): +> +> - `POST /api/admin/classes` — UI calls this to add a new detection class (`handleAddClass`). Today: 404. Pre-existing bug. +> - `DELETE /api/admin/classes/{id}` — UI calls this to delete a class (`handleDeleteClass`). Today: 404. Pre-existing bug. +> - `PATCH /api/admin/classes/{id}` — UI does NOT call this today; AZ-512 (UI workspace) needs to call it to deliver the in-place edit affordance promised by Architecture Vision principle P12. Currently the route does not exist either. +> +> nginx.conf in the ui workspace routes `/api/admin/` to `http://admin:8080/`, so the path inside the admin service is `/classes` and `/classes/{id}`. The admin service's `Program.cs` exposes only `/login`, `/users*`, `/resources*` today (search 2026-05-13 in this UI workspace's chat transcript). +> +> The UI is the authoritative wire-shape contract via `ui/src/api/endpoints.test.ts` — `endpoints.admin.classes()` and `endpoints.admin.class(id)` pin the URLs. +> +> **Acceptance**: +> +> 1. `POST /classes` accepts `{ name, shortName, color, maxSizeM }` (and any of `photoMode`, etc. that the live backend already supports for ADD), returns the created class object on 200/201. +> 2. `DELETE /classes/{id}` deletes the class by id, returns 200/204. +> 3. `PATCH /classes/{id}` accepts a partial-merge body `{ name?, shortName?, color?, maxSizeM? }`, returns the updated class object on 200. Send-complete-body semantics are also fine — the UI sends every field per AZ-512 spec Risk 2 mitigation. +> 4. All three routes guarded by the same auth middleware as `/users` (admin role required). +> 5. After this ticket lands, AZ-512 (UI workspace) un-blocks and the existing add+delete affordances start working end-to-end. +> +> **Story points**: 3 (single Program.cs file, 3 minimal-API handlers, an `IDetectionClassService` injected like `IUserService` is today). + +**Suggested epic**: whatever the admin/ workspace's "API contract / CRUD coverage" epic is — to be decided by the user when filing. + +## Reason for blockage + +Spec-defined BLOCKING gate. The AZ-512 task spec explicitly forbids inventing a workaround that bypasses the missing endpoint: + +> *"Do not invent a workaround that bypasses the missing endpoint."* + +The spec's three options at the gate: + +- **A**: File a hard-prerequisite ticket on the `admin/` workspace, pause AZ-512 until it lands. +- **B**: Implement only the UI form, MSW-stubbed in tests, mark Step 11 blocked-on-admin/PATCH, ship draft PR. +- **C**: Drop AZ-512 from cycle 3, defer to a future cycle. + +User was prompted via AskQuestion in the same chat turn; user skipped the prompt. The autodev defaulted to **A** (most conservative; spec-aligned; respects workspace boundary). + +## Replay obligation + +This entry is NOT auto-replayable from the UI workspace alone — it requires (a) cross-workspace ticket creation that the UI's autodev should not do unilaterally, and (b) actual implementation work on the admin/ workspace which is owned by a separate Cursor workspace per `.cursor/rules/coderule.mdc`. + +When AZ-512 batch 15 is re-attempted (next `/autodev` invocation that covers cycle 3 leftovers, or any cycle that re-prioritises P12), the leftovers replay step should: + +1. Re-run the verification: `grep -E "MapPost|MapPatch|MapDelete" /Users/.../suite/admin/Azaion.AdminApi/Program.cs | grep classes`. +2. If routes exist → move `_docs/02_tasks/backlog/AZ-512_*.md` back to `_docs/02_tasks/todo/`, update this leftover with the resolution, and proceed with batch 15. +3. If routes still missing → leave the leftover as-is, surface to the user that the prerequisite is still outstanding. + +## Side note (separate concern, do not bundle) + +While verifying the gate, I noticed that `AdminPage.tsx` already calls `POST /api/admin/classes` (handleAddClass) and `DELETE /api/admin/classes/{id}` (handleDeleteClass) today, neither of which is served by the admin/ service. So the existing add+delete buttons on the Detection Classes table are broken end-to-end against the live admin/ service in production. This is a **pre-existing bug**, NOT introduced by AZ-512 or any cycle 3 work. It should be tracked as its own UI-workspace ticket once the admin/ work is filed (the same admin/ ticket above will likely fix the production behaviour for free, but a UI-side test would confirm the wire-up post-fix).