Files
resolutionflow/.ai/HANDOFF.md

81 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- Keep under ~2K tokens. Old handoffs live in SESSION_LOG.md. Do not let this file accumulate history. -->
# HANDOFF.md
**Last updated:** 2026-05-30
**Active task:** Executing the **L1 AI Tree Builder Phase 2A** plan
(`docs/superpowers/plans/2026-05-29-l1-ai-tree-builder-phase-2a.md`, 19 tasks) via
subagent-driven-development on branch `feat/l1-ai-tree-builder-phase-2a`
(branched from `main` @ `87236b5`; **not pushed**, `main` untouched).
## ⚠️ Tooling note (read first)
This session repeatedly hit an unreliable **Bash output channel** — intermittently
returns stale/cached output (e.g. a unique `echo` probe returned a prior `wc`
result) or fabricated success. The **Read/Write/Edit channel stayed reliable.**
Two derived lessons:
- Run backend tests as `docker exec resolutionflow_backend pytest <path> --override-ini="addopts=" -q`.
Do **NOT** use `-p no:cov``pytest.ini` bakes `--cov` into `addopts`, so disabling
the cov plugin makes `--cov` an unrecognized arg and pytest exits non-zero **before
running**, which silently mislabels `&& echo PASS || echo FAIL` chains as failures.
- After any Bash result that matters, cross-check against a `Read`/`grep` of the file.
If a probe returns stale output, **stop and recover the shell** before committing.
## Status: backend complete (Tasks 112), frontend not started (Tasks 1319)
**Tasks 112 — DONE & committed** (17 commits `16b9abf``04b5511`). Last reliable
full run: **114 passed** across all 11 Phase 2A backend test files
(test_l1_ai_build_model, test_account_l1_categories_column, test_flow_proposal_l1_source,
test_l1_category_service, test_ai_tree_builder, test_match_or_build,
test_l1_session_service, test_l1_endpoints, test_l1_api_ai_build, test_l1_categories_api,
test_l1_ai_build_flow). 3 alembic migrations applied; head is `1fd88a68b145`.
What shipped backend-side:
- Migrations/models: `ai_build` session kind; `accounts.enabled_l1_categories` (10-key
default); `FlowProposal.l1_session_id` (+ `source_session_id` nullable + exactly-one
CHECK), `FlowProposalSummary` schema made source_session_id optional + l1_session_id added.
- Services: `l1_category_service` (defaults + hard floor + get/set), `ai_tree_builder`
(constrained node gen, validate, depth cap, `normalize_walked_path`, **skips `meta`
entries**), `match_or_build` (match→suggest→build bands; flow_id normalized to str),
`l1_session_service.start_ai_build_session` / `advance_ai_build` (records node incl.
`node_text`) / flywheel capture in `resolve` / engineer notify in `escalate`.
- Notifications: `l1.session.escalated` event + link `/escalations` + body/title templates;
`_resolve_recipients` now treats an explicit empty `target_user_ids` as "no recipients".
- API: `/l1/intake` dispatches via `match_or_build` (build seeds a hidden
`{"node_type":"meta","category":...}` walked_path entry); `POST /l1/sessions/{id}/next-node`;
`GET /l1/escalations` (require_engineer_or_admin); `GET|PATCH /accounts/me/l1-categories`;
`require_account_owner_or_admin` dep. Config action keys `l1_realtime_build`/`l1_classify`.
## Resume point — Tasks 1319 (all frontend + final)
1. **Task 13 — frontend api/types.** `frontend/src/types/l1.ts` + `frontend/src/api/l1.ts`
are still **Phase-1 stubs** (api/l1.ts is a rough 36-line stub — read it carefully).
Add: `IntakeOutcome`/`IntakeResult` (outcome matched|suggest|out_of_scope|build,
optional session fields, near_miss, category), `TreeNode` union, `NextNodeResult`,
`L1Categories`; methods `nextNode`, `getCategories`, `setCategories`, `escalations`;
retype `intake` to `IntakeResult`. **Carry-forward:** `nextNode` body must include
`node_text` (the rendered node text — backend `advance_ai_build` stores it).
2. **Task 14**`L1Dashboard.tsx` dispatch on `outcome` (matched/build → walker;
suggest → prompt; out_of_scope → adhoc/escalate prompt).
3. **Task 15**`L1WalkTreeVariant.tsx` real node rendering via `/next-node` + disclaimer
banner; pass `node.text` as `node_text`; terminal nodes → existing Resolve/Escalate.
4. **Task 16** — new `pages/account/L1CategoriesPage.tsx` + route + nav (owner/admin gated).
5. **Task 17**`ProposalDetail.tsx` L1-source block (branch on `l1_session_id`);
`EscalationQueuePage.tsx` L1-escalations section via `l1Api.escalations()`.
6. **Task 18** — extend `frontend/e2e/l1-workspace.spec.ts` (network-stubbed); rely on CI
for the run (chromium can't launch here).
7. **Task 19** — full backend suite + `tsc -b`/`npm run lint`/`npm run build`; migration
downgrade/upgrade roundtrip; push branch + open PR to `main` listing deferred items.
Frontend gate: `docker exec -w /app resolutionflow_frontend npx tsc -b` and
`docker exec -w /app resolutionflow_frontend npm run build` (per PROJECT_CONTEXT).
**Working tree:** uncommitted at handoff time — only this `HANDOFF.md` edit (and possibly
`backend/tests/test_l1_api_ai_build.py` if its last lint-clean edit wasn't committed; verify
with `git status` once the shell recovers, then commit WIP).
## Carry-forward (Phase O — separate, still user-side, gated on EIN)
Phase O self-serve cutover (Stripe live-mode, apex DNS, Railway prod env, flag flip) remains
the prior active task — all code blockers closed; blocked on user's EIN. See SESSION_LOG /
git history for detail. Not touched this session.