개념 증명: Jira가 튜링 완전(Turing-Complete)한 이유
수년 동안 엔지니어링 업계의 전설처럼 내려오던 이야기가 있었습니다. 바로 Jira가 튜링 완전하다는 것이었습니다. 많은 이들이 Jira의 복잡한 자동화 기능을 그 증거로 막연하게 지적해 왔지만, 이를 증명하기 위한 공식적인 환원(reduction)을 제시한 사람은 거의 없었습니다. 최근 기술 심층 분석에서 Nicolas Seriot는 단순한 전설을 넘어, Atlassian의 프로젝트 추적 도구가 Minsky register machine을 구현함으로써 실제로 범용 컴퓨터로 기능할 수 있음을 입증했습니다.
이 발견은 단순한 이론적 호기심 그 이상입니다. 복잡한 Jira 자동화가 왜 종종 프로그래밍처럼 느껴지는지를 설명해 줍니다. 형식적인 의미에서, 그것은 실제로 프로그래밍이기 때문입니다.
계산 모델: Minsky Machine
튜링 완전성을 증명하기 위해 Seriot는 Minsky register machine을 활용합니다. 이 모델은 튜링 머신과 계산적으로 동등하지만, 비즈니스 도구에 매핑하기에는 훨씬 더 간단합니다. Minsky machine은 단 두 개의 무한한 카운터(레지스터)와 라벨이 지정된 유한한 명령어 세트만을 필요로 합니다:
- 증가 (
INC r; goto S): 레지스터 r의 값을 증가시키고 상태 S로 이동합니다. - 감소/분기 (
DEC r; if r == 0 goto S else goto S'): 레지스터 r의 값을 감소시킵니다. 만약 레지스터가 이미 0이었다면 상태 S로 이동하고, 그렇지 않으면 상태 *S'*로 이동합니다.
Jira의 자동화 언어 내에서 이 모델을 보여줌으로써 환원이 완성되며, Jira는 튜링 완전함이 증명됩니다.
Minsky를 Jira에 매핑하기
Seriot의 증명은 Minsky machine의 추상적 구성 요소를 특정 Jira 엔티티로 매핑합니다:
| Minsky Machine Component | Jira Implementation |
|---|---|
| Register A | Bug 타입의 연결된 이슈(linked issues) 개수 |
| Register B | Task 타입의 연결된 이슈(linked issues) 개수 |
| Program Counter | 단일 Epic 이슈의 상태(status) |
| Dispatch Table | Jira Automation 규칙 (명령어 상태당 하나씩) |
| Clock | 자동화로 트리거되는 전환 또는 외부 재트리거 |
이 아키텍처에서 Epic의 상태는 현재 명령어를 인코딩합니다. 자동화 규칙은 연결된 이슈의 개수를 검사하고 다음 상태 전환을 결정합니다. INC와 DEC 작업은 연결된 이슈를 생성하거나 삭제함으로써 수행되며, 조건부 분기는 JQL 조건부 규칙을 통해 처리됩니다.
사례 연구: 덧셈 구현하기
이론을 입증하기 위해, 하나의 Epic, 다섯 개의 연결된 이슈, 그리고 상태당 하나의 자동화 규칙을 사용하여 최소한의 덧셈 머신을 구축했습니다. 워크플로우는 다음과 같은 상태로 구성됩니다: BACKLOG $\rightarrow$ TODO $\rightarrow$ DEV $\rightarrow$ PROD.
TODO를 위한 규칙 (DEC A; if A=0 halt, else goto DEV): 연결된 Bug가 존재하면, 이를 삭제하고 Epic을DEV로 전환합니다. Bug가 없다면PROD로 전환합니다(중단).DEV를 위한 규칙 (INC B; goto TODO): 새로운 Task를 생성하고, 이를 Epic에 연결한 뒤, Epic을 다시TODO로 전환합니다.
2개의 Bug (A=2)와 3개의 Task (B=3)로 초기화했을 때, 머신은 일련의 전환을 실행합니다. Epic은 결국 0개의 Bug와 5개의 연결된 Task를 가진 상태로 PROD에 도달하며, 결과적으로 $2 + 3 = 5$를 계산합니다.
확장하기: 피보나치 수열과 "Convert" 단축키
기본적인 환원이 핵심을 증명하지만, Seriot는 Jira의 Convert Issue Type 기능이 더 효율적인 구현을을 가능하게 한다고 언급합니다. Bug를 Story나 Task로 즉시 변경함으로써, 번거로운 DEC + INC 사이클을 피할 수 있습니다.
세 개의 레지스터(Bug, Task, Story)와 세 개의 상태(TODO, QA, DEV)를 사용하여 피보나치 수열 생성기를 구현할 수 있습니다. 이 머신은 무한히 실행되며, Task 개수에서 1, 1, 2, 3, 5, 8, 13...과 같은 수열열을 생성합니다. Jira Cloud는 체인 깊이 제한(보통 10개의 트리거)을 두기 때문에,