Phase 1 (pipeline blockers):
- Stage 6 normalizer: move Claude call to BackgroundTasks (fixes 504 at proxy);
frontend polls useStageArtifacts(6) + useClientAssets every 2s with a
2-min soft cap and a "Normalizing… ~30s" banner.
- Stage 8 ratecard: raise ValueError when no Stage-7 matches selected so
the user gets a clear 400 instead of silent "0 lines built" success.
- Stage 4 Q&A pack: visible amber empty-state callout when no clarifications.
- Stage 1 intake: green CTA banner after metadata lands telling the user
to scroll down and click Complete Stage 1.
- APP_PUBLIC_URL: log a warning at startup if empty / not fully-qualified
so approval-email links don't ship as broken relative URLs.
Phase 2 (reviewer UX):
- Remove "Operating model" select from intake form (sales lead doesn't
know the solution yet); default model_type='current_oplus'.
- Inline-edit pencil for opportunity name in OpportunityView header.
- Stage 3 TROWLS sliders default to 0/10 (was 5/10 — anchored everyone
to "average" and the reviewer could save without engaging).
- Trim APPROVAL_ROLES to ['commercial', 'solution'] (was 5 roles).
- Stage 6 confirm dialog only fires on re-run, not first run.
- "+ Add manually" → "+ Add deliverable manually" with helper text.
- Asset normalizer prompt + post-hoc stop-list filter excluding internal
pitch artefacts (pitch decks, response decks, win-themes, etc.) that
were appearing as job routes in Stage 7.
Phase 3 (hardening):
- with_for_update() row locks on stage_machine.complete_stage and
approvals.submit_decision so double-clicks can't double-advance.
- 30s idempotency window on Stage 7 matching kick-off.
Deferred (next round): paste-link upload, single-use approval tokens,
FK indexes migration, datetime.utcnow → now(timezone.utc) sweep,
notes-owner schema change, file-extraction "unsearchable" UI badge.
Source: REVIEW-SESSIONS/Sales Op Platform Feedback NV_ 060526.xlsx
(rows R6-R48, 25+ feedback items mapped to specific stages).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>