fix(prompt): review/deploy stage 의 role hint 를 stage-aware 하게 분리

자기야 발견: 다랑이의 review 답변이 "수석 1명은 ...전체 원문 다시 제출,
선임 1명은 CRUD 재정리, 신입 A는 ..., 신입 B는 ..., 나는 마지막에 승인"
형태로 나옴 — 즉 verdict 가 아니라 가상 팀 분배 plan 을 출력.

원인: prompts.ts 의 roleOutputHint 가 stage 와 무관하게 동일했음.
- manager hint: "이 작업을 어떻게 분해할지, 어떤 팀(수석/선임/신입) 을 배치할지"
- principal hint: "구체적으로 어떤 리스크... 어떻게 분해되어야 하는지"
- lead hint: "신입에게 어떻게 나눠줄지, 검증 포인트"

이게 plan/implement 단계에서는 맞는데 review/deploy 에서는 작동 모델이
완전히 다름. 다랑이 manager 가 review 단계에서 "팀 분배" 지시를 받으니
review verdict 대신 가짜 팀 plan 을 내놓고 있었음. 이랑이 deploy 도 동일.

수정: stage-specific role hint 분리.

reviewHintForRole(role):
- manager: 절대 분해/분배 금지. 첫 줄 APPROVE/REQUEST_CHANGES/ABORT, 다음
  bullet 1~3개 근거. "내가 마지막에 본다" 같은 미래 약속 금지.
- principal: critical 결함 1~3개. 형식: [심각도] 어디 — 무엇 — 왜 — 어떻게 고쳐야
- lead: 사용자 요구사항의 각 핵심 기능별 통과 여부 한 줄. ✓ <기능>: ... 또는 ✗
- junior: 첫 줄 verdict, 한 문단 이유. 코드 다시 짜지 마.

deployHintForRole(role):
- manager: 종합 한 문단 + 마지막 줄 DEPLOY_DONE/DEPLOY_FAILED.
- principal: 배포 환경 리스크 (브라우저/CSP/CDN/의존성) 1~3개 또는 "리스크 없음".
- lead: "□ <확인 절차>" 체크리스트.
- junior: 기존 그대로.

plan/implement 의 hint 는 그대로 보존 — 거기선 분해가 맞으니까.
This commit is contained in:
2026-04-11 02:29:36 +09:00
parent fe9ec0d9db
commit 6c43cccca5

View File

