Linear and Jira Integration

Every intent ties to a ticket. Every commit updates the ticket.

Overview

Most engineering teams run their work out of a ticket tracker — Linear or Jira, primarily. Aura's intent log is, structurally, the same kind of artifact: a chronological record of why code was changed. The Linear/Jira integration binds those two artifacts together.

Once configured, Aura:

  1. Enforces ticket references in intents. aura_log_intent rejects intents that don't cite a ticket (configurable).
  2. Updates ticket status on intent. Logging an intent moves the ticket to "In Progress"; merging its branch moves it to "Done".
  3. Posts semantic comments on the ticket. Each intent attaches a summary of changed nodes, so the ticket has a permanent semantic record.
  4. Maps intents to tickets bidirectionally. Opening a ticket shows the intents that touched it; opening an intent links to its ticket.

This is what turns Aura's intent log from a developer tool into a product-level audit trail.

Setup

Linear

  1. In Linear, go to Settings → API → Personal API keys. Create a key scoped to your workspace.
  2. Store it:
aura secret set linear_token "$LINEAR_TOKEN"
  1. Configure Aura:
aura integration enable linear \
  --workspace acme \
  --team ENG \
  --require-ticket-in-intent
  1. Test:
aura integration test linear
# -> Linear connection OK. Found team ENG. Test issue ENG-1234 fetched successfully.

Jira

  1. In Atlassian, create an API token (id.atlassian.com → Security → API tokens).
  2. Store the token and account email:
aura secret set jira_token "$JIRA_TOKEN"
aura secret set jira_email "you@example.com"
  1. Configure:
aura integration enable jira \
  --base-url 'https://acme.atlassian.net' \
  --project ENG \
  --require-ticket-in-intent

Self-hosted Jira Data Center works with the same flags; point --base-url at your internal instance.

  1. Test:
aura integration test jira

Configuration

.aura/integrations.toml

[linear]
enabled = true
workspace = "acme"
team = "ENG"
require_ticket_in_intent = true
ticket_pattern = '\b([A-Z]{2,6}-\d+)\b'   # default matches ENG-123, PLAT-4567

status_map = {
  intent_logged    = "In Progress",
  branch_merged    = "Done",
  prove_failed     = "Blocked"
}

comment_on_intent = true
comment_on_merge = true

[jira]
enabled = true
base_url = "https://acme.atlassian.net"
project = "ENG"
require_ticket_in_intent = true
ticket_pattern = '\b([A-Z]{2,10}-\d+)\b'

status_map = {
  intent_logged = "In Progress",
  branch_merged = "Done",
  prove_failed  = "Blocked"
}

Ticket pattern

The default regex matches most conventions: ENG-123, PLAT-4567, AUR-89. Override ticket_pattern if your tracker uses a non-standard prefix length or numeric style.

Status mapping

status_map is a dict from Aura event to tracker status name. The name must match the tracker exactly, including case. Run aura integration statuses to list the available statuses on the configured tracker:

$ aura integration statuses linear
Backlog, Todo, In Progress, In Review, Done, Canceled

Examples

Logging intent with a ticket

With require_ticket_in_intent = true:

aura save -m "Refactor retry_logic to use exponential backoff [ENG-1421]"

The bracketed ticket is parsed, attached to the intent, and pushed to Linear. The ticket moves to In Progress and gets a comment:

Aura intent from ashiq on feat/retry-backoff

Switch linear backoff to exponential for rate-limit compliance.

Semantic changes: 3 nodes modified, 1 added. Commit: abc1234.

An intent without a ticket is rejected:

$ aura save -m "small cleanup"
error: intent is missing a ticket reference (pattern: [A-Z]{2,6}-\d+)
hint: add [ENG-123] to your intent, or disable require_ticket_in_intent

Automatic status updates on merge

When a PR is merged and the branch's last intent is tied to a ticket, Aura transitions the ticket to the branch_merged status. If the branch had intents tied to multiple tickets, all of them transition.

If aura prove fails on main, linked tickets transition to prove_failed (commonly Blocked) until the failure is resolved.

Multi-ticket intents

An intent can reference multiple tickets if the change spans them:

aura save -m "Add shared session utility [ENG-1421] [ENG-1422] [PLAT-301]"

All three tickets receive the intent comment and status update.

Reverse lookup: tickets in the IDE

