Risks & dependencies
Track project risks on a 5×5 severity × probability heatmap, and declare task dependencies. Auto-flag risks from status updates and meeting transcripts.
PMs in the wild work from a RAID log (Risks, Assumptions, Issues, Dependencies). M3 ships the two pieces that pay back fastest: a risk register with a standard 5×5 matrix, and task dependencies so the plan can express what blocks what.
Risk register
Open a project, switch to the Risks tab.
- 5×5 heatmap — severity (1 trivial → 5 catastrophic) × probability (1 rare → 5 almost certain). Standard PRINCE2 / PMI shape. The heatmap counts open risks per cell; cells colour by RAG (green ≤ 6, amber 7–14, red ≥ 15).
- Status —
open/mitigated/accepted/closed. Closing a risk setsclosed_atautomatically. - Owner + mitigation plan — assign a team member, write down what you'll do. Both optional but encouraged.
- Source provenance — every risk records where it came from
(
manual,status_update,transcript,ai_detected). Auto-flagged risks are clearly labelled so editors know they need a human pass.
Auto-flagging from status updates (M1)
When you publish a status update, the Blockers & risks section gets a
small + Track N blockers as risks button. One click drops them into the
register with source='status_update' and a link back to the source update.
Tune severity / probability after.
Auto-flagging from transcripts (M2)
The transcript-extract modal already surfaces a separate Risks flagged
list. When you confirm the extraction, click + Track N risks in the register to push them through with source='transcript'. The AI sets
severity/probability to 3/3 (medium); adjust afterwards.
Task dependencies
In the Edit Task modal, scroll to the Dependencies block:
- Blocked by — tasks that must finish before this one can start.
- Blocks — tasks that wait on this one.
v1 supports finish_to_start (the most common type). The schema stores a
type field that accepts start_to_start, finish_to_finish, and
start_to_finish too — those will surface in the UI in a later polish pass.
Guard rails
- A task cannot depend on itself (DB CHECK).
- The trivial 2-cycle (A blocks B AND B blocks A) is rejected at insert time by a trigger.
- Longer cycles are caught by an application-layer BFS walk
(
src/lib/risks/dependencies.ts:wouldCreateCycle) capped at 200 nodes. - Cross-project dependencies are rejected — both tasks must live in the same project.
Gantt visibility
The Gantt view shows a small banner at the top: "N task dependencies in this project — click a task to view or edit relationships." Full SVG arrow rendering over the Gantt bars is on the roadmap (M3.5).
MCP usage
Both risks and dependencies are exposed via the MCP server for Claude Desktop / Cursor:
# List risks for a project
GET /api/mcp/projects/<id>/risks
# Create a single risk
POST /api/mcp/projects/<id>/risks
{ "title": "...", "severity": 4, "probability": 3, "source": "manual" }
# Bulk create (e.g. from an AI batch)
POST /api/mcp/projects/<id>/risks
{ "source": "ai_detected", "risks": [{"title": "..."}, ...] }
# Update / close
PUT /api/mcp/risks/<id>
{ "status": "closed" }
# Delete
DELETE /api/mcp/risks/<id>
# Dependencies (per task)
GET /api/mcp/tasks/<id>/dependencies
POST /api/mcp/tasks/<id>/dependencies
{ "direction": "blocks", "otherTaskId": "<uuid>", "type": "finish_to_start" }
# Remove an edge
DELETE /api/mcp/dependencies/<id>
Requires read:risks / write:risks for risks, and read:tasks /
write:tasks for dependencies. Both scopes are in the default key
permissions for new MCP keys.
Compliance
- Both new tables enforce RLS that mirrors the projects predicate (owner OR
team member). See
migrations/add-risks-and-dependencies.sql. - Every risk + dependency action emits to the activity feed (
risk_created,risk_closed,dependency_added, …) and audit log (RISK_CREATED,DEPENDENCY_REMOVED, …). - See
docs/compliance/asset-inventory.mdfor the data classification.
Roadmap
- Gantt SVG arrow overlay between dependent task bars (M3.5).
- Critical-path highlight based on dependencies + estimated hours.
- Date-cascade respects dependencies — extending the
shift_project_datesRPC so cascading a milestone date forward propagates through dependency edges, not just calendar order. - Assumptions + Issues entities to round out the full RAID log.