We write about the tools in Anyshift's ecosystem: the CLIs and platforms that Annie integrates with. This one is about acli, Atlassian's command-line interface for Jira. It's the third in a series with Annie meets pup and Annie meets gcx.
The problem
A developer opens a PR that modifies validate_session() in shared/auth/session.py. Three services in production import it: checkout-service, notification-worker, and inventory-sync. Their teams (payments, notifications, catalog) should know now, not a sprint later when something breaks in staging.
PR #1923 (shared/auth/session.py)
│
├─→ checkout-service → payments
├─→ notification-worker → notifications
└─→ inventory-sync → catalogThe information existed at PR time: which services consume the change, which teams own them, who reviewed the last similar change. Jira is the right system of record for the follow-up work. The production context that determines where that work should land usually lives outside Jira, in code, deploys, and infrastructure state.
That is the partnership shape: Atlassian records the work; Anyshift explains where the work should go.
Introducing annie do, with Atlassian's acli
annie do turns a single PR into one Jira epic plus one ticket per affected team: a heads-up that the team's service is impacted by the change. Each ticket lands on the right team's board, assigned to the engineer most likely to be the right reviewer.
What Annie adds before acli runs
The information that determines where each ticket should land lives outside Atlassian: in code, deploys, Terraform state, and live cloud. The Anyshift graph pulls it together so acli can write the right tickets on the right boards.
annie do is the planning surface. It reads the Anyshift context (which services consume the change, who owns them, who reviewed the last similar one), writes the runbook, and stops.
acli is the execution surface. It owns Jira auth, project keys, assignees, and the work-item commands (create, bulk-create, link). Annie hands the runbook over; acli is the one that touches Jira.
Here's annie-cli's output for one PR. The graph findings come first; the acli steps follow.
annie-cli then renders that into the JSON shape acli's create-bulk expects. One child looks like:
The Anyshift graph already knows which services consume the change and which team owns each one. acli writes the tickets.
The handoff
The handoff is just a file boundary. Annie returns one JSON object: the parent epic, plus for each affected service its team, assignee, evidence chain, and link back to the PR. annie-cli renders that into a runbook with exact Jira payloads and exact acli commands. acli does the Jira writes with the operator's Atlassian credentials.
The last step is the linking pass. It reads the parent epic key, loops over each child ticket key, and asks acli to create one Jira Relates link per child:
annie-cli writes that. acli runs it with its own credentials. The full runbook has six steps in this same shape, one per phase of the handoff.
Before annie do runs, the affected teams' Jira boards have no tickets for this PR yet. The Anyshift graph already knows which services are impacted; Jira just has no signal.

Before: the impacted services are known to the Anyshift graph; no Jira tickets exist yet.
After one approval, an epic appears in ENG with three tickets linked under it. Each ticket lands on the right team's board, with the assignee already filled in from the Anyshift graph.

After: one epic, three tickets, on the right boards. PAY has its routed assignee; the others fall back to project default.
Where it is going
acli is the third vendor CLI Annie hands off to. Same shape across all of them: read the Anyshift graph, render a runbook, hand it to the CLI that owns the writes.
The verbs we'd run next on the same shape:
- Continuous ticket sync as the Anyshift graph changes. A service moves to a new team and the open ticket gets reassigned. A code path gets renamed and the affected tickets get an updated link. A blast radius grows and the priority moves with it.
- Dedup against open work. Before filing a new ticket, annie do searches Jira for any already referencing the same module. If one exists, evidence is appended as a comment instead of a fresh duplicate landing on the team's board.
- Stale-ticket cleanup. The graph knows when a code path is deprecated or a service is decommissioned. annie do scans its open tickets and closes the ones whose underlying issue has resolved, with a comment explaining why.
