107 lines
7.1 KiB
Markdown
107 lines
7.1 KiB
Markdown
<!-- 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 — why this session stopped at Task 16)
|
||
The harness's **Bash output channel became intermittently unreliable** — returning
|
||
stale/cached output (a Bash command that wrote `/tmp/perm.txt` instead returned a
|
||
PRIOR command's `/tmp/vc.txt` content; a `cat` returned the wrong commit SHA). The
|
||
Write/Edit channel stayed reliable; Read mostly reliable but occasionally served a
|
||
stale temp file. Work stopped at Task 16 because wiring a new route/nav requires
|
||
accurately reading `router.tsx` + `AccountSettingsPage.tsx` then editing them, and
|
||
read-then-edit against stale reads is exactly what produced the broken Tasks 14–15
|
||
earlier this session. **On resume: confirm the shell is reliable first** — write a
|
||
unique sentinel to a file and read it back; cross-check any Read against a fresh
|
||
`grep`; never commit without a sentinel-wrapped `tsc -b`/pytest verification whose
|
||
unique sentinel you can see in the same output.
|
||
|
||
Earlier-this-session gotcha that cost ~an hour: pytest `-p no:cov` conflicts with the
|
||
`--cov` baked into `pytest.ini` addopts → pytest exits before running → `&& echo PASS`
|
||
chains mislabel. Always use `--override-ini="addopts="`, never `-p no:cov`.
|
||
|
||
Backend test invocation that works:
|
||
`docker exec resolutionflow_backend pytest <path> --override-ini="addopts=" -q`
|
||
Do **NOT** use `-p no:cov` — `pytest.ini` bakes `--cov` into `addopts`; disabling the
|
||
cov plugin makes `--cov` unrecognized so pytest exits before running, silently turning
|
||
`&& echo PASS || echo FAIL` chains into false FAILs (this cost ~an hour of confusion).
|
||
Frontend gate via file-redirect:
|
||
`docker exec -w /app resolutionflow_frontend sh -c 'npx tsc -b > /app/_o.txt 2>&1; echo EXIT=$? >> /app/_o.txt'`
|
||
then Read `frontend/_o.txt` (frontend is bind-mounted at /app).
|
||
|
||
## Status: Tasks 1–15 DONE & committed. Tasks 16–19 remain (all frontend + final).
|
||
|
||
**Backend (Tasks 1–12)** — 17 commits `16b9abf`…`04b5511` + handoff `fdac72e`.
|
||
Last full run: **114 passed** across all 11 Phase 2A backend test files. 3 alembic
|
||
migrations applied; head `1fd88a68b145`. Shipped: `ai_build` session kind;
|
||
`accounts.enabled_l1_categories`; `FlowProposal.l1_session_id` (+ nullable
|
||
source_session_id + exactly-one CHECK + schema made optional); `l1_category_service`;
|
||
`ai_tree_builder` (constrained gen, validate, depth cap, `normalize_walked_path`,
|
||
**skips `meta` entries**); `match_or_build` (bands; flow_id→str); session-service
|
||
`start_ai_build_session`/`advance_ai_build` (stores `node_text`)/flywheel capture in
|
||
`resolve`/engineer notify in `escalate`; `l1.session.escalated` notification (+ link
|
||
`/escalations` + `_resolve_recipients` honors explicit empty list); API
|
||
`/l1/intake` (dispatch; build seeds hidden `{"node_type":"meta","category":...}`
|
||
walked_path entry), `POST /l1/sessions/{id}/next-node`, `GET /l1/escalations`,
|
||
`GET|PATCH /accounts/me/l1-categories`, `require_account_owner_or_admin` dep.
|
||
|
||
**Frontend (Tasks 13–15) — committed; whole-project `tsc -b` + eslint clean. VERIFIED HEAD `076a9ec`, tree clean.**
|
||
- `03e8748` Task 13 — `types/l1.ts` (+ai_build, IntakeOutcome/Result, NearMiss, TreeNode,
|
||
NextNodeRequest/Result, L1Categories) + `api/l1.ts` (intake→IntakeResult; nextNode,
|
||
escalations, getCategories, setCategories). nextNode body carries `node_text`.
|
||
- Tasks 14/15 took THREE commits because the flaky shell caused two broken commits
|
||
(`df7150f`, `f483196` had missing-export/props errors; `ad9c4c8` was committed with
|
||
TSC_EXIT=2 because I batched the commit with its own failing verification). The REAL
|
||
working fix is **`076a9ec`** — confirmed via single-value commands: committed
|
||
`L1WalkTreeVariant.tsx` has `advanceNode` (grep -c = 3), committed `L1Dashboard.tsx`
|
||
has `useSuggestedFlow` (= 2); and a sentinel-wrapped `npx tsc -b` returned TSC=0,
|
||
eslint=0 on the on-disk files before commit. What landed:
|
||
- `L1Dashboard.tsx`: outcome dispatch on the REAL page (matched/build→walker;
|
||
suggest→use-flow/build-new; out_of_scope→escalate-without-walk). Original
|
||
PageMeta/greeting/inputs/open-tickets layout preserved.
|
||
- `L1WalkTreeVariant.tsx`: real props `{session,onSessionUpdate,onDone}` +
|
||
ResolveModal/EscalateModal + header + transcript sidebar kept; added ai_build branch
|
||
that walks nodes via /next-node (passes node_text), disclaimer banner (`bg-warning/10`
|
||
— NOTE: `*-dim` tokens are NOT `--color-*-dim`; use `/10` opacity), terminal→modals.
|
||
flow/proposal keep the Phase-1 synthetic path.
|
||
- `L1WalkPage.tsx` unchanged (already routes ai_build → tree variant).
|
||
NOT browser-verified (chromium can't launch here).
|
||
- **SHELL DISCIPLINE for resume:** single-value Bash commands (`grep -c`, `wc -l`,
|
||
`git rev-parse --short`, `git log -1 --format=%s`) are RELIABLE; multi-line
|
||
`{ echo; … } > file` blocks get GARBLED/interleaved. NEVER batch a commit with its
|
||
own verification — verify in a separate step and READ the result before committing.
|
||
|
||
## Resume point — Tasks 16–19
|
||
|
||
16. **`pages/account/L1CategoriesPage.tsx`** (does NOT exist yet) — checkbox list of
|
||
`available` toggling `enabled` via `l1Api.getCategories/setCategories`; read-only
|
||
hard-floor list. Register lazy route under the `account` children in `router.tsx`
|
||
(the L1CategoriesPage import is NOT yet there — verify) and add a link card in
|
||
`AccountSettingsPage.tsx` (AccountLayout has no sidebar nav — see CLAUDE.md
|
||
"Account sub-page"). Gate visibility to owner/admin via `usePermissions`.
|
||
17. **`ProposalDetail.tsx`** — branch on `l1_session_id` to show an L1-source block
|
||
instead of the `/pilot/{source_session_id}` link (add `l1_session_id?: string|null`
|
||
to its proposal type). **`EscalationQueuePage.tsx`** — add an "L1 escalations"
|
||
section via `l1Api.escalations()`.
|
||
18. **`frontend/e2e/l1-workspace.spec.ts`** — network-stubbed AI-build flow; rely on CI
|
||
to run it (chromium can't launch here).
|
||
19. **Final:** full backend suite + `tsc -b`/`npm run lint`/`npm run build`; migration
|
||
downgrade/upgrade roundtrip (head `1fd88a68b145`, down 3); push branch + open PR to
|
||
`main` listing deferred items (KB grounding/connectors, PSA reassign, escalation
|
||
package, AI chat handoff, proposal-matching). Then run requesting-code-review +
|
||
finishing-a-development-branch per the subagent-driven-development skill.
|
||
|
||
**Working tree:** clean except this HANDOFF.md edit (committing now). Temp `_*.txt`
|
||
files under `frontend/` were scratch — delete any that remain.
|
||
|
||
## Carry-forward (Phase O — separate, 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. Not
|
||
touched this session.
|