You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Quick 260707-cvz: Live progress surface for Deepen analysis Summary
Gave the "Deepen analysis" action a live, in-place HTMX progress surface: the
#deepen-result-{file_id} anchor now shows a self-polling fragment that renders the
N/M windows idiom ("Re-analyzing Β· 34/62 windows") and settles into a terminal
"Deepen complete" state that stops polling β replacing the old single static line.
What changed
New deepen_progress.html β three-state (queued/running/complete) + gone poll target.
Mirrors scan_progress_card.html's terminal-halt idiom exactly: non-terminal branches
(running/queued) carry hx-get + hx-trigger="every 2s" + hx-swap="outerHTML"; terminal
branches (gone/complete) OMIT all three, so the outerHTML swap removes the trigger and HTMX
halts automatically. Root element is an inline <span aria-live="polite"> in every branch.
Counts are numeric ints only (None-guarded to 0 by the endpoint) β no essentia strings, no raw HTML.
deepen_response.html β replaced ONLY the success {% else %} branch with a bootstrap
poller (hx-trigger="load, every 2s") that fires the first fetch and hands off to
deepen_progress.html (single poll loop, no double-poll). not_found / no_active_agent
branches are byte-unchanged static one-liners.
pipeline.py β added GET /pipeline/files/{file_id}/deepen-progress?since=<epoch> and
threaded since = datetime.now(UTC).timestamp() (captured BEFORE the enqueue) + file_id
into the deepen POST success context. The deepen POST guards/enqueue/dedup/routing and the
not_found/no_active_agent branches are untouched.
Completion predicate (verbatim from plan)
requested_at = datetime.fromtimestamp(since, tz=UTC)
complete = (analysis is not None
and analysis.analysis_completed_at is not None
and analysis.analysis_completed_at > requested_at)
since is captured at click time. A stale pre-click sampled result has
completed_at <= requested_at β NOT complete (kills the misleading-complete edge). A fresh
put_analysis stamps func.now() > requested_at β complete. post_analysis_progress is
counter-only and never touches analysis_completed_at, so a re-deepen of an already-ANALYZED
file keeps its OLD completed_at until the fresh put_analysis lands β completion is NOT gated
on completed_at being NULL.
Full test_pipeline.py suite β 103 passed; phaze.routers.pipeline coverage 95.45% (β₯90 gate).
uv run ruff check clean, uv run ruff format clean, uv run mypy src/phaze/routers/pipeline.py clean.
Pre-commit hooks ran on both commits (no --no-verify).
Deviations from Plan
[Rule 3 - Blocking] The plan's verify commands used just test-db up, but the test-db
recipe takes no argument (up was forwarded to docker β exit 125). Ran just test-db
(no arg) and exported TEST_DATABASE_URL / MIGRATIONS_TEST_DATABASE_URL / PHAZE_REDIS_URL
(per the integration-test recipe) so pytest hit the ephemeral DB on 5433/6380 instead of the
dev DB on 5432. No source impact.
Deferred (intentional, per plan)
Chart auto-refresh after completion is deferred: the poll endpoint has file_id only, but
analysis_timeline is keyed by proposal_id, so a refetch would require threading proposal_id
through the poll (higher risk). The terminal "reload to see the updated analysis" message is the
accepted low-risk fallback (planner's call, required_outcome #2).
Known Stubs
None.
Self-Check: PASSED
src/phaze/templates/pipeline/partials/deepen_progress.html β FOUND
src/phaze/templates/pipeline/partials/deepen_response.html β FOUND