문제의 출발점
두 함수의 반환값이 맞아도 기존 함수를 재사용하라는 요청은 어길 수 있었어요. 이제 필요한 질문은 Task를 몇 개 만들지에 대한 질문보다 먼저 나와요. 어떤 해결 방법이 목표와 제약을 함께 만족할 수 있을까요?
AI가 첫 번째로 만든 작업 목록을 곧바로 실행하면, 그 목록에 담긴 접근 자체가 맞는지 검토할 기회를 놓치기 쉬워요. 반대로 가능한 방법마다 모든 파일과 명령을 상세히 정하면 실행하지 않을 후보에도 많은 작업을 하게 돼요. VibeMarshal의 계획기는 먼저 경로의 뼈대를 검토하고, 남은 후보를 상세 Plan으로 확장해요.
먼저 적합하지 않은 경로를 걸러내기
계산 사례에 다음 대안을 놓아 볼 수 있어요. 이 표는 설계 판단을 설명하기 위한 비교이며, 실제 모델이 세 후보를 생성한 실행 기록은 아니에요.
| 설명용 접근 | 목표와 제약을 대조할 내용 |
|---|---|
A 두 함수만 구현하고 기존 cents 재사용 | 반환값, 재사용 조건, 허용 파일과 전체 검사를 확인 |
| B 금액 처리를 새 모듈로 통합하고 공개 함수까지 변경 | 설계상 장점이 있어도 기존 인터페이스 유지 조건을 넘음 |
| C 두 함수를 따로 구현하고 반환값 검사만 실행 | 값은 맞을 수 있지만 재사용 조건과 전체 검사 근거가 부족함 |
이 표에서 B는 인터페이스 유지 조건을, C는 재사용 조건과 전체 검사 요구를 어겨요. A만 남으므로 이 사례가 보여주는 것은 여러 적합 후보의 우열보다 부적합 경로를 걸러내는 과정이에요. 비용이나 코드 모양을 비교하기 전에 목표와 제약을 만족할 후보인지 확인해야 해요.
검토를 통과한 후보가 여러 개 남았을 때는 별도의 선택 규칙이 필요해요. 후보의 적합성을 판단하는 단계와, 적합 후보 사이에서 하나를 고르는 단계를 나누어 볼게요.
상세 명령보다 먼저 전략의 뼈대를 검토하기
SkeletonFirstPlanner는 Goal과 현재 상태, 파일·지침 색인인 Project Map을 받아 Skeleton 후보를 생성해요. Skeleton에는 전략과 Task 목적, 입출력 및 dependency가 있어요. 먼저 결정적 검사인 skeleton_gate를 적용하고 의미 검토를 거쳐요. 의미가 같은 후보는 묶고, shortlist를 상세 Plan으로 확장한 뒤 다시 검사해요. Skeleton-first 탐색
Goal과 현재 관측
↓
Skeleton 생성 → 구조 검사와 의미 검토
↓
shortlist → 상세 Plan → 구조 검사와 의미 검토
↓
Core가 실행 적합 후보 중 선택계획을 만드는 모델과 검토하는 모델의 역할도 달라요. Reviewer는 근거가 붙은 결함인 finding 또는 rating을 제출해요. 후보를 받아들일지 직접 선언하지는 않아요. Core의 derive_candidate_decision이 제출물로 admission 상태와 점수를 계산해요. 결함 진단과 최종 상태가 서로 모순되는 조합을 규칙으로 제한하는 구조예요. Reviewer 제출과 Core 판정
현재 구현이 모든 요청에서 여러 경로를 만드는 것은 아니에요. 기본 후보 수는 legacy_refactor와 migration_modernization에서 2개, 나머지 mission에서 1개예요. 초기 후보와 shortlist, 역할 호출 및 수정에도 한도가 있어요. 따라서 여기서 말하는 다중 경로 비교는 제한된 후보 탐색 기능이지 모든 가능한 방법을 탐색하는 최적화가 아니에요. 기본 후보 수
점수는 검토를 통과한 뒤의 선택 규칙
admissible은 정의한 검토 기준을 통과해 실행 후보로 받아들인 상태예요. 최종 선택은 이 상태의 상세 Plan에 한정해요. 실제 코드도 후보를 먼저 걸러낸 뒤 점수와 digest로 순서를 정해요. 아래는 planning.py의 최종 선택 부분이에요. 최종 Plan 선택
feasible = [
item
for item in plan_evaluations
if item.decision.status is CandidateStatus.ADMISSIBLE
]
selected = min(
feasible,
key=lambda item: (
-(item.decision.fitness_score or 0),
item.plan.activation_digest,
),
default=None,
)통과 후보 중 fitness 점수가 높은 Plan을 선택하고, 동점이면 activation digest로 순서를 정해요. 후보가 하나면 그 후보가 선택되고, 하나도 없으면 선택 결과는 None이에요. 이것은 같은 평가 입력에 대한 선택을 결정적으로 만드는 규칙이에요. 앞의 A/B/C 예제에서 B와 C는 이 점수 비교 대상에 들어오지 않아요.
fitness는 Reviewer가 다섯 항목에 부여한 0~4점의 rating을 합산하고 0~100점으로 환산한 값이에요. 실제 성공 확률이나 수학적으로 입증한 최적성은 아니에요. 점수가 좋아도 범위 초과나 요구 누락을 통과시키는 근거로 사용해서는 안 돼요. 의미 검토 자체가 틀릴 가능성도 남아요. fitness 계산
이 문제는 과거 실험에서도 드러났어요. R3.1 campaign 10은 150개 cell을 모두 실행했지만 최종 결과는 FAIL이었어요. 결함 후보를 받아들이거나 정상 후보를 지나치게 막은 사례가 있었어요. 관련 모순을 현재 Engine의 회귀 fixture로 보존했지만, 이것이 의미 판단의 정확성 문제가 모두 해결됐다는 뜻은 아니에요. 이 수치 역시 이전 실험의 기록이지 현재 Engine의 성공률은 아니에요. 과거 평가 결과, 회귀 fixture
계획이 맞아도 실행 입력은 다시 준비해야 해요
T1이 money.py를 고치면 T2가 읽을 파일은 처음 계획할 때와 달라져요. 모든 실행 명령과 Context를 최초 계획에 고정하면 뒤 작업은 오래된 입력을 사용할 수 있어요.
Engine은 Task가 ready가 됐을 때 TaskExecutionSpecRevision을 준비해요. 실행할 대상과 명령, 필요한 파일과 지침, 검증 단계 등을 현재 관측에 연결해요. 등록할 때 활성 Plan의 Task 의미와 StateSnapshot, Project Map을 대조하고, 실행 명세로 작업의 의미를 바꾸려 하거나 오래된 입력을 쓰면 거부해요. 실행 명세 등록
예를 들어 T1에는 money.py와 변환 검사 명령을, T2에는 T1의 변경을 반영한 파일과 합계 검사 명령을 넣을 수 있어요. Goal은 달성할 결과, Plan은 선택한 작업 경로, 실행 명세는 지금 수행할 구체적인 방법을 담아요. 서로 바뀌는 시점이 다르므로 같은 객체로 묶지 않아요.
경로를 선택했다고 실행 권한까지 얻는 것은 아니에요. 다음 편에서는 사람, AI와 Core가 어떤 결정을 맡아야 선택한 경로를 승인 범위 안에서 실행하고 결과를 확인할 수 있는지 살펴봐요.