Phase 28 — Multi-reviewer collaboration + budget cap UX¶
Last updated: 2026-05-10
Two related improvements that close partner-workflow gaps at moderate-to-high engagement volume.
Phase 28a — Default budget cap UX¶
The platform default budget cap was $15 — conservative, suitable for the 12-doc synthetic test corpus. On real-world corpora (50–200 documents), audits could hit the cap and abort half-finished. Phase 28a makes the budget field more prominent in firm setup with an explicit hint about realistic values.
- FirmManagement firm-edit form: "Default audit budget (USD)" now sits in its own "Engagement defaults" section with a helpful explanatory paragraph: "$15 is the conservative default; $200 gives real corpora room to complete naturally."
- The new-engagement form already reads from the firm's
default_budget_cents, so once the firm is configured the partner experience flows through automatically.
This is a pure UX nudge, not a logic change. The platform-level default in code remains $15 to preserve backward compat for existing firms.
Phase 28b — Engagement assignment + per-finding threaded comments¶
Two partners reviewing the same engagement need a way to (a) signal "I'm the lead reviewer" and (b) leave context for each other without polluting the public auditor_notes field that goes into the deliverable.
Engagement assignment¶
The assignee is shown as a chip in the engagement detail header (Assigned: Pat Partner). Clicking it opens a dropdown of admin/partner users in the engagement's firm; pick one to (re-)assign, or "Unassign" to clear.
Constraints: - Admin or any partner in the engagement's firm can assign - Associates can't (Phase 15 read-only) - Cross-firm assignment is blocked with 409 unless the caller is a platform admin - The dropdown filters out associate-role users — only partner/admin candidates appear
Per-finding threaded comments¶
GET /auditforge/finding/{id}/comments?engagement_id=<eng>
POST /auditforge/finding/{id}/comments?engagement_id=<eng> # body: {"body": "text"}
DELETE /auditforge/comment/{comment_id}?engagement_id=<eng>
Comments accumulate chronologically (oldest first) on each finding. Each comment carries author user_id + cached display name + timestamp + body (1–4000 chars). Author or admin can delete.
The comments thread is internal-only:
- Not rendered in the deliverable
- Not part of the audit log of LLM calls
- Stored at auditforge/engagements/<id>/comments.json in the engagement's isolated S3 bucket (Phase 7+25 storage isolation applies)
Why threaded (not nested replies)¶
A chronological list with author + timestamp covers ~95% of partner-collaboration use cases (review handoff, "I checked clause 4.2, looks clean", "investigate further before accepting"). Reply trees add UI complexity and don't change the primary workflow. If real partner usage demands threading, a future polish phase can add parent_comment_id.
What this doesn't include (deferred)¶
- @-mentions: would require user-mention parsing + UI auto-complete. Not in scope.
- Notifications: SES is sandboxed in the AWS account; transactional email isn't available. Notifications would require Resend integration — deferred.
- Edit-in-place: today comments are immutable post-create (delete + recreate to edit). Edit is straightforward to add but not done.
- Per-engagement comment digest: a future polish item — "show me all comments across this engagement, by author."
Files¶
app/auditforge/engagement.py—assigned_user_idfield onAuditEngagementapp/auditforge/comments.py—FindingCommentdataclass +CommentStore(per-engagement JSON, S3-backed)app/auditforge_endpoints.py— assignment endpoint + 3 comment endpoints (GET/POST/DELETE); user list endpoint auto-scopes to caller's firmfrontend/src/api/auditforge.ts—AuditUser,FindingComment,assignEngagement,listFindingComments,postFindingComment,deleteFindingComment,listUsersfrontend/src/components/EngagementDetail.tsx— assignee chip + dropdown picker in engagement headerfrontend/src/components/FindingDetail.tsx—CommentsThreadcomponent below the finding bodyfrontend/src/components/FirmManagement.tsx— engagement-defaults section with budget hinttests/test_auditforge_endpoints.py— 9 endpoint tests covering auth/role gating, validation, lifecycle