A developer changes shared/auth/session.py in anyshift-backend#1923. On paper, it is one PR in one repo. In production, checkout uses it directly, notifications uses it directly, and catalog depends on it through a shared library.

That kind of PR often looks harmless inside Jira. The ticket has a repo link and a reviewer, but it does not show which running services consume the changed module or which teams need a heads-up before merge.

The split is simple:

  • Anyshift answers the impact question: which production services depend on this PR, who owns them, and where should the work land?
  • annie do packages that answer into a runbook and stops for review.
  • acli is Atlassian's Jira CLI. After approval, it creates the work items through Jira's own auth and work-item commands.

A runbook is the handoff file between Annie and acli: a saved YAML plan with the evidence, Jira payloads, and commands that will run after approval.

Jira stays where teams plan and track the work. Anyshift supplies the production truth Jira cannot infer from a PR alone.

Before: Jira has no impact context

Before Annie runs, Jira has no advisory work for this PR. The PR already exists in GitHub; the question is whether the affected teams get useful Jira work before it merges.

The demo starts with empty Jira work lists for engineering, payments, notifications, and catalog so the before/after is visible. Jira is ready to track work; it just has no reason yet to know this PR crosses team boundaries.

Jira before the run: the cross-team spaces are selected, but the work list is empty and shows "There's nothing matching your search".

For anyshift-backend#1923, the missing facts are concrete: which production services import shared/auth/session.py, which teams own them, which advisories already exist, and who can review the change without creating noise for everyone else.

The handoff: Annie plans, acli writes

The engineer preparing the merge asks Annie to turn the PR impact into Jira advisories. At this point, nothing has been written to Jira. annie do --print renders the plan and saves the runbook under ~/.annie/runbooks/.

The runbook is the control point. The full YAML includes the JSON payloads for Jira, but the useful part fits on the page:

Color-highlighted YAML runbook generated by annie do. It keeps the original advisories, skipped services, tags, and acli steps, with comments in muted blue, YAML keys in yellow, values in green, and acli commands in cyan.

That split is the product shape. Anyshift provides the graph and identity context. Annie turns that context into an action plan. annie-cli renders deterministic JSON and shell steps. acli owns the Jira writes.

What Anyshift adds

Anyshift starts from the diff, not from a Jira project. For this change it finds checkout-service for the payments board, notification-worker for notifications, and inventory-sync for catalog. Each advisory is routed from production evidence, not from a guess about which team owns the repository.

It also skips legacy-billing, which is deprecated, and playground, which has no production traffic. A fan-out workflow only works if it knows who not to bother.

Anyshift Identity adds the next layer. When the graph can map a GitHub reviewer, Slack user, IAM principal, and Atlassian account to the same person, the advisory can be assigned directly instead of landing as generic ticket noise.

After: Jira has the right advisories

After approval, acli creates the work in the real demo tenant: one engineering parent item, then one advisory in each affected team space.

Jira after the run: PAY-1, NOTIF-1, ENG-1, and CAT-1 appear in the work list, with the PAY advisory assigned to Roxane and the other advisories unassigned.

The same result is visible from the terminal. This is a real acli jira workitem search against the demo tenant on May 26, 2026.

Terminal output from a real acli search against anyshift-acli-demo.atlassian.net. It shows acli version 1.3.18-stable and four work items: PAY-1, NOTIF-1, ENG-1, and CAT-1, all in Backlog, with PAY-1 and ENG-1 assigned to Roxane and NOTIF-1/CAT-1 unassigned.

The useful part is the specificity: PAY-1 exists for checkout-service, NOTIF-1 for notification-worker, CAT-1 for the indirect inventory-sync dependency, and ENG-1 links the advisories under one parent item.

Why two CLIs?

Could this be one Jira API call? Technically, yes. The control story would be worse.

annie do is the planning and control surface. It reads Anyshift context, writes the runbook, and stops. acli is the execution surface. It uses Jira auth, Jira project keys, Jira assignees, and Jira work item commands.

That boundary is useful for the exact PRs where this workflow matters: shared authentication, permissions, billing, data contracts, deployment modules, or any code path where the affected teams are not obvious from the repository path.

If Anyshift wrote directly to Jira, the team would lose a clean review step and a Jira-native auth boundary. If acli ran alone, it would create tickets with no production graph behind them. The value is in the handoff: production impact becomes reviewed Jira work, with evidence attached before the PR merges.