@@ -93,6 +93,19 @@ export function buildPrompt(ctx: PromptContext): string {
}
function roleOutputHint(role: Role, stage: PromptContext["stage"]): string {
// Stage-specific instructions take precedence. The original "decompose
// into team" wording only makes sense for plan / implement — for review
// and deploy it's actively wrong, because the manager would then output
// a fake team plan ("수석 1명은…, 선임 1명은…") instead of an actual
// verdict.
if (stage === "review") {
return reviewHintForRole(role);
}
if (stage === "deploy") {
return deployHintForRole(role);
}
// ── plan / implement ─────────────────────────────────────────
if (role === "manager") {
return `이 작업을 어떻게 분해할지, 어떤 팀(수석/선임/신입)을 어디에 배치할지 한 문단으로 결정해.`;
}
@@ -117,11 +130,73 @@ function roleOutputHint(role: Role, stage: PromptContext["stage"]): string {
`여러 파일이 필요하면 각각 별도 블록으로. 설명은 최소화.`,
].join("\n");
}
if (stage === "review") {
return `위 결과물을 평가하고 APPROVE 또는 REQUEST_CHANGES 로 시작해서 이유를 한 문단.`;
}
if (stage === "deploy") {
return `이 결과물을 어떻게 배포 검증할지 짧게 설명하고 마지막 줄에 "DEPLOY_DONE" 또는 "DEPLOY_FAILED" 표기.`;
}
return `결과를 명확히 제출해.`;
}
/**
* Review-stage hints: every role outputs an actual verdict, never a team
* plan. The manager is the FINAL authority and must commit to APPROVE or
* REQUEST_CHANGES — no decomposition, no delegation, no "수석 1명은…" lists.
*/
function reviewHintForRole(role: Role): string {
switch (role) {
case "manager":
return [
`너는 review 단계의 최종 결정권자다. 절대 작업을 분해하거나 팀(수석/선임/신입)을 배치하지 마. 본인이 직접 결정한다.`,
``,
`위 priorStages 에 들어 있는 implement 결과물 (코드 본문) 을 처음부터 끝까지 읽고, 다음 형식으로만 답해:`,
``,
`1) 첫 줄: \`APPROVE\` 또는 \`REQUEST_CHANGES\` 또는 \`ABORT\` 중 하나.`,
`2) 둘째 줄부터: 그 판정의 핵심 근거를 1~3개 bullet 로. 각 bullet 은 어떤 파일의 어떤 부분이 어떤 이유로 통과/미달인지 구체적으로.`,
``,
`금지: 작업 분배, 가상 팀 구성, "내가 마지막에 본다" 같은 미래 약속, 코드를 다시 짜는 행위.`,
`허용: APPROVE 한 줄 + 짧은 이유 / REQUEST_CHANGES + 결함 bullet.`,
].join("\n");
case "principal":
return [
`너는 기술 리뷰 담당이다. 코드 본문을 보고 critical 결함만 1~3개 골라 bullet 로 정리해.`,
`각 bullet 은: [심각도] 어디(파일/라인/함수) — 무엇이 — 왜 문제 — 어떻게 고쳐야`,
`심각도는 critical / major / minor 중 하나.`,
`작업을 분배하거나 팀을 구성하지 마.`,
].join("\n");
case "lead":
return [
`너는 기능 동작 검증 담당이다. 사용자 요구사항의 각 핵심 기능 (예: 추가, 수정, 삭제, 완료체크, 새로고침 후 유지) 별로 한 줄씩 통과 여부와 근거를 적어.`,
`형식: "✓ <기능명>: 동작 OK — <근거>" 또는 "✗ <기능명>: 실패 — <원인>"`,
`작업을 분배하거나 신입에게 위임하지 마.`,
].join("\n");
case "junior":
return [
`위 priorStages 의 implement 결과물 코드를 직접 읽고 평가해. 첫 줄에 \`APPROVE\` 또는 \`REQUEST_CHANGES\` 또는 \`ABORT\` 로만 시작.`,
`그 다음 줄부터 한 문단 이내로 핵심 이유. 코드를 다시 작성하지 마.`,
].join("\n");
}
}
/**
* Deploy-stage hints: every role focuses on deployability / verification,
* never on decomposition.
*/
function deployHintForRole(role: Role): string {
switch (role) {
case "manager":
return [
`너는 deploy 단계의 최종 결정권자다. 작업을 분해하거나 팀을 배치하지 마.`,
`위 priorStages 의 review 결과 + implement 결과물을 보고 배포 검증 결과를 한 문단으로 종합한 뒤,`,
`**마지막 줄** 에 \`DEPLOY_DONE\` 또는 \`DEPLOY_FAILED\` 중 하나만 적어.`,
].join("\n");
case "principal":
return [
`배포 환경에서 발생할 수 있는 리스크 (브라우저 호환성, CSP, CDN, 의존성 누락 등) 를 1~3개 bullet 로.`,
`해당 없으면 "리스크 없음" 한 줄.`,
].join("\n");
case "lead":
return [
`배포 후 즉시 확인할 검증 체크리스트를 bullet 로. 각 항목은 "□ <확인 절차>" 형식.`,
].join("\n");
case "junior":
return [
`이 결과물을 어떻게 배포 검증할지 짧게 설명하고 마지막 줄에 "DEPLOY_DONE" 또는 "DEPLOY_FAILED" 표기.`,
].join("\n");
}
}