Jira Is Turing-Complete: When Workflow Automation Becomes a Programming Language
Jira automation has always had a strange smell to it. A few rules become a convenience. A few dozen rules become a system. After that, the line between “workflow configuration” and “programming language” starts to get thin.
Nicolas Seriot made the joke “Jira is Turing-Complete”. The point is not that Jira is a good place to run programs. It is that the pieces inside Jira Cloud automation are expressive enough to simulate a classic model of computation. Once you can simulate that model, the familiar complaint changes shape: complex Jira automations do not merely feel like code. Under the usual theoretical assumptions, they are code.
The Smallest Useful Machine
The proof uses a Minsky register machine, a compact computational model described in Marvin Minsky’s 1967 book Computation: Finite and Infinite Machines. A register machine has:
- a finite list of labeled instructions,
- a program counter that says which instruction runs next,
- counters that hold non-negative integers,
- an increment operation,
- a decrement-and-branch operation,
- and a halt state.
The interesting part is how little machinery is required. A two-counter machine can simulate arbitrary computation when the counters are unbounded and the program can branch on zero versus nonzero. That makes it a convenient target for proving that something unexpected has computational power.
Here is the shape of the instruction set:
INC register; goto state
if register == 0:
goto zero_state
else:
DEC register
goto nonzero_state
That is enough to build loops, move values between registers, branch, halt, and compose larger programs.
The Jira Translation
Seriot’s construction maps those abstract parts onto ordinary Jira concepts:
| Minsky machine part | Jira representation |
|---|---|
| Register A | Count of linked Bug issues |
| Register B | Count of linked Task issues |
| Program counter | Status of one Epic |
| Instruction table | Automation rules, one per state |
| Clock tick | Status transition that triggers the next rule |
The Epic is the running process. Its status tells Jira which instruction is active. Linked issues become register storage. Adding a linked issue increments a register. Deleting or converting one linked issue decrements or moves a value. Automation rules become the dispatch table that decides what happens next.
This works because Jira automation can react to issue transitions, inspect related issues, create issues, link issues, and transition issues again. Atlassian’s own documentation shows that automation can transition issues, work with related and linked issues, and use JQL-style checks over linked work items. Another Atlassian support note explains the important switch: rules normally do not fire from changes made by other rules, but the rule details screen has an “Allow rule trigger” option for exactly that chained behavior.
That option is what lets one instruction hand control to the next instruction.
A Jira Program That Adds Two Numbers
The demonstration program adds A into B:
1. if A == 0 goto 3 else DEC A; goto 2
2. INC B; goto 1
3. HALT
In plain terms: while A still has items, remove one item from A and add one item to B. When A reaches zero, stop.
In Jira, the setup looks like this:
- Create a workflow with statuses such as
BACKLOG,TODO,DEV, andPROD. - Allow transitions between the statuses used by the machine.
- Create a single Epic to act as the running machine.
- Treat linked Bugs as register A.
- Treat linked Tasks as register B.
- Add one automation rule for the
TODOinstruction. - Add one automation rule for the
DEVinstruction. - Enable rule-triggered chaining for both rules.
The TODO rule is the conditional decrement:
When the Epic enters TODO:
if at least one linked Bug exists:
delete one linked Bug
transition the Epic to DEV
else:
transition the Epic to PROD
The DEV rule is the increment:
When the Epic enters DEV:
create one linked Task
transition the Epic to TODO
PROD is not a production deployment in this machine. It is the halt state.
Start with two linked Bugs and three linked Tasks. That means A = 2 and B = 3. Transition the Epic into TODO, and the rules run the machine:
(A=2, B=3) TODO
(A=1, B=3) DEV
(A=1, B=4) TODO
(A=0, B=4) DEV
(A=0, B=5) TODO
(A=0, B=5) PROD
The Epic stops in PROD. The linked Bugs are gone. The linked Tasks now count to five. Jira has executed 2 + 3.
This is not impressive as arithmetic. It is impressive as a reduction. If Jira can encode the operations of a two-counter machine, then the automation layer has crossed from workflow helper into computational substrate.
Why Issue Types Matter
The basic addition example uses issue creation and deletion for increment and decrement. Seriot also points out a more convenient trick: changing an issue type can behave like moving a token from one register to another.
For example:
Bug -> Story
Story -> Task
Task -> Bug
This does not add new theoretical power. A conversion can be expanded into “decrement one register, increment another register.” But it does make larger examples much smaller, because moving a token becomes one practical Jira action instead of a mini-loop.
That matters for programs like Fibonacci.
Fibonacci as a Workflow
The Fibonacci machine uses three registers:
- Bugs represent A.
- Tasks represent B.
- Stories represent C.
The desired transformation is:
(A, B) -> (B, A + B)
Using issue-type conversion, the machine can cycle values through temporary storage:
TODO:
if any linked Task exists:
convert one Task to Story
create one Bug
goto TODO
else:
goto QA
QA:
if any linked Bug exists:
convert one Bug to Task
goto QA
else:
goto DEV
DEV:
if any linked Story exists:
convert one Story to Bug
goto DEV
else:
goto TODO
Start with A = 1, B = 1, C = 0. After each full cycle, B advances through the Fibonacci sequence:
1, 1, 2, 3, 5, 8, 13, ...
This version does not halt on its own. It keeps cycling until the platform stops the chain. On Jira Cloud, that practical cap matters operationally. In the theoretical proof, the cap is treated the same way we treat finite memory in physical computers: real machines are bounded, but the model asks what the system can express under unbounded resources.
The Cloud Quota Objection
The immediate objection is fair: Jira Cloud is not infinite. It has automation limits, issue limits, rate limits, permissions, audit logs, and failure modes. The machine can be interrupted by chain-depth limits. Humans may need to nudge it forward. Data Center deployments expose different configuration knobs.
Those limits do not really refute the computational claim. They refute the idea that Jira is a practical general-purpose computer.
The same distinction applies everywhere. A laptop has finite RAM. A process has time limits. A database has quotas. A cloud account has billing alarms. We still call programming languages Turing-complete because the language model can express arbitrary computation when the resource bounds are abstracted away.
Jira automation fits that convention surprisingly well. It has state. It has transitions. It can branch. It can allocate new storage. It can update the program counter. It can loop.
That is the whole game.
The Real Lesson for Teams
The useful takeaway is not “run Fibonacci in Jira.” The useful takeaway is that sufficiently powerful workflow automation deserves software engineering discipline.
Once rules can trigger other rules, create new work items, inspect related work, branch on JQL, and move issues through workflows, they become a distributed program with side effects. The bugs look familiar:
- loops that are hard to stop,
- hidden coupling between rules,
- state encoded in names and statuses,
- permissions changing behavior,
- manual retries that become part of the runtime,
- and production incidents caused by “configuration” nobody reviewed like code.
If a Jira automation estate is big enough, it needs the same habits as a small service:
- clear ownership,
- versioned exports where possible,
- rule naming conventions,
- small rules with narrow responsibilities,
- audit-log review,
- test projects for risky changes,
- explicit limits on rule chaining,
- and documentation that explains the state machine instead of only the business intent.
The comedy of the proof is that Jira can simulate a computer. The serious part is that many organizations already use it like one, just without the tooling, review culture, or operational model that usually comes with software.
Configuration Is Still Code
Turing-completeness is sometimes treated like a party trick. In this case, it is a warning label.
A workflow system powerful enough to encode a Minsky machine is powerful enough to create real accidental complexity. The more business process moves into no-code and low-code automation, the less useful the word “configuration” becomes as a comfort blanket.
Jira does not stop being Jira because it can add two numbers with linked issues. But the experiment makes one thing hard to ignore: when workflow rules start carrying state, branching, allocating records, and triggering each other, they have become a program.
And programs need engineering.