Inspiration
Every team loses work when someone goes on leave, changes team or quits. The handover doc gets written the night before, misses the risky items and is out of date within a week. Meanwhile Atlassian's Teamwork Graph already knows who owns what, who they work with and what depends on what. We wanted to turn that context into a handover that nobody has to write by hand.
What it does
Relay turns "Priya is away from the 11th to the 25th" into a safe handover:
- Sweep: finds everything she owns through the Teamwork Graph (assigned work items, open pull requests, linked goals, teams) and enriches it with Jira and Confluence.
- Score: gives every item a risk score from 0 to 100 with the reasons shown, e.g. due while away · blocks 3 open items · only one other person has context.
- Suggest: proposes a new owner for each item based on recent expertise, involvement, Teamwork Graph team membership and current workload, spread so one person doesn't inherit everything.
- Publish: writes a Confluence handover pack with status, next step, new owner and who to ask, linked to every source.
- Apply: reassigns the issues and leaves a context comment on each one. An issue panel shows "Covered by a handover".
- While away: a daily check catches new work landing on the absent person and points to whoever is covering.
- Return briefing: "Welcome back": what's finished, what's still open, new comments.
All of this is available from a Jira page, a Rovo agent ("I'm on leave for two weeks, what could fall through?") and an MCP server, so other AI clients can ask "who owns KAN-3?".
How we built it
- Forge (Node 22, UI Kit):
jira:globalPage,jira:issuePanel,scheduledTrigger, Forge KVS storage, with Jira required and Confluence optional. - Teamwork Graph curated queries:
atlassianUserAssignedJiraWorkItems,atlassianUserPullRequests,jiraWorkItemGoals,atlassianUserInTeams,atlassianTeamMembers. - Rovo: a
rovo:agentwith six actions; four of them are exposed as tools throughrovo:mcp. - Jira and Confluence REST for enrichment, reassignment, comments and the handover page.
The risk model is explainable by design:
$$\text{risk} = 100\,(0.35\,u + 0.25\,b + 0.20\,f + 0.15\,v + 0.05\,a)$$
where \(u\) is urgency (priority, plus due before, during or right after the absence), \(b\) is how many open items it blocks, \(f\) is the bus factor, \(v\) is visibility (watchers, linked goals) and \(a\) is whether it's in progress. Owners are ranked by
$$\text{fit} = 0.45\,e + 0.25\,i + 0.15\,t + 0.15\,(1-\ell) - 0.06\,r$$
where \(e\) is expertise, \(i\) is involvement, \(t\) is team membership, \(\ell\) is current load and \(r\) is the number of items already received in this handover. That last penalty is what spreads the work across the team.
Challenges
- Raw Cypher isn't available to new apps, so everything goes through curated queries, with paging capped at 25 rows.
- Graph errors come back as HTTP 200, and a missing scope silently returns empty results. Every graph call checks the response body and fails softly to Jira data, so a scan always completes.
- Teamwork Graph only runs as the user, so the daily background job uses Jira data only.
- Forge's ESM bundling, multi-product installs and per-object-type graph scopes all needed careful setup.
What we learned
Context is what makes automation trustworthy. Showing why an item is risky and why someone is the right owner gets people to accept a suggestion instead of overriding it.
What's next
Detecting absence automatically from calendar events in the Teamwork Graph, handing items back automatically on return, Slack notifications, and a Marketplace listing.
Built With
- atlassian-forge
- confluence
- forge-ui-kit
- graphql
- javascript
- jira
- mcp
- node.js
- react
- rovo
- teamwork-graph