With the IDE extensions installed, hovering a function shows the most recent intent and any tickets tied to it. Click through to open the ticket in the tracker. This works for Linear (deep link via linear://) and Jira (https://<base-url>/browse/ENG-123).

Using tickets as Prove goals

You can bind a Prove goal directly to a ticket's description:

aura prove --from-ticket ENG-1421

Aura reads the ticket's "Acceptance criteria" section and treats each line as a goal. Failing goals are posted back to the ticket.

API

Beyond the built-in integration, the tracker data is available via the Aura HTTP API. Tickets appear as fields on intent objects:

{
  "intent_id": "itn_01HW3K9Z4X7P2Q8R",
  "summary": "Refactor retry_logic to use exponential backoff",
  "tickets": [
    { "system": "linear", "id": "ENG-1421", "url": "https://linear.app/acme/issue/ENG-1421" }
  ],
  "nodes_changed": 3
}

This lets you build dashboards that group intents by epic, sprint, or assignee.

Troubleshooting

Status update returns 403. The API token lacks issues:write (Linear) or the token owner isn't a member of the target project (Jira). Regenerate with correct scopes.

Tickets not being linked. Your ticket_pattern didn't match. Test with aura integration match "my intent text" to see what gets extracted.

Linear subtasks confuse the integration. Set link_subtasks_to_parent = true to additionally comment on the parent issue.

Jira workflow rejects the transition. Status names are case-sensitive and must match exactly. Jira workflows can also forbid direct transitions (e.g. In ProgressDone may require passing through Review). Configure status_map to use a reachable status, or ask a Jira admin to adjust the workflow.

Status updates flap. Multiple developers working the same ticket each trigger a transition. Enable quiet_period_seconds = 300 in .aura/integrations.toml to coalesce updates.

Self-hosted Jira with private CA. Set AURA_CA_BUNDLE — Aura's HTTP client honors it for all integrations including Jira.

Enforcing Ticket Lifecycle

Beyond status updates, Aura can enforce lifecycle rules:

  • No intent on closed tickets. If a ticket is Done or Cancelled, reject intents that reference it. Catches "I'll just sneak one more fix in."
  • No merges without tracker close. Block merges to main unless the linked ticket is at or past In Review.
  • Warn on ticket priority mismatch. If a ticket marked P0 has no intent logged in 48h, post a warning to the team channel.

Configure via .aura/integrations.toml:

[linear.enforce]
reject_intent_on_closed = true
require_review_status_for_merge = true
warn_p0_stale_hours = 48

These are opt-in. Start with warnings and promote to hard enforcement once the team is comfortable.

Reporting Across Tickets

Since every intent knows its ticket, Aura can produce engineering reports grouped by the tracker's hierarchy:

aura report ticket-velocity --project ENG --since 30d

Sample output:

ENG-1200 (Refresh login flow)       | 14 intents | 6 nodes/intent | 0 prove-fail
ENG-1300 (Billing refactor)         | 31 intents | 12 nodes/intent | 2 prove-fail
ENG-1400 (Scheduled jobs migration) |  7 intents | 4 nodes/intent | 0 prove-fail

This exposes which tickets are semantically expensive — lots of churn, many Prove failures — well before the velocity problem shows up in planning.

When Aura comments on a Linear issue or Jira ticket, it includes a deep link back to the intent view in your Aura dashboard. Conversely, the intent view shows the current ticket status, last update, and assignee — fetched on demand from the tracker. This gives you a round trip:

  • From Linear: click a comment, land on the intent with its node diff.
  • From Aura: click a ticket chip, land on the Linear/Jira issue in your browser.

The round trip matters for audits. A compliance review can start from a ticket, drill to the intent, drill to the AST diff, drill to the commit. No manual cross-referencing.

Mapping Epics and Sprints

For teams that plan in epics, Aura can group intents by epic automatically. In Linear, the parent-child relation is read from the API; in Jira, the Epic Link custom field is used. Dashboards then show intent volume per epic, average Prove failures per epic, and which epics stall vs. flow.

Using With Custom Workflows

If your Jira project uses a custom workflow (e.g. Backlog → Triaged → Scoped → In Progress → In Review → Done), make sure every transition Aura attempts is reachable from the current status. If not, either:

  1. Configure status_map to use a reachable status.
  2. Enable status_map_transitions which does a BFS through the workflow to find the shortest path.
  3. Ask a Jira admin to simplify the workflow for teams using Aura.

Option 2 is implemented via Jira's transitions API and is the most forgiving, but adds latency.

Privacy and Data Residency

The tracker integration makes outbound API calls only — Aura never ingests ticket bodies into its own storage beyond a short-lived cache for deep links. If your compliance regime requires that ticket bodies not leave the tracker, set:

[linear.privacy]
embed_body_in_intent = false

Intents will link to the ticket by ID and URL only.

See Also