Phase 2 작업을 끝내고 main에 머지했다. Phase 3의 목표인 RefreshCoordinator 구현이었다. Account와 Market의 자동 갱신 Timer 책임을 MainWindow 밖으로 옮기고, 기존 옵션과 기본값, 갱신 주기와 동작은 그대로 유지하는 작업이었다. Phase 2가 꽤 큰 작업이었기 때문에 Phase 3 계획을 다시 확인하면서 처음 든 생각은 단순했다.
이건 큰 작업은 아니겠네.
그런데 실제 작업은 예상과 전혀 다른 방향으로 흘러갔다.
Phase 3를 시작했는데 이미 끝나 있었다
Phase 2 작업을 완료한 후, 상태에서 Phase 3 작업을 Codex에게 진행시켰는데 프롬프트 실행후 얼마되지 않아 바로 작업 완료 및 Codex가 PR까지 요청한 상태로 마무리 되어있었다.


그리고 Codex는 아래와 같은 프롬프트 실행 결과를 보고하였는데....
현재 main에는 Phase 2에서 이미 RefreshCoordinator 책임 이전이 완료되어 있어 production code를 중복 변경하지 않았습니다.
계획에서는 Phase 2와 Phase 3를 나눠놨는데, 실제 Phase 2 작업에서 Account 구조를 정리하다 보니 Account와 Market의 periodic Timer까지 이미 RefreshCoordinator로 이동해 있었다. 굳이 Phase 3라는 이름에 맞추기 위해 이미 끝난 production code를 다시 건드릴 이유는 없었다.
그래서 방향을 바꿨다. 이미 목표 구조가 만들어져 있다면 다시 고치지 않고, 그 구조가 Phase 3의 의도대로 동작하는지 테스트로 고정하기로 했다. Phase 3에서는 production code를 변경하지 않았다. 대신 Timer 소유권, 기존 옵션과 기본값, 수동·자동 갱신 진입점, Signal 중복 방지, startup prefetch, 종료 시 Timer 정리 등을 회귀 테스트로 확인했다.
결과적으로 Phase 3는 새 구조를 만드는 작업이 아니라, Phase 2에서 선행된 구조를 명시적인 계약으로 고정하는 작업이 됐다.
간헐적 파괴자인 ChatGPT가 또 사고를 쳤다
문제는 그다음이었다. 나는 보통 Step 하나를 끝내고 결과를 확인한 뒤 다음 Step으로 넘어가는 방식으로 작업해왔다. ChatGPT도 그 패턴을 계속 보고 있었기 때문에 이번에도 그 흐름이 유지될 거라고 생각했다. 그런데 ChatGPT가 만든 Codex 전달 프롬프트에는 정작 중요한 문장이 빠져 있었다.
현재 Step이 끝나면 멈춘다.
Step 단위로 작업하라고는 적혀 있었지만, Step 하나만 하고 멈추라고는 적혀 있지 않았다.
Codex는 프롬프트대로 움직였다.
Step 1 → Step 2 → 최종 검증 → commit → push → PR → Connector review → CLEAN
최종 응답에는 PR #13이 열려 있고 Connector 리뷰도 CLEAN이라고 적혀 있었다. 아니, 누가 PR까지 하랬냐.
Codex가 말을 안 들은 게 아니었다. 아직 PR 생성 시점을 별도 규칙으로 정해둔 것도 아니었다. 다만 평소 작업은 Step별로 끊어서 확인해왔기 때문에 나도 그 패턴이 그대로 이어질 거라고 생각했다. 문제는 내 작업 습관을 알고 있던 ChatGPT가 그것을 실제 실행 규칙으로 꼼꼼하게 옮기지 않았다는 것이었다. 물론 자세히 확인하지 않는 내 문제도 있었다. 매번 ChatGPT가 수백라인의 프롬프트를 생성하니 그녀석도 실수하고 나도 알아서 잘했겠지라는 안일하게 행동해서 공동 참사가 발생했다. 뭐 실제 벌어진 일은 큰 문제는 아니었으나, 현 작업 프로세스에서 관가하고 있던 문제가 발생한 것이다. 이것에 대해 조금 고민해 필요가 있어 보였다.
찜찜해서 다시 확인했다
거기다 이번 작업은 원래 구현용으로 쓰던 Luna가 아니라 Sol로 Codex가 끝까지 진행한 상태였다. Codex 대화창은 PR 단위로 새로 생성해서 작업하기 때문에 기본 값인 Sol 모델로 설정이 된 상태로 작업을 진행하였다. 그렇다고 결과가 틀렸다는 의미는 아니었지만, 예상보다 너무 빨리 Phase 3가 끝나버렸기 때문에 정말 완료된 것이 맞는지 다시 확인하기로 했다.
이번에는 Luna에게 코드 수정, commit, push, PR 조작을 모두 금지하고 Git 계보와 Phase 2/3 devlog, production code, 테스트만 읽기 전용으로 다시 검증하게 했다. 결과는 명확했다.
Phase 2는 정상적으로 main에 머지되어 있었고, Phase 3 branch도 그 이후 main에서 시작했다. 그리고 Phase 2 작업 과정에서 이미 RefreshCoordinator 책임 이전이 완료돼 있었다. Phase 3 branch의 production code 변경은 없었고, 추가된 테스트도 원래 Phase 3에서 확인하려던 계약을 제대로 검증하고 있었다. 결론은 Phase 3 완료, PR #13 merge 가능이었다.
실제 동작까지 다시 확인한 뒤 머지했다. 이번에는 결과적으로 코드에 문제가 없었지만 대신 작업 방식에서 두 가지를 확실히 알게 됐다.
- Phase 계획이 실제 코드 경계를 보장하지 않는다.
- 앞 Phase를 진행하다 보면 코드 의존성 때문에 다음 Phase의 작업까지 선행될 수 있다.
- ChatGPT가 내 작업 습관을 안다고 해서 그 습관이 자동으로 실행 규칙이 되는 것은 아니었다.
그래서 다음 Phase부터는 시작 전에 이전 Phase가 실제로 어디까지 변경했는지 먼저 확인하고, Codex에는 현재 Step만 수행한 뒤 테스트, devlog, commit, push까지 마치고 반드시 멈추도록 명시하기로 했다. 처음에는 작은 구조 정리라고 생각했다.
막상 끝나고 보니 이번 Phase에서 가장 크게 바뀐 것은 코드가 아니라 AI와 작업하는 방식이었다.
