# ๐Ÿ“‘ Target State Transitions and CAS Specification - **Document Version**: Rev.2 - **Issue**: [Gitea Issue #5](https://git.godopu.com/tmpl/multi-agent-mux/issues/5) - **Scope**: Target Compare-And-Swap (CAS) State Machine & Attribution Contract --- ## 1. ์ด๋ฒคํŠธ(Event)์™€ ์ƒํƒœ(Status)์˜ ๊ฐœ๋…์  ๋ถ„๋ฆฌ ๊ธฐ์กด ์‹œ์Šคํ…œ์˜ ํ˜ผ์„ ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์šฉ์–ด๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•˜์—ฌ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค: - **์ด๋ฒคํŠธ (Event)**: ์—์ด์ „ํŠธ, ์›Œ์ฒ˜(Watcher), ๋˜๋Š” ์™ธ๋ถ€ ์šด์˜์ž๊ฐ€ ํŠน์ • ์‹œ์ ์— ๋ฉ”์‹œ์ง• ๋ฐฑํ”Œ๋ ˆ์ธ(MQTT)์ด๋‚˜ ๋กœ์ปฌ ์ฑ„๋„๋กœ ์ „๋‹ฌํ•˜๋Š” **์‚ฌ๊ฑด(Fact)**์ž…๋‹ˆ๋‹ค (`started`, `progress`, `permission_required`, `completed`, `error`, `cancelled`). - **์ƒํƒœ (Status)**: ๋‹จ์ผ ์ƒํƒœ ์ œ์–ด ์—”์ง„(Engine)์ด ์›์ž์  CAS ํŠธ๋žœ์žญ์…˜์„ ํ†ตํ•ด ๊ณตํ†ต ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ์˜์†์ ์œผ๋กœ ๊ธฐ๋กํ•˜๋Š” **ํ˜„์žฌ ์ž‘์—…์˜ ๊ณต์‹ ์ƒ์• ์ฃผ๊ธฐ ๋‹จ๊ณ„**์ž…๋‹ˆ๋‹ค (`pending`, `running`, `completed`, `error`, `cancelled`). > ๐Ÿ“Œ **ํ•ต์‹ฌ ์›์น™**: ์ด๋ฒคํŠธ๋Š” ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•ด ๋‹ฌ๋ผ๋Š” **์ „์ด ์š”์ฒญ(Transition Request)**์ผ ๋ฟ์ด๋ฉฐ, ์—”์ง„์˜ ์œ ํšจ์„ฑ ๊ฒ€์ฆ๊ณผ CAS ๊ฒŒ์ดํŠธ๋ฅผ ํ†ต๊ณผํ•˜๊ธฐ ์ „๊นŒ์ง€๋Š” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. --- ## 2. 4์ค‘ ์‹คํ–‰ ๊ท€์†(Execution Attribution) ๋ณด์žฅ ๊ณ„์•ฝ ๋‹จ์ˆœํžˆ ์—์ด์ „ํŠธ ํ„ฐ๋ฏธ๋„์ด ์œ ํœด(`idle`) ์ƒํƒœ๋ผ๊ณ  ํ•ด์„œ ์ž‘์—…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ข…๋ฃŒ๋˜์—ˆ๋‹ค๊ณ  ์ถ”๋ก (Inferred Completion)ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์ด์ „ ์ž‘์—…์˜ ์ž”์—ฌ ์œ ํœด ์ƒํƒœ, ์„ธ์…˜ ์žฌ์‚ฌ์šฉ, ๋˜๋Š” ํ”„๋กœ์„ธ์Šค ์žฌ์‹œ์ž‘์œผ๋กœ ์ธํ•œ ์˜คํƒ์„ ์›์ฒœ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ **4์ค‘ ์‹๋ณ„์ž ํŠœํ”Œ**์„ ํ•„์ˆ˜๋กœ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค: $$\text{Attribution Tuple} = (\text{job\_id}, \text{attempt\_id}, \text{agent\_session\_uuid}, \text{pane\_process\_generation})$$ 1. **`job_id`**: ๋“ฑ๋ก๋œ ๊ณ ์œ  ์ž‘์—… ์‹๋ณ„์ž (32-bit hex ๋˜๋Š” UUID). 2. **`attempt_id`**: ๋‹จ์ผ Job ๋‚ด์—์„œ ์žฌ์‹œ๋„ ์‹œ ๋‹จ์กฐ ์ฆ๊ฐ€ํ•˜๋Š” ์‹œ๋„ ๋ฒˆํ˜ธ. 3. **`agent_session_uuid`**: ์—์ด์ „ํŠธ ํ”„๋กœ์„ธ์Šค ๊ธฐ๋™ ์‹œ ํ• ๋‹น๋œ ์˜์† ๊ณ ์œ  ์‹๋ณ„์ž. 4. **`pane_process_generation`**: TMUX/Herdr ์ฐฝ ๋ฐ ๊ธฐ์ € ์…ธ ํ”„๋กœ์„ธ์Šค์˜ ์‹œ์ž‘ ์‹œ๊ฐ(`lstart`) ๋ฐ PID ์กฐํ•ฉ. ### ๊ท€์† ๋ฐ ์‹คํ–‰ ์•ต์ปค ๋ถˆ๋ณ€์‹: - ๋™์ผ ์—์ด์ „ํŠธ ์„ธ์…˜์—๋Š” ๋™์‹œ์— ๋‹จ ํ•˜๋‚˜์˜ ํ™œ์„ฑ ์ž‘์—…(`job_id`)๋งŒ ๋ฐฐ์ •๋ฉ๋‹ˆ๋‹ค. - ๋””์ŠคํŒจ์น˜ ํ™•์ธ(`dispatch_ack`) ์ดํ›„, ํ•ด๋‹น `attempt_id`์— ์†ํ•˜๋Š” ์‹ค์ œ ํ„ฐ๋ฏธ๋„ ์ถœ๋ ฅ ๋ฐ ํ™œ๋™(Execution Anchor)์ด ๊ด€์ธก๋œ ๊ฒฝ์šฐ์—๋งŒ ์™„๋ฃŒ ํ›„๋ณด๋กœ ์ธ์ •ํ•ฉ๋‹ˆ๋‹ค. - ๋„ค์ดํ‹ฐ๋ธŒ API๊ฐ€ ์ œ๊ณตํ•˜์ง€ ๋ชปํ•˜๋Š” ์‹๋ณ„์ž๋Š” `null + reason`์œผ๋กœ ํ‘œ๊ธฐํ•˜๋ฉฐ, ๊ฐ€์งœ ๊ฐ’์„ ์ž„์˜๋กœ ์ฃผ์ž…ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. --- ## 3. ๋ชฉํ‘œ CAS ์ƒํƒœ ์ „์ดํ‘œ (Target State Machine) ๋ชจ๋“  ์ƒํƒœ ๋ณ€๊ฒฝ์€ Registry Lock ๋ณดํ˜ธ ํ•˜์—์„œ ๊ธฐ๋Œ€ ์ƒํƒœ(`expected_state`), ์‹œ๋„ ์„ธ๋Œ€(`attempt_id`), ๋ฒ„์ „ ๋ฒˆํ˜ธ(`version`)๋ฅผ ์›์ž์ ์œผ๋กœ ๋น„๊ตํ•œ ํ›„ ๊ฐฑ์‹ (CAS)ํ•ฉ๋‹ˆ๋‹ค. | ํ˜„์žฌ ์ƒํƒœ (`Current`) | ์š”์ฒญ ์‹ ํ˜ธ (`Request`) | ์ „์ด ์กฐ๊ฑด ๋ฐ ๊ฒ€์ฆ ๊ทœ์น™ | ๊ฒฐ๊ณผ ์ƒํƒœ (`Next`) | ๋น„๊ณ  ๋ฐ ๊ฐˆ๋“ฑ ์ฒ˜๋ฆฌ | |---|---|---|---|---| | `pending` | `started` / `claim` | ์ž‘์—… ํ• ๋‹น ์„ธ์…˜ ๋ฐ `attempt_id` ์ผ์น˜ ํ™•์ธ | `running` | `started`๋Š” ์ƒํƒœ enum์ด ์•„๋‹ˆ๋ฉฐ `running`์œผ๋กœ ์ „์ด | | `running` | `progress` | ๋น„-Terminal ์œ ์ง€. ์ตœ๊ทผ ํ™œ๋™ ์‹œ๊ฐ ๋ฐ ์„ธ๋ถ€ ์ •๋ณด ๊ฐฑ์‹  | `running` | ์ƒํƒœ ๋ณ€๊ฒฝ ์—†์ด ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋งŒ ๊ฐฑ์‹  | | `running` | `permission_required` | ๋น„-Terminal ์œ ์ง€. `blocked_reason` ๊ธฐ๋ก | `running` | ๊ถŒํ•œ ๋Œ€๊ธฐ ์ค‘์—๋Š” ์ž๋™์™„๋ฃŒ ์ „๋ฉด ๊ธˆ์ง€ | | `running` | `explicit terminal` | ์œ ํšจํ•œ ์ž‘์—…์ž ์„ธ์…˜์˜ ์„œ๋ช…๋œ `completed`/`error`/`cancelled` ์ˆ˜์‹  | ์š”์ฒญ๋œ Terminal | ์ •์ƒ ์ข…๋ฃŒ ์ปค๋ฐ‹ | | `running` | `inferred completed` | 4์ค‘ ๊ท€์† ์ผ์น˜ + ์‹คํ–‰ ์•ต์ปค ํ™•์ธ + ํ™•์ • ํ•ด์‹œ/๋งค๋‹ˆํŽ˜์ŠคํŠธ ์กด์žฌ + Fresh `idle/done` + ๋ธ”๋กœ์ปค ์—†์Œ + ๋ถ€์ˆ˜ํšจ๊ณผ ๊ฒ€์ฆ | `completed` | Fail-Closed AND ๊ฒŒ์ดํŠธ ํ†ต๊ณผ ์‹œ์—๋งŒ CAS ์ปค๋ฐ‹ | | `terminal` | ๋™์ผ ๋…ผ๋ฆฌ์  ์™„๋ฃŒ ์žฌ์ˆ˜์‹  | ๊ธฐ ์ปค๋ฐ‹๋œ Terminal ์ƒํƒœ์™€ ๋™์ผํ•œ ์š”์ฒญ | `terminal` (No-op) | ๋ฉฑ๋“ฑ(Idempotent) ACK ๋ฐ˜ํ™˜, ์ถ”๊ฐ€ ๋””์ŠคํŒจ์น˜ ๊ธˆ์ง€ | | `terminal` | ์ƒ์ถฉ ์‹ ํ˜ธ (`progress`/๋‹ค๋ฅธ Terminal) | ์ด๋ฏธ Terminal ์ƒํƒœ์— ๋„๋‹ฌํ•œ ํ›„ ๋Šฆ๊ฒŒ ๋„์ฐฉํ•œ ์‹ ํ˜ธ | ๊ธฐ ์ปค๋ฐ‹ ์ƒํƒœ ์œ ์ง€ | ์ƒํƒœ ์—ญํ–‰ ๋ฐ ๋ฎ์–ด์“ฐ๊ธฐ ๊ฑฐ๋ถ€, Conflict Audit Log ๊ธฐ๋ก | | ์ž„์˜ ์ƒํƒœ | Stale Attempt / Generation | ๊ณผ๊ฑฐ ์‹œ๋„ ์„ธ๋Œ€ ๋˜๋Š” ํ”„๋กœ์„ธ์Šค ์„ธ๋Œ€ ๋ถˆ์ผ์น˜ ์‹ ํ˜ธ | ์ „์ด ๊ฑฐ๋ถ€ | Stale Attempt ๊ฒฝ๊ณ  ๊ธฐ๋ก ๋ฐ ํŒจํ‚ท ํ๊ธฐ | | `running` | `deadline_timeout` | ์ž‘์—… ํƒ€์ž„์•„์›ƒ ๊ฒฝ๊ณผ ๋ฐ ์‹คํ–‰ ์ค‘๋‹จ ํ™•์ธ | `error` | ํƒ€์ž„์•„์›ƒ ์›์ธ ๊ธฐ๋ก | --- ## 4. ๋ฆฌํฌํŠธ ํ™•์ • ๋‹จ๊ณ„ (Report Finalization Lifecycle) ์ž๋™์™„๋ฃŒ ์ถ”๋ก  ์‹œ ํŒŒ์ผ ์“ฐ๊ธฐ ๋„์ค‘ ๋ฐœ์ƒํ•˜๋Š” ๋ถˆ์™„์ „ ๋ฆฌํฌํŠธ ์ฑ„ํƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด 3๋‹จ๊ณ„ ํ™•์ • ๊ณ„์•ฝ์„ ์ˆ˜๋ฆฝํ•ฉ๋‹ˆ๋‹ค: ``` [writing] โ”€โ”€(์“ฐ๊ธฐ ์ง„ํ–‰ ์ค‘)โ”€โ”€> [stable_candidate] โ”€โ”€(์›์ž์  ๊ต์ฒด ๋ฐ ๋งค๋‹ˆํŽ˜์ŠคํŠธ)โ”€โ”€> [finalized] ``` 1. **`writing` ๋‹จ๊ณ„**: - ์—์ด์ „ํŠธ๊ฐ€ ์ž„์‹œ ํŒŒ์ผ(`report-final.md.tmp`)์„ ์ž‘์„ฑ ์ค‘์ธ ์ƒํƒœ. - ์›Œ์ฒ˜๋Š” ์ด ์ƒํƒœ์—์„œ ์™„๋ฃŒ๋ฅผ ์ ˆ๋Œ€ ์ธ์ •ํ•˜์ง€ ์•Š์Œ (Hold). 2. **`stable_candidate` ๋‹จ๊ณ„ (1์ฐจ/๋ณด์กฐ ํ•„ํ„ฐ)**: - ๋ฆฌํฌํŠธ ํŒŒ์ผ์˜ mtime์ด ๋‹จ์กฐ ์‹œ๊ณ„(monotonic clock) ๊ธฐ์ค€ **์ตœ์†Œ 15์ดˆ(๊ธฐ๋ณธ ๊ถŒ์žฅ๊ฐ’)** ๋™์•ˆ ๋ถˆ๋ณ€์ธ ์ƒํƒœ. - โš ๏ธ **๋ถˆ๋ณ€์‹**: **๋””๋ฐ”์šด์Šค ๊ฒฝ๊ณผ(15s)๋งŒ์œผ๋กœ๋Š” ์™„๋ฃŒ ๊ถŒํ•œ์ด ์„ฑ๋ฆฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** ์ด๋Š” ์ผ์‹œ์ ์ธ LLM ์ƒ๊ฐ ์ค‘๋‹จ์ด๋‚˜ ๋„คํŠธ์›Œํฌ ์ง€์—ฐ์ผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์˜ค์ง 'ํ›„๋ณด ํ•„ํ„ฐ'๋กœ๋งŒ ๊ธฐ๋Šฅํ•ฉ๋‹ˆ๋‹ค. 3. **`finalized` ๋‹จ๊ณ„ (2์ฐจ/ํ™•์ • ๊ณ„์•ฝ)**: - ์ตœ์ข… ๋Œ€์ƒ ๊ฒฝ๋กœ(`report-final.md`)๋กœ์˜ **์›์ž์  ์ด๋ฆ„ ๋ณ€๊ฒฝ(Atomic Rename)** ์™„๋ฃŒ. - ํ•ด๋‹น ์‹œ๋„์˜ `attempt_id`์™€ `report SHA-256 hash`๊ฐ€ ๋ช…์‹œ๋œ **์™„๋ฃŒ ๋งค๋‹ˆํŽ˜์ŠคํŠธ(Commit Manifest)** ์ƒ์„ฑ ์™„๋ฃŒ. - ์™ธ๋ถ€ ๋ถ€์ˆ˜ํšจ๊ณผ(Git push, API ํ˜ธ์ถœ)๊ฐ€ ์ˆ˜๋ฐ˜๋˜๋Š” ์ž‘์—…์ธ ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ถ€์ˆ˜ํšจ๊ณผ์˜ ์™„๋ฃŒ ์ฆ๊ฑฐ๊ฐ€ ๋งค๋‹ˆํŽ˜์ŠคํŠธ์— ์ฒจ๋ถ€๋˜์–ด์•ผ ํ•จ. - ๋ฆฌํฌํŠธ๊ฐ€ ์žฌ์ž‘์„ฑ๋˜๋ฉด ์ด์ „ ํ•ด์‹œ๋Š” ์ฆ‰์‹œ ๋ฌดํšจํ™”๋˜๋ฉฐ ์ƒˆ๋กœ์šด ํ™•์ • ์ ˆ์ฐจ๊ฐ€ ํ•„์š”ํ•จ. --- ## 5. ์ง€์—ฐ ์•Œ๋ฆผ (Pending Notification) ๋ฐ ํŠธ๋žœ์žญ์…˜ ๋ณต๊ตฌ ์„ค๊ณ„ ์ƒํƒœ ์ „์ด ๋ฝ(Registry Lock) ํ•˜์—์„œ ์™ธ๋ถ€ I/O(MQTT ๋ธŒ๋กœ์ปค ์ „์†ก, ๋„คํŠธ์›Œํฌ ํ˜ธ์ถœ)๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋ฐ๋“œ๋ฝ๊ณผ ์‹ฌ๊ฐํ•œ ์ง€์—ฐ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ **๋‚ด๊ตฌ์„ฑ ์ง€์—ฐ ์•Œ๋ฆผ(Pending Notification) ํŠธ๋žœ์žญ์…˜**์„ ๋ช…์„ธํ•ฉ๋‹ˆ๋‹ค: ```mermaid sequenceDiagram participant Engine participant Registry as Job Registry (Disk) participant Publisher as Async Publisher (Wire) participant Broker as MQTT Broker Note over Engine: 1. CAS ์ „์ด ๊ฒฐ์ • activate Engine Engine->>Registry: ๋ฝ ํš๋“ (fcntl.flock) Engine->>Registry: ์›์ž์  ์ƒํƒœ ์ปค๋ฐ‹ (status=completed, pending_notification=intent) Engine->>Registry: ๋ฝ ์ฆ‰์‹œ ํ•ด์ œ deactivate Engine Note over Publisher: 2. ๋น„๋™๊ธฐ ์•Œ๋ฆผ ์ „์†ก Publisher->>Broker: MQTT ์ด๋ฒคํŠธ ๋ฐœํ–‰ (HMAC ์„œ๋ช… ํฌํ•จ) alt ์ „์†ก ์„ฑ๊ณต Broker-->>Publisher: ACK (PUBACK) Publisher->>Registry: pending_notification ์™„๋ฃŒ ํ‘œ์‹œ else ์ „์†ก ์‹คํŒจ / ํฌ๋ž˜์‹œ Note over Publisher: ๋ฐฑ์˜คํ”„ ์žฌ์‹œ๋„ ๋ฐ ๊ธฐ๋™ ์‹œ ๋ฏธ์™„๋ฃŒ ์•Œ๋ฆผ ๋ณต๊ตฌ ์ „์†ก end ``` ### ํŠธ๋žœ์žญ์…˜ ๋ณด์žฅ ๊ทœ์น™: 1. **๋‹จ์ผ ๋‚ด๊ตฌ์„ฑ ์ž‘์—… ๋ ˆ์ฝ”๋“œ**: - ๋…๋ฆฝ๋œ ๋ณ„๋„์˜ Outbox DB๋ฅผ ์‹ ์„คํ•˜์ง€ ์•Š๊ณ , ๊ธฐ์กด `.mam/jobs/.json` ๋ ˆ์ฝ”๋“œ ๋‚ด์— `pending_notification: { event, timestamp, seq, signature }`๋ฅผ ์›์ž์ ์œผ๋กœ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. 2. **๋ฝ ํ•ด์ œ ํ›„ ์ „์†ก**: - ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋ฝ์„ ํ•ด์ œํ•œ ํ›„ ๋น„๋™๊ธฐ ์›Œ์ปค๊ฐ€ MQTT ๋ฐœํ–‰์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. 3. **ํฌ๋ž˜์‹œ ๋ณต๊ตฌ(Crash Recovery)**: - ์—”์ง„ ์žฌ์‹œ์ž‘ ์‹œ `status in TERMINAL`์ด๋ฉด์„œ `pending_notification`์ด ๋‚จ์•„์žˆ๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ์Šค์บ”ํ•˜์—ฌ ๋ฉฑ๋“ฑ์ ์œผ๋กœ ์žฌ์ „์†กํ•ฉ๋‹ˆ๋‹ค. --- ## 6. ๊ถŒํ•œ ์ฐจ๋‹จ(Permission Blocked) ํ•ด์ œ ์ •์ฑ… - ์—์ด์ „ํŠธ ํ„ฐ๋ฏธ๋„์ด `blocked` (๊ถŒํ•œ ์Šน์ธ ๋Œ€๊ธฐ) ์ƒํƒœ๋กœ ๊ด€์ธก๋˜๋ฉด, **์–ด๋– ํ•œ ๊ฒฝ์šฐ์—๋„ ์ž๋™์™„๋ฃŒ ์ „์ด๋ฅผ ์‹œ๋„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** - ์ฐจ๋‹จ ํ•ด์ œ ํŒ๋‹จ: - ๋ฌต์‹œ์  ์ „์ด ๊ธˆ์ง€: ๋‹จ์ˆœํžˆ ๋‹ค์Œ ๊ด€์ธก์—์„œ `working`์ด ๋˜์—ˆ๋‹ค๊ณ  ํ•ด์„œ ์ด์ „ ์ฐจ๋‹จ์ด ์ •๋‹นํ•˜๊ฒŒ ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค๊ณ  ๋‹จ์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. - ๋ช…์‹œ์  ์Šน์ธ ์ฆ๊ฑฐ ๋˜๋Š” ์šด์˜์ž์˜ ์Šน์ธ ์ž…๋ ฅ ๋กœ๊ทธ๊ฐ€ ํ™•์ธ๋˜์ง€ ์•Š๋Š” ํ•œ, ์ž‘์—…์€ `running (blocked)` ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋ฉฐ ๋ฐ๋“œ๋ผ์ธ ๋„๋‹ฌ ์‹œ ์•ˆ์ „ํ•˜๊ฒŒ ํƒ€์ž„์•„์›ƒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.