๐ ์ธ์์ธ๊ณ์ ์ด๋ ฅ ์์นด์ด๋ธ (๊ฐฑ์ 1~47, 2026-05)
๐งญ ์ ๋ํ๋ฐฉ ์ฝ๊ธฐ ์ ์ฐจ (๊ธฐ๋ณธ ์ง์นจ)
์ ์ธ์
์ ์ธ์์ธ๊ณ์๋ง ์ฝ์ง ๋ง๊ณ ์๋ 3๋จ๊ณ๋ฅผ ๋ชจ๋ ๊ฑฐ์น๋ค.
1. ์ธ์์ธ๊ณ์ โ ๋งจ ์๋ '์ต์ ๊ฐฑ์ '๋ถํฐ. (๋งจ ์๋ ์ต์ ๊ฐฑ์ , "โ
์ต์ โ ์ฌ๊ธฐ๋ถํฐ ์ฝ์ผ๋ฉด ํ์ฌ ์ํ ๋ณต์๋จ".) ์ด ํ์ด์ง์ ๊ฐ์ฅ ์ค์ ๋ถ๋ถ = ์ต์ ๊ฐฑ์ ์์ โ ํ์ฌ 1์์ ๋๊ธฐ + โก ๋ค์ ์์์ ๋ ํญ๋ชฉ์ด๋ค. ๊ทธ ์ ๊ฐฑ์ (1)~(์ง์ )์ ์ด๋ ฅ ์ฐธ๊ณ ์ฉ.
2. ๐ ์ฃผ์ ์์ธ (๋ชฉ์ฐจ) โ ์ต์ ๊ฐฑ์ ์ด ์ธ๊ธํ ๊ด๋ จ ์ฃผ์ ์ ๋ฒํธยท์ํ ๋ผ๋ฒจ([ํ์ ์ฌ์ค]/[ํฉ์]/[๋
ผ์์ค]/[๊ฒฐ์ ] ๋ฑ)์ ํ์ธํ๋ค.
3. ๐ ํญ๋ชฉ๋ณ ์ธ๋ถ ์์ โ ํด๋น ยง์ฃผ์ ๋ก ์ต์ปค ๋งํฌ(notion-anchor-mcp) ์ ํํด ๋
ผ์ยท๊ฒฐ๋ก ยท๋ฏธ๊ฒฐ์ ํ์ธํ๋ค. ์ธ์์ธ๊ณ์ ์์ฝ๋ง์ผ๋ก ๋ถ์กฑํ ๊ทผ๊ฑฐ๋ ์ฌ๊ธฐ์ ํ์ธ.
โ ๏ธ ์ ๋ํ๋ฐฉ START HERE โ ์ด ํ์ด์ง์ ํ์ฌ ์ํ๋ ๋งจ ์๋ ์ต์ ๊ฐฑ์ ๋จ ํ๋๋ค. ๊ทธ ์์ ํ ์ค ๋งฅ๋ฝยทํ์ ์ฌ์คยท๋ฏธ๊ฒฐยท๋ค์๋จ๊ณ ๋ฐ ๊ฐฑ์ (1)~(23)์ ์ ๋ถ ๊ณผ๊ฑฐ ๊ธฐ๋ก(history). ์ธ๋ถ์ ๋ ๋๋ "์ธ์ ์์ฝ v3 (2026-05-05, soft delete)" ๋ ํ๊ธฐ๋จ โ soft deleteยทTier A/BยทbaselineยทJob1 ์ ๋ชจ๋ ์ด๋ฏธ ์ข ๋ฃ๋ ๋จ๊ณ์ด๋ฉฐ ํ์ฌ ์์ ๊ณผ ๋ฌด๊ดํ๋ค. ํ ์ค ๋งฅ๋ฝ ๐ด ํ์ฌ 1์์ ๋๊ธฐ: ์ฝ๋๊ฐ
codi-silentblock-confirm-and-unblock.md์์ ์ค โ ๊ทธ ๊ฒฐ๊ณผ ์์ ์ด ๋ค์ ํ๋์ 1์์. (์ฑํฐโ์ฝ๋ ์๋์ํ silent block ๊ทผ๋ณธ์์ธ ํ์ + ํ ์คํธ์๋ฒ ์ต์ ๋จ์ผ๋ณ๊ฒฝ + 1ํ ์ฌ์ดํด PASS)๋ณต์ ์ ์ฐจ: ๋งจ ์๋ ๊ฐฑ์ (32) ๋ถํฐ ์ฝ๋๋ค. ๊ทธ ์ธ ์๋จ/์ค๊ฐ ์น์ ์ ์ด๋ ฅ ์ฐธ๊ณ ์ฉ.
ํ์ ์ฌ์ค
- ์ฝ๋ ์คํ:
claude -p --output-format json --max-turns 100 --permission-mode acceptEdits(stdin prompt, timeout 900s). ํ์ผbridge/app/services/codi_runner_cli.py. git์ด ground truth. - ์ฑํฐ ์คํ:
claude_client.chat()โ SDKquery(), cmdboard MCP ๋๊ตฌ๋ง,max_turns=8. ํ์ผbridge/app/services/claude_client.py. - ์บํฌ ๊ฒฉ์ฐจ: ๋ ๋ค ์ต์ข ์์ฝ๋ง ๋จ๊ธฐ๊ณ ์ค๊ฐ transcript(๋๊ตฌ ์ ๋ ฅ/๊ฒฐ๊ณผ/์ค๋ฅยทstderr) ํ๊ธฐ.
- ํ ํฐ ์นฉ: ํ์ฌ mock/0k. stream-json
result.usage๋ก ์ค์ธก ๊ฐ๋ฅ. - ๊ธฐ์กด ์์ ๊ฐ๋:
CODI_AUTORUN_ENABLED๊ธฐ๋ณธ false, cycle limit(์ฝ 15), allowlist,--dangerously-skip-permissions๊ธ์ง, master-only push.
ํฉ์๋ ๋ฐฉํฅ
- ๋ ๋ฒ ์์: โ stream-json ์บํฌ โ โก ์ธ์ ์ฌ๊ฐ/ํต๋์คํ โ โข ์ง๋จ adminโ์นด๋์์ธ ์ด์ .
- ์ด์ด๊ฐ๊ธฐ: resume + ์ ์ธ์ +ํต๋์คํ. ํต๋์คํ ์๋จ = ์นด๋์ continuation brief ์์ํ(์ฝ๋=git, ์ฑํฐ=chati_work_summary ์ต์ปค). ์์น: repo/์นด๋=์ง์ค, brief=์๋ด+๊ฒ์ฆ.
- ๋ฉํฐ์์ด์ ํธ: worker(์คํ) / monitor(์ฝ๋ยท๋ฌด๋ฃ) / supervisor(์ด๋ฒคํธ ๊ตฌ๋ LLM).
- supervisor ๋ฑ๊ธ = C(๋ฅ๋ ๊ฐ์ ). ๋ Job: Job2(์ค๋จ์์ ํ๋จ) ์ ํ โ Job1(์ฒดํฌํฌ์ธํธ goal-keeping) ํํ.
- supervisor ์์ : ํ์ ํ๋์งํฉ + ๊ธฐ์กด ๊ฐ๋ ๋ด + escalate-to-user 1๊ธ + ๊ฒฐ์ ๋ก ์ ํ๋์ธก์ด ํญ์ฃผ ์ ์ด์ ๋ฐ๋ฅ(์์ด์ ํธ๊ฐ ์๋).
๋ฏธ๊ฒฐ ๊ฒฐ์
- supervisor ํ๋์งํฉ ํ์ (์ด์: retry / retry-with-fix / ์์ธ์ ํต๋์คํ / ์ฌ๋ผ์ฐํ / ์ฌ์ฉ์์์ค์บ๋ ์ดํธ / abort).
- CONTINUATION_STATE ํ๋ ํ์ (์ฝ๋ 6ํ๋ ์ด์) + ์์ฑ ์ฃผ์ฒด(ํ์ด๋ธ๋ฆฌ๋ ์ถ์ฒ).
- ์์ด์ ํธ ์ธ๋ถํ ๊น์ด โ ์ด๋ ์๋ช ์ฃผ๊ธฐ ์ง์ ๊น์ง LLM ํ๋จ.
- ํญ์ฃผ ํ๋์ธก ์์น (์นด๋๋ณ ํ ํฐ/ํธ์ถ/๊ฐ์ /์๊ฐ).
- Job1 ์ฒดํฌํฌ์ธํธ ๊ตฌ๊ฐ ํฌ๊ธฐ (๊ฐ๋ ๋ฐ๋โ๋น์ฉ).
๋ค์ ๋จ๊ณ
- Job2๋ถํฐ. ๋์์ stream-json ์บํฌ PoC๋ก ํ ํฐ ์ค์ธก baseline ํ๋ณด โ ์์ต ์ ๋ํ.
๊ฐ์ฒด ์ ์ (์ฉ์ด)
- ์ฑํฐ: ์นด๋๋ณ ์์ ์ค์ผ์คํธ๋ ์ดํฐ(๋ถ์ยท๋ผ์ฐํ ). ์ฝ๋: ์ค์ ์ฝ๋ ์คํ์(Claude CLI). ์ฌ๋ผ: ์ ์ญ ์ฑํ ํ๋ฅด์๋(=supervisor ํ๋ณด). monitor: ๋น-LLM ์ฝ๋ ๊ฐ์์ธต. supervisor: ์ด๋ฒคํธ ๊ตฌ๋ LLM ๊ฐ๋ (C๋ฑ๊ธ).
์ต์ข ๊ฐฑ์ : 2026-05-23
๊ฐฑ์ 2026-05-23 โ (a) ๊ฒฐ์ ๋ก ์ ํ๋์ธก + ์ฌ์ฉ์ top-up
- ์ธก ์์๊ฐ ํฉ์: per-run(codi
max_turns100 / ์ฑํฐ 25, per-run wall-clock codi 900sยท์ฑํฐ 180s), per-card(์ด ํธ์ถ ~30, supervisor ๊ฐ์ ~5, wall-clock 30~60๋ถ, ํ ํฐ ์์ฐ=์ค์ธก ํ), ํจํด์ฐจ๋จ๊ธฐ(stall โฅ3, ์ฐ์์คํจ โฅ3, ์ปจํ ์คํธ ํฝ์ฐฝโํต๋์คํ). - ์ธก ๋๋ฌ = abort ์๋ โ ์ผ์์ ์ง + ๋ณด๊ณ + bounded top-up(์ฌ์ฉ์ ์น์ธ,
actor=user๊ธฐ๋ก). ์งํํ=top-up ์ ์ / ํจํดํ=ํต๋์คํ ๊ถ๊ณ . ์ฐ์ฅ ์ ์ ๋ ์ฒ์ฅ ํ์. - ๋ฏธ๊ฒฐ(๊ฐฑ์ ): ์ ๋ ์ฒ์ฅ ์์น, ํ ํฐ ์์ฐ ์์น(์ค์ธก), supervisor ํ๋์งํฉ ํ์ , ์์ด์ ํธ ์ธ๋ถํ ๊น์ด.
๊ฐฑ์ 2026-05-23 (2) โ ์ ๋ ์ฒ์ฅ ํ์ + ์์ ์ฒด์ธ
- per-card ์ ๋ ์ฒ์ฅ ํ์ : top-up ์ต๋ 3ํ + lifetime ํธ์ถ 100 (๋ณํ).
- ์์
์ฒด์ธ(work chain): ์นด๋ ์ ๋
ผ๋ฆฌ ์์
๋จ์. ์นด๋ ์ฒ์ฅโ์ ์นด๋๋
chain_id์์. ํ ํฐยทํธ์ถยท์ฌ์ดํด์ ์ฒด์ธ ๋จ์๋ก rollup โ ๊ฐ์์ฑ + ์นฉ ์ฐํ ์ฐจ๋จ ๋ ๋ค. - per-chain ์ฒ์ฅ(์ ๊ท): ์ฒด์ธ ์นด๋ ~5 / ์ฒด์ธ ์ด ํธ์ถ ~300 โ ์ฒด์ธ ์ฐจ์ escalate.
- ์ ์ : chain rollup์ ์ค์ธก per-card ํ ํฐ(๋ ๋ฒ1 stream-json) ์์๋ง. ํ mock ํ ํฐ ์นฉ ๋จผ์ ์ค์ธกํ ํ์.
- ๊ตฌํ ์ต์ปค:
chain_idํ๋ + continuation brief๊ฐ chain_idยท๋์ totals ์ด๋ฐ + rollup=์ฒด์ธ agent_runs SUM.
๊ฐฑ์ 2026-05-23 (3) โ (a) ์ข ๋ฃ + ๋ค์ ๋ํ๋ฐฉ ์์์
- (a) ๊ฒฐ์ ๋ก ์ ํ๋์ธก = ์ข ๋ฃ. ํ์ : per-card ์ฒ์ฅ(top-up 3ํ / lifetime ํธ์ถ 100), per-chain ์ฒ์ฅ(์ ์ 5์นด๋ / 300ํธ์ถ โ ์ฒด์ธ ์ฐจ์ escalate), ํ ํฐ ์์ฐ์ stream-json ์ค์ธก ํ ํ์ .
- ์ฒด์ธ ์ฒ์ฅ = ๋ง๋ค๋ฅธ ๋ฒฝ ์๋ ์ฒดํฌํฌ์ธํธ. ๋๋ฌ ์ ์ฌ์ฉ์ ์ ํ: ๊ฐ์ ์ฒด์ธ ์ฐ์ฅ(rollup ํตํฉ) / ์ ์ฒด์ธ ์์(rollup ๋ฆฌ์ + ์ด์ ์ฒด์ธ ๋งํฌ). ์ธก์ ์๋ ํญ์ฃผ๋ง ๋ฌถ๊ณ ์ฌ์ฉ์ ์๋์ ์ํ์ ๋ง์ง ์์.
- โถ ๋ค์ ๋ํ๋ฐฉ ์์์ : (b) ํ์ดํ๋ผ์ธ ์ธ๋ถํ ๊น์ด โ ๋ฏธ์ฐฉ์. ์์ ์๋ช ์ฃผ๊ธฐ 6์ง์ (pre-run / per-checkpoint=Job1 / on-stop=Job2 / on-completion=critic / continuous=monitorยท์ฝ๋ / outer-bound=์นฉยท์ฝ๋) ์ค ์ด๋๊น์ง LLM ํ๋จ์ ๋ฃ์์ง ๊ฒฐ์ ํ๋ ์ฃผ์ . continuousยทouter-bound๋ ์ฝ๋(๋ฌด๋ฃ) ๊ณ ์ , ๋๋จธ์ง LLM ์ง์ ์ ์ฑํ ๋ฒ์๊ฐ ํต์ฌ.
- ์ธ๊ณ ๋ฐฉ๋ฒ: ์ ๋ํ๋ฐฉ์ ์ด ํ๋ก์ ํธ ์์์ ์ด๊ณ , ๋ณธ ์ธ์์ธ๊ณ์ + ์ธ๋ถ ์์ ํ์ด์ง๋ฅผ ๋จผ์ ์ฝ๊ฒ ํ ๊ฒ. (ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ๋ ๋ณด์กฐ โ ์์ฝ ์์ค + ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ฐฑ์ ์ด๋ผ ์ฆ์ยท์์ ํ์ง ์์.)
๊ฐฑ์ 2026-05-23 (4) โ (b) ์ข ๋ฃ + ๋ค์ ์์์
- (b) ํ์ดํ๋ผ์ธ ์ธ๋ถํ ๊น์ด = ์ข ๋ฃ. ๊น์ด = ์ด๋ฒคํธ ๊ฒฝ๊ณ๊น์ง.
- ์ฑํ(LLM): pre-run(๋ผ์ฐํ ยท๊ธฐ์กด) + Job2(on-stop) + ํฌ๋ฆฌํฑ(on-completion).
- ๋ณด๋ฅ(LLM): Job1(per-checkpoint) โ ๋ฐ์ดํฐ ๊ฒ์ดํธ(๋ ๋ฒ1 stream-json ์ค์ธก + Job2
failed_attempts๋๋ฆฌํํธ ๋น๋ ํ์ธ ํ ์ฑํ ํ๋จ). - ๊ณ ์ (์ฝ๋): continuous(์ํยท์๋ฌ ๊ฐ์ง) + outer-bound(ํญ์ฃผ์นฉ).
- ์์น: LLM ํ๋จ์ ์ด์ฐ ์ด๋ฒคํธ ๊ฒฝ๊ณ์๋ง, ์ฐ์ ๊ตฌ๊ฐ์ ๊ฒฐ์ ๋ก ์ฝ๋๊ฐ ์์ . Job2(๋ฉ์ถค)+ํฌ๋ฆฌํฑ(์๋ฃ) = ๋์ผ supervisor 1๊ฐ์ ์ข ๋ฃ์ํ ๋ถ๊ธฐ(์ ์์ด์ ํธ ์๋, "worker ์ LLM 1๊ฒน"ยท๋น์ฌ๊ท ์ ์ง).
- ๋ค์ ๋ํ๋ฐฉ ์์์ : supervisor ํ๋์งํฉ ํ์ โ ๋ฏธ์ฐฉ์. ์ด์ 6์ข : retry / retry-with-fix / ์์ธ์ ํต๋์คํ / ์ฌ๋ผ์ฐํ / ์ฌ์ฉ์์์ค์ปฌ๋ ์ดํธ / abort. ๊ฐ ํ๋์ ๋ฐ๋ ์กฐ๊ฑดยท์ ๋ ฅ(์บํฌ+brief+git)ยท๊ฒฐ๊ณผ(activity_log)ยท์ฒ์ฅ ์ฐ๋์ ํ์ ํ๋ ์ฃผ์ .
- ๋จ์ ๋ฏธ๊ฒฐ: supervisor ํ๋์งํฉ(๋ค์) / CONTINUATION_STATE ํ๋ ํ์ / ํ ํฐ ์์ฐ ์ค์ธก(๋ ๋ฒ1 ํ) / Job1 ์ฑํ(๋ฐ์ดํฐ ๊ฒ์ดํธ).
๊ฐฑ์ 2026-05-23 (5) โ supervisor ํ๋์งํฉ ํ์
- 8์ข ๋ช ๋ช ํ์ : accept / resume / retry / retry-with-fix / ์์ธ์ ํธ๋์คํ / ์ฌ๋ผ์ฐํ / ์ฌ์ฉ์์์ค์ปฌ๋ ์ดํธ / abort.
- ์ด์ 6์ข +accept(ํฌ๋ฆฌํฑ ์์ฑ ์ข ๊ฒฐ) +resume(๊ฐ์ ์ธ์ ์ํ, retry์ ๊ตฌ๋ถ). ๋ฐ๋ ํธ๋ฆฌยท์ ๋ ฅ(์บํฌ+brief+git)ยท์ถ๋ ฅ(activity_log)์ ์ธ๋ถ ์์ ยง13.
- 5์ข ํ๋ผ๋ฏธํฐํ๋ ๊ตฌํ ์์ ๋์(์ฝ๋ ๊ฒฝ๋กโยท๋ก๊ทธ ๊ฐ๋ ์ฑโ) โ ์ํคํ ์ฒ ๋ธ๋ก์ปค ์๋.
- ๋ค์ ์์์ : CONTINUATION_STATE ํ๋ ํ์ โ ๋ฏธ์ฐฉ์. ์ฝ๋ 6ํ๋ ์ด์(goal / done / repo_state / remaining / failed_attempts / gotchas) + ์ฑํฐ ๋ณํ + ์์ฑ ์ฃผ์ฒด(ํ์ด๋ธ๋ฆฌ๋ ์ถ์ฒ) ํ์ . resumeยท์์ธ์ ํธ๋์คํ ํ๋์ด ์ด brief์ ์ง์ ์์กด.
- ๋จ์ ๋ฏธ๊ฒฐ: CONTINUATION_STATE ํ๋(๋ค์) / ํ ํฐ ์์ฐ ์ค์ธก(๋ ๋ฒ1 ํ) / Job1 ์ฑํ(๋ฐ์ดํฐ ๊ฒ์ดํธ).
๊ฐฑ์ 2026-05-23 (6) โ ์ฝ๋ ๊ฐ์ฌ ์๋ฃ + CONTINUATION_STATE ์ฌ์ ์ด
- ์ฝ๋ ์ ์ ๊ฐ์ฌ(ํ์ผ:๋ผ์ธ ๊ทผ๊ฑฐ) ์๋ฃ. FINDINGS =
cmdboard_supervisor_continuation_audit_FINDINGS.md(๋ก์ปฌ). ์ธ๋ถ ์์ ยง14์ ์ฌ์ค ๋ฐ์. - CONTINUATION_STATE = ์ ๊ท ์ค๊ณ ์๋. brief๋ ์ด๋ฏธ
codi_result_v1๋ดํฌ(41ํค). v2 = 2๊ณ์ธต: - Tier A(์ฆ์ยท์ ์บํฌ 0): ์ธ์ ActivityLog join โ head_before/after, commit_hashes, ํ ํฐ(usage_status), dirty/snapshot/restore ๋ดํฌ ๋ณํฉ.
- Tier B(gated): failed_attemptsโ๋ ๋ฒ1(stream-json) / ์ฑํฐ ํ๋ยทํ ํฐโclaude_client ๋ณด๊ฐ / chain_contextโchain_id migration / supervisor ๋ผ๋ฒจโmode 'sara' or ALTER.
- ๋ง์คํฐ ๊ฒ์ดํธ = ๋ ๋ฒ1(stream-json). ์ฝ๋๋ก ํ์ :
--output-format json์ terminal result๋ง ์ค์ +exit_code=0ํ๋์ฝ๋ฉ โ per-stepยทfailed_attempts ๋ถ๊ฐ. ๋ ๋ฒ1์ด failed_attempts + ํ ํฐ ์ค์ธก + per-step์ ๋์ ํด๊ฒฐ. - ์ ์ (๋ ธ์ stale): ํ ํฐ=์นฉ๋ง mock(codi ์ค์ธก์ ์บํฌยทadmin ํ์ ); chati_instruction ์ํฐํฉํธ ๋ฏธ์ฌ์ฉ(write ํธ์ถ ์์); escalate asking ์นด๋ ๊ธฐ๋ณธ ๋นํ์ฑ + notify-step/done ์๋ํฌ์ธํธ cmdboard์ ์์(ยง13 ์์ค์ปฌ๋ ์ดํธ ์ฑ๋ = ์ ํ๊ณผ์ ).
- ๋ค์ ์์์ : (1) ๋ ๋ฒ1 stream-json ์ ํ ๊ตฌํ(์ฝ๋ ์์) โ Tier Bยทํ ํฐ ๊ณตํต ๊ฒ์ดํธ + ํ ํฐ ์ค์ธก baseline ํ๋ณด. (2) Tier A ๋ดํฌ join์ ๋ ๋ฒ1 ๋ฌด๊ดํ๊ฒ ๋ณํ ๊ฐ๋ฅ(์ ์ํ). (3) ยง13 ์์ค์ปฌ๋ ์ดํธ ์ฑ๋ ํ์ฑํ ๊ฒํ .
- ๋จ์ ๋ฏธ๊ฒฐ: ๋ ๋ฒ1 ๊ตฌํ โ ์ค์ธก baseline โ Job1 ์ฑํ ํ๋จ / chain_id migration ์์น(12-B) / ์์ค์ปฌ๋ ์ดํธ ์ฑ๋ / per-chain ์ฒ์ฅ ์์น.
๊ฐฑ์ 2026-05-23 (8) โ Tier A ๋ดํฌ join ๊ตฌํ ์๋ฃ (๋ฏธ๋ฐฐํฌ)
- codi_result_v2 Tier A ๊ตฌํ ์๋ฃ (์ฝ๋ ์์ , ๋ฏธ์ปค๋ฐยท๋ฏธ๋ฐฐํฌ).
- ์ ๊ท ํฌํผ
_join_codi_runner_audit_metadata(db, task_id, โฆ)์ถ๊ฐ._build_codi_result_handoff_payload์db=Nonekwarg ์ถ๊ฐ โ ๋ด๋ถ์์ join. - ์ ๊ท 13ํค: head_before/head_after / commit_hashesยทcommit_oneline(โค50)ยทcommit_countยทchanged_file_count / input_tokensยทoutput_tokensยทtotal_tokensยทtoken_usage_status / dirty_beforeยทsnapshot_idยทrestore_available.
- ๋ชจ๋ ๋ดํฌ ์์ฑ ๊ฒฝ๋ก ์ผ๊ด ์ ์ฉ(๋ฉ์ธ enqueue / handoff_artifacts rebuild / admin_autorun_debug 3๊ฒฝ๋ก / chati claim rebuild). db ๋ฏธ์ง์ ์ 13ํค ์กด์ฌยทnull(ํ์ํธํ).
- ์๊ด๊ด๊ณ ์ค์ผ ๋ฐฉ์ง: ํ ํฐ์
run_id์ ํ ๋งค์นญ๋ง. ๋งค์นญ ์์ผ๋ฉด null/'unknown'. - schema_version:
codi_result_v1โcodi_result_v2/codi_result_md_v1โcodi_result_md_v2(3๊ฒฝ๋ก ๋ชจ๋). - ๊ฒ์ฆ:
_test_codi_result_v2_tierA_envelope_join.pya~e ์ ๋ถ PASS(๊ฒฉ๋ฆฌ in-memory SQLite). ํ๊ท 35๊ฐ ์ค 27 PASS. ์คํจ 8๊ฑด = ๊ธฐ์กด ์คํจ(3๊ฑด) + ์ค์๋ฒ E2E(5๊ฑด) โ ์ฝ๋ ๋ณ๊ฒฝ ๋ฌด๊ด. - ๋ณ๊ฒฝ ํ์ผ:
app/api/tasks.py/app/api/handoff_artifacts.py/app/api/admin_autorun_debug.py/app/api/chati.py/scripts/_test_phase127_codi_result_artifact.py/scripts/_test_codi_result_v2_tierA_envelope_join.py. - ๋ฏธ๋ฐฐํฌ ์ํ: commitยทpush ๋ฏธ์๋ฃ.
cmd์๋๋ฐฐํฌ์น์ธ ๋๊ธฐ. - ๋ค์ ์์์ : ํ ์คํธ ์๋ฒ ๊ตฌ์ถ + ๋ ๋ฒ1(stream-json) ๊ตฌํ.
๊ฐฑ์ 2026-05-23 (7) โ ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ ํ์ด์ง ์ ์ค
- cmdboard ํ๋ธ ํ์์ ๐ง ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ (๋ ํผ๋ฐ์ค) ์ ์ค (pfs ๋์ผ ํจํด โ Claude ๋ฉ๋ชจ๋ฆฌ 30๊ฐ ํ๋ ๋ณด์). ์ธํ๋ผยท์ํคํ ์ฒยทDB ์คํค๋ง(๊ฐ์ฌ ํ์ )ยท์ด์ ํจํดยท์ฝ๋ ํ์ต์ ์ฌ์ค ๋ ํผ๋ฐ์ค๋ก ์ ์ฅ.
- ๊ฐฑ์ ์ํฌํ๋ก ํธ์ : ์ดํ ์์ ๊ฐฑ์ ์ ์ธ๋ถ ์์ยท์ธ์์ธ๊ณ์์ ํจ๊ป, ํ์ ๋ ์ฌ์ค์ ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ ํ์ด์ง์๋ ๋ฐ์ํ๋ค(ํ๋ธ ์ด์ ๊ท์น ๊ฐฑ์ ์๋ฃ).
- ์ญํ ๊ตฌ๋ถ: ๋ฉ๋ชจ๋ฆฌ='์ด๋ป๊ฒ ํ๋ํ ์ง', ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ ํ์ด์ง='๋ฌด์์ ์์์ผ ํ ์ง', ์ธ๋ถ ์์/์ธ์์ธ๊ณ์='์์ ๊ธฐ๋ก'.
๊ฐฑ์ 2026-05-23 (9) โ ํ ์คํธ ์๋ฒ ๊ตฌ์ถ ๊ณํ ํ์ (๋ฏธ์ฐฉ์)
- ๊ตฌ์ฑ: EC2 ํฌํธ 8003 ํ
์คํธ ์๋น์ค + RDS
cmdboard_testDB. - ์ด์ : ์ด์(EC2 Ubuntu + pyenv 3.11.10)๊ณผ ๋์ผ ํ๊ฒฝ ๋ณด์ฅ. Windows ๋ก์ปฌ์ OS ์ฐจ์ดยทphase133 E2E HTTP ํธ์ถ ๊ตฌ์กฐ์ ๋ถ์ ํฉ.
- ๊ตฌ์กฐ:
Windows PC (Bridge)โEC2 :8002 (์ด์)โRDS cmdboardWindows PC (Bridge)โEC2 :8003 (ํ ์คํธ)โRDS cmdboard_test- ์์
๋ชฉ๋ก (๋ฏธ์ฐฉ์):
1. RDS โ SSM์์
cmdboard_testDB ์์ฑ + ์ ์ฒด ๋ง์ด๊ทธ๋ ์ด์ ์ ์ฉ 2. EC2 โ/home/ubuntu/cmdboard/.env.test์์ฑ (BOARD_DB_NAME=cmdboard_test, PORT=8003) 3. EC2 โcmdboard-test.servicesystemd ์๋น์ค ๋ฑ๋ก 4. ๋ณด์๊ทธ๋ฃน โ 8003 ์ธ๋ฐ์ด๋, Tailscale CIDR(100.64.0.0/10) ๋ด๋ถ๋ง ํ์ฉ 5. Bridge โ.env์CMDBOARD_API_BASE_TEST์ถ๊ฐ, ์ ํ ๋ฐฉ๋ฒ ์ ๋น - ๋ค์ ์์์ : ํ ์คํธ ์๋ฒ ๊ตฌ์ถ ์ฐฉ์ โ ์ดํ ๋ ๋ฒ1(stream-json) ๊ตฌํ ์ฝ๋ ์์.
๊ฐฑ์ 2026-05-23 (11) โ ํ ์คํธ ์๋ฒ ๊ตฌ์ถ ์งํ ์ค + ๋ง์ด๊ทธ๋ ์ด์ ๋ฒ๊ทธ ๋ฐ๊ฒฌ
์งํ ํํฉ (์ฝ๋ ์ง์๋ฌธ #1~#5)
- #1 ์ฌ์ ์ง๋จ: โ
์๋ฃ. EC2 ์ ์, ๋ง์ด๊ทธ๋ ์ด์
001~013 ์กด์ฌ, ์ด์ DB 17๊ฐ ํ
์ด๋ธ.
- #2 ํ
์คํธ ์๋ฒ ๊ตฌ์ถ ์๋: SG 8003(211.209.165.141/32) ์ถ๊ฐ โ
, ๋๋ ํฐ๋ฆฌยทvenv โ
.
- #3~#4 ๋ง์ด๊ทธ๋ ์ด์
๋ฒ๊ทธ ๋ฐ๊ฒฌ ๋ฐ ์ด์ DB ์ง๋จ.
- #5 mysqldump ๋ฐฉ์์ผ๋ก ์ฌ๊ตฌ์ฑ ์ค (๊ฒฐ๊ณผ ๋๊ธฐ).
๋ง์ด๊ทธ๋ ์ด์
๋ฒ๊ทธ (์ฅ๊ธฐ ์์ ํ์)
- USE cmdboard; ํ๋์ฝ๋ฉ โ 9๊ฐ ํ์ผ. ์ฐ๊ฒฐ ์ -D ์ต์
๋ฌดํจํ.
- TABLE_SCHEMA = 'cmdboard' ํ๋์ฝ๋ฉ โ 8๊ฐ ํ์ผ. information_schema ์กฐํ ์ ํญ์ ์ด์ DB ๊ธฐ์ค์ผ๋ก ํ๋จ โ ํ
์คํธ DB์์ ์ปฌ๋ผ ์ถ๊ฐ skip.
- WHEN DATABASE() <> 'cmdboard' THEN (SELECT ... WHERE 1/0) ์์ ๊ฐ๋ โ MySQL์์ 1/0=NULL๋ก ์๋ฌ ๋ฏธ๋ฐ์, ๊ฐ๋ ๋ฌด๋ ฅํ.
- ์ด์ DB ์ํฅ ์์: idempotent ๊ฐ๋ + ํ๋์ฝ๋ฉ์ด ์ด์(=cmdboard)์์๋ ์ ํํ ๋์. ์ด์ ์คํค๋ง ์ ์ ํ์ธ.
- ์์ ๋ฐฉํฅ: USE ์ ๊ฑฐ / DATABASE() ๊ธฐ๋ฐ์ผ๋ก ๊ต์ฒด / ๊นจ์ง ๊ฐ๋ ์ ๊ฑฐ โ ๋ณ๋ PR(์ง์๋ฌธ #6 ์์ ).
ํ
์คํธ ์๋ฒ ๊ตฌ์ฑ ํ์ ์
- EC2 :8003 + RDS cmdboard_test (mysqldump --no-data ์คํค๋ง ๋ณต์ )
- BRIDGE_API_BASE ๋น์๋ (์ด์ Bridge ํ ์ถฉ๋ ๋ฐฉ์ง)
- systemd: cmdboard-test.service / ๋๋ ํฐ๋ฆฌ: /home/ubuntu/cmdboard-test/
๋ค์ ์์์ : #5 ๊ฒฐ๊ณผ ํ์ธ โ ํ
์คํธ ์๋ฒ ์ ์์ด๋ฉด #6(๋ง์ด๊ทธ๋ ์ด์
์๋ณธ ์์ PR) ์งํ.
๊ฐฑ์ 2026-05-23 (10) โ ์ฝ๋ ์ง์๋ฌธ ์ ๋ฌ ๋ชจ๋ + ์ด์ ๊ท์น ๋ณ๊ฒฝ
- ์ฝ๋ ์ง์๋ฌธ ์ ๋ฌ ๋ชจ๋ ์์ (์ฌ์ฉ์๊ฐ ํด์ ์ ์ธ ์๊น์ง ์ง์).
- ์ด์ ๊ท์น ๋ณ๊ฒฝ: ์ฝ๋ ์ง์๋ฌธ์ ํญ์
.mdํ์ผ๋ก ์์ฑ โC:\dev\cmdboard\instructions\์ ์ฅ, ์ฑํ ์๋ ํ์ผ๋ช ๋ง ํ๊ธฐ. - ๋ค์ ์ง์๋ฌธ: EC2ยทRDS ์ฌ์ ์ง๋จ(์ฝ๊ธฐ ์ ์ฉ) โ ๊ฒฐ๊ณผ ๊ธฐ๋ฐ์ผ๋ก ํ ์คํธ ์๋ฒ ๊ตฌ์ฑ ์ง์๋ฌธ ์์ฑ ์์ .
๊ฐฑ์ 2026-05-23 (12) โ ํ ์คํธ ์๋ฒ ๊ตฌ์ถ ์๋ฃ + ๋ก์ปฌ ์ ๋ฆฌ
ํ
์คํธ ์๋ฒ ๊ตฌ์ถ ์๋ฃ
- cmdboard-test.service active (running) โ Main PID 17045, gunicorn workers 2๊ฐ
- ํฌํธ 8003 LISTEN, /api/tasks HTTP 200, DB ์ฐ๊ฒฐ ์ ์
- cmdboard_test DB: 17๊ฐ ํ
์ด๋ธ (mysqldump ์คํค๋ง ๋ณต์ , ์ด์๊ณผ ๋์ผ)
- tasks.deleted_at ์ปฌ๋ผยทidx_tasks_deleted_at ์ธ๋ฑ์ค ํฌํจ ํ์ธ
์ด์ DB Soft Delete ์ํ ํ์ธ
- tasks.deleted_at DATETIME NULL MUL + idx_tasks_deleted_at BTREE ์ด๋ฏธ ์กด์ฌ
- ๊ด๋ จ ์ฝ๋(models.py / api/tasks.py / api/agent.py)๋ ์ด๋ฏธ master(78a029b)์ ๋ฐ์๋จ
- ์ถ๊ฐ ๋ง์ด๊ทธ๋ ์ด์
๋ถํ์ โ ํด๋ก์ฆ
๋ก์ปฌ ๋๊ธฐํ + ์ ๋ฆฌ (์ง PC)
- git pull โ Already up to date (์ฌ๋ฌด์ค ์์
์ด๋ฏธ ๋ฐ์)
- bridge/.env.before-* gitignore ๋ฑ๋ก (7bd116a)
- ๋ก์ปฌ ์ ์ฉ ํ์ผ gitignore + ์์ ์คํฌ๋ฆฝํธ 6๊ฐ ์ญ์ (c598ad7)
- ์ phase INSTRUCTION ํ์ผ ์ญ์ ๋ฐ์ (aa460f1) โ 6ํ์ผ, 3557 deletions
- git status ํด๋ฆฐ
์ด์ ํจํด ํ์ต (์ฌ๊ณ ๊ธฐ๋ก)
- PowerShell Remove-Item ์์ผ๋์นด๋๋ git ์ถ์ ์ฌ๋ถ ๋ฌด๊ด ๋งค์น โ ์ถ์ ์ค์ธ 247๊ฐ ์คํฌ๋ฆฝํธ ์ผ์ ์ญ์ ๋ฐ์
- ์ฆ์ git restore -- scripts/ ๋ก ์์ ๋ณต๊ตฌ, ๋ฐ์ดํฐ ์์ค ์์
- ํฅํ ์ญ์ ์ง์๋ฌธ ์์น: git ls-files --others --exclude-standard ํํฐ ์ฌ์ฉ
ํ์ฌ master: aa460f1
๋ค์ ์์์ : ์ฐจํ ์์
ํ๋ณด โ ๋ ๋ฒ1(stream-json) ๊ตฌํ ์ฝ๋ ์์ / ๋ง์ด๊ทธ๋ ์ด์
๋ฒ๊ทธ ์์ PR(USE ํ๋์ฝ๋ฉ ์ ๊ฑฐ) / ์นด๋ ์ญ์ ๋ฒํผ UI
๊ฐฑ์ 2026-05-23 (13) โ ๋ ๋ฒ1ยท๋ง์ด๊ทธ๋ ์ด์ ๋ฒ๊ทธ ์์ ยทํ ์คํธ ์๋ฒ ๋ณด์๊ทธ๋ฃนยทTailscale ์กฐ์ฌ
๋ ๋ฒ1 stream-json ์ ํ ์๋ฃ (commit 022f1f9)
- --output-format json โ --output-format stream-json --verbose
- _parse_stream_json ํฌํผ ์ถ๊ฐ (NDJSON ํ์ฑ, cache ํ ํฐ ํฌํจ)
- ๊ธฐ์กด ๋จ์ผ json.loads 5๊ณณ โ parsed ๊ฒฐ๊ณผ ์ฃผ์
๋ฐฉ์์ผ๋ก ๊ต์ฒด
- exit_code ์ค์ธก, input/output/total/cache_read/cache_write ํ ํฐ ์ค์ธก
- E2E ์ค์ธก: input=2, output=58, cache_write=19436
- ๋จ์ ํ
์คํธ bridge/tests/test_lever1_stream_json.py 5์ผ์ด์ค ALL PASS
๋ง์ด๊ทธ๋ ์ด์
๋ฒ๊ทธ ์์ ์๋ฃ (commit f8b60c0)
- USE cmdboard; 9๊ฐ ํ์ผ ์ ๊ฑฐ
- TABLE_SCHEMA='cmdboard' 33๊ฑด โ DATABASE() ๊ต์ฒด
- ๊นจ์ง ์์ ๊ฐ๋ 8๊ฐ ํ์ผ ์ ๊ฑฐ
ํ
์คํธ ์๋ฒ ๋ณด์๊ทธ๋ฃน (commit ์์ โ SG ์ง์ ๋ณ๊ฒฝ)
- 8003 ์ธ๋ฐ์ด๋: ์ง PC 112.170.234.238/32 + Tailscale CIDR 100.64.0.0/10 ์ถ๊ฐ
- ๊ณต์ธ IP ์ ์: http://13.209.147.168:8003 โ
Tailscale TCP ๋ฌธ์ (์ถํ ์กฐ์ฌ)
- tailscale ping/tsmp ์ฑ๊ณต, ์ค์ TCP ์ฐ๊ฒฐ ์คํจ
- ts-input rule 3 DROP(100.64.0.0/10) ์์ธ ํ๋ณด โ iptables ACCEPT ์ถ๊ฐ ํ์๋ ๋ฏธํด๊ฒฐ
- Bridge๋ ๊ณต์ธ IP(13.209.147.168:8002) ์ฌ์ฉ ์ค โ Tailscale ๋ฌด๊ดํ๊ฒ ๋์
ํ์ฌ master: f8b60c0
๋ค์ ์์์ : 3์์ โ ์นด๋ ์ญ์ ๋ฒํผ UI (ํ์ฌ API๋ง ๊ตฌํ, ํ๋ฉด ๋ฏธ๊ตฌํ)
๊ฐฑ์ 2026-05-23 (14) โ ์ ๋ํ๋ฐฉ ์ธ๊ณ ์ค๋น
๋ค์ ์์์ : Tier B ๊ตฌํ ์งํ ์ค
- ์์
ํธ๋์ปค ์ฐธ๊ณ : ๐ ์์
ํธ๋์ปค
ํ์ฌ master: 628c2e9 (์์ค์ปฌ๋ ์ดํธ ์ฑ๋)
์๋ฃ ๋ชฉ๋ก (์ด๋ฒ ์ธ์
)
- Tier A codi_result_v2 ๋ดํฌ join (commit 96dcada)
- chain_id migration (migrations/014_chain_id.sql)
- Job2 on-stop supervisor (commit acbe817)
- ํฌ๋ฆฌํฑ on-completion (commit e602906)
- ์์ค์ปฌ๋ ์ดํธ ์ฑ๋ notify-escalate + Bridge ์ฐ๊ฒฐ (9fd7fff + 628c2e9)
์งํ ์์ ์์
1. Tier B ๊ตฌํ โ ํ์ฌ ์์
(์ฝ๋ ์ง์๋ฌธ: codi_tierB.md)
2. Job1 ์ฑํ ํ๋จ (๋ฐ์ดํฐ ๊ฒ์ดํธ)
๋ณด๋ฅ
- ๋ ๋ฒ1 ์ค์ธก run ํ ํฐ baseline (Sara ๋ณต๊ตฌ ํ)
- per-chain ์ฒ์ฅ ์์น ํ์ (์ค์ธก ํ)
- ํ ํฐ ์์ฐ ์์น ํ์ (์ค์ธก ํ)
- Tailscale TCP ๋ฌธ์ ์ถํ ์กฐ์ฌ
- audit โ cmdboard E2E ๊ฒ์ฆ (mock ์ฒ๋ฆฌ๋ก ๋ฏธ์)
์ด์ ํจํด (์ด๋ฒ ์ธ์
ํ์ต)
- PowerShell Remove-Item ์์ผ๋์นด๋ โ git ls-files --others ํํฐ ํ์
- Bridge CMDBOARD_API_BASE: ๊ณต์ธ IP(13.209.147.168:8002) ์ฌ์ฉ (Tailscale IP ์ฃผ์)
- ์์
๋จ๊ณ๋ณ ์๋ฃ ์๋ง๋ค ๋ฉ๋ชจ๋ฆฌ + ์ธ์์ธ๊ณ์ + ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ ํ์ด์ง ๊ฐฑ์
๊ฐฑ์ 2026-05-23 (15) โ Soft Delete ์ ์ฒด ํ์ธ ์๋ฃ + ์ญ์ ๋ฒํผ UI ํํฉ ํ์
Soft Delete 4๋จ๊ณ ์ ๋ถ ์ด๋ฏธ ์๋ฃ (2026-05-05 ์์
๋ถ)
- Step 1: tasks.deleted_at DATETIME NULL MUL + idx_tasks_deleted_at BTREE โ RDS ์ด๋ฏธ ์ ์ฉ
- Step 2: feat(tasks): soft delete โ 3095521 ์ปค๋ฐ master ๋ฐ์
- Step 3: ์ด์ ์ค โ DB ์ด 91๊ฑด, active 5, soft_deleted 86 (์ ์ ๋์)
- Step 4: Bridge push โ 022f1f9 ์ปค๋ฐ master ๋ฐ์
- โ ์ถ๊ฐ ๋ง์ด๊ทธ๋ ์ด์
ยท๋ฐฐํฌ ๋ถํ์. ์์ ํด๋ก์ฆ.
์ญ์ ๋ฒํผ UI ํํฉ (์ฝ๋ ์ง๋จ)
- ์ญ์ ๋ฒํผ: app/static/js/app.js:4702-4703 โ renderTaskDetail() ๋ด "์ํ ์์
" row์ ์ด๋ฏธ ์กด์ฌ
- ํด๋ฆญ ํธ๋ค๋ฌ: app.js:5143-5152 โ confirm ํ DELETE /api/tasks/<task_code> ํธ์ถ (soft delete)
- ๋ณต์ ๋ค์ด์ผ๋ก๊ทธ: openDeletedTasksDialog() app.js:2087 โ #open-deleted-tasks ๋ฒํผ์ผ๋ก ํธ๋ฆฌ๊ฑฐ
- ์ฒดํฌ๋ฆฌ์คํธ ์ญ์ : app.js:5009-5014 โ DELETE /api/tasks/<code>/checklist/<id>
- ๊ฒฐ๋ก : UI ์์ฒด๋ ์ด๋ฏธ ๊ตฌํ ์๋ฃ. ๋ค์ ์์
์ UX ๊ฐ์ (์์นยท๋ฌธ๊ตฌยทํด์งํต ํ๋ฉด) ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ ๊ฒ.
๋ค์ ์์์ : ์ญ์ ๋ฒํผ UI ๊ฐ์ ๋ฒ์ ๊ฒฐ์ (ํํ ์ ์ง / ์์นยท๋ฌธ๊ตฌ ๋ณ๊ฒฝ / ํด์งํต ํ๋ฉด ์ถ๊ฐ)
๊ฐฑ์ 2026-05-23 (16) โ ์์ด์ ํธ ํ์ดํ๋ผ์ธ ๊ตฌํ ์๋ฃ + Tier B ์งํ ์ค
์๋ฃ (์ด๋ฒ ์ธ์
)
- Tier A codi_result_v2 ๋ดํฌ join โ _join_codi_runner_audit_metadata() 13ํค, commit 96dcada
- chain_id migration โ migrations/014_chain_id.sql, ์ด์ยทํ
์คํธ RDS ์ ์ฉ
- Job2 on-stop supervisor โ bridge/app/services/supervisor.py, 8์ข
ํ๋ ํ๋จ+๊ธฐ๋ก, commit acbe817
- ํฌ๋ฆฌํฑ on-completion โ judge_completion(), exit_code=0 ๋ถ๊ธฐ, commit e602906
- ์์ค์ปฌ๋ ์ดํธ ์ฑ๋ โ POST /tasks/<code>/notify-escalate, CHATI_ANSWER_CARDS_DISABLED ๋ถ๋ฆฌ, Bridge ์ฐ๊ฒฐ, commit 628c2e9
- ์์
ํธ๋์ปค DB ์ ์ค, ์ต์ปค ๋งํฌ ์ ์ฒด ์ ์ฉ (notion-anchor-mcp)
ํ์ฌ ์งํ ์ค
- Tier B ๊ตฌํ (์ฝ๋ ์ง์๋ฌธ: codi_tierB.md)
- failed_attempts (stream-json ์ถ์ถ)
- chain_context (chain_id + rollup ์๋ฆฌ)
- supervisor mode enum
- ์ฑํฐ ํ ํฐ ์ค์ธก
๋ค์ ์์์ : Tier B ์๋ฃ ๋ณด๊ณ ์์ โ Job1 ์ฑํ ํ๋จ (๋ฐ์ดํฐ ๊ฒ์ดํธ)
ํ์ฌ master: 628c2e9
๊ฐฑ์ 2026-05-24 (17) โ Tier B ์๋ฃ + migration 015 RDS ์ ์ฉ
Tier B ๊ตฌํ ์๋ฃ (commits: cmdboard 521a6f2 / bridge 8b9f678)
- failed_attempts: ๊ธฐ๊ตฌํ ํ์ธ (codi_runner_cli.py:72-95) โ ๋ณ๋ ์์
์์
- chain_context 3ํค ๋ดํฌ ์ถ๊ฐ: chain_id (tasks ์ง์ ์กฐํ) / chain_card_count / chain_total_calls (None โ rollup ์ถํ)
- supervisor mode enum: migrations/015_supervisor_mode.sql โ ActivityLog.mode์ 'supervisor' ์ถ๊ฐ (๊ธฐ์กด 5์ข
๋ณด์กด)
- cmdboard_client.add_task_log์ mode ํ๋ผ๋ฏธํฐ ์ถ๊ฐ (๊ธฐ๋ณธ 'sara')
- supervisor.py / critic audit ์ mode='supervisor' ์ ๋ฌ
- claude_client.chat ์๋ต์ ํ ํฐ 5์ข
+ stop_reason + num_turns + token_usage_status ๋
ธ์ถ
migration 015 RDS ์ ์ฉ ์๋ฃ
- ํ
์คํธ RDS (cmdboard_test) โ ์ด์ RDS (cmdboard) ์์๋ก ALTER ์คํ
- ์์ชฝ activity_logs.mode enum: ('chati','codi','coki','manual','sara','supervisor') ํ์ธ
- supervisor.py์ mode='supervisor' INSERT ์ด์ enum ๊ฑฐ๋ถ ์์ด ์ ์ ๋์
๋ฏธ์ (ํ์ ์์
)
- ์ฑํฐ ํ ํฐ โ activity_log ๊ธฐ๋ก ์ฐ๋: ํธ์ถ ์ธก 7๊ณณ ์์ ํ์ (๋ณ๋ ์์
)
- chain rollup (chain_card_count / chain_total_calls) ๊ตฌํ (ํ์)
ํ์ฌ master: 8b9f678 (bridge) / 521a6f2 (cmdboard)
๋ค์ ์์์ : Job1 ์ฑํ ํ๋จ (๋ฐ์ดํฐ ๊ฒ์ดํธ)
๊ฐฑ์ 2026-05-24 (18) โ Tier B ๋ฐฐํฌ + migration 015 + ํ ์คํธ ์๋ฒ ์ค์ธก ํ๊ฒฝ ์ ๋น
์๋ฃ
- Tier B ๊ตฌํยท๋ฐฐํฌ (cmdboard 521a6f2 / bridge 8b9f678): chain_context 3ํค, supervisor mode enum, ์ฑํฐ ํ ํฐ ์๋ต ํค, failed_attempts(๊ธฐ๊ตฌํ ํ์ธ)
- migration 015 RDS ์ ์ฉ: ํ
์คํธโ์ด์ ์์, activity_logs.mode enum์ 'supervisor' ์ถ๊ฐ ํ์ธ
- ํ
์คํธ ์๋ฒ ํ๋ก์ ํธ ์๋ ํฌ์
(์ด์โํ
์คํธ projects ๋ณต์ฌ)
- Bridge ์์ ์ ํ (8002โ8003): ์ฑํฐ ์๋ ํ์ธ
ํ
์คํธ ์๋ฒ 500 ์๋ฌ ํด๊ฒฐ ์งํ ์ค
- ์ฆ์: ์ฑํฐ๊ฐ mode='supervisor' ๋ก๊ทธ INSERT ์ฑ๊ณต(DB enum ํ์ฉ) โ ์นด๋ GET ์ to_dict lazy load์์ enum ๋์ฝ๋ฉ LookupError โ 500
- ๊ทผ๋ณธ ์์ธ: ํ
์คํธ ์ฝ๋๊ฐ master(521a6f2) ๋ฏธ๋ฐ์ (6ddb458 phase134์ ์ ์ฒด). ๋ชจ๋ธ enum์ด ๊ตฌ๋ฒ์ ์ด๋ผ supervisor ๋์ฝ๋ฉ ๋ถ๊ฐ
- ์์ : cmdboard-test git pull๋ก master ๋๊ธฐํ โ ์๋น์ค ์ฌ์์ (์ฝ๋ ์ง์๋ฌธ ์ ๋ฌ, ์๋ฃ ๋ณด๊ณ ๋๊ธฐ)
ํต์ฌ ํ์ต (ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ ๋ฐ์)
- ํ
์คํธ ์๋ฒ ์ฝ๋ ๋๊ธฐํ๋ ์๋(์๋๋ฐฐํฌ๋ ์ด์๋ง). ๋ฏธ๋๊ธฐํ ์ DB๋ ๋ง์๋ ๋ชจ๋ธ enum/์ปฌ๋ผ ๋ถ์ผ์น๋ก 500
- mysqldump --no-data๋ ์๋ ์์ โ projects ๋ฑ ๋ณ๋ ๋ณต์ฌ ํ์
- Bridge๋ ๋จ์ผ ํ๊ฒ๋ง ํด๋ง โ ํ
์คํธ ์นด๋ ์ฒ๋ฆฌํ๋ ค๋ฉด ์์ ์ ํ ํ์
๋ฏธ์ (Job1 baseline ์ ํ ๊ณผ์ )
- ์ฑํฐ ํ ํฐ โ activity_log ๊ธฐ๋ก ์ฐ๋ (ํธ์ถ ์ธก 7๊ณณ) โ ๋ฏธ์ฐ๋์ด๋ผ ํ์ฌ ์ฑํฐ ํ ํฐ์ด ์ด๋์๋ ์์ ๊ธฐ๋ก ์ ๋จ
- chain rollup (card_count/total_calls)
- Bridge 8002 ๋ณต๊ท (์ธก์ ํ)
ํ์ฌ master: cmdboard 521a6f2 / bridge 8b9f678
๋ค์ ์์์
1. ํ
์คํธ ์๋ฒ ๋๊ธฐํ ์๋ฃ ๋ณด๊ณ โ ์ฑํฐ ์ฌ์คํ + 500 ํด์ ํ์ธ
2. Job1 baseline ์ํ ํ ํฐ ๊ธฐ๋ก ๊ฒฝ๋ก ๊ฒฐ์ (A: ๋ก๊ทธ 1ํ grep / B: activity_log ์ฐ๋ ๋จผ์ )
3. Job1 ์ฑํ ํ๋จ (๋ฐ์ดํฐ ๊ฒ์ดํธ: ํ ํฐ ๋ถํฌ + failed_attempts ๋๋ฆฌํํธ ๋น๋)
๊ฐฑ์ 2026-05-24 (19) โ ๋ฌถ์1 ์๋ฃ + ํ์ดํ๋ผ์ธ E2E ๊ฒ์ฆ + Job1 baseline ์ฒซ ์ค์ธก (์์จ ์งํ๋ถ)
์์
๋ฐฉ์: ์ฌ์ฉ์ ์๋ฆฌ ๋น์ ๋์ ์ฑํฐ๊ฐ claude-code:Bash โ AWS SSM send-command๋ก ์ง์ ์คํ (Agent spawn ๋ฏธ์ง์). ์์ ์ (pfs/deploy-live/์ด์DB ํ๊ดด) ์ ์ง.
๋ฌถ์1 ์๋ฃ โ ํ
์คํธ ์๋ฒ 500 ํด์
- cmdboard-test git reset --hard origin/master โ HEAD 8b9f678, models.py supervisor enum ๋ฐ์
- ์๋น์ค env ํ์ผ์ .env(NOT .env.test) โ ์๋น์ค ์ฌ์์ ํ ์นด๋ GET 200, modes=[sara, supervisor]
- ์ฑํฐ ์๋ ์ฒ๋ฆฌ ์ฌ๊ฐ โ ์ฝ๋ ์คํ๊น์ง E2E ์ ์ ํ๋ฆ ํ์ธ
ํ์ดํ๋ผ์ธ E2E ๊ฒ์ฆ (์ค์๋ฒ ์ฒซ ํ์ธ)
- ์ฑํฐ ๋ถ์ โ next_codi โ ์ฝ๋ ์คํ(completed) โ codi_result_reported โ agent_token_usage_recorded โ critic_decision (mode=supervisor)
- migration 015 + Tier B supervisor mode๊ฐ ์ค์๋ฒ์์ ์ ์ ๋์ ํ์ธ
Job1 baseline ์ฒซ ์ค์ธก (์ฝ๋ run 1๊ฑด)
- run_id ccli-20260523-181040: total 1024(in 6/out 1018), cache_read 126702, cache_write 12869, step_count 8, failed_attempts 1, usage_status known, source claude_cli_stream_json
- ์ฑ๊ณต run์๋ failed_attempts=1 โ ๋๋ฆฌํํธ ์ค์ฌ. ๋จ 1๊ฑด์ด๋ผ ๋น๋ ๋ฏธํ์ (N๊ฑด ํ์)
ํต์ฌ ๋ฐ๊ฒฌ
- ํ ํฐ ์ค์ธก์ agent_token_usage_recorded ๋ก๊ทธ(payload)์ ๊ธฐ๋ก๋จ. codi_result payload์ token ํค๋ NULL(run_id ๋งค์นญ ์ ๋จ). ์นด๋ ์นฉ token_total์ ์ฌ์ ํ mock=0
- ๊ธฐ๋ก ํต๋ก: add_task_log(action='agent_token_usage_recorded') โ admin_usage_stats ์๋ ์ง๊ณ
๋ฌถ์2 ์ค๊ณ ํ์ (์ฑํฐ ํ ํฐ โ activity_log, B ๊ฒฝ๋ก)
- ์ฑํฐ chat() ์๋ต ํ ํฐ์ ์ฝ๋์ ๋์ผ ๋ฉ์ปค๋์ฆ(agent_token_usage_recorded)์ผ๋ก ๊ธฐ๋ก
- payload: agent='chati', model, input/output/total/cache_, usage_status
- ์์ ๋ฒ์: chat() ํธ์ถ 7๊ณณ ์ค task_code ์๋ ํ๋ฆ(supervisorยทchati). ์ ํ
์ด๋ธ/์๋ํฌ์ธํธ ๋ถํ์
- ์ด์ ๋ฐฐํฌ(master push) ๋๋ฐ โ ์ฌ์ฉ์ ๋ณต๊ท ํ ์น์ธ ๊ถ๊ณ
ํ์ฌ ์ํ ์ฃผ์
- Bridge๋ ์์๋ก 8003(ํ
์คํธ) ํด๋ง ์ค โ ์ด์(8002) ์์
๋ฉ์ถค. ์ธก์ ์๋ฃ ํ 8002 ๋ณต๊ท ํ์
๋ค์ ์์์ *
1. ๋ฌถ์2 ๊ตฌํ(์ฑํฐ ํ ํฐ ์ฐ๋) ์น์ธ โ ๊ตฌํยท๋ฐฐํฌ
2. ์ค์ธก run N๊ฑด ๋ฐ๋ณต โ ํ ํฐ ๋ถํฌ + failed_attempts ๋น๋ ์์ง
3. Job1 ์ฑํ ํ๋จ
4. Bridge 8002 ๋ณต๊ท
๊ฐฑ์ 2026-05-24 (20) โ ๋ฌถ์2 ์๋ฃ: ์ฑํฐ ํ ํฐ โ activity_log ์ฐ๋ (๋ก์ปฌ ๊ตฌํยท๊ฒ์ฆ, ๋ฏธ๋ฐฐํฌ)
๊ตฌํ (bridge/app/services/chati.py, ๋ก์ปฌ๋ง โ master push ์ ํจ)
- chat ์๋ต ํ ํฐ 0/0 ํ๋์ฝ๋ฉ ์ ๊ฑฐ โ chat_resp์ input/output/total/cache_/usage_status ์ค์ธก ์ถ์ถ
- analysis ๋ก๊ทธ ์งํ agent_token_usage_recorded(action) ๊ธฐ๋ก ์ถ๊ฐ โ ์ฝ๋(codi_runner_cli)์ ๋์ผ ๋ฉ์ปค๋์ฆ ์ฌ์ฌ์ฉ, agent='chati', source='claude_agent_sdk', best-effort try/except
- ์ ํ
์ด๋ธยท์๋ํฌ์ธํธ ๋ถํ์: cmdboard admin_usage_stats / tasks.py ํ ํฐ ์ง๊ณ๊ฐ ๊ทธ๋๋ก ์ธ์
๊ฒ์ฆ (ํ
์คํธ 8003, ์ ๊ท ์นด๋ pfs-2026-34)
- AST ํ์ฑ OK โ Bridge ์ฌ์์(์์
์ค์ผ์ค๋ฌ) โ ์นด๋ ์์ฑ โ ์ฑํฐ ์๋ ์ฒ๋ฆฌ
- agent_token_usage_recorded id 7723: agent=chati, input 21/output 2227/total 2248, cache_read 93845, usage_status=known
- ์นด๋ token_total ์นฉ: mock=0 โ ์ค์ธก 2248(2.2k), source=agent_runs (mock ํ์ถ ํ์ธ)
Job1 baseline ์ค์ธก ๋์ ์์ (ํ์ฌ 2๊ฑด)
- codi run ccli-...93e0d5ed: total 1024, cache_read 126702, failed_attempts 1
- chati run 467: total 2248, cache_read 93845 (์ฑํฐ๋ failed_attempts ๋ฏธํด๋น)
๋ฏธ์ / ํ์
- chati.py ์ธ chat() ํธ์ถ 6๊ณณ(chat_consumer/chati_chat_consumer/supervisorร2/chat router) ํ ํฐ ์ฐ๋ โ ๋ฉ์ธ ๋ถ์ ํ๋ฆ ์ฐ์ ๊ตฌํ, ๋๋จธ์ง๋ ํ์ ์ ๋์ผ ํจํด ํ์ฅ
- ์ด์ ๋ฐฐํฌ(master push): ์ฌ์ฉ์ ์ง์๋๋ก ๊ฐ์ฅ ๋ง์ง๋ง์. ํ์ฌ ๋ก์ปฌ ์ปค๋ฐ๋ ๋ฏธ์คํ
- chain rollup (card_count/total_calls)
ํ์ฌ ์ํ
- Bridge: ์์ 8003 ํด๋ง ์ ์ง ์ค (์ด์ 8002 ๋ฉ์ถค). ๋์ผ ํ๊ฒ/์ ํ ์ฉ์ดํ ๋ฐฉ์์ ๋ค์ ๋
ผ์ ์์
- ๋ก์ปฌ bridge ์ฝ๋ ๋ณ๊ฒฝ ์์(๋ฏธ์ปค๋ฐ)
๋ค์ ์์์ *
1. Bridge ๋์ผ ํ๊ฒ(8002+8003) ๋๋ ์ ํ ์ฉ์ดํ ๋ฐฉ์ ์ค๊ณ
2. ์ค์ธก run N๊ฑด ๋ฐ๋ณต ์์ง (ํ ํฐ ๋ถํฌ + failed_attempts ๋น๋)
3. Job1 ์ฑํ ํ๋จ
4. (์ต์ข
) ์ด์ ๋ฐฐํฌ
๊ฐฑ์ 2026-05-24 (21) โ 2nd Bridge(ํ ์คํธ 8766) ๊ตฌ์ฑ + ํธ๋ ์ด ํตํฉ
ํ
์คํธ ์ ์ฉ 2nd Bridge (๋ฌถ์3)
- ํด๋ C:\dev\cmdboard\bridge-test, ํฌํธ 8766, ์์
CmdboardBridgeTest(AtLogOn ์๋์์), ํด๋ง ํ๊ฒ :8003
- ์ด์ Bridge๋ 8002 ๋ณต๊ท. ๋ Bridge ํ๊ฒ ๋ถ๋ฆฌ(์ด์ :8002 / ํ
์คํธ :8003)๋ก ์นด๋ ์ค๋ณต claim ์์
- ํฌํธ๊ฐ BRIDGE_PORT env๋ก ๋ถ๋ฆฌ๋ผ ์์ด ์ฝ๋ ์์ ์์ด .env + ์์
๋ช
๋ง ๋ณ๊ฒฝ
ํธ๋ ์ด ํตํฉ (๋จ์ผ ์์ด์ฝ)
- bridge/scripts/bridge_tray.ps1 ์ฌ์์ฑ: $Script:Instances์ prod(8765/CmdboardBridge/:8002)ยทtest(8766/CmdboardBridgeTest/:8003) ์ ์
- ํจ์ ์ผ๋ฐํ: Test-BridgeHealth/Invoke-CheckStatus/Invoke-RestartBridge/Invoke-ForceKillBridge/Open-LogsFolder๊ฐ -Inst ํด์ํ
์ด๋ธ ์์
- ๋ฉ๋ด 2์น์
: [โ ์ด์ Bridge (8765 โ :8002)] ํค๋+5ํญ๋ชฉ / [โ ํ
์คํธ Bridge (8766 โ :8003)] ํค๋+5ํญ๋ชฉ / diagnostics(์ด์) / ํธ๋ ์ด ์ข
๋ฃ. ํด๋ก์ ์บก์ฒ ๋ฒ๊ทธ ํํผ์ฉ ToolStripMenuItem.Tag์ ์ธ์คํด์ค ์ ์ฅ
- tooltip ํตํฉ "Bridge ์ด์:OK ํ
์คํธ:OK"(63์ ์ ํ ์์ ), HealthTimer ์ธ์คํด์ค๋ณ ์ถ์
- ํ
์คํธ ์ ์ฉ ํธ๋ ์ด CmdboardBridgeTrayTest ํ๊ธฐ (๋ณธ์ฒด CmdboardBridgeTest 8766์ ์ ์ง)
๊ฒ์ฆ
- ํธ๋ ์ด ํ๋ก์ธ์ค 1๊ฐ(PROD only) / health 8765=200ยท8766=200
- ๊ฒฉ๋ฆฌ ์ฌ์์: CmdboardBridgeTest ์ ์ง ์ค 8765=200 ์ ์ง โ ์ด์ ๋ฌด์ํฅ ํ์ธ
- ์์
์ํ: CmdboardBridge Running, CmdboardBridgeTest Running, CmdboardBridgeTray Ready, CmdboardBridgeTrayTest ์์
์ด์ ํจํด ํ์ต (ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ ๋์)
- PowerShell ํธ๋ ์ด ps1์ BOM ํ์(ํ์ 1์ฐจ ์คํจ โ BOM ์ถ๊ฐ ํด๊ฒฐ)
- ๋ฉ๋ด ํธ๋ค๋ฌ ํด๋ก์ ์บก์ฒ๋ ๋ฃจํ ๋ณ์ ๋์ ToolStripMenuItem.Tag ์ฌ์ฉ
ํ์ฌ ์ํ
- Bridge: ์ด์ 8002 / ํ
์คํธ 8003 ๋ถ๋ฆฌ ์๋ฃ. ํธ๋ ์ด ๋จ์ผ ํตํฉ
- ๋ก์ปฌ chati.py(์ฑํฐ ํ ํฐ ์ฐ๋) ๋ฏธ์ปค๋ฐ ์ ์ง. ์ด์ ๋ฐฐํฌ ์ต์ข
๋จ๊ณ๋ก ๋ณด๋ฅ
๋ค์ ์์์
1. baseline ์์ง โ ํ
์คํธ ์ธ์คํด์ค๋ก ์นด๋ N๊ฑด โ ํ ํฐ ๋ถํฌ + failed_attempts ๋น๋
2. Job1 ์ฑํ ํ๋จ
3. (์ต์ข
) ์ด์ ๋ฐฐํฌ
๊ฐฑ์ 2026-05-24 (22) โ ์ ๋ํ๋ฐฉ ์ธ๊ณ ์ค๋น (๊ตฌ๋ฒ์ ยท ์ด๋ ฅ)
์ง๊ธ ์ํ ์ค๋ ์ท
- master: cmdboard
521a6f2/ bridge8b9f678 - Bridge: ์ด์ 8765โ:8002 / ํ ์คํธ 8766โ:8003 ๋ถ๋ฆฌ ์๋ฃ. ํธ๋ ์ด ๋จ์ผ ํตํฉ(์ด์/ํ ์คํธ 2์น์ ). ๋ ๋ค AtLogOn ์๋์์
- ํ ์คํธ ์๋ฒ: EC2 :8003 + DB cmdboard_test, master ๋๊ธฐ ์๋ฃ(500 ํด์). DB enum์ supervisor ํฌํจ(migration 015 ์ด์ยทํ ์คํธ ์ ์ฉ)
- ๊ณ์ธก: ํ ํฐ ์ค์ธก์ด
agent_token_usage_recorded๋ก๊ทธ payload์ ๊ธฐ๋ก๋จ (์ฝ๋=stream-json, ์ฑํฐ=SDK). ์นด๋ ์นฉ mock ํ์ถ ํ์ธ - ๋ฏธ์ปค๋ฐ:
bridge/app/services/chati.py์ฑํฐ ํ ํฐ ์ฐ๋ โ ๊ฒ์ฆ ์๋ฃ, ์ด์ ๋ฐฐํฌ๋ ๊ฐ์ฅ ๋ง์ง๋ง(์ฌ์ฉ์ ์ง์) - baseline ๋์ (2๊ฑด): ์ฝ๋ total 1024/failed_attempts 1 ยท ์ฑํฐ total 2248(์ฑํฐ๋ failed_attempts ๋ฏธํด๋น)
์งํ ๋ชจ๋
- ์ฝ๋ ์ง์๋ฌธ ์ ๋ฌ ๋ชจ๋ (์ฌ์ฉ์ ํด์ ์ ์ธ ์๊น์ง). ๋ชจ๋ ์ง์๋ฌธ
.md๋ก๋ง, ์ฑํ ์ ํ์ผ๋ช +์์ฝ - ์์ ์ : pfs / deploy-live / ์ด์ DB ํ๊ดด์ ๋ณ๊ฒฝ ์ ๋ ๊ธ์ง
๋ค์ ์์์ (์ฐ์ ์์)
- baseline ์์ง (์งํ ์ง์ ) โ ํ์ค ์นด๋ 10๊ฑด. ์ง์๋ฌธ
codi_baseline_collect.md์ ๋ฌ๋จ, ์๋ฃ ๋ณด๊ณ ๋๊ธฐ. ์ฑํฐ/์ฝ๋ ํ ํฐ ๋ถํฌ + ์ฝ๋ failed_attempts ๋น๋ ์ง๊ณ (์ฝ๋ run ์ต์ 5๊ฑด ๊ถ์ฅ) - Job1 ์ฑํ ํ๋จ โ ๊ฒ์ดํธ ์กฐ๊ฑด: ๋ ๋ฒ1 ํ ํฐ ์ค์ธก(์๋ฃ) + failed_attempts ๋๋ฆฌํํธ ๋น๋(์์ง ์ค). ๋ฐ์ดํฐ ๋ณด๊ณ ํ ์ฑํ/๋ณด๋ฅ ๊ฒฐ์
- (์ต์ข ) ์ด์ ๋ฐฐํฌ โ ๋ฏธ์ปค๋ฐ chati.py + ๊ทธ๊ฐ ๋ก์ปฌ ๋ณ๊ฒฝ ์ผ๊ด master push
ํ์ค ์นด๋ ์ ์ (baseline์ฉ)
- ๋์ผ ๋์ด๋ยท๋ฌดํดยท๋ฉฑ๋ฑ. description: "์ฝ๊ธฐ ์ ์ฉ git ์กฐํ๋ง, ์ฝ๋ ๋ณ๊ฒฝ/์ปค๋ฐ/push ๊ธ์ง". baseline-์ธก์ -01~10
- ๊ฐ๋: ์ฝ๋ ๋๋ฌ 0๊ฑด์ด๋ฉด ์ค๋จยท๋ณด๊ณ (์ฑํฐ๊ฐ done์ผ๋ก๋ง ๋๋๋ฉด description ์ฌ์ค๊ณ), cycle_limit/hold ๋ฃจํ ์ ํด๋น ์นด๋ ์คํต
์ธ๊ณ ๋ฐฉ๋ฒ
- ์ ๋ํ๋ฐฉ์ ์ด ํ๋ก์ ํธ ์์์ ์ด๊ณ , ์ด ์ธ์์ธ๊ณ์(ํนํ ๊ฐฑ์ 22) + ๐ง ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ(๋ ํผ๋ฐ์ค) ํ์ด์ง๋ฅผ ๋จผ์ ์ฝ๊ฒ ํ ๊ฒ
- ์์ ํธ๋์ปค: ๐ ์์ ํธ๋์ปค ํ์ด์ง ์ฐธ์กฐ
๊ฐฑ์ 2026-05-24 (23) โ baseline ์์ง ์๋ฃ + ํธ๋์คํ read-only fix + Job1 ๋ณด๋ฅ ๊ฒฐ์ (๊ตฌ๋ฒ์ ยท ์ด๋ ฅ)
์ง๊ธ ์ํ ์ค๋ ์ท
- master: cmdboard
521a6f2/ bridge8b9f678 - ๋ฏธ๋ฐฐํฌ(๊ฒ์ฆ์๋ฃ, ์ด์ push ๋๊ธฐ 2๊ฑด): (a) ํธ๋์คํ read-only
no_deployfix (tasks.py+admin_autorun_debug.py+ ๊ฒ์ฆ ์คํฌ๋ฆฝํธ) (b) ์ฑํฐ ํ ํฐ ์ฐ๋chati.py(๊ฐฑ์ 20) - Bridge: ์ด์ 8765โ:8002 / ํ ์คํธ 8766โ:8003 ๋ถ๋ฆฌ ์ ์ง, ํธ๋ ์ด ๋จ์ผ ํตํฉ
- ์งํ ๋ชจ๋(ํ์ฌ): ์ฑํฐ๋ claude-code ๋๊ตฌ ์ฌ์ฉ ๊ธ์ง. ์ฝ๋ ์ง์๋ฌธ์ ์ฌ์ฉ์์๊ฒ
.mdํ์ผ๋ก ์ ๋ฌ(์ฑํ ์ ํ์ผ๋ช +์์ฝ). ์์ ์ pfs/deploy-live/์ด์DB ํ๊ดด ๊ธ์ง.
baseline ์์ง ์๋ฃ (ํ์ค ์นด๋ 10๊ฑด pfs-2026-35~44, read-only git ์กฐํ)
- agent ํ ํฐ ๋ถํฌ: ์ฑํฐ 10run avg_total 4605 / ์ฝ๋ 11run avg_total 1001 (์ฑํฐ ~4.6๋ฐฐ). cache_read ์ฑํฐ~145K ยท ์ฝ๋~85K (๋ ๋ค ์บ์ ํ๋ฐ)
- ์ฝ๋ failed_attempts ๋ถํฌ: [0ร9, 2, 3] โ ์ ๋ถ
pfs-2026-44ํ ์นด๋(2ํ retry)์ ์ง์ค. zero-failed 9/11 - ์ฑํฐ-only ์ข ๋ฃ 0๊ฑด (git ์กฐํ description์ด NEXT=codi ์ ๋ ์ฑ๊ณต). run ์ค์๊ฐ 3 step
- ์ ์ ์ผ์ด์ค ์ฝ๋ ํ ํฐ ์ค์๊ฐ ~400 (read-only baseline)
ํธ๋์คํ read-only fix (๊ฒ์ฆ์๋ฃ, ๋ฏธ๋ฐฐํฌ)
- ๊ทผ๋ณธ์์ธ: read-only ์๋ฃ ์นด๋๋
deploy_status='unknown'โ validator๊ฐcompleted์ deploy_status ํ์ ์๊ตฌ โ handoff invalid โ ์ฑํฐ ๊ฒฐ๊ณผ ๋ฏธ์์ (chati_reanalysis_skipped handoff_payload_invalid). baseline ์นด๋ ์ ์ฒด ํด๋น - ์์ :
_build_codi_result_handoff_payload์no_deploy๋ถ๊ธฐ(changed_files์์ + not pushed) โdeploy_status='no_deploy'.admin_autorun_debug๋ณ๋ชฉdeploy_state_missing๋ ๋๋ฐ ์ ์ธ. validator ๋ณธ๋ฌธ ๋ถ๋ณ(๋น๋๊ฐ ์ฌ์ค ์ ์ ) - ๊ฒ์ฆ: ๋จ์ A/B/C 3/3 PASS(๋ก์ปฌ+ํ
์คํธ์๋ฒ), E2E
pfs-2026-46โpending_chati_requests #485no_deploy+pendingํ์ ํ์ธ - ์์ฌ:
codi_done์์ transient ์ด๋ฅธ-fire skip 1๊ฑด(result=None, ๋ฌดํด) โ ์ ํ์ ์ ๋ฆฌ ํ์์ - ๋ณ๊ฒฝ ํ์ผ:
app/api/tasks.py/app/api/admin_autorun_debug.py/scripts/_test_handoff_readonly_no_deploy.py
Job1 ์ฑํ ํ๋จ = ๋ณด๋ฅ ์ ์ง (๋ฐ์ดํฐ ๊ฒ์ดํธ ๊ฒฐ๊ณผ)
- ๊ฒ์ดํธ(failed_attempts ๋๋ฆฌํํธ ๋น๋): 1์นด๋ ์ง์ค + run ์ค์๊ฐ 3 step โ per-checkpoint LLM ์ด๋ < ๋น์ฉ. Job2(on-stop)+critic(on-completion)+retry chain์ด ์ด๋ฏธ ๊ทธ 1๊ฑด ์ปค๋ฒ
- ๋จ ํ๋ณธ์ด read-only ์งง์ run ํธํฅ โ ์ค์์ (์ฝ๋๋ณ๊ฒฝ/๊ธด run) baseline ์์ง ํ ์ฌ๊ฒ์ดํธ ์กฐ๊ฑด๋ถ
- ๊ถ๊ณ : Job1 ๋์
๋ณด๋ค
pfs-2026-44๋จ์ผ ์ด์์น(2ํ retry ๋ชจ๋ failed>0, done-but-codi_failed ์ข ๋ฃ) ๊ฐ๋ณ ์ง๋จ
pending_question ์ง๋จ ์ข ๊ฒฐ
- ์์ ์น์ธ(
dangerous_command_detected,git status) grouped ๋ชจ๋ ์ ์ consume.task_questions0๊ฑด, ๊ฐ๋ #4 ๋ง์ ํ์ ์์ โ ๋น์ด์
๋ค์ ๋ฐฉํฅ (์ฌ์ฉ์ ์ ๊ท ์ง์ โ On the horizon)
- ์ฌ์ฉ์-์ฑํฐ ๋ํ๋ฐฉ ์ ๋ฉด ๊ฐํธ: ๋ถํ์ํ ๋ณ๋ ๋ต๋ณ ์ ๋ ฅ์ฐฝ ์ญ์ + Claude ๋ฐ์คํฌํฑ ์ ์ฌํ๊ฒฝ(claude-code ๋๊ตฌ ์ ๊ทน ํ์ฉ)์ผ๋ก ๊ต์ฒด ์งํฅ
- ์ฑํฐ-์ฝ๋ ์๋์ํ ์์ ์์คํ ์ฒ ์ ์ฌ๊ฒ์ฆ
- (๋๊ธฐ) ์ด์ ๋ฐฐํฌ โ ๋ฏธ๋ฐฐํฌ 2๊ฑด ์ผ๊ด master push (์ฌ์ฉ์ ์น์ธ ์)
- (์ ํ)
pfs-2026-44์ด์์น ๊ฐ๋ณ ์ง๋จ
๊ฐฑ์ 2026-05-24 (24) โ ํ์ฉ์น bypass ํ์ค ํ ์คํธ ์ ์ฉ + ์๋์ํ silent block ์ง๋จ(์งํ ์ค) (๊ตฌ๋ฒ์ ยท ์ด๋ ฅ โ ๊ฐฑ์ 25๋ก ๋์ฒด๋จ)
์งํ ๋ชจ๋ (ํ์ฌ)
- ์ฑํฐ๊ฐ claude-code ๋๊ตฌ ์ง์ ์ฌ์ฉ ํ์ฉ โ ํ
์คํธ ์๋ฒ ํ์ SSM/ํ์ผ ์ง์ ์์
์ฑ๋ ํ๋ฆฝ(
aws ssm send-command, Online/Ubuntu ํ์ธ). ์ด์(8002)ยทmaster ๋ฏธ์ ์ด, master push ๊ธ์ง. ์ฝ๋ ์ง์๋ฌธ.md์ ๋ฌ๋ ๋ณํ.
ํ ์คํธ ์๋ฒ ์ ์ฉยท๊ฒ์ฆ (๋ฏธ๋ฐฐํฌ โ ์ด์ push ์ ํจ)
- ํ์ฉ์น bypass ํ์ค (Part A) โ
app/admin_settings_store.py:auto_clean_fd_attemptยทauto_stash_pop_attemptask_userโallow_with_audit(Tier1),wildcard_allowlist_attemptยทallow_any_task_true_attemptโHARDCODED_MIN(Tier3 ์๊ตฌ),dangerous_command_detectedask_user์ ์ง, Tier1/2/3 ํ์ค ์ฃผ์. ํ ์คํธ์๋ฒ ์ ์ฉยทservice activeยทHTTP 200ยท๊ฐ ๊ฒ์ฆ ์๋ฃ. - codi_done transient skip ์ ๊ฑฐ (Part B) โ
app/api/tasks.py_maybe_enqueue_chati_reanalysis_after_codi์if not _hp_valid:์trigger_action=='codi_done'early-return ์ถ๊ฐ. ํ ์คํธ์๋ฒ ์ ์ฉ. - ์ง์ ํธ๋์คํ read-only
no_deployfix ๋ ํ ์คํธ์๋ฒ ๋ฐ์๋จ. - ๋ก์ปฌ ๋ฏธ์ปค๋ฐ:
app/admin_settings_store.py,app/api/tasks.py(+ bridgechati.pyํ ํฐ์ฐ๋). ์ด์ ๋ฐฐํฌ = Tier2 ์ฌ์ฉ์ ์น์ธ ๋๊ธฐ.
ํ์ฉ์น ํ์ค (์ด๋ฒ ํ์ โ ์ถํ CLAUDE.md/ํ๋ก์ ํธ๋ฉ๋ชจ๋ฆฌ ๊ณต์ ๊ธฐ๋ก ์์ )
- Tier1 ์๋ํ์ฉ(
allow_with_audit): ํ์ผ read/edit/write, ๋นํ๊ดด git, ํ ์คํธ/๋น๋, venv ์ค์น, ํ ์คํธ์๋ฒ ์ฌ์์ยทgit pull, ์ผ๋ฐ bash ์กฐํ. - Tier2 ์ฌ์ฉ์์น์ธ(
ask_user): master push/์ด์๋ฐฐํฌ(cmd์๋๋ฐฐํฌ), operational rollback, ๋๋ ๋ณ๊ฒฝ. - Tier3 ํ๋์ฐจ๋จ(
block): rm-rf/DROP/TRUNCATE/DELETE FROM, force push, ์ด์ RDS write, SG ๋ณ๊ฒฝ, env/secret ์ถ๋ ฅ, ์๊ธฐ ๊ถํํ์ฅ, pfs/deploy-live.
์๋์ํ silent block ์ง๋จ (C ์ฌ๊ฒ์ฆ ์ค)
- ํ
์คํธ ์นด๋(dbg-cyc1-*) 2ํ ๋ฏธํฝ์
โ 1์ฐจ allowlist
dbg-๋ฏธ๋ฑ๋ก(์ฌ์ฉ์ ๋ฑ๋ก). ํ์ฌ allowlist(admin override) =cmdboard-/dbg-/pfs-prefix. - ์ฝ๋ 1์ฐจ audit ์๋ฃ (
codi-audit-card-constraints.mdโ ๋ณด๊ณ ์codi-audit-card-constraints-report.md, 18์น์ ). ํต์ฌ ๋ฐ๊ฒฌ: ์ฐจ๋จ์ ์ฑํฐ ํฝ์ ์ด ์๋๋ผ ๊ทธ ๋ค์ ๋จ๊ณ โchati_next_codi_requested๊น์ง ์ ์ INSERT, ์ดํcodi_execution_requested๋ฏธ์์ฑ silent block. ์ ๋ ฅ ๊ฒ์ดํธdangerous_command_detected=blockadmin override(data/admin_settings.jsonv12). ๋ฏธํ์ = ์ค์ ํธ๋ฆฌ๊ฑฐ + silent skip ์ฝ๋ ๊ฒฝ๋ก. - ์งํ ์ค ์ง์๋ฌธ:
codi-silentblock-confirm-and-unblock.md(deduplicated ํ์). Step1 ํธ๋ฆฌ๊ฑฐ ํ์ (codi_autorun_blocked ๋ก๊ทธยท์ ๊ท์ ๊ณผํ) โ Step2 silent skip ์ฝ๋ ๊ฒฝ๋ก โ Step2.5 DB-value ํธ๋์คํยท์๋ฒ ์ค๋ฒ๋ผ์ด๋(์ด ๊ตฌ๊ฐ ํ์ , ์ถ๊ฐ์์ฒญ) โ Step3 ๊ทผ๋ณธ์์ธ ํ์ โ Step4 ์ต์ ๋จ์ผ ๋ณ๊ฒฝ์ผ๋ก ์๋ํ๋ฆ ๋ณต๊ตฌ + 1ํ ์ฌ๊ฒ์ฆ. ์ฝ๋ ์์ ์ค, ๊ฒฐ๊ณผ ์ ๋ํ๋ฐฉ์์ ์์ ์์ .
๊ฒ์ฆ ํ๋์ค (ํ๋ฆฝ)
- ์นด๋ ์์ฑ โ
created+sent_to_chati+initial_instruction_enqueuedโ ์๋ ์ฑํฐโ์ฝ๋. Bridge-test(8766โ:8003) ํด๋ง ๊ฐ๋. - ์นด๋ ์์ฑ ๋ด๋ถ ๊ฒฝ๋ก:
enqueue_chati_message_for_task+build_initial_chati_instruction(admin_autorun_debug.py)./create-test-card์๋ํฌ์ธํธ(admin auth +autorun_debug_write๊ฒ์ดํธ, pfs-* 2์ฐจํ์ธ). - ๋๋ผ์ด๋ฒ
scripts/_cycle_verify_one.py(๋ก์ปฌโSSM ์คํ). ํ ์คํธ DB ์กฐํ: SSM + .env ์์ฑ + mysql.
๋ค์ ์์์ (์ ๋ํ๋ฐฉ)
codi-silentblock-confirm-and-unblock.md์ฝ๋ ๊ฒฐ๊ณผ ์์ โ ๊ทผ๋ณธ์์ธ ํ์ + ์ต์ ๋ณ๊ฒฝ + 1ํ ์ฌ์ดํด PASS ํ์ธ- (์ฑํฐ ์ง์ ) DB-relay ๋ฌด๊ฒฐ์ฑยท์๋ฒ ์ค๋ฒ๋ผ์ด๋ ๊ต์ฐจ ์ถ๊ฐ ์ง๋จ
- ์๋์ํ 10ํ ์ฐ์ PASS ๊ฒ์ฆ
- ํ์ฉ์น ํ์ค
CLAUDE.md+ํ๋ก์ ํธ๋ฉ๋ชจ๋ฆฌ ๊ณต์ ๊ธฐ๋ก - ์ด์ ๋ฐฐํฌ Tier2 ์น์ธ(ํ์ฉ์น+ํธ๋์คํ+chati ํ ํฐ์ฐ๋ ์ผ๊ด master push)
- (๋๊ธฐ) ์ฑํฐ ๋ํ๋ฐฉ ์ ๋ฉด ๊ต์ฒด ์ค๊ณ / ์๋์ํ ์์คํ ์ฌ๊ฒ์ฆ ๋ง๋ฌด๋ฆฌ
๊ฐฑ์ 2026-05-24 (25) โ silent block ๊ทผ๋ณธ์์ธ ํ์ + ์๋ํ๋ฆ 1์ฌ์ดํด PASS (์ด๋ ฅ ยท ๊ฐฑ์ 26์ผ๋ก ๋์ฒด๋จ)
๊ทผ๋ณธ์์ธ ํ์ (codi v2 ์ง์๋ฌธ codi-silentblock-confirm-and-unblock.md ๊ฒฐ๊ณผ)
- ์ค์ ์ฐจ๋จ =
dbg-*์นด๋์ debug marker ๋ถ์ฌ._maybe_enqueue_codi_autorun(tasks.py:6826) 10๊ฐ skip ๋ถ๊ธฐ ์ค marker ๊ฒ์ฌ ๋ถ๊ธฐ๊ฐcodi_autorun_blocked reason=debug_marker_missing๋ฅผ ๋ก๊น ํ skip (๋ผ์ด๋ธ ํ๋๋ก๊ทธ log_id 8497ยท8503 ์ง์ ํ์ธ). โ silent ์๋. 1์ฐจ ๋ณด๊ณ ์์ "silent"๋ bridge-test ํ์ผ ๋ก๊ทธ๋ง ๋ณธ ์ง๋จ ์ค์ธ. - ๋ฌด๊ด ํ๋ช
3๊ฒ์ดํธ:
dangerous_command_detected(draft ์๋ฌธ regex ์ง์ ๋งค์นญ 0๊ฑด) /CODI_AUTORUN_ENABLED(๋ผ์ด๋ธ effective-automation = admin_override true) /AGENT_REANALYSIS_ENABLED(admin_override true). ๋ชจ๋ silent block๊ณผ ๋ฌด๊ด. - ํ๋ณด์๋
_is_codi_autorun_enabled() False(tasks.py:6863-6865)๋ ์ค์ ๋ก enabled=true๋ผ ๋ฏธ๋ฐ๋ ๋ถ๊ธฐ.
๋จ์ผ ๋ณ๊ฒฝ โ 1์ฌ์ดํด PASS
- ์ฝ๋ 0์ค + audit 2ํ(=marker ์ฃผ์
) ๋ง์ผ๋ก ์๋ํ๋ฆ ๋ณต๊ตฌ. ์ํ์ค:
codi_execution_requested(8507) โcodi_done(8530) โcodi_result_reported(8531) โchati_reanalysis_after_codi_requested(8532). handoff_payload_invalid 0๊ฑด. - ์ดํ critic์ด ์ฌ์ฉ์ escalate(question_id=73, log 8536ยท8537ยท8538)๋ก ์ ์ ์ข ๊ฒฐ โ ์นด๋ 1411(dbg-confirm-01) status=prog / next_mode=chati / chati_state=asking, ์ฌ์ฉ์ ๋ต๋ณ ๋๊ธฐ.
- ๋ณด๊ณ ์:
codi-silentblock-confirm-and-unblock-report.md(๋ก์ปฌ).
์ด์ ๊ฒฐ๋ก
- ์ ์(pfs-*) ์นด๋ ์๋์ํ์๋ ๋ฒ๊ทธ ์์. ์ฐจ๋จ์ dbg-* ํ ์คํธ ์นด๋๊ฐ marker ์์ด ์์ฑ๋ ์ค๊ณ์ ๊ฒ์ดํธ์์.
์์ฌ ๊ถ์ฅ (ยง8, ๋ฏธ์ ์ฉ)
- (a) tasks.py:6863-6865 autorun-enabled-false ๋ถ๊ธฐ์ audit ๋ก๊ทธ 1์ค ์ถ๊ฐ(๊ฐ์ํ).
- (b) POST /api/tasks ์ง์ ์ ์์ dbg-* + ์ ์ source/purpose๋ฉด marker ์๋ INSERT(ํ ์คํธ ํธ์ โ 10ํ PASS enabler).
์ค๋ณต ๋ฐํ ๋ฉ๋ชจ
- ์ง์๋ฌธ ํ์ผ 14:00 ์์ฑ ํ ๋ฏธ๋ณ๊ฒฝ. 14:16 ScheduleWakeup ์๋ ๋ฐํ๋ก ๋์ผ prompt ์ฌ์ ๋ฌ โ codi ์ฌ์คํ ์ ํจ(์ ์ ํ๋จ).
๋ค์ ์์์
- ยง8(b) marker ์๋ํ โ dbg-* ์นด๋ ์๋ํ๋ฆ enabler ํ๋ณด (์ฝ๋ .md ์์, ํ ์คํธ ์๋ฒ ์ ์ฉ)
- ์๋์ํ 10ํ ์ฐ์ PASS ๊ฒ์ฆ
- DB-relay ๋ฌด๊ฒฐ์ฑยท์๋ฒ ์ค๋ฒ๋ผ์ด๋ ๊ต์ฐจ ์ถ๊ฐ ์ง๋จ(์ฑํฐ ์ง์ )
- ํ์ฉ์น ํ์ค CLAUDE.md+ํ๋ก์ ํธ๋ฉ๋ชจ๋ฆฌ ๊ณต์ ๊ธฐ๋ก
- (๋๊ธฐ) ์ด์ ๋ฐฐํฌ Tier2 ์น์ธ / ์ฑํฐ ๋ํ๋ฐฉ ์ ๋ฉด ๊ต์ฒด ์ค๊ณ
๊ฐฑ์ 2026-05-24 (26) โ pfs-2026-47 ์ค์์ ์ง๋จ: ์ฌ์ฉ์ ๊ฐ์ ๋ณด๊ณ ๊ณ์ธต ๋ถ์ฌ + timeout ์ค๋ผ๋ฒจ + supervisor ํ์ฑ์คํจ ๋ ธ์ถ (์ด๋ ฅ)
์ฌ๊ฑด
- ์ค์์ ์นด๋ pfs-2026-47(ํ ์คํธ01): codi๊ฐ base.html OMC collapsible ๋ ๋๋ง + ํ ์คํธ RDS display_order(950/951/952) + commit f3c28a2 master push + ํ ์คํธ์๋ฒ(8001) HTTP 200๊น์ง ์ค์ ์๋ฃ. codi๋ Telegram์ผ๋ก 1/3~์๋ฃ ์ง์ ํต์ง(์ฌ์ฉ์ ์บก์ฒ ํ์ธ).
- ๊ทธ๋ฌ๋ cmdboard ํ์: status=prog / ์คํจ. claude CLI 900s timeout(exit -1, 14:34~14:49; ์ปค๋ฐ์ 14:45 โ window ๋ด ์๋ฃํ์ผ๋ ํ๋ก์ธ์ค ๋ฏธ๋ฐํ โ runner๊ฐ timeout kill).
ํ์ธ๋ 4์ธต ๊ฒฐํจ
- timeout โ git ๋ฏธ๋์กฐ (์ค๋ผ๋ฒจ): head_after / commit_sha(f3c28a2) / changed_files๊ฐ ๋ดํฌ์ ์๋๋ฐ๋ exitโ 0์ด๋ฉด ๋ฌด์กฐ๊ฑด
result=failed. ์ฑ๊ณตํ ์์ ์ ์คํจ๋ก ํ์. - supervisor ํ์ฑ ์คํจ๊ฐ "๊ฒฐ๊ณผ"๋ก ๋
ธ์ถ: exitโ 0 โ Job2
judge_codi_resultโ supervisor LLM ์๋ต์ด ์ ํจ action JSON์ผ๋ก ํ์ฑ ์ ๋จ(llm_error ์์) โ fallbackescalate, reason'supervisor ์๋ต ํ์ฑ ์คํจ'โ notify-escalate๋ก ์ฌ์ฉ์์๊ฒ ๊ฒฐ๊ณผ์ฒ๋ผ ํ์. (criticjudge_completion๋ ๋์ผ fallback ๊ตฌ์กฐ โ supervisor.py ํ์ธ.) - ์งํ ๋น๊ฐ์: codi_progressยท์์ฝ์ ๋ด๋ถ activity_log์ผ ๋ฟ. Chat Visibility Guard๊ฐ process ๋ฉ์์ง๋ฅผ ์ฌ์ฉ์ ์ฑํ ์์ ์จ๊น(visible_process_messages_count=0). Telegram์ codi๊ฐ ๋ณ๋ ์ง์ ํต์ง๋ผ ๋ณด์์ ๋ฟ, cmdboard ๋์ ์ฑ๋ ์์.
- ์๋ฃ ๋น๋ณด๊ณ (๊ฐฑ์ 25 ์งํ ํ์ธ): critic
accept์ notify ํธ์ถ ์์ฒด๊ฐ ์์. escalate๋ง ์ฌ์ฉ์ ์๋ฆผ.
์ข ํฉ ๊ฒฐ๋ก
- cmdboard์ ์๋์ํ ์ฌ์ฉ์-๊ฐ์ ๋ณด๊ณ ๊ณ์ธต(์งํ / ์๋ฃ / ์ ํํ ์คํจ)์ด ์ฌ์ค์ ์์. codi Telegram์ด ์ ์ผํ ๊ฐ์ ํต๋ก. ์ฑ๊ณต์ด ์คํจ๋ก ๋จ๊ณ , ๋ด๋ถ ํ์ฑ ์คํจ๊ฐ ๊ฒฐ๊ณผ๋ก ๋จ๋ ์ค์๋๊น์ง ๊ฒน์นจ.
์์ ์ฐ์ ์์
- P1 timeoutโgit ๋์กฐ: ์ปค๋ฐ ๋ฐ์(head_afterโ head_before) ์ completed ๊ณ์ด ์ ํธ๋ก ์ฌ๋ถ๋ฅ + ๋ดํฌ ๋ฐ์. exit ๋ถ๊ธฐ๋ critic ์ชฝ์ผ๋ก ์ ๋ โ P2 ๋ ธ์ถ ๋๋ฐ ์ํ.
- P2 supervisor/critic JSON ํ์ฑ ๊ฒฌ๊ณ ํ: ํ์ฑ ์คํจ ์ 1ํ ์ฌํ๋กฌํํธ ๋๋ action ๋์์ด ๋งคํ. ํ์ฑ ์คํจ fallback์ ์ฌ์ฉ์ "๊ฒฐ๊ณผ"์ ๋ถ๋ฆฌ(๋ด๋ถ ํ์ ๋ณด๋ฅ๋ก).
- P3 ์ฌ์ฉ์-๊ฐ์ ๋ณด๊ณ ๊ณ์ธต: ์ฃผ์ ์งํ 1์ค ๋ ธ์ถ + accept ์๋ฃ ์์ฝ ๋ฉ์์ง + status ์ ์ด. Chat Visibility Guard ํ์ดํธ๋ฆฌ์คํธ ๊ฒํ .
- 10ํ PASS ๊ธฐ์ค ๊ฐฑ์ : ์ฑ๊ณต run์ด failed๋ก ์ ๋ธ + ์งํ์ด ์นด๋์ ๋ณด์ + ์๋ฃ ๋ณด๊ณ ๊ฐ ์ฌ์ฉ์์๊ฒ ๋ธ.
๋ค์ ์์์
- P1ยทP2(์ค์๋ ๋ฒ๊ทธ) ๋จผ์ ์์ โ ์ฝ๋ .md ์์(ํ ์คํธ ์๋ฒ)
- P3(๊ฐ์์ฑ ๊ณ์ธต) ์ค๊ณยท๊ตฌํ
- ์๋์ํ 10ํ ์ฐ์ PASS ์ฌ๊ฒ์ฆ(์ ๊ฐฑ์ ๊ธฐ์ค)
๊ฐฑ์ 2026-05-24 (27) โ P1/P2/P3 ๊ตฌํยท๋จ์๊ฒ์ฆ ์๋ฃ(๋ก์ปฌ) + timeout ์ ์ฑ ์ฌ์ค๊ณ(P4) ๋ฐฉํฅ (์ด๋ ฅ ยท ๊ฐฑ์ 32๋ก ๋์ฒด๋จ)
codi-autocycle-reporting-fix ๊ฒฐ๊ณผ (๋ก์ปฌ commit + ๋จ์ํ ์คํธ, ์ด์ ๋ฏธ์ ์ด)
- P1 timeoutโgit ๋์กฐ (53dbba7):
codi_runner_clipost-run summary๋ฅผ ๊ฒฐ๊ณผ ๋ถ๋ฅ ์ง์ ์ผ๋ก ์ด๋. timeout์ด์ด๋ commit ์์ผ๋ฉดcompleted_with_timeout=True์ ํธ + ๋ดํฌ์ head/commit. commit ์๋ timeout์ failed ์ ์ง. codi.py๊ฐ ์ด ์ ํธ๋ฅผ critic์ผ๋ก ๋ผ์ฐํ (์๋ done์ critic ์์). 6/6 PASS. - P2 ํ์ฑ ๊ฒฌ๊ณ ํ+๋
ธ์ถ๋ถ๋ฆฌ (c179973):
_SUPERVISOR_ACTION_SYNONYMS(์/ํ)+_coerce_action, 1์ฐจ ์คํจ+LLM์๋ต ์์ผ๋ฉด 1ํ ์ฌํ๋กฌํํธ(LLM ์์ฒด์คํจ๋ ์ฌ์์ฒญ ์ ํจ). fallback ์ฌ์ฉ์ ๋ฉ์์ง_FALLBACK_USER_REASON='์๋ ํ์ ์ ์๋ฃํ์ง ๋ชปํด ์ฌ์ฉ์ ํ์ธ์ด ํ์ํฉ๋๋ค.'โ audit์ ์ ํํ ๋ด๋ถ์ฌ์ ๋ณด์กด. 10/10 PASS. - P3 ์ฌ์ฉ์-๊ฐ์ ๋ณด๊ณ ๊ณ์ธต (d15f35c): admin_settings ํ ๊ธ
autocycle_visible_reporting_enabled(๊ธฐ๋ณธ OFF, env fallback)._chati_progress.pyPROGRESS_TEMPLATES 5์ข (๊ธ์งํจํด ๋ฏธํฌํจ). tasks.py_maybe_emit_autocycle_visible_progresshook โ ํ ๊ธ ON์ ์๋ฏธ๋จ๊ณ(codi_progress stageโ{requested,completed,error} / critic actionโ{accept,์ฌ์ฉ์์์ค์ปฌ๋ ์ดํธ})๋ฅผ role='system' ๋ฉ์์ง INSERT, 30์ด dedup. ์๋ done ์ ์ด ์ ํจ(๋ฉ์์ง๋ง). 11/11 PASS. - ์ด์ ๋ฌด์ ์ด: ์ด์ bridge 8765 PID 11788 unchangedยท/health 200ยทmaster push 0ํ. ํ ์คํธ bridge 8766 ์ฌ์์ PID 19060ยท/health 200.
Step 0 ํ์ธ (ํ์ ์ฌ์ค โ ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ ๋์)
- bridge โ bridge-test = ๋์คํฌ ๋ณ๋ ๋ณต์ฌ๋ณธ. bridge-test/๋ git untracked. ์ ์ฉ์ ์ฐจ:
bridge/commit โbridge-test/๋ก manual copy โ CmdboardBridgeTest๋ง ์ฌ์์(์ด์ CmdboardBridge ์ฌ์์ ๊ธ์ง). visible_to_user(tasks.py 7791/8349/8445)=์ฝ๋ handoff payload ๋ฉํํ๋๊ทธ(๋ชจ๋ False).- Chat Visibility Guard(admin_autorun_debug.py 5112-5183): read-only ์ง๋จ. ํ์ฉ source 5์ข
/ ๊ธ์ง content 8์ข
.
role='system'+sender_kind='system'์ ํญ์ ํต๊ณผ(P3๊ฐ ์ด ๊ฒฝ๋ก ์ฌ์ฉ).
๋ฏธํด๊ฒฐ
- P3 ํตํฉ๊ฒ์ฆ ๋ฏธ์: cmdboard๋ EC2 Flask์ฑ. P3 end-to-end๋ :8003 ์ ์ฉ + ํ ๊ธ ON ํ์. ๋จ master push ๋ถํ์ โ ๊ฐฑ์ 24 ์ฑ๋(SSM ์ง์ ํ์ผ ๋๊ธฐํ๋ก :8003 ๋ฐ์)๋ก ํ ์คํธ๋ง ๊ฐ๋ฅ. (์ฝ๋ ๋ณด๊ณ ๋ ์ด๋ฅผ Tier2๋ก ์ค์ธ.)
- pre-existing ์คํจ
bridge/tests/test_supervisor_job2.py::case_d_audit_recorded(test mock์ด mode= kwarg/notify_escalate ๋ฏธ์์ฉ) โ P2 ๋ฌด๊ด, ๋ฒ์ ๋ฐ ๋ฏธ์์ .
์ ๊ท ๋ฐฉํฅ (P4) โ timeout ์ ์ฑ ์ฌ์ค๊ณ (์ฌ์ฉ์ ์ง์)
- 900s ๊ณ ์ timeout์ด ์ค์์ ์ ๋ถ์กฑ โ ๊ณ ์ wall-clock kill ํ์ง/์ํ, ๋์ stall(๋ฌด์งํ) ๊ฐ์ง + ์ค๋ฅ/์ค๋จ ๋ณด๊ณ ๋ก ์์ ์ค๋จ์ ์บ์น.
- ์ค๊ณ(์ถ์ฒ): ๊ณ ์ 900s โ โ stall heartbeat(stream-json/codi_progress ๋ฌด์งํ ์ผ์ ์๊ฐโ
codi_stalled์ค๋จ ์ ํธ) + โก ์ ๋ ์ฒ์ฅ์ ๋๊ฒ ์ค์ ๊ฐํ(ํญ์ฃผ backstop ์ ์ง). ์์ ๋ฌด์ ํ์ hung ํ๋ก์ธ์ค ํญ์ฃผ ์ํ์ด๋ผ ๋น์ถ์ฒ.
๋ค์ ์์์
- P4 timeout ์ฌ์ค๊ณ(stall+๋์์ฒ์ฅ) ์ฝ๋ .md โ ํ ์คํธ ์ ์ฉ
- P1~P4 ํตํฉ๊ฒ์ฆ: :8003 SSM ์ง์ ๋๊ธฐํ + ํ ๊ธ ON + ํ ์คํธ์นด๋ 1๊ฑด (master push ์์ด)
- (๋๊ธฐ) ์ด์ ๋ฐฐํฌ Tier2 โ P1/P2/P3/P4 + ํ์ฉ์น ๋ฑ ์ผ๊ด push
๊ฐฑ์ 2026-05-24 (28) โ P4 timeout/stall + UI U1/U2 ๊ตฌํ(๋ก์ปฌยทํ ์คํธ), U3 ๋ณด๋ฅ (์ด๋ ฅ)
Phase A backend (codi-autocycle-p4-ui-bundle ์ ๋ฐ๋ถ) โ ๋ก์ปฌ commitยทํ ์คํธ ์ ์ฉ
- P4(a) config.py:
CODI_RUNNER_TIMEOUT_SECONDS900โ3600,CODI_STALL_SECONDS=300์ ์ค. - P4(b) codi_runner_cli.py(805-916):
_drain_with_stall_watchdog()โ line-by-line stdout reader + stall/abs-timeout ๋์ ๊ฐ์(๋จ์ผ communicate ๊ต์ฒด). - P4(c)
codi_stallederror_code /completed_with_stallํ๋๊ทธ /codi_run_abortedaudit /_diag.{stalled,timed_out,timeout_seconds_effective,stall_seconds_effective}. codi.py(431) critic ๋ผ์ฐํ ์ stall ์ถ๊ฐ. - admin_settings:
codi_run_timeout_seconds/codi_stall_secondsํค +get_effective_*, admin_settings.py(466-549)_AUTORUN_LIMITSํ์ฅ, bridge.py(337-358) claim-next์ runner_settings 4ํค ์ ๋ฌ. - ๊ฒ์ฆ: P4 ๋จ์ 5/5 PASS(stall/abs_timeout/normal_exit/long_progress_survives/stdin) + P1 ํ๊ท 6/6. bridge-test 8766 ์ฌ์์ /health OK. :8003 effective๊ฐ(timeout3600/stall300/visible_reporting admin_override true) ํ์ธ.
Phase B frontend
- U1 qa_helper ์ด์: app/static/jsยทcss/qa_helper., localStorage
cmdboard.qa.items.v1, ํ ๊ธ ์ฐ์๋จโ์ฐํ๋จ(bottom:96px right:18px)* ์ฌ์ฉ์ ๋ฉ๋ด ๋ฌด๊ฐ๋ฆผ.app/__init__.pyQA_HELPER_ENABLEDconfig,_base.html์กฐ๊ฑด ๋ก๋. statics HTTP 200. - U2 ์ฝ๋ ์ค์๊ฐ ๋ชจ๋ํฐ: app/static/js/codi_live_monitor.js ์ฐ์ธก fixed ํจ๋ 5s ํด๋ง. backend
GET /api/tasks/<code>/codi/live(tasks.py 5492+, since_id ๋ธํ, codi 12์ข action prefix). endpointpfs-2026-48/codi/liveโ ok/events_count=1. - U3 ๋ณด๋ฅ: spec ๊ฐ๋("ํ์ ๋ณด๊ณ ํ์๋ง") ์ค์ โ enumeration๋ง. ํตํฉ ๋์ ํ์ ์: ์ฑํฐ ์
๋ ฅ
#chati-inputโ chat-pane ํก์ + ์นด๋์์ธ chati ๋ฉ์์ง/์ฒจ๋ถ surface ํตํฉ.
โ ๋ฏธํด๊ฒฐยทํ์ธ ํ์
- U2๊ฐ QA_HELPER_ENABLED ํ๋๊ทธ์ ๋ฌถ์(_base.html 243). U2๋ ๊ฒ์ฆ๋๊ตฌ๊ฐ ์๋๋ผ ์์ ๋ชจ๋ํฐ ์๋ โ ํ๋๊ทธ ๋ถ๋ฆฌ ํ์(๋ณ๋ ํ ๊ธ or ์์). ์ฌ์ฉ์ ํ์ธ ๋๊ธฐ.
- U2 ์คํ์ ๋ฏธ๊ฒ์ฆ: endpoint 200ยทevents_count=1์ ๋ฐ์ดํฐ ๊ฒฝ๋ก๋ง ์ฆ๋ช . ์ฐ์ธก ํจ๋์ด ์ค์ ํ๋ฉด์ ๋จ๊ณ 5s ๊ฐฑ์ ๋๋์ง :8003 ๋ธ๋ผ์ฐ์ ํ์ธ ํ์. (๋ง์ดํธ ํฌ์ธํธ๊ฐ _base/_chat_pane grep์ ์ ์กํ โ JS ๋์ ์์ฑ ์ถ์ , ์ก์ ํ์ธ ํ์.)
- U3 ํตํฉ ๋์ ํ์ ํ์(ํ๊ดด์ ์์ ).
- 900s์ด๊ณผ ์ ์์์ E2E๋ ์คํธ๋ฆฌ๊ฑฐ ์ด๋ ค์ โ ๋จ์(long_progress_survives)+stall ์งง๊ฒ๋ก ๋์ฒด ๊ฒ์ฆ.
๋ฏธ์ปค๋ฐ ์ํ(๋ก์ปฌ, master push 0)
- M 12 + ?? ๋ค์(qa_helper.js/css, codi_live_monitor.js, test_p4_timeout_stall.py, bridge-test/ ๋ฑ). D 1(phase133 md). ์ด์ :8002 200ยท8765 unchangedยท์ด์ .env QA_HELPER_ENABLED ๋ฏธ์ค์ .
- ์ค์ ๊ธฐ๋ณธ๊ฐ: codi_run_timeout_seconds=3600 / codi_stall_seconds=300 (:8003 UI/API ๋ณ๊ฒฝ ๊ฐ๋ฅ).
๋ค์ ์์์
- U2 ํ๋๊ทธ ๋ถ๋ฆฌ + :8003 ๋ธ๋ผ์ฐ์ ์คํ์ ๊ฒ์ฆ(ํจ๋ ์ถ๋ ฅยท5s ๊ฐฑ์ ยท์ฝ๋ verbatim)
- U2 ์ถ๋ ฅ ํํ(์ฝ๋/์์ฐ์ด) ํ์ธ ํ ์ ์ ์ฌ๋ถ ํ๋จ
- U3 ํตํฉ ๋์ ํ์ โ ๊ตฌํ
- (๋๊ธฐ) ์ด์ Tier2 ์ผ๊ด push: P1/P2/P3/P4 + U1/U2(+U3) + ํ์ฉ์น ํ์ค
๊ฐฑ์ 2026-05-24 (29) โ U3 ๋กค๋ฐฑ + ๋ชจ๋ํฐ404 ์์ (์๋ฃ) / ๋ณธ๋ฌธ์ ๋จยท์ด์คํ์ ์งํ์ค (์ด๋ ฅ)
โ ์๋ฃยท๊ฒ์ฆ๋จ
๋ณต์ (codi-restore-chati-chatpane-8003.md) โ :8003 ์ ์ฉยท๊ฒ์ฆ
- U3 ํตํฉ ์คํฌ๋ฆฝํธ chati_chat_integration.js๊ฐ native ์ฑํฐ ๋ํ๋ฐฉ ํ์๋ฅผ ๊ฐ๋ก์ฑ ๊นจ๋จ๋ฆผ โ _base.html์์ <script> ๋ก๋ ๋ผ์ธ ์ ๊ฑฐ(JS ํ์ผ์ ๋ณด์กด, ์ถํ ์ฌ์ฌ์ฉ). :8003 ๋๊ธฐํ + cmdboard-test ์ฌ์์. U3 ๋ก๋ 0๊ฑด ํ์ธ.
- U2 ๋ชจ๋ํฐ 404 ์์ : ๋ชจ๋ํฐ๊ฐ ์นด๋ํค๋ .id-tag.strong์ textContent=display_code("PFS #48")๋ฅผ task_code๋ก ์จ์ /api/tasks/pfs #48/codi/live 404. โ getAttribute('title')(raw task_code) ์ฐ์ + dh-meta .id-tag:not(.strong) fallback์ผ๋ก ์์ . codi_live_monitor.js :8003 ๋๊ธฐํ.
- ์ด์ ๋ฌด์ ์ด(:8002 200, 8765 health OK, master push 0). chati endpoint msg_count=12, codi/live ok.
- ๋จ์ ์ก์ ํ์ธ(:8003 ๋ธ๋ผ์ฐ์ ): โ ์ฑํฐ ๋ํ๋ฐฉ ๋ฉ์์ง/๋ต๋ณ ๋์ โก ์นด๋ ์์ธ ๋ด .codi-live-monitor-section ํจ๋์ด raw task_code๋ก ์ ์ ํด๋ง.
๐ ์งํ์ค
codi-codi-result-full-body.md (์ฝ๋ ์์
์ค, ๊ฒฐ๊ณผ ๋๊ธฐ)
- P-2 ์ฆ์ ์ํ: codi.py:689 details_preview limit 1500โ12000.
- P-1 full ๋ณธ๋ฌธ ๋ณด์กด: bridge๊ฐ details ์ ๋ฌธ์ ์๋ฆฌ์ง ์๋ ํ๋(details_full ๋ฑ)๋ก ์ ์ฅ + cmdboard ์กฐํ๊ฒฝ๋ก(list_tasks/get_tasks)๊ฐ ์ฑํฐ์ full ์ ๊ณต. (์ฑํฐ๋ ํธ๋์คํ๊ฐ ์๋๋ผ get_tasks๋ก ์นด๋ ๋ก๊ทธ๋ฅผ ์ฝ์ผ๋ฏ๋ก ์ ์ฅ ์์ 1500์ ์ ๋จ์ด ๊ทผ๋ณธ ์์ธ.)
- 3-a ๋ฏธ์ฌ์ฉ ์์ฌ ์กฐ์ฌยท๋ณด๊ณ ๋ง(์ญ์ ๊ธ์ง, ์น์ธ ๋ถ๋ฆฌ): payloadํค/์ฝ๋๋ถ๊ธฐ/DB ํ
์ด๋ธยท์ปฌ๋ผ/์ฃฝ์ ํจ์. ์ด์์กด์ฌ์ฌ๋ถ ๋ช
์.
- P5 ์ด์ค ํ์ ์ถฉ๋ (์ง์๋ฌธ ํ๋จ ์ถ๊ฐ): ์ฝ๋ ์ข
๋ฃ ์ โ ์๋ํ์ (codi.py:421~ critic/supervisorโnotify_escalate ์ง๋ฌธ) + โก์ฑํฐ ์ฌ๋ถ์(tasks.py codi_result_reportedโchati_reanalysis ํ์โ์ฑํฐ NEXT) ๋์ด ๋์ยท๋
๋ฆฝ ๋ฐ๋ํด ์ค๋ณต์ง๋ฌธยทํ์ ์ถฉ๋. 5-a ์กฐ์ฌ+๋จ์ผํ 3์(A์ฑํฐ๋จ์ผ/B์๋๋จ์ผ/C์ญํ ๋ถ๋ฆฌ) ๋ณด๊ณ ํ ์น์ธ. (pfs-2026-47 "supervisor ํ์ฑ์คํจ ๋
ธ์ถ"๋ ์ด ์ฐ๋ฌผ.)
- ํ์ฌ ๋ก์ปฌ commit ์ต์ d15f35c(P3 reporting-fix)๊น์ง๋ง โ ๋ณธ๋ฌธ์ ๋จ ์์
์ปค๋ฐ ์์ง ์์(์งํ์ค ์ ์).
๋ฏธ๋ฐฐํฌยท๋ฏธ์ปค๋ฐ ๋์ (๋ก์ปฌ, master push 0)
- ๋ก์ปฌ commits ahead=3: P1(53dbba7)/P2(c179973)/P3(d15f35c) reporting-fix.
- ๋ฏธ์ปค๋ฐ ๋ค์: P4(config/codi_runner_cli/codi/admin_settings/bridge), U1(qa_helper.*), U2(codi_live_monitor.js), ๋ณต์(_base.html), bridge-test/ ๋ฑ.
- ์ค์ ๊ธฐ๋ณธ๊ฐ: codi_run_timeout_seconds=3600 / codi_stall_seconds=300 / autocycle_visible_reporting_enabled OFF.
๋ค์ ์์์
codi-codi-result-full-body.md๊ฒฐ๊ณผ ์์ โ P-2/P-1 ๊ฒ์ฆ + 3-aยท5-a ๋ณด๊ณ ๊ฒํ- 3-b(๋ฏธ์ฌ์ฉ ์ญ์ ) / 5-b(ํ์ ๊ฒฝ๋ก ์ ๋ฆฌ) โ ์ฌ์ฉ์ ์น์ธ ํ
- P1~P4 + U1/U2 + ๋ณธ๋ฌธ์ ๋จ + ํ์ ์ ๋ฆฌ :8003 ํตํฉ๊ฒ์ฆ (master push ์์ด)
- (๋๊ธฐ) ์ด์ Tier2 ์ผ๊ด push
๊ฐฑ์ 2026-05-24 (30) โ ๋ณธ๋ฌธ์ ๋จ P-2/P-1 ์๋ฃ + ์ด์คํ์ C์+signalํ ๊ธ ๊ตฌํ (์ด๋ ฅ ยท ๊ฐฑ์ 31์์ ๊ณผ๋๊ธฐ๋ก ๊ฐ๋ฑ)
โ
๋ณธ๋ฌธ ์ ๋จ (codi-codi-result-full-body.md) โ ์๋ฃยท๊ฒ์ฆ
- P-2:
codi.py details_previewlimit 1500โ12000(_DETAILS_PREVIEW_LIMIT). - P-1:
apply_codi_result๊ฐdetails_full(64KB cap, ellipsis ์์)์ legacy+standard payload์ ์ ์ฅ. codi_runner_cli_diag.cli_result_text_full(64KB). cmdboard_build_codi_result_handoff_payloadยท_rp_kw๊ฐ full ์ฐ์ ์ฌ์ฉ(report_markdown full์ 64KB/์์ผ๋ฉด 8KB). ๋จ์ 4/4 + ํ๊ท P1 6/6ยทP4 5/5. - 3-a ๋ฏธ์ฌ์ฉ ์์ฌ = ์ ๊ท 0๊ฑด(P-1 ์์ additive, ๊ธฐ์กด ํ๋ ์ ๋ถ fallback, activity_logs.payload schema-less). 3-b ์คํต.
โ
์ด์ค ํ์ ์ถฉ๋ (codi-dual-verdict-C-signal-toggle.md, ์ฑํ์ C) โ ๊ตฌํยท๊ฒ์ฆ
- C-1: supervisor/critic
notify_escalate(supervisor.py:333/518)๋ฅผ๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)๋ฅผ)SUPERVISOR_USER_ESCALATE_ENABLED(๊ธฐ๋ณธ OFF=C) ํ ๊ธ ์ฐจ๋จ. ์ฐจ๋จ ์supervisor_escalate_suppressedaudit๋ง, ํ์ ยทdecision audit ์ ์ง. codi.py:427 runner_settings>env>False ๊ฒฐ์ . โ ์ฌ์ฉ์ ์ง๋ฌธ ์ฑํฐ ๋จ์ผ ๊ฒฝ๋ก. - C-2: ์ ์ญ
supervisor_signal_injection_enabled(OFF) + ์นด๋๋ณsupervisor_signal_override(TINYINT NULL, migration 016 cmdboard_test๋ง). effective helper(NULLโ์ ์ญ/1/0). handoff envelope์supervisor_signal(action/reason/fallback/audit_log_id) ์ฒจ๋ถ + effective/override ๋ ธ์ถ. update_task PATCH 3-state. ์นด๋์์ธsupervisor_signal_toggle.js3-state ๋ผ๋์ค. PATCH 1/0/null ๊ฒ์ฆ OK. - ์ด์ ๋ฌด์ ์ด(migration016 cmdboard_test only, master push 0).
โ ๋จ์ ์ฐ๊ฒฐ (๋ค์ ์์ )
- ์ฑํฐ ํ๋กฌํํธ ํ์ฉ ๋ฏธ์ฐ๊ฒฐ: envelope์ supervisor_signal์ด ์ค๋ ค๋ ์ฑํฐ LLM์ด ๋ช
์์ ์ผ๋ก ์ ๋ด โ ํ ๊ธ ON ์คํจ ์ํด
_build_chati_prompt/chati persona์ "envelope.supervisor_signal ์์ผ๋ฉด ์ฐธ๊ณ " ์ง์ ์ถ๊ฐ ํ์(ํ์ฌ ๋ฐ์ดํฐ ๊ฒฝ๋ก๋ง). โ ํ์ ์ง์๋ฌธ ์์ . - ์ถฉ๋ ํด์ 1์ฌ์ดํด ์ค์ฆ: ์ค ์ฝ๋ ์นด๋๋ก (a)escalate ์ task_questions ๋ฏธ์์ฑ(suppressed audit๋ง) (b)signal_effective=true์ envelope ์ฒจ๋ถ โ ์๋ ํธ๋ฆฌ๊ฑฐ ์ด๋ ค์ ์๋ ๊ถ์ฅ.
๋์ ์ํ (๋ก์ปฌ, master push 0)
- commits ahead=3(P1/P2/P3 reporting-fix). ๋ฏธ์ปค๋ฐ: P4, U1/U2, ๋ณต์(_base.html), ๋ณธ๋ฌธ์ ๋จ(codi.py/codi_runner_cli/tasks.py), C-1(config/supervisor/codi.py), C-2(admin_settings/models/tasks/bridge/supervisor_signal_toggle.js/migration016), bridge-test/.
- ํ ๊ธ ๊ธฐ๋ณธ๊ฐ ์ด์ ๋ฆฌ(์ ๋ถ ๊ธฐ๋ณธ OFF/๋ณด์์ ): autocycle_visible_reporting_enabled OFF / supervisor_user_escalate_enabled OFF(=C) / supervisor_signal_injection_enabled OFF. codi_run_timeout=3600ยทstall=300.
- ๋ง์ด๊ทธ๋ ์ด์ : test=015(supervisor enum)+016(signal_override). ์ด์=015๊น์ง.
๋ค์ ์์์
- ์ฑํฐ ํ๋กฌํํธ์ supervisor_signal ์ฐธ๊ณ ์ง์ ์ฐ๊ฒฐ(ํ ๊ธ ์คํจํ) โ ํ์ .md
- ์ถฉ๋ ํด์ + signal ์ฃผ์ 1์ฌ์ดํด ์ค์ฆ(์๋ ํธ๋ฆฌ๊ฑฐ)
- :8003 ํตํฉ๊ฒ์ฆ(P1~P4+U1/U2+๋ณธ๋ฌธ์ ๋จ+C์)
- (๋๊ธฐ) ์ด์ Tier2 ์ผ๊ด push + ์ด์ RDS migration016 ์น์ธ
๊ฐฑ์ 2026-05-24 (31) โ ๋ฐฉํฅ ์ฌ์ ์: supervisor/critic ํ๊ธฐ ๊ฒํ + ํ ๊ธ ์๋ฏธ ์ ์ + ๋ฌด์ธ ์๋์๋ฃ (์ด๋ ฅ)
์ฉ์ดยท์๋ ์ฌ์ ๋ ฌ (์ฌ์ฉ์ ์ ์ + ์ฝ๋ ํ์ธ)
์ ์ค๊ณ(ยง9~ยง13): supervisor = ์ฌ๋ผ/์ฑํฐ๊ฐ ๋งก์ ์นด๋ ์์
์ ๋ฌด์ธ์ผ๋ก ์ต์ข
์๋ฃ๊น์ง ์๋ ํ๋จยท์ํ. monitor=์ฝ๋(๋ฌด๋ฃ), worker=์ฑํฐ1.
๊ทธ๋ฐ๋ฐ ํ์ฌ bridge ๊ตฌํ judge_codi_result/judge_completion(supervisor.py)์ ๋ณ๋ LLM ํ์ ๊ณ์ธต์ผ๋ก ์ฝ๋ ๊ฒฐ๊ณผ๋ง ๋ณด๊ฒ ๋ง๋ค์ด์ ธ ์๋์ ์ด๊ธ๋จ.
ํ์ ์ฌ์ค (์ฝ๋ ๊ทผ๊ฑฐ)
- ๋ฌด์ธ ์๋์๋ฃ๋ ์ด๋ฏธ ์ฑํฐ์ ์์: chati.py:154 NEXT ๋ผ์ฐํ
done โ status='done'. ์ฑํฐ๊ฐ ์๋ฃ ํ๋จ ์ ์ฌ์ฉ์ ๊ฐ์ ์์ด ์นด๋ done ์ ์ด. ์๋์ํ(codiโ์ฑํฐ์ฌ๋ถ์โdone)์ด ์ฑํฐ๋ง์ผ๋ก ๋ซํ. - supervisor/critic์ ์๋์๋ฃ์ ๊ธฐ์ฌ ์์: accept๋ status๋ฅผ done์ผ๋ก ๋ฐ๊พธ์ง ์์(ํ์ ยทaudit๋ง). escalate๋ ์ฑํฐ์ ์ค๋ณต ์ง๋ฌธ ์ถฉ๋๋ง ์ ๋ฐ. โ ์๋ ๋ถ์ผ์น + ์คํจ ์์ + ์ถฉ๋์.
- ํ๊ธฐ ์ ์๋ ๊ฒ = critic์ ์ฑ๊ณต์ฃผ์ฅ ๊ฒ์ฆ(git/test/goal ๋์กฐ)๋ฟ โ ์ฑํฐ NEXT ํ์ ์ ํก์ ๊ฐ๋ฅ(done ์ ์ธ ์ git/test ํ์ธ).
๋ฐฉํฅ ๊ฒฐ์ (์ฌ์ฉ์ ์ง์)
- D1 supervisor/critic ํ๊ธฐ ๊ฒํ : ์ ์ญ OFF๋ฅผ ๋์ด
judge_codi_result/judge_completionํธ์ถ ๊ฒฝ๋ก ํ๊ธฐ ํ๋ณด. critic ๊ฒ์ฆ๊ฐ์น๋ ์ฑํฐ๋ก ํก์. (์ด์ C์ = ๊ณผ๋๊ธฐ, ์ต์ข ์ ํ๊ธฐ ๋ฐฉํฅ.) - D2 ํ ๊ธ ์๋ฏธ ์ ์ : ์นด๋์์ธ/์์นด๋ ๋ชจ๋ฌ ํ ๊ธ์ "supervisor signal ์ฃผ์ "์ด ์๋๋ผ ์ฌ๋ผ/์ฑํฐ์ ๊ฐ์ ์ฌ๋ถ ํ ๊ธ์ด์ด์ผ ํจ. ๊ฐฑ์ 30์ supervisor_signal_override/injection ํ ๊ธ์ ์ฌ์ ์ ํ์ โ "์ด ์นด๋์ ์ฌ๋ผ/์ฑํฐ๊ฐ ์๋ ๊ฐ์ ํ ์ง" ์ค์์น๋ก.
- D3 ๋ฌด์ธ ์๋์๋ฃ ๊ฐํ: ์ฌ์ฉ์ ๋ถ์ฌ ์์๋ ์ฌ๋ผ/์ฑํฐ๊ฐ ์นด๋๋ฅผ ์ต์ข ์๋ฃ๊น์ง ์๋ ํ๋จยท์ํ. escalate(์ฌ์ฉ์ ํธ์ถ)๋ ๋งํ ๋๋ง. ยง13 8์ข ํ๋์งํฉ์ ์ฑํฐ/์ฌ๋ผ๊ฐ ์ํ.
- D4(=1๋ฒ ์์ ) 8์ข ํ๋ ํํฉ ๊ฐ์ฌ: accept/resume/retry/retry-with-fix/์์ธ์ ํธ๋์คํ/์ฌ๋ผ์ฐํ /์ฌ์ฉ์์์ค์ปฌ๋ ์ดํธ/abort ์ค ์ค์ ์๋/๋ฏธ์๋ ์ฌ์ค ๋ชฉ๋ก.
๋ ๋ฒ1(stream-json) ํํฉ
- ์ฝ๋: ๊ตฌํ๋จ(codi_runner_cli.py:1190 --output-format stream-json + _parse_stream_json). ํ ํฐ ์ค์ธกยทresult_text ์บก์ฒ ์ฐ๋.
- ์ฑํฐ: ResultMessage.usage ํ ํฐ ์ค์ธก ์ผ๋ถ. max_turns=8(๋ ธ์ 25 ๋ฏธ๋ฐ์), transcript ํ ์บก์ฒ ๋ฏธ์.
๋ค์ ์์์
- D4 ํํฉ ๊ฐ์ฌ(8์ข ํ๋ ์๋ ์ฌ๋ถ) โ ์ฝ๋ .md, ์ฌ์ค ๋ณด๊ณ ๋ง
- ๊ฐ์ฌ ๊ฒฐ๊ณผ ๊ธฐ๋ฐ: D1 ํ๊ธฐ ๋ฒ์ + D2 ํ ๊ธ ์ฌ์ ์ + D3 ๋ฌด์ธ์๋ฃ ๋ณด๊ฐ ์ค๊ณ
- ์ฌ๋ผ/์ฑํฐ supervisor ์ญํ ํตํฉ(mode ๋ผ๋ฒจ ํฌํจ) ๊ตฌํ
- (๋๊ธฐ) ์ด์ Tier2
์ง์ ๊ฐฑ์ 30 ๋๋น ๋ณ๊ฒฝ
- ๊ฐฑ์ 30์ C์(supervisor signal ํ ๊ธ)์ ๊ณผ๋๊ธฐ ์กฐ์น๋ก ๊ฐ๋ฑ. ์ต์ข ๋ฐฉํฅ์ D1(ํ๊ธฐ)+D2(ํ ๊ธ ์ฌ์ ์). ์ฝ๋ revert๋ D ์ค๊ณ ํ์ ํ ์ผ๊ด.
- ๋ชจ๋ธ ๊ถ๊ณ (์ด๋ฒ ์ธ์
์ถ๊ฐ): ๊ฐ์ฌยท์ง๋จยท์ค๊ณ์ฒ๋ผ ์ฝ๋๋ฒ ์ด์ค ์ ์ฒด๋ฅผ ์ข
ํฉ ์ถ๋ก ํ๋ ์์
์ Opus ๊ถ์ฅ(8์ข
๊ฐ์ฌ๊ฐ ํด๋น). ํ์ ๋ ๋จ์ผ ๋ณ๊ฒฝยท์์ ์์ ์ Sonnet์ผ๋ก ์ถฉ๋ถ(ํ์ง์ฐจ ๋ฏธ๋ฏธยท์๋ ์ ๋ฆฌ). ์ด๋ฒ
codi-autocycle-audit-8actions.md๊ฐ์ฌ๋ Opus ๊ถ์ฅ. - ๋ค์ ๋ํ๋ฐฉ ์ธ๊ณ: ์ฝ๋์ 8์ข ๊ฐ์ฌ ๊ฒฐ๊ณผ๋ ์ ๋ํ๋ฐฉ์์ ์ ๋ฌ ์์ . ์ ๋ํ๋ฐฉ์ ์ฝ๊ธฐ ์ ์ฐจ(์ธ์์ธ๊ณ์ ์ต์ ๊ฐฑ์ โ ๐ ์ฃผ์ ์์ธ ยง9~ยง13 โ ๐ ์ธ๋ถ ์์ ์ต์ปค)๋๋ก ๋ณต์ ํ, ๊ฐ์ฌ ๊ฒฐ๊ณผ ์์์ D1(supervisor/critic ํ๊ธฐ ๋ฒ์)ยทD2(๊ฐ์ ํ ๊ธ ์ฌ์ ์)ยทD3(๋ฌด์ธ์๋ฃ ๋ณด๊ฐ) ์ค๊ณ ์ฐฉ์.
๊ฐฑ์ 2026-05-25 (32) โ 8์ข ๊ฐ์ฌ ์์ + D1/D2/D3 ์ค๊ณ ํ์ + ํ๋ก ํธ 3-zone + ๋ฌถ์1 ์ต์ข โ ์ต์ โ ์ฌ๊ธฐ๋ถํฐ ์ฝ์ผ๋ฉด ํ์ฌ ์ํ ๋ณต์๋จ
๐ด ํ์ฌ 1์์ ๋๊ธฐ
๋ฌถ์1 ์ฝ๋ ์ง์๋ฌธ(codi-bundle1-d1-absorb-d3a.md) ์ฝ๋ ์ ๋ฌ ๋๊ธฐ. ์ ๋ฌ โ ์คํ โ ๊ฒ์ฆ(supervisor judge audit 0๊ฑด + ๋ฌด์ธ 1์ฌ์ดํด ๋ซํ) ํ ๋
ธ์
๊ฐฑ์ 33 + ๋ฌถ์2(D2)๋ก ์งํ.
๋ค์ ์์์
- ๋ฌถ์1 ์ฝ๋ ์ ๋ฌ โ ๊ฒฐ๊ณผ ์์ (๋ณ๊ฒฝํ์ผ ยท 1์ฌ์ดํด ๋ก๊ทธ ยท audit 0๊ฑด ์ฟผ๋ฆฌ) โ :8003 ๊ฒ์ฆ
- ๋ฌถ์2(D2) ์์ฑ โ D2 ํ ๊ธ + ์ฑํฐ ๋ํ๋ฐฉ 3-zone(๋ฌถ์2.5)์ ํฉ์น ์ง ๋ถ๋ฆฌํ ์ง๋ ๋ฌถ์1 ๊ฒ์ฆ ํ ๊ฒฐ์
- ๋ฌถ์3(D1 ์ญ์ ) โ ๋ฌถ์4(D3-b) โ ๋ฌถ์5(D3-c) โ ์ด์ Tier2 ๋ฐฐํฌ
8์ข
๊ฐ์ฌ ๊ฒฐ๊ณผ ์์ (codi-autocycle-audit-8actions-report.md, ๋ก์ปฌ)
- ๋ฌด์ธ์๋ฃ ํ๋ก๋ ์ฑํฐ ๋จ๋
์ผ๋ก ์ด๋ฏธ ์์ฑ:
chati.py:154NEXT=doneโstatus=done. codi โ ์ฑํฐ์ฌ๋ถ์(cmdboardtasks.py:8127) โ done์ด supervisor ์์ด ๋ซํ. - supervisor 8์ข = 7์ข audit-only ์ฃฝ์ ๊ฒฝ๋ก + escalate 1์ข (ํ ๊ธ OFF ๊ธฐ๋ณธ). ์ด๋์๋ ํ๋์ ์ค์ ์คํํ๋ ์ฝ๋ ์์.
- ๋ฌด์ธ์ํ ๋ฏธ๋ฐ์ ์์ธ = ์ด์ ๋ํดํธ G1(
CODI_AUTORUN_ENABLED) ยท G2(AGENT_REANALYSIS_ENABLED) OFF + G3(์ด์์นด๋ allowlist). ๋ฉ์ถค ๊ฒ์ดํธ ์ ์ G1~G15 ์ ๋ฆฌ๋จ. - D1/D2/D6 ์ฌ์ ์กฐ์ฌ ์๋ฃ(์ ๊ฑฐ๋์ ยท ํก์๊ฐ๋ฅ ยท ํ ๊ธ ๊ฑฐ๋ ์ง์ ).
D1/D2/D3 ์ค๊ณ ํ์ (cmdboard-D1-D2-D3-design.md, ๋ก์ปฌ)
- D1: supervisor ํ๊ธฐ โ ํก์(critic 4๊ธฐ์ค commit/exit/summary/goal โ CHATI_SYSTEM_PROMPT) โ ๊ฒ์ฆ โ ์ญ์ ์. migration 015/016 ยท enum ยท ์ปฌ๋ผ ๋ณด์กด(D2 ์ฌ์ฌ์ฉ).
- D2:
supervisor_signal_overrideโ "์ฌ๋ผยท์ฑํฐ ๊ฐ์ ์ฌ๋ถ" 3-state(NULL=์ ์ญ / 1=์๋ / 0=์๋). ๋ฌผ๋ฆฌ ์ปฌ๋ผ ยท ์์ ฏ ์ฌ์ฌ์ฉ, ๋ผ๋ฒจ๋ง ๋ณ๊ฒฝ(๋ง์ด๊ทธ๋ ์ด์ 0). G1 ยท G2 ํตํฉ. G3(์ด์์นด๋ ๊ฐ๋) ์ ๊ฑฐ + pfs ๋์ผ ํ ๊ธ ํตํฉ โ pfs ์ค์ ์์ (repo write / deploy-live / master push)์ Tier3 ํ๋์ฐจ๋จ์ด ์ ์ง(๊ด์ฌ์ฌ ๋ถ๋ฆฌ, G3 ์ ๊ฑฐ โ pfs ๋ณดํธ ์ฝํ). - D3: ยง13 8์ข ์ ๋ถ ์ฑํฐ NEXT๋ก ๋งคํ. ์์กด์ฑ 3๋จ๊ณ โ D3-a(accept/retry/retry-with-fix/escalate, ์ฆ์) / D3-b(resume ยท ์์ธ์ ํธ๋์คํ = ๋ ๋ฒ1 ์ฑํฐ transcript + continuation brief + chain_id + per-chain cap) / D3-c(์ฌ๋ผ์ฐํ ยท abort terminal). ์ ์ง ํ์ฑํ(๊ฒ์ฆ์นด๋ per-card ON โ 10ํ PASS โ ์ ์ญ ON ๊ฒฐ์ ).
์ฌ์ฉ์ ๊ฒฐ์
- D3 ๋งคํ = 8์ข ์ ๋ถ. ํ์ฑํ = ์ ์ง. pfs = ํน๋ก ์ ๊ฑฐ ยท ๋์ผ ํ ๊ธ ํตํฉ(์์ ์ Tier3).
ํ๋ก ํธ โ ์ฑํฐ ๋ํ๋ฐฉ ๊ฐํธ (= ๋ฌถ์2.5)
- ๋ฒ์ ์ ์ : ์ฌ๋ผ ๋ํ๋ฐฉ(์ฌ์ด๋๋ฐ
#chat-input)์ ์ถํ ๊ฐ์ . ์ด๋ฒ ๋์ = ์นด๋์์ธ ์ฐ์ธก "์ฑํฐ์ ๋ํ" ์ธ๋ก ํจ๋(#chati-input์์ญ). - ํํฉ: ์ํ ์์ ฏ 6์ข ๋ถ์ฐ(state banner / error / cycle dashboard / monitor / work summary / history) + ๋ํ ๋ณธ์ฒด + ์๋ ์ฌ๋ถ์ + supervisor ํ ๊ธ.
- ๊ฐํธ ์์น: ๊ธฐ์กด ์ฐ์ธก ์ธ๋ก ์ปฌ๋ผ ํญ ยท ์์น ์ ์ง(๊ฐ๋ก ํ์ฅ ๊ธ์ง). ๋ด๋ถ๋ง 3-zone ์ธ๋ก ์คํ โ ๊ด์ฐฐ(์ํ 6์ข ์์ถ ยท ์ ์ด์ ํตํฉ) / ๋ํ(๋ฉ์์ง ์คํธ๋ฆผ, ๊ณต๊ฐ ๋๋ถ๋ถ) / ๊ฐ์ (๊ฐ์ ํ ๊ธ + ์ ๋ ฅ์ฐฝ ํ๋จ). ์๋ ํธ๋ฆฌ๊ฑฐ๋ ์ ํ.
- ๋ชฉ์ ์ผ๋ก ํ์ (ํด๋ก๋ ๋์์ธ ๋ ๋๋ง). ๋์์ธ ์ง์๋ฌธ์ ์ทจ์(๋ชฉ์ ์ผ๋ก ์ถฉ๋ถ).
์ํ ์์ (6๋ฌถ์ ยท ๊ฐ :8003 ๊ฒ์ฆ ํ ์งํ ยท master push๋ ๋ง์ง๋ง)
- ๋ฌถ์1 = D1 ํก์ + D3-a + supervisor ํธ์ถ ๋นํ์ฑ
- ๋ฌถ์2 = D2(ํ ๊ธ ์๋ฏธ์ ํ + G1/G2 ํตํฉ + G3 ์ ๊ฑฐ)
- ๋ฌถ์2.5 = ํ๋ก ํธ ์ฑํฐ ๋ํ๋ฐฉ 3-zone
- ๋ฌถ์3 = D1 ๋ฌผ๋ฆฌ ์ญ์
- ๋ฌถ์4 = D3-b(๋ ๋ฒ1 ์ฑํฐ + brief + chain cap)
- ๋ฌถ์5 = D3-c(์ฌ๋ผ์ฐํ + abort) โ ์ด์ ๋ฐฐํฌ
๋ฌถ์1 ์ต์ข
์์ฑ ์๋ฃ (codi-bundle1-d1-absorb-d3a.md)
- ๊ฒ์ฆ ํ๋กฌํํธ ๋ธ๋ก ์ค์ ๋ฌธ์ +
SUPERVISOR_JUDGE_ENABLED(๊ธฐ๋ณธ False, ๊ฒฐ์ ์์ runner_settings > env > False) ํ๋๊ทธ + ์๋์ํ ๋ฌด์ํฅ ๊ทผ๊ฑฐ + supervisor judge audit 0๊ฑด DB ๊ฒ์ฆ์ฟผ๋ฆฌ. ์ฝ๋ ์ ๋ฌ ๋๊ธฐ.
์ฐ์ถ ํ์ผ (๋ก์ปฌ C:\dev\cmdboard)
codi-autocycle-audit-8actions-report.md(๊ฐ์ฌ ๊ฒฐ๊ณผ)cmdboard-D1-D2-D3-design.md(์ค๊ณ ํ์ )codi-bundle1-d1-absorb-d3a.md(๋ฌถ์1 ์ต์ข )
๊ฐฑ์ 2026-05-25 (33~38) โ ๋ฌถ์1 ์กฐ๊ฑด๋ถํต๊ณผ โ V2 ๋ผ๋ฒจ Phase1 ๋ฐฐํฌ โ ๋ฌถ์1.5 ๊ตฌ์กฐ๋ฐฐํฌ (์์ถ ์ด๋ ฅ)
- (33) ๋ฌถ์1 ์กฐ๊ฑด๋ถ ํต๊ณผ: judge ํธ์ถ 0 / supervisor audit 0๊ฑด / ๋ฌด์ธ 1์ฌ์ดํด ๋ซํ. ๋จ hold ๋ถ๋ฅ๊ฐ ํก์ ํ๋กฌํํธ๊ฐ ์๋๋ผ ์ฝ๋ instruction ๋ณธ๋ฌธ 4๊ธฐ์ค ์ปจํ
์คํธ ๋๋ถ โ D1 ํก์ ๋ฏธ๋ฐฐ์ โ ๋ฌถ์1.5์์ ์ข
๊ฒฐํค๋ก. ๋ณ๊ฒฝ:
persona.py(SYSTEM_PROMPT 4๊ธฐ์ค) /config.py(SUPERVISOR_JUDGE_ENABLED๊ธฐ๋ณธ False) /codi.py(judge ๊ฒ์ดํธ). ์ด์/master/pfs ๋ฏธ์ ์ด. ํ๊ฐ์cmdboard_progress_evaluation.md: ์ํ์ โ ์ค๊ณ ๋ช ์นญ vs ์ค์ ๊ฒฝ๋ก ๋ถ์ผ์น โก ๊ฒ์ดํธ ์ฐจ๋จ ์ฌ์ UI/๋ก๊ทธ ๋น๊ฐ์. ํตํฉ์ ์ ๊ท 3์ข = silent block ๊ฐ์ํ(autorun_blocked_reason ํ์ค)ยทํ ํฐ ๊ณตํต๊ธฐ๋กยทchain rollup(D3-b ์ ์ ). - (34) ์๋ฒ ํ๋ฅด์๋ ํ์ด์ง ํ๊ธฐ:
chati_persona/codi_personaoverride = ์๋น์ฒ ์๋ ์ฃฝ์ ๊ธฐ๋ฅ(ํ๋กฌํํธ ์ฃผ์ ์ฝ๋ ์์). Bridge๋bridge/app/services/persona.pyํ์ผ์์ ์ง์ import. ํธ์ง UIยท๋ผ์ฐํธยทstoreํคยท์ํ์นฉ ํ๊ธฐ โ ํ๋ฅด์๋ ๋จ์ผ ์ถ์ฒ =persona.py(์ฌ์์ ์ ๋ฐ์). ์ง์๋ฌธcodi-deprecate-server-persona-page.md. - (35) V2 SARA ๋ํ ๊ตฌ์กฐ ํ์ : V2 = ์ ๋ฉด ์ฌ๊ฐ๋ฐ ์๋ ๋ณด์. ์ ์ญ SARA ๋ํ๋ฐฉ=์ ์ฒด ๋น์, ์นด๋ ์์ธ๋ณ ์ฑํฐ ๋ํ๋ฐฉ=ํด๋น ์นด๋ ๋ด๋น SARA๋ก ํ์๋ช ยท๊ฐ๋ ๋ง ์ ํ(ํตํฉ ์๋). ์ฌ์ฉ์๋ PLANNER(=์ฑํฐ ์ ์ญํ ๋ช )/CODI/EVALUATOR/ROUTER์ ์ง์ ๋ํ ์ ํจ. EVALUATOR=CODI ๊ฒฐ๊ณผ ๋ ๋ฆฝ ๊ฒ์ฆ์ธต(์ฝ๋ ์์ ์ ํจ), ROUTER=๋ค์ ํ๋ ๊ฒฐ์ +silent block ์ฌ์ ๊ธฐ๋ก.
- (36) CODI Phase0 ๊ฐ์ฌ ์์ + Phase1 ๋ผ๋ฒจ ๋ฒ์ ํ์ : ์ฌ์ด๋ ์ฑํ
ํจ๋(
_chat_pane.html)์ ์ด๋ฏธ SARA ๋ช ์นญ. Phase1 ์ค์ ๋์ = 2ํ์ผ 9~11๋ผ์ธ ๋ผ๋ฒจ ํ ์คํธ ๊ต์ฒด(chati_chat_integration.js๋ผ๋ฒจ 9๊ฑด +app.js:4771/4802). DB/API/Bridge ๋ฌด๋ณ๊ฒฝ,chatienumยทURL ์ ์ง, UI ๋ ๋๋ง๋ง SARA alias. HandoffArtifact enum ํ์ฅ 1ํ๋ก task_contract/evaluator_report/routing_decision/continuation_state ์์ฉ ๊ฐ๋ฅ(Phase2 ํ๋ณด). - (37) V2 Phase โ ๋ฌถ์ ํธ๋ ๋งคํ: ๋ฌถ์(ํตํฉ์)=์คํ ์์ง, V2 Phase=์ญํ ์ดํ ์ค๋ฒ๋ ์ด. ๋ณ๋ ฌ ๊ธ์ง, ๋ฌถ์ ์์กด์ฑ ์์ ๋ฐ๋ฅด๊ณ V2 ์ญํ ๋ช ๋ณ๊ธฐ. Phase2=๋ฌถ์1.5+D1ํก์ / Phase4=D3 8์ข NEXT(=ROUTER) / Phase5=๋ฌถ์4(D3-b)+chain rollup+ํ ํฐ๊ณตํต / Phase6=๋ฌถ์2.5(3-zone). โ EVALUATOR ๋ ๋ฆฝ์ฑ = ์ต์ A ํ์ : D1 ํก์๋ฅผ baseline ์์ฑ โ ๋ ๋ฆฝ EVALUATOR๋ Phase3์์ ์ํ ์นด๋์๋ง ์ ์ง ๋์ (์ต์ B ๊ธฐ๊ฐ).
- (38) Phase1 ๋ผ๋ฒจ :8003 ๋ฐฐํฌยท๊ฒ์ฆ PASS + ๋ฌถ์1.5 ๊ตฌ์กฐ ๋ฐฐํฌ: ์ฌ์ฉ์-facing ์ฑํฐ 0๊ฑด ๋ฌ์ฑ(app.js 2์ค + integration.js ์ ์ฒด๊ต์ฒด, gzip+base64 SSM ์ ์ก, md5 ์ผ์น). cmdboard-test activeยท๋ฃจํธ 200ยท6๋ถ journal ๋ฌด์ค๋ฅ. ๋กค๋ฐฑ๋ฐฑ์
*.phase1bak.*. ๋ฌถ์1.5:bridge-test/app/services/persona.pyGENERAL_CHAT_PROMPT์ 4๊ธฐ์ค done-๊ฒ์ดํธ ์ฝ์ (๊ฒ์ดํธ 2๊ฐ: SYSTEM L158 ๋ฌถ์1 + GENERAL L277 ๋ฌถ์1.5), py_compile OK, ๋ฐฑ์persona.py.b15bak. ํ ์คํธ bridge๋ง ์ฌ์์(์ด์ :8765 PID 11788 ๋ฌด๋ณ๊ฒฝ). prodpersona.py๋ฏธ์ ์ฉ. cycle-verify ํ๋์ค(scripts/_cycle_verify_one.py) :8003 ์ ์ก ์๋ฃ, ์คํ๋ง ๋จ์ โ ๊ฐฑ์ 39์์ ์คํยท์ข ๊ฒฐ. - ์ด์ ํ์ต(์ด ๊ตฌ๊ฐ): dual-bridge ์ฌ์์์ ํฌํธ๋ก PID ๊ฒฉ๋ฆฌ(8765 prod ์ ๋ ๋ฌด์ ์ด, pythonw ์ผ๊ด kill ๊ธ์ง). ์ ์ JS ๊ฒฉ๋ฆฌ๋ฐฐํฌ = gzip+base64 SSM + md5 ๋์กฐ. aws CLI cp949 ์ถ๋ ฅ์ค๋ฅ โ
PYTHONUTF8=1. SSM ๋ช ๋ น์ ํ๊ตญ์ด/b64+์ค์ฒฉ๋ฐ์ดํ = ์์ ๋น๋ฐ โ ์๋ฒ์ ํ์ผ ๋๊ณ ์ง์ ์คํ or b64 ์ธ์ฝ๋ฉ(JSON ASCII ์ ์ง).
๊ฐฑ์ 2026-05-25 (38) โ Phase 1 ๋ผ๋ฒจ :8003 ๋ฐฐํฌยท๊ฒ์ฆ + ๋ฌถ์1.5 ๊ตฌ์กฐ ๋ฐฐํฌ
Phase 1 (๋ผ๋ฒจ) โ :8003 ๋ฐฐํฌยท๊ฒ์ฆ PASS
- ์ฌ์ฉ์-facing ์ฑํฐ 0๊ฑด ๋ฌ์ฑ:
chati_chat_integration.js๋ผ๋ฒจ 11๊ฑด + L204ยทL368 ๋งค์ฒ,app.jsL4771(๐ฌ SARA์ ์นด๋ ๋ํ)ยทL4802(SARA์๊ฒ ๋ฉ์์งโฆ) ํ๊น ์นํ. git/master/์ด์ ๋ฌด์ ์ด. gzip+base64 SSM ์ ์ก, md5 ์ผ์น. cmdboard-test activeยท๋ฃจํธ 200ยท6๋ถ journal ๋ฌด์ค๋ฅ. ๋กค๋ฐฑ๋ฐฑ์*.phase1bak.*. - โธ ยง3-4 ์๋ ์๊ฐ/๋ชจ๋ฐ์ผ/ํญ๋ ๋ ์ฒดํฌ๋ฆฌ์คํธ = ๋ธ๋ผ์ฐ์ ํ์(๋ณต๊ท ํ).
๋ฌถ์1.5 (=Phase 2 ์ฐฉ์) โ ๊ตฌ์กฐ ๋ฐฐํฌ
bridge-test/app/services/persona.pyGENERAL_CHAT_PROMPT์ 4๊ธฐ์ค done-๊ฒ์ดํธ ์ฝ์ (๊ฒ์ดํธ 2๊ฐ: SYSTEM L158 Bundle1 + GENERAL L277 Bundle1.5). py_compile OK, ๋ฐฑ์persona.py.b15bak. ํ ์คํธ bridge๋ง ์ฌ์์(์ด์ :8765 PID 11788 ๋ฌด๋ณ๊ฒฝ). prodpersona.py๋ฏธ์ ์ฉ.- cycle-verify ํ๋์ค(
scripts/_cycle_verify_one.py) :8003 ์ ์ก ์๋ฃ, ์คํ์ ๊ฐฑ์ 39์์.
๊ฐฑ์ 39~47 (2026-05-25) โ ์ธ์์ธ๊ณ์ ๋ณธ๋ฌธ์์ ์ด๋ (์๋ฃ ์ด๋ ฅ)
์ธ๋ถ ํ์ ์ฌ์คยท์ฝ๋ ํ์ต์ ๐ง ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ์๋ ๋ฐ์๋จ.
(39) ๋ฌถ์1.5 ๊ฒ์ฆ ์ข ๊ฒฐ + ๋ฌถ์1.6/1.6b(done ์๋์๋ฃ) PASS + ๋ฌ๋ ํฌ์ค ๋ณต๊ตฌ
- ๋ฌถ์1.5: CHATI_GENERAL_CHAT_PROMPT 4๊ธฐ์ค ๋ถ๋ฅ ์ ์. 1์ฐจ FAIL์ ํ๋์ค/ํ๊ฒฝ ๋ฌธ์ (๋ง์ปค ๋๋ฝยทํธ๋์ญ์ ๊ฒฉ๋ฆฌยทํ๊น wsgi.pyยทmax_turns). ์ ํ ์์ 1๊ฑด: read-only completed โ deploy_status='not_deployed' ๋ถ๊ธฐ.
- ๋ฌถ์1.6: chati_next_detected ํธ๋ค๋ฌ์ NEXT=done ์๋์๋ฃ ๋ถ๊ธฐ(ํ ๊ธ CHATI_AUTODONE_ENABLED ๊ธฐ๋ณธ False, ํ ์คํธ .env๋ง true, ๋ฉฑ๋ฑ, asking>0 skip, audit). ์นด๋ dbg-cyc1-010811 ๋ฌด์ธ ์ฌ์ดํด ์์ ๋ซํ.
- ๋ฌถ์1.6b: ์ฑํฐ max_turns ํ๋์ฝ๋ฉ 8 โ settings.CHATI_MAX_TURNS. PC bridge-test .env=20, ์ด์ ๋ฏธ์ค์ .
- ๋ฌ๋ ํฌ์ค: Start-Process ๊ธฐ๋ Bridge๊ฐ ์ฌ์ฉ์ PATH(claude CLI) ๋ฏธ์์ โ claude_cli_missing. ํด๊ฒฐ=PATH ์์ ํ bash ์ ธ์์ ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ธฐ๋(cli ๋ชจ๋).
(40) ๋ฌถ์1.6 race ๋ณด๊ฐ (์ค๊ณ B) PASS
- ์์ฌ ์ฝ๋ ์์ธ=REPEATABLE READ ์ค๋ ์ท ๊ณ ์ ์ผ๋ก done ๊ฐ๋ ์ฐํ. ํด๊ฒฐ=_maybe_enqueue_codi_autorun ์ต์ข INSERT ์ง์ ๊ฐ๋#10: SELECTโฆFOR UPDATE ์ ๊ธ์ฝ๊ธฐ๋ก ์ต์ status ํ์ธ, done/hold๋ฉด codi_autorun_blocked(reason=task_status_done_fresh). ๊ฒฐ์ ์ PASS.
(41) ๋ฌถ์2(D2) ํ ์คํธ ์ ์ฉยท๊ฒ์ฆ PASS + ํ๋์ธต ๋ณด๊ฐ
- G3 ์ ๊ฑฐ ์ ์ (force push๋ง ์ฐจ๋จ, ์ผ๋ฐ master/deploy-live pushยทpfs write ๋ฏธ์ฐจ๋จ) ๋ถ์ผ์น ๋ฐ๊ฒฌ โ B์: ํ๋์ธต ๋จผ์ ๋ณด๊ฐ. ๊ถํ ๋ธ๋ก์ปค whitelist.py DANGER_PATTERNS+G7์ master/deploy-live push AUTO_DENY, ์ด์ํ์ผ write AUTO_DENY.
- D2: supervisor_signal_override 3-state(NULL=์ ์ญ/1=์๋/0=์๋), _intervention_mode, G1/G2 per-card ํตํฉ, G3 ์๋์ํ 2๊ณณ ์ ๊ฑฐ. ๊ธฐ๋ฅ 14/14 PASS.
(42) ํ ํฐ ๊ณตํต ๊ธฐ๋ก(Tier B) ์๋ฃ
- ํฉ๊ณ SoT=agent_runs.tokens_used. record_agent_token_usage() ๊ณตํตํจ์. UI 3-state(known/partial/mock) + _token_unmeasured_for. ๋ง์ด๊ทธ๋ ์ด์ 0. ๊ฒ์ฆ PASS(token_usage_source known:11/mock:1).
(43) ๋ฌถ์3 D1 supervisor ๋ฌผ๋ฆฌ ์ญ์ ์๋ฃ
- judge ๊ธฐ๋ณธ False๋ก ์ฌ๋ฌธํ ํ์ธ โ codi.py judge ๋ธ๋กยทsupervisor.pyยทconfig ํ ๊ธ2๊ฐยทsupervisor ํ ์คํธ4๊ฐ ์ ๊ฑฐ. ๋ณด์กด: migration 015/016ยทenum 'supervisor'ยทsupervisor_signal_override ์ปฌ๋ผ(D2)ยทDB ๋ฌด์ ์ด. app/ ์์ฌ ์ฐธ์กฐ0, py_compile/import OK.
(44) chain rollup A๋จ๊ณ(์ง๊ณ) ์๋ฃ
- _chain_rollup_for(db,chain_id): ๊ฐ์ chain_id(deleted_at IS NULL) card_count/total_calls/total_tokens/total_cycles. _join_codi_runner_audit_metadata ๋ดํฌ ๋ ธ์ถ. ๋ง์ด๊ทธ๋ ์ด์ 0. AGG SQL ์ค์คํค๋ง PASS. B๋จ๊ณ(per-chain ์ฒ์ฅ+UI)=baseline ํ์.
(45) ์งํ์์ ์ ํฉํ + ๋ฌถ์4(D3-b) ์ฐฉ์(์ง๋จยทA์ยท์ง์๋ฌธ)
- ํธ๋์ปค ์ ์นด๋ ์ ํฉํ, ์งํ์์ ์ถฉ๋ 5๊ฑด ํด์(๋ฐฑ๋ณธ 0.5โ1โ1.5โ1.6โ1.65โ2โ2.5โ3โ4โ5โ6โ7โ8).
- ๋ฌถ์4 ์ง๋จ: ์ฑํฐ NEXT=4-primitive๋ง, resumeยทํธ๋์คํ ๋ฏธ๋ฐฐ์ . ์ค๊ณ=A์(SDK ์ธ์ ๋ฏธ๋ณด์กด, continuation brief ์ฌ์ฃผ์ ). ๋น์์ค ์ ์ฝ(context_basis/remaining ์์ฝยท์ญ์ ๊ธ์ง). ์ง์๋ฌธ codi-bundle4-d3b-resume-handoff.md ์์ฑ. (์ด ์์ ์ฝ๋ 0๊ฑด, ๋ฐฑ์ ๋ง)
(46) ๋ฌถ์4 ์ง๋จ: ๋ค๋ฅธ ์ธ์ ์ ์ ์ฉ ๋ฐ๊ฒฌ โ 1์์ ์ฌ์ ์(์ ์ฉโ๊ฒ์ฆ)
- ๊ฐฑ์ 45 ๋ฐฑ์ ์งํ ๋ค๋ฅธ ์ธ์ ์ด 16:52~17:01 ๋ฌถ์4 ๊ฑฐ์ ์ ๋ถ ์ ์ฉ. bridge-test chati/persona/chati_chat_consumer ์ ์ฉยทclaude_client ๋ฏธ๋ณ๊ฒฝ. EC2 tasks.py์ _latest_continuation_brief/_chain_rollup_for/CHAIN_CAP_ENABLED(OFF)/_maybe_handoff_new_card ์ ์ฉ. 1์์=๊ฒ์ฆ์ผ๋ก ์ฌ์ ์(๋ฎ์ด์ฐ๊ธฐ ๊ธ์ง).
- ํจ์ : EC2 sys py3.6.9 py_compile ์คํโvenv3.11.10. SSM cp949โ--output json+PYTHONUTF8=1. aws-api MCP ssm:SendCommand ๋ถ๊ฐโclaude-code Bash ๋ก์ปฌ aws.
(47) ๋ฌถ์4(D3-b) ๊ฒ์ฆ 4์ข ์ ๋ถ PASS โ ๋ฌถ์4 ์๋ฃ (์ฝ๋ ๋ณ๊ฒฝ 0๊ฑดยท๊ฒ์ฆ๋ง)
-
1 claude_client ๋ฏธ๋ณ๊ฒฝ=์๋(resume ์ฌ์ฃผ์ ์ chati_chat_consumer๊ฐ ํ๋กฌํํธ ํ ์คํธ 220~247ํ์ผ๋ก ์ํ, claude_client๋ SDK ๋ฆด๋ ์ด; ๋ฐฑ์ ๊ณผ byte-identical).
-
2 ๋ฐฐ์ ์๊ฒฐ: EC2 tasks.py chati_next_detected ํธ๋ค๋ฌ(add_log 11176, ๋ถ๊ธฐ 11346)
if next_val in ('resume','handoff'). resume(11349)=chati_resume_brief+์นด๋ prog ์ ์ง(get_task detail 4313 _latest_continuation_brief ์ฌ์ฃผ์ ). handoff(11360)=_maybe_handoff_new_card try/except. helper 5์ข ์ ์ ์กด์ฌ(NameError0). -
3 ๋จ์ A(brief context_basis/remaining 6004โ6004 ๋ฌด์์ค)ยทB(NEXT 6์ข ยท๊ธฐ์กด4๊ฐ ํ๊ท0ยทrouting prog)ยทC(handoff chain_id ์์, source chain_id ์์ผ๋ฉด task_code ๋ฃจํธ ํ๋ฆฝ, brief ๋น์์ค ์๋, DB ๋กค๋ฐฑ ์์ํ0) PASS.
-
4 EC2:8003 + bridge-test:8766 health 200ยทpy_compile OK. ์ด์ 8765 ๋ฌด์ ์ด.
-
5 ๋ฌด์ธ 1์ฌ์ดํด PASS: ๋ผ์ด๋ธ ์นด๋ dbg-cyc1-111633 ์์จ codiโdoneโchati_autodone_appliedโstatus=done. resume/handoff ๋ฏธ๋ฐํ(read-only)=๋ฌดํ๊ท.
- ๋ฐฑ๋ก๊ทธ(๋ฌถ์4 ๋ฐยท๋น์ฐจ๋จ): codi_done ํธ๋ฆฌ๊ฑฐ ์ฌ๋ถ์์ด handoff_payload_invalid(codi_handoff_payload_mismatch_detected) skip๋๋ codi_result_reported ๊ฒฝ๋ก๋ก ์ฌ์ดํด ๋ซํ. ๋ฌถ์1.5 read-only ํ์ด๋ก๋ nuance ์ถ์ .
- ์ฐ์ถ(read/๊ฒ์ฆ ์ ์ฉ): scripts/probe_b4wiring.pyยทread_b4handler.pyยทverify_ec2b4.pyยทfindsession.pyยทtestc_handoffchainid.pyยทcheck_cyccard.py, bridge-test scripts/unit_b4verify.py.
๊ฐฑ์ 2026-05-25 (48) โ ๋ฌถ์5(D3-c ์ฌ๋ผ์ฐํ ยทabort) ๊ตฌํ + ๊ฒ์ฆ #1/#2/#3 PASS, #4 reroute PASS ยท abort ๋ฐํ์ ๋ฒ๊ทธ ๋๋ฒ๊น ์งํ ์ค
NEXT ์ดํ 6๊ฐ โ 8๊ฐ ํ์ฅ (reroute ยท abort ์ ๊ท)
- ยง13 ๋งคํ ๊ณ์ฝ: acceptโdone / resumeโresume / retryโcodi / retry-with-fixโcodi+draft / ์์ธ์ ํธ๋์คํโhandoff / ์ฌ๋ผ์ฐํ โreroute(์ ๊ท, status=progยทnext_mode=codiยทaction=chati_next_reroute) / ์ฌ์ฉ์์์ค์ปฌ๋ ์ดํธโholdยทmanual / abortโabort(์ ๊ท, status=holdยทnext_mode=manualยทaction=chati_next_abort, terminal).
- reroute ๋ฐ๋ = ํจํด์ฐจ๋จ(stallโฅ3/์ฐ์์คํจโฅ3)+๋์ ์ ๊ทผ ๆ โ ๋ค๋ฅธ ์ ๊ทผ ์ ํ(์์ค์ปฌ๋ ์ดํธ ์ฐ์ ). abort = ๊ฐ๋ง์์/๋ฒ์๋ฐ/์์ ์๋ฐฐ ๋๋ ์ฌ์ฉ์ ์ค๋จ, terminal ์ข ๊ฒฐ.
bridge-test 3ํ์ผ ํธ์ง ์๋ฃ (๋ฐฑ์ *.b5bak)
chati.py: _NEXT_RE ์ ๊ท์|reroute|abort์ถ๊ฐ, _VALID_NEXT 8๊ฐ, _NEXT_ROUTING์ reroute(prog/codi/chati_next_reroute)+abort(hold/manual/chati_next_abort).chati_chat_consumer.py(์ค์ ์๋์ํ ๊ฒฝ๋ก): _NEXT_ALLOWED_VALUES 8๊ฐ, _NEXT_BRIEF_VALUES ๋ถ๋ณ(resumeยทhandoff), next_value_counts์ reroute/abort ํค, dispatch์์ chati_next_detected payload๋next_val in ("codi","reroute")์ผ ๋ draft ๋๋ฐ, codi-pending ํธ๋ฆฌ๊ฑฐ๋("codi","reroute")๋ก ํ์ฅ(reroute๋ autorun ๋ฐํ) + payload์ reroute/next ๋ง์ปค.persona.py: NEXT 8๊ฐ ๋ฌธ์ํ, reroute/abort ๋ฐ๋๊ธฐ์ค bullet, codi_instruction_draft ๊ท์น์ next=codi ๋๋ reroute๋ก ํ์ฅ.- ๊ฒ์ฆ: 3ํ์ผ py_compile PASS.
EC2-test tasks.py ํธ์ง ์๋ฃ (๋ฐฑ์
tasks.py.b5bak, ํจ์น ์คํฌ๋ฆฝํธ _ec2_patch_b5_d3c.py base64 ์ ์กยทubuntu ์คํ, ๋ฉฑ๋ฑ ๊ฐ๋)
- code_map(L11291)์
'reroute':'next_codi','abort':'next_hold'์ถ๊ฐ. - chati_next_detected ํธ๋ค๋ฌ add_log(def L11176) resume/handoff ๋ธ๋ก ๋ค์ ๋ถ๊ธฐ ์ฝ์
:
if next_val=='reroute':chati_next_reroute audit /elif next_val=='abort':task.status='hold'ยทnext_mode='manual'ยทdetach_chati_pending_for_task(done=False)ยทchati_next_abort auditยท_chati_progress(next_hold). - EC2 py_compile PASS, cmdboard-test.service ์ฌ์์ยท:8003 healthy. ์ด์ :8002ยท:8765 ๋ฌด์ ์ด.
๊ฒ์ฆ ๊ฒฐ๊ณผ
- #1 ๋ฐฐ์ + #2 ๋จ์ (bridge-test): ALL_PASS 32/32 (8๊ฐ ์ ํฉยทreroute prog/codiยทabort hold/manualยทdraft ๋ณด์กดยทbrief ๋ฌด์ํฅยท๊ธฐ์กด6๊ฐ ํ๊ท0ยทdispatch ๋ฐฐ์ ). ์คํฌ๋ฆฝํธ
bridge-test/scripts/_unit_b5_verify.py(PYTHONPATH=. ํ์). - #3 health: PASS (:8003ยท:8766 healthy, ์ ํ์ผ py_compile OK, ์ด์ ๋ฌด์ ์ด).
- #4 EC2 ๋ฐํ์ (test_client,
_ec2_verify_b5_runtime.py): reroute ์ ๋ถ PASS (audit 1๊ฑดยทstatus ๋ฏธ์ ์ฐฉยทtask_question ๋ฏธ์์ฑ), manual ํ๊ท PASS. abort 3๊ฑด FAIL(statusยทnext_mode ๋ฏธ๋ณ๊ฒฝ, chati_next_abort audit 0).
๐ด ๋ฏธํด๊ฒฐ ๋ฒ๊ทธ โ abort ๋ฐํ์ ๋ฏธ์คํ (๋ค์ ์ธ์ 1์์)
- ์ฆ์: EC2 add_log ๋ผ์ฐํธ๋ฅผ test_client๋ก ํธ์ถ ์ abort ๋ถ๊ธฐ๋ง ๋ฏธ์คํ(statusยทnext_mode ๋ฏธ๋ณ๊ฒฝ + chati_next_abort audit 0). reroute(
if)๋ ์ ์ ๋์. POST๋ 200 ๋ฐํ(add_log outer try์ except ์์ โ ์์ธ ์ 500์ด์ด์ผ ํ๋ 200). - ๋ถ๊ธฐ ๋ก์ง ์์ฒด๋ ์ ์ ์ฆ๋ช : (a) abort ๋ถ๊ธฐ statements ์ง์ ์คํ โ status=hold/next_mode=manual ์์. (b) generic _log + code_map _chati_progress(next_hold) + abort ๋ถ๊ธฐ ์ ์ฒด ์์ ์ฌํ โ ์ ์. (c) _maybe_emit_autocycle_visible_progress๊น์ง ํฌํจํ ํ์ ๋ธ๋ก ์ฌํ โ status hold/next_mode manual/abort_audit 1 ์ ์ ์ปค๋ฐ.
- inert fixture(status=wait/next_mode=chati)๋ก๋ abort๋ง FAIL โ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ปค ๋ ์ด์ค ์๋.
- repr ํ์ธ: EC2 ํ์ผ L11378
if next_val=='reroute':/ L11384elif next_val=='abort':๋ค์ฌ์ฐ๊ธฐยท๋ฌธ์ ์ ์. - ๊ฒฐ๋ก : ๊ฒฉ๋ฆฌ ์คํ์ ์ ๋ถ ์ ์์ธ๋ฐ ์ค์ test_client ๋ผ์ฐํธ์์๋ง abort ๋ถ๊ธฐ๊ฐ ๋ฏธ์คํ/๋กค๋ฐฑ๋จ โ ์์ธ ๋ฏธ๊ท๋ช
. ๋ค์ ์กฐ์ฌ ํ๋ณด: ์ค์ add_log ๋ณธ๋ฌธ์์ reroute
if์ abortelif์ฌ์ด ์ฐจ์ด๋ฅผ ๋ง๋๋ ๋ฌด์ธ๊ฐ / test_client ํ๋ก์ธ์ค create_app() ๋ถ์ํจ๊ณผ / ํธ๋ค๋ฌ ๋ก๋ ์ฝ๋์ ๋์คํฌ ์ฝ๋ ๋ถ์ผ์น(cmdboard-test.service๋ ์ฌ์์ํ์ผ๋ test_client๋ ๋ณ๋ ํ๋ก์ธ์ค create_app()๋ก ๋์คํฌ ์ฌ๋ก๋).
๋๋๋ฆฌ๊ธฐ
- bridge-test *.b5bak 3๊ฐ + EC2 tasks.py.b5bak ๋ณต์ ํ ๊ฐ ์ฌ์์. DB ๋ฌด๋ณ๊ฒฝ(fixture๋ soft-delete ์ ๋ฆฌ)์ด๋ผ ๋กค๋ฐฑ ๋ถ์์ฉ 0.
์ด์ ํจ์ ํ์ต (์ด ์ธ์ )
- SSM ๋น๋ํํ ์คํ = AWS-StartNonInteractiveCommand ๋ฌธ์ (AWS-RunShellCommand๋ IAM poinadmin ๊ถํ ์์). ํ์:
aws ssm start-session --region ap-northeast-2 --target i-03225ba8bc12a929e --document-name AWS-StartNonInteractiveCommand --parameters 'command=["bash -lc \"...\""]'. exec ์ง์ ์คํ์ด๋ผ ์ ธ ์ฐ์ฐ์(;ยท&&)๋bash -lc "..."๋ก ๊ฐ์ผ๋ค. ssm-user ์คํ โ ubuntu ์์ ํ์ผ์sudo -H -u ubuntu. ํฐ/ํ๊ธ ์คํฌ๋ฆฝํธ๋ base64 ์ธ์ฝ๋ฉ(JSON ASCII ์ ์ง) ํecho <b64>|base64 -d>/tmp/x.py && sudo -H -u ubuntu <venv> /tmp/x.py. - EC2-test venv = /home/ubuntu/cmdboard-test/venv/bin/python(3.11.10). import ๊ฒฝ๋ก: app.create_app / app.db.SessionLocal,engine / app.models.Task,ActivityLog,TaskQuestion. add_log ๋ผ์ฐํธ =
POST /api/tasks/<task_code>/log. detach_chati_pending_for_task(db,task,*,source,hold=False,done=False).
์ฐ์ถ ํ์ผ (๋ก์ปฌ C:\dev\cmdboard)
_ec2_patch_b5_d3c.py(EC2 ํจ์น, ์ ์ฉ ์๋ฃ) /_ec2_verify_b5_runtime.py(#4 ๋ฐํ์ ๊ฒ์ฆ) /bridge-test/scripts/_unit_b5_verify.py(#1ยท#2, ALL_PASS).- EC2 ๋๋ฒ๊ทธ์ฉ(base64 ์ ์ก): /tmp/dbgabort.pyยทdbg2.pyยทdbg3.pyยทrepr.pyยทprobe.pyยทprobe2.pyยท_findroute.py.
๋ค์ ์์์
- abort ๋ฐํ์ ๋ฒ๊ทธ ์์ธ ๊ท๋ช โ ์์ โ #4 ์ฌ๊ฒ์ฆ(abort status=holdยทnext_mode=manualยทchati_next_abort audit 1).
- ๋ฌถ์5 ์๋ฃ โ ์ด์ Tier2 ์ผ๊ด ๋ฐฐํฌ(master push=Tier2 ์น์ธ ํ์) ์ฌ์ฉ์ ๊ฒฐ์ .
๊ฐฑ์ 2026-05-25 (48) โ ๋ฌถ์5(D3-c ์ฌ๋ผ์ฐํ ยทabort) ๊ตฌํ + ๊ฒ์ฆ #1/#2/#3 PASS, #4 reroute PASS ยท abort ๋ฐํ์ ๋ฒ๊ทธ ๋๋ฒ๊น ์งํ ์ค
NEXT ์ดํ 6๊ฐ โ 8๊ฐ ํ์ฅ (reroute ยท abort ์ ๊ท)
- ยง13 ๋งคํ: acceptโdone / resumeโresume / retryโcodi / retry-with-fixโcodi+draft / ํธ๋์คํโhandoff / ์ฌ๋ผ์ฐํ โreroute(์ ๊ท, progยทcodiยทchati_next_reroute) / ์์ค์ปฌ๋ ์ดํธโholdยทmanual / abortโabort(์ ๊ท, holdยทmanualยทchati_next_abort, terminal).
- reroute ๋ฐ๋ = ํจํด์ฐจ๋จ(stallโฅ3/์ฐ์์คํจโฅ3)+๋์ ๆ โ ๋ค๋ฅธ ์ ๊ทผ ์ ํ. abort = ๊ฐ๋ง์์/๋ฒ์๋ฐ/์์ ์๋ฐฐ ๋๋ ์ฌ์ฉ์ ์ค๋จ, terminal.
bridge-test 3ํ์ผ ํธ์ง (๋ฐฑ์ *.b5bak) + EC2-test tasks.py ํธ์ง (๋ฐฑ์ tasks.py.b5bak)
- chati.py: _NEXT_RE
|reroute|abort, _VALID_NEXT 8๊ฐ, _NEXT_ROUTING reroute/abort. - chati_chat_consumer.py(์ค์ ์๋์ํ): _NEXT_ALLOWED_VALUES 8๊ฐ, dispatch์์ chati_next_detectedยทcodi-pending ํธ๋ฆฌ๊ฑฐ
next_val in ("codi","reroute")๋ก ํ์ฅ(reroute๋ autorun) + reroute/next ๋ง์ปค. - persona.py: NEXT 8๊ฐ ๋ฌธ์ํ + ๋ฐ๋๊ธฐ์ค.
- EC2 tasks.py: code_map(L11291) rerouteโnext_codiยทabortโnext_hold. add_log(L11176) resume/handoff ๋ค
if next_val=='reroute':(audit) /elif next_val=='abort':(status=holdยทnext_mode=manualยทdetachยทauditยท_chati_progress). - ์ ๋ถ py_compile PASS, cmdboard-test ์ฌ์์ยท:8003 healthy. ์ด์ :8002ยท:8765 ๋ฌด์ ์ด.
๊ฐฑ์ 49 (2026-05-25) โ ๋ฌถ์5 abort ๋ฐํ์ ๋ฒ๊ทธ ๊ท๋ช ์๋ฃ
๊ฒฐ๋ก : abort ๋ฐํ์ ๋ฒ๊ทธ๋ ์ฝ๋ ๊ฒฐํจ ์๋. ๋ฌถ์5(D3-c) ๊ฒ์ฆ ์๋ฃ.
์กฐ์ฌ ๊ฒฝ์: ๊ฐฑ์ 48์ abort ๋ฒ๊ทธ(EC2 add_log ๋ผ์ฐํธ๋ฅผ test_client๋ก ํธ์ถ ์ abort ๋ถ๊ธฐ๋ง ๋ฏธ์คํ) ์์ธ ๊ท๋ช
์ ์ํด SSM์ผ๋ก EC2-test์์ fresh-process ์ฌํ ์คํ 3ํ ์ํ.
์คํ ๊ฒฐ๊ณผ:
1. ๊ธฐ์กด test DB์ chati_next_abort audit 5๊ฑด / reroute 3๊ฑด ์ด๋ฏธ ์กด์ฌ โ abort ๋ถ๊ธฐ๋ ๊ณผ๊ฑฐ์ ์ค์ ์ปค๋ฐ๋จ. ๊ฐฑ์ 48์ "audit 0"์ ๋น์ ๊ฒ์ฆ ์ธ์
์ด ๋ณด์ง ๋ชปํ ๊ฒ.
2. ์ dbg ์นด๋ abort POST โ POST 200. FRESH ์ธ์
ยทSTALE ์ธ์
ยทrollback ํ ๋ชจ๋ status=holdยทnext_mode=manualยทabort_audit=1 ๊ด์ธก. MySQL REPEATABLE READ ๊ฐ์ค์ stale ์ธ์
๋ ๋ฐ์์ ๋ดค์ผ๋ฏ๋ก ๊ธฐ๊ฐ.
3. ํ ํ๋ก์ธ์ค์์ rerouteโabort ์ฐ์ ์คํ(๊ฐฑ์ 48 ์์ฌ ์คํจ ํํ) ์ฌ๊ฒ์ฆ: VERDICT reroute=PASS abort=PASS โ ALL_PASS. reroute readback status=progยทreroute_audit=1, abort readback status=holdยทnext_mode=manualยทabort_audit=1.
๋์คํฌ ์ฝ๋ ํ์ธ: EC2-test tasks.py(์ด 11471์ค) add_log ํธ๋ค๋ฌ L11289~11469 ์ ํฉ. L11378 if next_val=='reroute'(chati_next_reroute audit only) / L11384 elif next_val=='abort'(task.status='hold'; task.next_mode='manual'; detach_chati_pending_for_task(source='chati_next_abort'); chati_next_abort audit; _chati_progress('next_hold')). ๋ค์ฌ์ฐ๊ธฐยท๋ก์งยทcommit(L11468) ๋ชจ๋ ์ ์.
์์ธ ํ์ : ์ด์ #4 "abort FAIL"์ ๊ทธ ์์ ๊ฒ์ฆ ํ๋ค์ค ์ํฐํฉํธ(๋จ์ผ ์ฅ๊ธฐ ํ๋ก์ธ์ค ๋ด ํธ์ง ์ ๋ชจ๋/test_client ์บ์ โ create_app ๋ถ์ํจ๊ณผ ๋๋ ํธ๋ค๋ฌ ๋ก๋โ๋์คํฌ ๋ถ์ผ์น). #4 ์ฌ๊ฒ์ฆ์ ๊นจ๋ํ fresh-process๋ก ์ํํ๋ ALL_PASS.
๊ฒ์ฆ ์ํ: ๋ฌถ์5(D3-c) ๊ฒ์ฆ #1/#2/#3 PASS, #4 rerouteยทabort ๋ชจ๋ PASS. ๋ฌถ์5 ๊ฒ์ฆ ์๋ฃ.
๋ค์: ๋ง์ง๋ง ์ด์ Tier2 ์ผ๊ด ๋ฐฐํฌ(master push 1ํ) = 1.x + D2 + 2.5 + ํ ํฐ๊ณตํต + D1 + chainA + ๋ฌถ์4 + ๋ฌถ์5. master push = Tier2 ์ฌ์ฉ์ ์น์ธ ํ์(์ฑํฐ ์์ ์งํ ๊ธ์ง). ํธ๋ฆฌ๊ฑฐ ํค์๋ cmd์๋๋ฐฐํฌ.
๋๋๋ฆฌ๊ธฐ: bridge-test .b5bak 3๊ฐ + EC2 tasks.py.b5bak ๋ณต์ยท์ฌ์์(DB ๋ฌด๋ณ๊ฒฝ, ๋กค๋ฐฑ ๋ถ์์ฉ 0).
๋ถ์ ์ฐ์ถ๋ฌผ(๋ฌดํด): EC2-test /tmp/dbgintrospect.pyยทdbg_abortrepro.pyยทdbg_b5verify.py ์์กด. test DB dbg ์นด๋: dbg-abrt-135407(id1443,hold), dbg-rr-135502(id1444), dbg-ab-135502(id1445,hold). dbg- prefix ๊ด๋ก์ ๋ฌดํด.
SSM ์๋ ํจํด(์ด๋ฒ ์ธ์
ํ์ )*: AWS-StartNonInteractiveCommand๋ start-session์ฉ ๋ฌธ์(send-command๋ InvalidDocument). ํ๊ธ/๋ํ ์คํฌ๋ฆฝํธ๋ base64 -w0 ์ธ์ฝ๋ฉ ํ echo B64 | base64 --decode | sudo -H -u ubuntu bash๋ก ์ ์ก(์ ์ฌ์ค๋ฅ ์ฐจ๋จ). ํ๊ฒฝ๋ณ์๋ set -a; . /home/ubuntu/cmdboard-test/.env; set +a ์ ํ. --parameters๋ JSON ํ์ผ file:// ์ ๋ฌ(shorthand ๋จ์ผ๋ฐ์ดํ ๊นจ์ง).
๊ฐฑ์ 49 (2026-05-25) โ ๋ฌถ์5(D3-c) ๊ฒ์ฆ ์๋ฃ (๋ฐฐํฌ ์น์ธ ๋๊ธฐ ์์ )
๋ฌถ์5(D3-c ์ฌ๋ผ์ฐํ ยทabort) ๊ฒ์ฆ ์๋ฃ. NEXT 6๊ฐโ8๊ฐ(rerouteยทabort) ํ์ฅ ์๋ฃ. bridge-test 3ํ์ผ + EC2-test tasks.py ํธ์งยท์ ์ฉ ์๋ฃ. ๊ฒ์ฆ #1/#2/#3 PASS, #4 rerouteยทabort ๋ชจ๋ PASS. abort ๋ฐํ์ ๋ฒ๊ทธ = ์ฝ๋ ๊ฒฐํจ ์๋(๊ท๋ช ์๋ฃ): EC2-test ๋์คํฌ ์ฝ๋(L11378 if reroute / L11384 elif abort) ์ ์, fresh-process test_client์์ abort ์ ์ ์คํ. ์ด์ #4 "abort FAIL"์ ๊ฒ์ฆ ํ๋ค์ค ์ํฐํฉํธ(๋จ์ผ ์ฅ๊ธฐ ํ๋ก์ธ์ค ํธ์ง ์ ๋ชจ๋ยทtest_client ์บ์ / create_app ๋ถ์ํจ๊ณผ)๋ก ํ์ . MySQL REPEATABLE READ ๊ฐ์ค ๊ธฐ๊ฐ. ๋ค์(๋น์): ๋ง์ง๋ง ์ด์ Tier2 ์ผ๊ด ๋ฐฐํฌ(master 1ํ) ์น์ธ ๋๊ธฐ. โ ๊ฐฑ์ 50์์ ์์ค ์ ํฉ์ฑ ๋ถ์ผ์น ๋ฐ๊ฒฌยทํด์.
๊ฐฑ์ 50 (2026-05-25) โ ๋ฌถ์5(D3-c) ์์ค ์ ํฉ์ฑ ๋ถ์ผ์น ๋ฐ๊ฒฌยทํด์ + ๊ฒฉ๋ฆฌํ ํ๊ท ALL_PASS
๊ฒฐ๋ก : D3-c ์ํ์ abort ์ฝ๋ ๋ฒ๊ทธ๊ฐ ์๋๋ผ ๋ฐฐํฌ ์์ค(๋ก์ปฌ master) โ EC2-test ๊ฒ์ฆ๋ณธ ์ ํฉ์ฑ ๋ถ์ผ์น์์. ํด์ ์๋ฃ.
๋ฐ๊ฒฌ(read-only): ๋ก์ปฌ master app/api/tasks.py ์ ๋ฌถ์4(maybe_handoff_new_card)ยท๋ฌถ์5(chati_next_reroute/abort) ์๋ฒ๋ถ๊ธฐ ๋ถ์ฌ. git grep 0๊ฑด. ์ด์(521a6f2)๋ ๋ง์ปค 0๊ฑด. ๋ฒ๋ค ๋ณ๊ฒฝ๋ถ(1.x/D2/2.5/ํ ํฐ/D1/chainA/๋ฌถ์4/๋ฌถ์5)์ EC2-test ๋์คํฌ์๋ง ๋ฏธ์ปค๋ฐ(685+/42-)์ผ๋ก ์กด์ฌ. ์ด๋ ฅ ๋ถ๊ธฐ: ๋ก์ปฌ HEAD d15f35c(=8b9f678+P1/P2/P3, origin/master=8b9f678 โ ๋ฏธํธ์ 3) / EC2-test HEAD 8b9f678+๋์คํฌ๋ฏธ์ปค๋ฐ / ์ด์ 521a6f2.
ํฌํ
(ํ
์คํธ ๋ฒ์ยท์ปค๋ฐ/ํธ์ ์์): EC2-test ๊ฒ์ฆ๋ณธ tasks.py(11471์ค/513840B/sha256 67d89ff5โฆ)๋ฅผ gzip+base64 SSM ์ฒญํฌ ์ ์ก โ ๋ก์ปฌ Python39 ๋ณต์(sha ์ผ์น). ๋ก์ปฌโEC2-test diff = EC2์๋ง 265์ค ์ถ๊ฐ, ๋ก์ปฌ์๋ง 20์ค(L114/L159 token ํจ์ docstring ํ
์คํธ ์ฐจ์ด + ๊ตฌ๋ฒ์ 4๊ฐ code_map). ์ฆ EC2-test๊ฐ ๋ก์ปฌ์ ๊ธฐ๋ฅ์ superset. ๋ฐฑ์
app/api/tasks.py.b5bak ์์ฑ ํ ๊ฒ์ฆ๋ณธ์ CRLF๋ก ๋ก์ปฌ์ ๊ธฐ๋ก โ LF์ ๊ทํ sha 67d89ff5 ์์ ์ผ์น, py3.9 ์ปดํ์ผ OK, ๋ง์ปค 4๊ฑด. git diffstat 570+/42-.
ํ๊ท(:8003/cmdboard_test, fixture soft-delete): 1์ฐจ ํ๋ค์ค(ec2_verify_b5runtime.py, ํ test_client ๋ธ๋ก ๊ณต์ ์ธ์
)๋ abort FAIL ์ฌํ. abort ๋จ๋
ํ๋ก๋ธ(ec2_probeabort.py)๋ PASS(status=holdยทnext_mode=manualยทchati_next_abort 1ยทdetach 1ยท์์ธ ์์). โ abort ์ฝ๋ ์ ์, 1์ฐจ FAIL์ ๊ณต์ test_client ์ธ์
๋์(ํ๋ค์ค ์ํฐํฉํธ). ๊ฒฉ๋ฆฌํ ํ๋ค์ค(ec2_verify_b5iso.py, ์ผ์ด์ค๋ณ ์ test_client+์ SessionLocal): ALL_PASS(0 fails) โ reroute๋จ๋
/abort๋จ๋
/rerouteโabort ์ฐ์(๊ฐ์ ์นด๋ยทํ๋ก์ธ์ค)/manual ํ๊ท. ๊ฐฑ์ 49 ๊ฒฐ๋ก (abort ์ฝ๋ ์ ์) ์ฌํ์ธ.
๋ชจ๋ธ enum ํ์ธ: status Enum('wait','prog','done','hold'), next_mode Enum('chati','codi','coki','manual') โ abort์ hold/manual ๋ชจ๋ ์ ํจ(enum ๊ฐ์ค ๊ธฐ๊ฐ).
๋ค์: (1) ๋ค๋ฅธ ๋ฒ๋คยท๊ธฐํ app/ ๋ณ๊ฒฝ ํ์ผ์ด ๋ก์ปฌ git ์์ค์ ๋ชจ๋ ๋ฐ์๋๋์ง ์ ์ฒด ํ์ผ ์ ํฉ ์ ๊ฒ โ (2) git ์ปค๋ฐ โ (3) master push(Tier2, cmd์๋๋ฐฐํฌ ์น์ธ). master push ์ฌ์ฉ์ ์น์ธ ํ์.
๋๋๋ฆฌ๊ธฐ: ๋ก์ปฌ app/api/tasks.py.b5bak ๋ณต์(DB ๋ฌด๋ณ๊ฒฝ, fixture๋ soft-delete ์ ๋ฆฌ๋จ).
์ฐ์ถ(๋ก์ปฌ): ๋ณด๊ณ ์ CLAUDE_CODE_๋ณด๊ณ _๋ฌถ์5_D3c_์ ํฉ์ฑํ์ธ2026-05-25.md, ํ๋ค์ค ec2_verify_b5iso.py / ec2_probeabort.py / ec2_verify_b5runtime.py, ๊ฒ์ฆ๋ณธ temp tasks_ec2test.py.
์ด์ ํ์ต: ๋ํ EC2 ํ์ผ ๋ก์ปฌ ๋ฐ์
= gzip -c | base64 -w0 โ SSM cut -c S-E ์ฒญํฌ โ ๋ก์ปฌ Python39 base64+gunzip โ sha256 ๋์กฐ. Windows native python์๋ C:/ ๊ฒฝ๋ก(์ฌ๋์) ์ ๋ฌ. ๋ก์ปฌ PowerShell ๋น๊ฐ์ฉ ํ๊ฒฝ์์๋ git-bash ๊ฒฝ๋ก(/c/...) + claude-code Bash ์ฌ์ฉ. SSM ๋ช
๋ น์ ( ๋ฑ sh ํน์๋ฌธ์ echo ๊ธ์ง(๊ตฌ๋ฌธ์ค๋ฅ).
๊ฐฑ์ 50~55 (2026-05-25~26 ยท ์์นด์ด๋ธ ์ด๋ 2026-05-26 ๊ฐฑ์ 56 ์์ )
๊ฐฑ์ 55 โ 3ํธ๋ ๋งค๋ญ
Track3 ๋งค๋ญ: Job1(per-checkpoint LLM supervisor)=๋ณด๋ฅ(์ค๋ฐ์ดํฐ 0๊ฑด, ํฌ์ ๊ทผ๊ฑฐ ๋ถ์กฑ), Job2(on-stop judge)=์ฑํ ์ ํจ(codi.py์์ judge ๋ฏธํธ์ถ=์ด๋ฏธ ๋ถ๋ฆฌ, ์ฑํฐ NEXT ๋ผ์ฐํ ์ด ์ข ๋ฃ-ํ ํ์ ), ๋ฏธํธ์ถ supervisor.py ๋ฌผ๋ฆฌ์ ๋ฆฌ(D1)=์ค๋ฐ์ดํฐ ํ ์ฌ๊ฒํ ๋ณด๋ฅ. 3ํธ๋ ์ ์ฒด: Track1=codi_done transient invalid ์ ๋ฆฌ(Phase137, +27์ค, EC2-test E2E PASS). Track2=per-chain cap baseline ์ ์ 5์นด๋/300ํธ์ถยทํ ๊ธ OFF(์ฝ๋๋ณ๊ฒฝ 0). Track3=์ฝ๋๋ณ๊ฒฝ 0. ์ค๋ฐ์ดํฐ ์์กด ํ์์ ๋์ ํ ์ฌ๊ฐ.
๊ฐฑ์ 54 โ Track2 ๋งค๋ญ
per-chain cap baseline ์ ์ ํ์ : cap=5์นด๋/300ํธ์ถ, CHAIN_CAP_ENABLED OFF ์ ์ง, ์ฐ์ฅ/์์ฒด์ธ UI๋ chain ์ค๋ฐ์ดํฐ ํ ์ฐฉ์. ๊ทผ๊ฑฐ: cmdboard_test chain ์ค๋ฐ์ดํฐ 0๊ฑด(54์นด๋ ๋จ๋ ), per-run baseline avg4,720/max11,450 ํ ํฐยทcycleโค3. ๊ฒ์ดํธยทescalateยทrollup์ ๋ฌถ์4 D3-b๋ก ๊ตฌํยทenv-configurable.
๊ฐฑ์ 53 โ Track1 ์๋ฃ(ํ ์คํธ ๋ฒ์)
codi_done ํธ๋ฆฌ๊ฑฐ transient invalid skip ์ ๋ฆฌ. Phase137 ๋ถ๊ธฐ: codi_done legacy ํ์ฒ๋ฆฌ ์ enriched codi_result_reported ๋์ฐฉ ์ payload invalid=์ ์ race โ await_codi_result_reported ์กฐ์ฉํ audit๋ง ๊ธฐ๋ก ํ return. ๋น-codi_done invalid๋ mismatch ๊ฒฝ๋ณด ๋ณด์กด. ๊ฒ์ฆ: ๋ก์ปฌ +27์ค(๋ฏธ์ปค๋ฐ, HEAD 7ae79e7) / EC2-test ์ ์ฉ(.p137bak)ยทE2E PASS. ์ด์ ๋ฏธ๋ฐ์.
๊ฐฑ์ 52 โ 3ํธ๋ ์์ ๋ถ๊ธฐ
ํ ์คํธ ๋ฒ์ 3ํธ๋ ์ ์(Track1 ๋ฐฑ๋ก๊ทธ๋ฒ๊ทธ/Track2 baselineยทํ๋์ธตB/Track3 supervisor ์ฑํํ๋จ). ์ด์ ์ผ๊ด๋ฐฐํฌ ๋ณด๋ฅ(์ ๋ฒ๋ค EC2-test ๊ฒ์ฆยท๋ก์ปฌ 7ae79e7 ๋ฏธํธ์4). ํธ๋์ปค ๋ฒ๋ค10 ์๋ฃยท์ด์๋ฐฐํฌ ๋ณ๋ ๋ณด๋ฅ์นด๋.
๊ฐฑ์ 51 โ git ์ ํฉ
๋ก์ปฌ ์ปค๋ฐ 7ae79e7(origin/master=8b9f678, ๋ฏธํธ์4=P1~P3+๋ฒ๋ค). ๋ก์ปฌ ์ํนํธ๋ฆฌ=๋ฐฐํฌ์์ค(EC2-test ๊ฒ์ฆ๋ณธ๊ณผ 77 ๋ฐ์ดํธ๋์ผ+์๋์ ์์์งํฉ3). ๋จ์ ๋จ๊ณ=์ด์ ์ผ๊ด๋ฐฐํฌ(์ฌ์ฉ์ ๋ช ์ ์): ์ด์RDS 016/009 ์ ์ฉโmaster pushโ๊ฒ์ฆ.
๊ฐฑ์ 50 โ ๋ฌถ์5(D3-c) ์์ค ์ ํฉ
EC2-test ๊ฒ์ฆ๋ณธ tasks.py๋ฅผ ๋ก์ปฌ ๋ฐ์ดํธ ๋์ผ ํฌํ (.b5bak, py์ปดํ์ผ OK). :8003 ๊ฒฉ๋ฆฌํ๊ท ALL_PASS. ์ด์ ๋ฐฐํฌ ์ ์ ์ฒด git ์ ํฉ ์ ๊ฒโ์ปค๋ฐโmaster push(Tier2) ํ์.
๊ฐฑ์ 51~55 (2026-05-26 ยท ์์นด์ด๋ธ ์ด๋: ๊ฐฑ์ 56 ์์ )
๊ฐฑ์ 51 โ git ์ ํฉ
๋ก์ปฌ ์ปค๋ฐ 7ae79e7(origin/master=8b9f678, ๋ฏธํธ์4=P1~P3+๋ฒ๋ค). ๋ก์ปฌ ์ํนํธ๋ฆฌ=๋ฐฐํฌ์์ค(EC2-test ๊ฒ์ฆ๋ณธ๊ณผ 77 ๋ฐ์ดํธ๋์ผ+์๋์ ์์์งํฉ3: _chati_progress=P3[HEAD]/models=docstring/app.js=์ฃผ์ยท์์). CRLF 11 LF์ ๊ทํ, py_compile OK, ๋ฐฐํฌ ๋ธํ 20ํ์ผ. ๋จ์ ๋จ๊ณ=์ด์ ์ผ๊ด๋ฐฐํฌ(์ฌ์ฉ์ ๋ช ์ ์): ์ด์RDS 016(tasks.supervisor_signal_override โ ๋ฏธ์ ์ฉ ์ tasks ์กฐํ 500)ยท009(task_code_mappings ๋ฉฑ๋ฑ) ์ ์ฉโmaster push(cmd์๋๋ฐฐํฌ)โ๊ฒ์ฆ. ์ด์ 521a6f2 active.
๊ฐฑ์ 52 โ 3ํธ๋ ์์ ๋ถ๊ธฐ
ํ ์คํธ ๋ฒ์ 3ํธ๋ ์ ์(Track1 ๋ฐฑ๋ก๊ทธ๋ฒ๊ทธ/Track2 baselineยทํ๋์ธตB/Track3 supervisor ์ฑํํ๋จ). ์ด์ ์ผ๊ด๋ฐฐํฌ ๋ณด๋ฅ(์ ๋ฒ๋ค EC2-test ๊ฒ์ฆยท๋ก์ปฌ 7ae79e7 ๋ฏธํธ์4). ํธ๋์ปค ๋ฒ๋ค10 ์๋ฃยท์ด์๋ฐฐํฌ ๋ณ๋ ๋ณด๋ฅ์นด๋ ๋ถ๋ฆฌ. ๊ธฐ๋ณธ ์น์ธ ๋ฒ์=ํ ์คํธ(:8003ยทcmdboard_test)๋ง.
๊ฐฑ์ 53 โ Track1 ์๋ฃ(ํ ์คํธ ๋ฒ์)
codi_done ํธ๋ฆฌ๊ฑฐ transient invalid skip ์ ๋ฆฌ. Phase137 ๋ถ๊ธฐ: codi_done legacy ํ์ฒ๋ฆฌ ์ enriched codi_result_reported ๋์ฐฉ ์ payload invalid=์ ์ race โ await_codi_result_reported ์กฐ์ฉํ audit๋ง ๊ธฐ๋ก ํ return. ๋น-codi_done invalid๋ mismatch ๊ฒฝ๋ณด ๋ณด์กด. codi_result_reported_missing ๋ณ๋ชฉํ์ง ์์ ๋ง ์ ์ง. ๊ฒ์ฆ: ๋ก์ปฌ app/api/tasks.py +27์ค(๋ฏธ์ปค๋ฐ, HEAD 7ae79e7) / EC2-test ์ ์ฉ(.p137bak)ยทcmdboard-test activeยท:8003 healthy / E2E 1์ฌ์ดํด PASS(handoff_invalid_skips=[], has_reanalysis=True). ์ด์ ๋ฏธ๋ฐ์. ๋๋๋ฆฌ๊ธฐ: git restore / cp .p137bak ํ ์ฌ์์. ๋ณด๊ณ ์ CLAUDE_CODE_๋ณด๊ณ _Track1_codi_done_skip_์ง๋จ์์ ๊ฒ์ฆ.md(๋ก์ปฌ).
๊ฐฑ์ 54 โ Track2 ๋งค๋ญ
per-chain cap baseline ์ ์ ํ์ : cap=5์นด๋/300ํธ์ถ, CHAIN_CAP_ENABLED OFF ์ ์ง(์ง๊ณ๋ง ๋ ธ์ถยทhandoff ์ฐจ๋จ ๋นํ์ฑ), ์ฐ์ฅ/์์ฒด์ธ UI๋ chain ์ค๋ฐ์ดํฐ ํ ์ฐฉ์. ๊ทผ๊ฑฐ: cmdboard_test chain ์ค๋ฐ์ดํฐ 0๊ฑด(54์นด๋ ์ ๋ถ ๋จ๋ )์ด๋ผ chain ํ ํฐ ์ค์ธก ๋ถ๊ฐ. per-run(์๋์ํ 1ํ) baseline=avg 4,720/max 11,450 ํ ํฐยทcycleโค3. 5์นด๋=๊ฒํ ์ฃผ๊ธฐ binding, 300ํธ์ถ=ํญ์ฃผ ์์ ๋ง. ๊ฒ์ดํธ(_chain_cap_status)ยทescalate(chati_handoff_blocked)ยทrollup์ ๋ฌถ์4 D3-b๋ก ๊ตฌํยทenv-configurable. ์ถ๊ฐ ์ฝ๋๋ณ๊ฒฝ/๋ฐฐํฌ ์์ด ๋งค๋ญ(์์ 5/300ยทํ ๊ธ OFF=ํ ์ฝ๋ ๊ธฐ๋ณธ๊ฐ).
๊ฐฑ์ 55 โ 3ํธ๋ ๋งค๋ญ(Track3)
Track3 ๋งค๋ญ(์ฑํํ๋จ): โ Job1(per-checkpoint LLM supervisor)=๋ณด๋ฅ(์ค์ ์ฝ๋๋ณ๊ฒฝ run baseline ๋ฏธ์์ง=chain/์ฝ๋๋ณ๊ฒฝ ์ค๋ฐ์ดํฐ 0๊ฑด, per-checkpoint LLM ํฌ์ ๊ทผ๊ฑฐ ๋ถ์กฑ, ํ๊ฐ๋ฌธ์ P2 ๊ถ๊ณ ์ผ์น) โก Job2(on-stop supervisor judge)=์ฑํ ์ ํจ(ํ ๋นํ์ฑ ์ ์ง: codi.py ์คํ๊ฒฝ๋ก์์ judge_codi_result/judge_completion ๋ฏธํธ์ถ=์ด๋ฏธ ๋ถ๋ฆฌ, ์ฑํฐ NEXT ๋ผ์ฐํ ์ด ์ข ๋ฃ-ํ ํ์ , ํ๊ฐ๋ฌธ์๋ ๊ธฐ๋ณธ OFF ๊ถ๊ณ ) โข ๋ฏธํธ์ถ supervisor.py ๋ฌผ๋ฆฌ์ ๋ฆฌ(D1 ๋ก์ปฌ bridge ์ ์ฉ)=์ค๋ฐ์ดํฐ ํ๋ณด ํ ์ฌ๊ฒํ ๋ณด๋ฅ. Track3 ์ถ๊ฐ ์ฝ๋๋ณ๊ฒฝ ์์. 3ํธ๋ ์ ์ฒด ๋งค๋ญ(ํ ์คํธ ๋ฒ์, ์ด์ ๋ฏธ๋ฐ์): Track1=codi_done transient invalid ์ ๋ฆฌ(Phase137, ๋ก์ปฌ+27์คยทEC2-testยทE2E PASS). Track2=per-chain cap baseline ์ ์ 5/300ยทํ ๊ธ OFF(์ฝ๋๋ณ๊ฒฝ 0). Track3=Job1 ๋ณด๋ฅยทJob2 ๋นํ์ฑ(์ฝ๋๋ณ๊ฒฝ 0). ์ค๋ฐ์ดํฐ ์์กด ํ์(Job1 ์ฑํยทchain cap ์ ๋ฐํยท์ฐ์ฅ/์์ฒด์ธ UIยทsupervisor ๋ฌผ๋ฆฌ์ ๋ฆฌ)์ ์ค์ฌ์ฉ chain/์ฝ๋๋ณ๊ฒฝ ๋ฐ์ดํฐ ๋์ ํ ์ฌ๊ฐ.
๊ฐฑ์ 56 (2026-05-26 ยท V2 Phase 1 ์๋ฃ)
V2 Phase 1(์นด๋์์ธ ๋ผ๋ฒจ ์ฑํฐโSARA) ์ด๋ฏธ ์ ์ฉยท๊ฒ์ฆ ์๋ฃ. ๋ผ๋ฒจ ๊ต์ฒด๊ฐ ์ด์ ๋ฒ๋ค(์ปค๋ฐ 7ae79e7ยท์๋ฒ HEAD 8b9f678) ๋ ํจ๊ป ๋ฐฐํฌ๋จ. ์ ๊ท ์ฝ๋๋ณ๊ฒฝ ๋ถํ์. ๊ฒ์ฆ: chati_chat_integration.js SARA ๋ผ๋ฒจยทsender ๋ถ๊ธฐ, app.js h3ยทplaceholder SARA, ๋ด๋ถ์๋ณ์ ์ ์ง, /api/tasksยท/api/agent/context 200, :8003 health 200. ์ด์ ๋ฏธ๋ฐ์(์ด์ ์ผ๊ด๋ฐฐํฌ ์นด๋ ํฌํจ). ๋ค์=์ฌ์ฉ์ ์ ๊ท ์ง์ ๋๊ธฐ(A ์ด์๋ฐฐํฌ / B ์ค๋ฐ์ดํฐ / C V2 Phase2+).
(2026-06-06 archive ์ด์ ) cmdboard ์์ด์ ํธ ํ์ดํ๋ผ์ธ ์ด๋ ฅ โ ๋ฌถ์1~5ยทJobยทPhase137
memory-agent-pipeline.md(memory-detail)์์ ์ด์ . ์๋ฌธ ๋ณด์กด(ํค๋ฉยท๋ณธ๋ฌธ). ํ ํฝ domain:agent.
๋ฌถ์1 ์คํ ๊ฒฐ๊ณผ + ์ฝ๋ ํ์ต (2026-05-25)
- ์ฝ๋ ๊ฒฐ๊ณผ ์ฌ๋ถ์ ๊ฒฝ๋ก =
chati_chat_consumer.pyโCHATI_GENERAL_CHAT_PROMPT(NOT CHATI_SYSTEM_PROMPT). CHATI_SYSTEM_PROMPT๋ ์ฌ๋ผ pull-mode ์ด๊ธฐ spawn ์ ์ฉ โ D1 4๊ธฐ์ค ํก์๋ GENERAL_CHAT_PROMPT์๋ ํ์(๋ฌถ์1.5). SUPERVISOR_JUDGE_ENABLED(config.py, ๊ธฐ๋ณธ False, runner_settings > env > False):codi.py(438-505) judge_codi_result/judge_completion ํธ์ถ ๊ฒ์ดํธ. False๋ฉด import๋ skip,supervisor_decision/critic_decision/supervisor_escalate_suppressedaudit ๋ฏธ๋ฐ์. ์๋์ํ์tasks.py_maybe_enqueue_chati_reanalysis_after_codi(8127~)๊ฐ ๋ด๋น โ judge OFF์ฌ๋ ๋ฏธ์ํฅ(ํ์ธ๋จ).- ๋ฌถ์1 ๊ฒ์ฆ(:8003, ์นด๋ dbg-bundle1-01): judge OFFยทaudit 0๊ฑดยท๋ฌด์ธ 1์ฌ์ดํด ๋ซํยทread-onlyโhold ์ ํ๋ถ๋ฅ ํ์ธ. ๋จ ํก์ ํ๋กฌํํธ ๋ฏธ๋ฐฐ์ (์) โ ์กฐ๊ฑด๋ถ ํต๊ณผ(๋ฌถ์1.5์์ ์ข ๊ฒฐ).
handoff_payload_invalid1๊ฑด =codi_done(rich payload ์์) ์์ ์๋๋ skip โcodi_result_reported์ฌํธ๋ฆฌ๊ฑฐ๋ก ์ฌ์ดํด ์ ์ ์ข ๊ฒฐ.- ์ํ ์์ = ํตํฉ์(์ธ์์ธ๊ณ์ ๊ฐฑ์ 33): ๋ฌถ์1.5 โ ๋ฌถ์2(D2)+๋ก๊ทธํ์คํ โ ๋ฌถ์2.5(3-zone)+๊ฒ์ดํธ์ง๋จ โ ํ ํฐ๊ณตํต๊ธฐ๋ก โ ๋ฌถ์3(D1์ญ์ ) โ chain rollup โ ๋ฌถ์4(D3-b) โ ๋ฌถ์5(D3-c)+๋ฐฐํฌ โ Job1์ฌ๊ฒํ . ํ๊ฐ์ 3๋ ๋ฐฉํฅ = supervisorโ์ฑํฐNEXT ์ฌ์ ๋ ฌ / ์ค๋จ์ฌ์ UIยท๋ก๊ทธ ๋ช ์ / ํ ํฐยท์ฒด์ธยทํธ๋์คํ ์ค์ธก ์ฐ๊ฒฐ.
์ฝ๋ ํ์ต ยท ์ด์ ํจํด ์ถ๊ฐ (2026-05-25, ๋ฌถ์1.5/1.6 ์ธ์ )
์๋์ํ done ๋ฐฐ์ (๋ฌถ์1.6)
- ์ฌ๋ถ์ ๊ฒฝ๋ก done์ status ์ ์ด๊ฐ ์ ๋์์:
chati_chat_consumer.pyPhase4๋ NEXT๋ฅผ activity_log๋ก๋ง ๊ธฐ๋ก. ์ด๊ธฐ spawn(chati.py:154 _NEXT_ROUTING)๋ง doneโstatus=done. ์ฌ๋ถ์ done์ด ์นด๋๋ฅผ ๋ชป ๋ซ์. - ์์ = cmdboard
app/api/tasks.py์chati_next_detectedํธ๋ค๋ฌ์ NEXT=done ์๋์๋ฃ ๋ถ๊ธฐ. ํ ๊ธCHATI_AUTODONE_ENABLED(๊ธฐ๋ณธ False) + ๋ฉฑ๋ฑ + asking>0 skip +chati_autodone_applied/skippedaudit + complete_task ๋์ผ ์ ์ด(status=done + completed_at +detach_chati_pending_for_task(done=True)). ํฌํผ_is_chati_autodone_enabled(). - ์์ฌ race: autodone done ์ ์ฉ ์งํ ์ง์ ํ์๋
chati_next_codi_requested๊ฐ done ์นด๋์์ ์ฝ๋ 1ํ ๋ ํธ๋ฆฌ๊ฑฐ(๊ฐ๋ ํ์ด๋ฐ ์ฐํ). ์๊ธฐ์๋ณต๋๋ ์์ฌ ์ฝ๋ 1ํ. ๋ณด๊ฐ์ = autodone ํธ๋์ญ์ ์์ ํ์ฑ pending_external codi ์์ฒญ ๋๋ฐ ์ ๋ฆฌ.
์ฑํฐ max_turns (๋ฌถ์1.6b)
- ์ฑํฐ SDK
max_turns๋bridge/app/services/claude_client.py์ ์์(์ฝ๋ runner์CODI_RUNNER_MAX_TURNS์ ๋ณ๊ฐ). ํ๋์ฝ๋ฉ 8 โsettings.CHATI_MAX_TURNS(config.py, ๊ธฐ๋ณธ 8). ์ฌ๋ถ์ ๊ฒฝ๋ก๋ ์ฝ๋ ๊ฒฐ๊ณผ ๋ถ์์ผ๋ก ๋๊ตฌ ํธ์ถ์ด ๋ง์ 8 ๋ถ์กฑ โ ์ด๊ณผ ์ fallback NEXT=manual. ํ ์คํธ 20์ผ๋ก ์ํฅ.
supervisor judge ์ ๊ฑฐ (ํ์ 2026-05-25 ยท ๊ฐฑ์ 43, ๋ฌถ์3 D1)
- bridge
supervisor.py(judge_codi_result/judge_completion/_summarize_codi_result(signal ๋น๋)/parse ํฌํผ) ์ญ์ . codi.pyrequest_codi_for_task์ judge ํธ์ถ ๋ธ๋กยทํ ๊ธ ํด์๋ถ ์ ๊ฑฐ.SUPERVISOR_JUDGE_ENABLEDยทSUPERVISOR_USER_ESCALATE_ENABLED(config) ์ ๊ฑฐ. - ์ฝ๋ ๊ฒฐ๊ณผ ํ์ ์ ์ฑํฐ CHATI 4๊ธฐ์ค ๋จ๋ (done/codi/hold/manual). timeout/stall+commit ์ผ์ด์ค(completed_with_timeout/stall)๋ ์ฑํฐ๊ฐ ํ์ . codi_result ํ์ฒ๋ฆฌ(codi_result_reportedโ์ฑํฐ ์ฌ๋ถ์)๋ ๋ณ๊ฒฝ ์์.
- ๋ณด์กด(D2 ์ฌ์ฌ์ฉยท๊ณผ๊ฑฐ ๋ก๊ทธ ํธํ): migration 015/016,
models.ActivityLog.modeenum 'supervisor',tasks.supervisor_signal_override์ปฌ๋ผ. DB ์คํค๋ง ๋ฌด์ ์ด. - supervisor ์์กด ํ
์คํธ 4๊ฐ ์ญ์ (test_supervisor_job2/test_p2_supervisor_critic_parse/test_p1_timeout_git_reconcile/test_critic_completion). ๋ฐฑ์
.d1bak. bridge-test ์ ์ฉยท์ด์/master ๋ฏธ๋ฐ์(๋ง์ง๋ง ์ผ๊ด).
๋ฌถ์4 (D3-b) ์ง๋จ ยท ์ค๊ณ ํ์ (2026-05-25)
- ์ฑํฐ NEXT ๋ผ์ฐํ
๊ตฌ์กฐ:
_VALID_NEXT = {manual, codi, done, hold}(bridgechati.py). ์๋ต ์ ์ด ๋ธ๋ก =chati_next{ next, codi_instruction_draft }.codi_instruction_draft๋ ์ด๋ฏธ ๋น์์ค ์์น(์์ฝ ๊ธ์งยท์ ๋ ๋ณด์กด)์ผ๋ก ์ด์ โ continuation brief๋ ๋์ผ ํจํด ์ ์ฉ. - ์ฑํฐ transcript ์์ง ์ํ:
ResultMessage.usageํ ํฐ ์ค์ธก +ToolUseBlock๋๊ตฌ๋ช โ /ToolResultBlock(๋๊ตฌ ๊ฒฐ๊ณผ)ยท์ ์ฒด transcript โ (claude_client.py). - chain rollup A:
_chain_rollup_for(db, chain_id)๊ตฌํ๋จ(card_count/total_calls/total_tokens/total_cycles, deleted_at IS NULL). per-chain ์ฒ์ฅ ๊ฒ์ดํธ(B) ๋ฏธ๊ตฌํ. - D3-b ์ค๊ณ = A์(SDK ์ธ์ ๋ณด์กด X, continuation brief ์ฌ์ฃผ์ ). ๋น์์ค ์ ์ฝ: context_basis(๊ฒฐ์ ยท์ด์ /์คํจ์๋+์์ธ/gotchas/repoยท์นด๋ ์ต์ปค)ยทremaining(์ด์ด์ง ์์ )์ ์์ฝยท์ญ์ ๊ธ์งยท์์ธ ๋ณด์กด. done_digest๋ง ์์ถ ํ์ฉ.
- handoff = ์ ์นด๋
chain_id์์ + brief seed + per-chain cap ๊ฒ์ดํธ(ํ ๊ธCHAIN_CAP_ENABLEDOFF ๊ธฐ๋ณธ, ์ ์ 5์นด๋/300ํธ์ถ).
๋ฌถ์4(D3-b) resumeยทํธ๋์คํ โ ๊ฒ์ฆ ํ์ ์ฌ์ค (2026-05-25 ๊ฐฑ์ 47)
- resume ์ฌ์ฃผ์
๊ฒฝ๋ก(A์): SDK ์ธ์
๋ฏธ๋ณด์กด.
chati_chat_consumer.py(220~247ํ)๊ฐ ์นด๋ detail ์continuation_brief๋ฅผ ํ๋กฌํํธ ํ ์คํธ("## ์ด์ด๊ฐ๊ธฐ ๋ธ๋ฆฌํ")๋ก ์ฃผ์ ํ๋ค.claude_client.py๋ SDK ๋ฆด๋ ์ด๋ผ ๋ณ๊ฒฝ ๋ถํ์(๋ฏธ๋ณ๊ฒฝ=์๋). EC2tasks.pyget_task detail(4313_latest_continuation_brief)์ด ์ต์ brief ๋ฅผ surface โ ๋ค์ ์ฌ์ดํด์ด ๊ฐ์ ์นด๋๋ฅผ ์ด์ด๊ฐ. - chati_next_detected ํธ๋ค๋ฌ ๋ฐฐ์ (EC2
tasks.pyadd_log 11176, ๋ถ๊ธฐ 11346):if next_val in ('resume','handoff'). resume(11349)=chati_resume_brief๋ก๊ทธ + status prog ์ ์ง(์นด๋ ์ ๋ซ์). handoff(11360)=_maybe_handoff_new_card(db, task, brief, payload)try/except. _maybe_handoff_new_card(7724): chain_id ์์(์์ผ๋ฉด source.task_code ๋ก ๋ฃจํธ ํ๋ฆฝ) + per-chain cap ๊ฒ์ดํธ(_chain_cap_status,CHAIN_CAP_ENABLED๊ธฐ๋ณธ OFF โ exceeded ํญ์ False) โ ์ ์นด๋ ์์ฑ(status='wait', next_mode='chati', chain_id ์์) + brief ๋น์์ค ์๋(context_basis/remaining ์ ๋) +chati_handoff_seeded/chati_handoff_created๋ก๊ทธ. cap ์ด๊ณผ ์ ์นด๋ ์์ฑ ์์ดchati_handoff_blocked+escalate.- ๋น์์ค ๋ถ๋ณ์:
_parse_continuation_brief(consumer)ยทhandoff ์๋ ๋ชจ๋ context_basis/remaining ๊ธธ์ด ์ํ ์์(์์ฝยท์ ๋จ ๊ธ์ง). done_digest ๋ฑ๋ง ์์ถ ํ์ฉ. - ๊ฒ์ฆ ํจํด(์ฌ์ฌ์ฉ): handoff chain_id ์์ ๊ฐ์ write ๋ก์ง์ EC2 venv 3.11.10 ์์
from app.db import SessionLocal์ธ์ ์ผ๋ก db.add+flush ํdb.rollback()โ ํ ์คํธ DB ์์ํ 0 ์ผ๋ก ๊ฒ์ฆ. ASCII-only Python probe +ensure_ascii=TrueJSON ์ถ๋ ฅ์ผ๋ก cp949 ํํผ. SSM ์ claude-code Bash ๋ก์ปฌ aws send-command(๋น๋๊ธฐ polling), aws-api MCP ๋ ssm:SendCommand ๋ถ๊ฐ.
๋ฌถ์4 ๋ฌด์ธ 1์ฌ์ดํด ๊ฒ์ฆ ๊ฒฐ๊ณผ + ๋ฐฑ๋ก๊ทธ ๊ด์ฐฐ (2026-05-25 ๊ฐฑ์ 47)
- ๋ฌด์ธ 1์ฌ์ดํด PASS: ๋ผ์ด๋ธ read-only ์นด๋(dbg-cyc1-111633) ์์จ ์ฌ์ดํด
wait โ chati(next=codi) โ codi ์คํ(๋ณ๊ฒฝ0) โ codi_done โ chati ์ฌ๋ถ์(next=done) โ chati_autodone_applied โ status=done. ๋ฌถ์1.6 autodone + bundle4 ๊ณต์กด ๋ฌดํ๊ท. resume/handoff ๋ถ๊ธฐ๋ read-only ์นด๋๋ผ ๋ฏธ๋ฐํ(์ ์). - ๊ฒ์ฆ ํจํด: ๋ฌด์ธ 1์ฌ์ดํด ๋๋ผ์ด๋ฒ =
scripts/_cycle_verify_one.py(EC2 venv ์คํ, project pfs, dbg- prefix +autorun_debug_test_started๋ง์ปค ํ์, build_initial_chati_instruction+enqueue_chati_message_for_task). bridge-test(:8766)๊ฐ :8003 ํด๋ง(claim-next/tasks?status=wait&next_mode=chati)์ผ๋ก ๊ตฌ๋. SSM ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ธฐ๋์setsid ... > log 2>&1 < /dev/null &ํ ๋ก๊ทธ ํด๋ง. - ๋ฐฑ๋ก๊ทธ(๋ฌถ์4 ๋ฒ์ ๋ฐ): read-only codi ๊ฒฐ๊ณผ์
codi_doneํธ๋ฆฌ๊ฑฐ ์ฌ๋ถ์์ดhandoff_payload_invalid(codi_handoff_payload_mismatch_detected)๋ก skip๋จ. ์ฌ์ดํด์codi_result_reportedํธ๋ฆฌ๊ฑฐ ์ฌ๋ถ์์ผ๋ก ์ ์ ์ข ๊ฒฐ๋๋ฏ๋ก ๋น์ฐจ๋จ. ๋ฌถ์1.5_build_codi_result_handoff_payloadread-onlyโnot_deployed ๋ถ๊ธฐ๊ฐ codi_done ํธ๋ฆฌ๊ฑฐ ๊ฒฝ๋ก์ ๋ฏธ์ ์ฉ์ผ๋ก ์ถ์ . cycle-verify ํ๋์ค PartB(handoff_invalid_skips empty ๊ธฐ๋)๊ฐ ์ด๋ก ์ธํด FAIL ํ๊ธฐ๋๋ ์ค ์นด๋๋ done. ์ถํ ์ ๋ฆฌ ํ๋ณด.
(2026-05-25 ๊ฐฑ์ 50) ๋ฌถ์5(D3-c) ์์ค ์ ํฉ์ฑ + ์ด์ ํจํด
- ์ด๋ ฅ ๋ถ๊ธฐ ์ฌ์ค: ๋ฒ๋ค(1.x/D2/2.5/ํ ํฐ/D1/chainA/๋ฌถ์4/๋ฌถ์5) ์๋ฒ ๋ณ๊ฒฝ๋ถ์ EC2-test ๋์คํฌ์๋ง ๋ฏธ์ปค๋ฐ ์กด์ฌ โ git(๋ก์ปฌ masterยทorigin)ยท์ด์ ๋ฏธ๋ฐ์. ๋ก์ปฌ HEAD d15f35c(=8b9f678+P1/P2/P3 codi-autocycle, origin/master=8b9f678 ๋ฏธํธ์3) / EC2-test HEAD 8b9f678 + tasks.py ๋์คํฌ 685+/42- / ์ด์ HEAD 521a6f2. โ ์ด์ ์ผ๊ด ๋ฐฐํฌ ์ git ์์ค ์ ํฉ ์ ์ฒด ์ ๊ฒ ํ์.
- D3-c abort ์ฝ๋ ์ ์ ํ์ : status Enum('wait','prog','done','hold'), next_mode Enum('chati','codi','coki','manual') โ abort์ hold/manual ๋ชจ๋ ์ ํจ. abort ๋จ๋ POST๋ status=holdยทnext_mode=manualยทchati_next_abort audit 1ยทdetach 1 ์ ์. ๊ณผ๊ฑฐ "abort FAIL"์ ํ test_client ๋ธ๋ก์์ ์ฌ๋ฌ POST ๊ณต์ ์ธ์ ๋์(๊ฒ์ฆ ํ๋ค์ค ์ํฐํฉํธ). ํ๊ท ํ๋ค์ค๋ ์ผ์ด์ค๋ณ ์ test_client + ์ SessionLocal๋ก ๊ฒฉ๋ฆฌํด์ผ ALL_PASS.
- D3-c ๋ผ์ฐํ : rerouteโstatus ๋ฏธ์ ์ฐฉ(prog ์ ํ์ bridge๊ฐ ํจ๊ป ๋ณด๋ด๋ chati_codi_pending(reroute=True) autorun ๊ฒฝ๋ก ๋ด๋น), abortโstatus=holdยทnext_mode=manual ์ง์ ์ธํ (terminal). EC2-test tasks.py L11291 6๊ฐ code_map, L11378 if reroute / L11384 elif abort, _maybe_handoff_new_card L7724.
- ์ด์ ํจํด โ ๋ํ EC2 ํ์ผ ๋ก์ปฌ ๋ฐ์
:
gzip -c FILE | base64 -w0 > /tmp/x.b64โ SSMcut -c S-E /tmp/x.b64์ฒญํฌ(20000์) ๋ฐ๋ณต ์์ ยท๋ก์ปฌ ๋์ โ ๋ก์ปฌ Python์ผ๋กgzip.decompress(base64.b64decode(...))โ sha256 ๋์กฐ. Windows native python์๋ C:/ ์ฌ๋์ ๊ฒฝ๋ก ์ ๋ฌ(/c/ git-bash ๊ฒฝ๋ก ์ธ์ ๋ชป ํจ). ๋ก์ปฌ PowerShell ๋น๊ฐ์ฉ ๋ฐํ์์์ claude-code Bash + git-bash ๊ฒฝ๋ก(/c/...). SSM AWS-RunShellScript commands์(๋ฑ sh ํน์๋ฌธ์ echo ๊ธ์ง(๊ตฌ๋ฌธ์ค๋ฅ). - ๊ฒ์ฆ๋ณธ SoT: EC2-test working-tree tasks.py(sha256 67d89ff5โฆ, 11471์ค/513840B)๊ฐ D3-c ๊ฒ์ฆ๋ณธ. ๋ก์ปฌ ํฌํ ๋ณธ์ LF์ ๊ทํ sha ๋์ผ.
์ฝ๋ ํ์ต โ Phase137 codi_done transient invalid (2026-05-26)
- ํ์: codi_done(legacy) ํธ๋ฆฌ๊ฑฐ ์ฌ๋ถ์ ํ์ฒ๋ฆฌ์์ handoff_payload_invalid skip ๋ก๊ทธ + mismatch ๊ฒฝ๋ณด + ์ฌ์ฉ์-๊ฐ์ "์ฌ๋ถ์ skip" ๋ฉ์์ง๊ฐ ๋งค ์ฌ์ดํด ๋ฐ์(์คํด์ฑ ๋ ธ์ด์ฆ).
- ๊ทผ๋ณธ์์ธ: Bridge
apply_codi_result(bridge/app/services/codi.py)๊ฐ ํ ์ฌ์ดํด์์ โ legacy codi_done โ โก ํ์ค codi_result_reported ๋ฅผ ๋ ๋ฒ์ ๋ถ๋ฆฌ๋ add_log ๋ก ์์ฐจ ์ ์ก. cmdboard_maybe_enqueue_chati_reanalysis_after_codi(app/api/tasks.py)๊ฐ ๋ ๋ก๊ทธ ๋ชจ๋์์ ํธ์ถ๋จ. codi_done ์ฒ๋ฆฌ ์์ ์ enriched codi_result_reported ๊ฐ ์์ง DB ์ ์์ด latest_report ๊ธฐ๋ฐ handoff payload ๊ฐ invalid(์ ์ race). ์งํ codi_result_reported ๊ฐ enriched payload ๋ก ์ ์ enqueue โ ์ฌ์ดํด์ ํญ์ ์ ์ ์ข ๊ฒฐ. - ํด๊ฒฐ(Phase137):
if not _hp_valid:์ต์๋จ์trigger_action=='codi_done'์ ์ฉ ๋ถ๊ธฐ. ์ฌ์await_codi_result_reported๋ก ์กฐ์ฉํchati_reanalysis_skippedaudit 1๊ฑด(transient:True, phase:137)๋ง ๊ธฐ๋ก ํ return._audit_skip๋ฏธ์ฌ์ฉ โ ์ฌ์ฉ์-๊ฐ์ ๋ฉ์์งยทmismatch ๊ฒฝ๋ณด ์์. ๋น-codi_done invalid ๋ ๊ธฐ์กด mismatch ๊ฒฝ๋ณด ๊ฒฝ๋ก ๋ณด์กด.codi_result_reported_missing๋ณ๋ชฉํ์ง๊ฐ ์์ ๋ง. - ๊ฒ์ฆ: ๋ก์ปฌ app/api/tasks.py +27์ค(๋ฏธ์ปค๋ฐ, HEAD 7ae79e7), EC2-test ์ ์ฉ(.p137bak ๋ฐฑ์ ), E2E 1์ฌ์ดํด PASS(handoff_invalid_skips=[], has_reanalysis=True). ์ด์ ๋ฏธ๋ฐ์(ํ ์คํธ ๋ฒ์). ๋ณด๊ณ ์ CLAUDE_CODE_๋ณด๊ณ _Track1_codi_done_skip_์ง๋จ์์ ๊ฒ์ฆ.md(๋ก์ปฌ).
์ํคํ ์ฒ ๊ฒฐ์ โ Job1/Job2 supervisor ์ฑํํ๋จ (2026-05-26 Track3)
- Job2 = on-stop supervisor judge(์ฝ๋ run ์ข
๋ฃ ์งํ codi_result ํ์ ). ๊ตฌํ: bridge/app/services/supervisor.py
judge_codi_result(accept/reroute/abort ๋ฑ) +judge_completion(critic). ํ์ฌ bridge/app/services/codi.py ์คํ๊ฒฝ๋ก์์ ๋ฏธํธ์ถ = ์ด๋ฏธ ๋นํ์ฑ. ์ฑํฐ NEXT ๋ผ์ฐํ ์ด ์ข ๋ฃ-ํ ํ์ ์ญํ ์ํ ์ค. โ ์ฑํ ์ ํจ(ํ ๋นํ์ฑ ์ ์ง). ํ๊ฐ๋ฌธ์(cmdboard_progress_evaluation.md ยง3.1) ๊ถ๊ณ ์ ์ผ์น: supervisor ๋ณ๋ LLM judge ๊ธฐ๋ณธ OFF, critic ๊ธฐ์คยทescalate ๋ก๊ทธยทaudit schema๋ง ์ถ์ ์กด์น. - Job1 = per-checkpoint LLM supervisor(์ฝ๋ ์งํ ์ค๊ฐ ์ฒดํฌํฌ์ธํธ๋ง๋ค ํฌ์ , ๋ฏธ๊ตฌํ). ํ๊ฐ๋ฌธ์ P2 ๊ถ๊ณ : "์ค์ ์ฝ๋๋ณ๊ฒฝ run baseline ์์ง ํ ํ๋จ, ํ์ฌ read-only baseline๋ง์ผ๋ก๋ per-checkpoint LLM ํฌ์ ๊ทผ๊ฑฐ ๋ถ์กฑ." chain/์ฝ๋๋ณ๊ฒฝ ์ค๋ฐ์ดํฐ 0๊ฑด โ ๋ณด๋ฅ.
- ๋ฏธํธ์ถ ์ฝ๋ ์ ๋ฆฌ: supervisor.pyยทtests/test_supervisor_job2.py ๋ bridge(๋ก์ปฌ)์ ์์กด, bridge-test ์ D1 ๋ฌผ๋ฆฌ์ญ์ ์ ์ฉ(.d1bak ๋ฐฑ์ ). ๋ก์ปฌ bridge ๋ฌผ๋ฆฌ์ ๋ฆฌ๋ ์ค๋ฐ์ดํฐ ํ๋ณด ํ ์ฌ๊ฒํ (๋ณด๋ฅ).
- ์ข ํฉ: ์ค์ฌ์ฉ chain/์ฝ๋๋ณ๊ฒฝ ๋ฐ์ดํฐ๊ฐ ์์ด๊ธฐ ์ ๊น์ง supervisor ๋ณ๋ LLM ๊ฒฝ๋ก๋ ๋ฏธ์ฑํ. ์ข ๋ฃ-ํ ํ์ ์ ์ฑํฐ NEXT ๋จ๋ ์ผ๋ก ์ถฉ๋ถ(ํ ์ด์ ํ๋ก).