一键导入
frame
작업 시작 전에 구체 질문으로 목표·성공 기준·범위·검증 초점을 함께 좁히고, 이후 /decide·/verify가 mechanically 읽을 수 있는 frame.json을 워크트리에 박제한다.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
작업 시작 전에 구체 질문으로 목표·성공 기준·범위·검증 초점을 함께 좁히고, 이후 /decide·/verify가 mechanically 읽을 수 있는 frame.json을 워크트리에 박제한다.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
현재 worktree를 최신 production 기반 새 branch로 in-place 전환해야 할 때 사용한다. "/to-production", "production으로 옮겨", "production 바라보게", "hotfix로 다시 쌓아" 요청에 사용한다. 기존 작업 commit은 backup 후 cherry-pick하고, 새 worktree가 필요하면 /wt fork --hotfix가 담당한다.
열린 PR의 리뷰 코멘트나 changes requested에 대해 부모/현재 대화와 작업 내역을 확인한 뒤, 표면적 답변이 아니라 근본 원인을 판단해 코드 수정·커밋·푸시·스레드 답글·review re-request까지 수행해야 할 때 사용한다. `--push-only` 모드에서는 코멘트/re-request 없이 커밋·푸시 후 수동 게시용 답글 초안을 세션에서 다듬는다. "PR 코멘트 대응", "리뷰 대응", "이거 대응작업-커밋-푸시-코멘트까지", "근본적으로 대응", "대응할 게 없으면 근거 코멘트" 요청에 사용한다.
Local guide for using interactive_shell in this repo. Prefer it for dev servers, TUI apps, REPLs, database shells, log viewers, and commands that need a visible terminal overlay. Do not use it for subagent-style delegation; use the subagent tool for that.
열린 PR의 GitHub Actions/CI 실패를 분석해 원인을 분류하고, 코드·generated artifact·테스트·환경 문제를 근본 대응한 뒤 검증, 커밋, push까지 수행해야 할 때 사용한다. "CI 실패 대응", "체크 실패 봐줘", "Actions 실패 고쳐줘", "pr-checks 실패", "ci-ship" 요청에 사용한다.
PR을 만들기 전 또는 remote에 올리기 전, 변경사항을 의도 단위로 커밋하고 lint/typecheck/test/build 같은 사전 검증을 통과시킨 뒤 push해야 할 때 사용한다. "ship 해줘", "커밋해서 푸시", "올리기 전에 검증", "push 준비" 요청에 사용한다.
PR/구현 검증을 PM·비개발자도 이해할 수 있는 캡처 중심 HTML 리포트로 만든다. Jira/Notion/Slack/와이어프레임/PR test plan 같은 기획 근거를 사용자-facing 동작과 매핑하고, 핵심 UI 흐름은 스크린샷/GIF를 primary evidence로 증명한다. 로직/API/DB/code diff 검증은 하단 기술 보조 검증으로 정리한다. 기본은 로컬 확인용이며 업로드/PR 업데이트는 명시 요청 시에만 한다.
| name | frame |
| description | 작업 시작 전에 구체 질문으로 목표·성공 기준·범위·검증 초점을 함께 좁히고, 이후 /decide·/verify가 mechanically 읽을 수 있는 frame.json을 워크트리에 박제한다. |
/frame은 구현 전 핵심 정렬이자 후속 TFT 사이클 setup이다. 목표·범위·성공 기준을 사용자가 함께 검토하고, 그 결과를 /decide·/verify·/verify-report가 읽을 수 있는 canonical contract로 저장한다.
산출물의 단일 원천은 frame.json이다. markdown과 Studio transcript는 사람이 읽기 위한 mirror/provenance이지 canonical source가 아니다.
이 스킬이 끝나면 다음이 보장된다:
frame.json에 검증 가능한 성공 기준과 verify plan이 박제됐다.frame.md는 frame.json에서 재생성 가능한 사람용 mirror다.kind="frame.decision" 태스크로 큐잉됐다.핵심 원칙: frame.json이 없으면 /verify는 의미 있게 동작하지 못한다.
/frame은 모든 작업을 full TFT로 키우는 명령이 아니다. 시작할 때 먼저 작업 무게를 가볍게 분류한다.
| 무게 | 신호 | frame 깊이 |
|---|---|---|
| light | 단일 hotfix/copy/style, 영향 파일·route가 작고 side effect 없음 | 목표/범위/검증 축 한 번만 잠그고 바로 실행 |
| standard | UI/BE/event 중 여러 축이 있음 | 기본 frame + 필요한 결정/verify plan |
| full | 정책·DB·다중 role/viewport/before-after·릴리즈 리스크 | 정책축/레이어맵/decide/verify-report까지 풍부하게 사용 |
사용자가 “간단한 hotfix”, “빨리”, “문구만”, “이거 하나만”처럼 좁은 의도를 주면, 먼저 light frame으로 시작한다. 진행 중 검증 축이나 위험이 늘어나면 standard/full로 승격하되, 승격 이유를 한 문장으로 적는다.
Jira, Notion, Slack, wireframe, PRD, 디자인 캡처처럼 정확한 기획 근거가 있으면 /frame은 큰틀 요약으로 끝나지 않는다. 기획 근거 원문을 Requirement Matrix → Domain Work Map → Verification Evidence로 변환해야 한다.
트리거:
필수 산출물:
source_evidence — 사용한 기획 근거와 provenancerequirement_matrix — 기획 원문 ID별 구현 계약과 검증 증거domain_work_map — FE Web/Admin/Mobile, BE, DB/Ops, Verification 같은 작업 레인 지도backend_layer_map — backend/action/API 경계가 얽힌 경우 요구사항 ID가 붙은 Backend Layer Map / Backend/Action Boundary Map / 레이어 책임 지도architecture_flow_map — 화면·action·API·DB·검증 증거 흐름이 구현·검증 이해를 좌우하면 요구사항 ID가 붙은 Architecture/Data Flow Map / Architecture/User Flow Mapdata_model_migration_map — DDL/DML/backfill/DB 관계가 이해·검증을 좌우하면 요구사항 ID가 붙은 Data Model / Migration Map규칙:
gap 또는 decision-needed다.원문 요구 → 위험 → 대안 → 승인 필요 여부를 Step 3/4 질문으로 승격한다.| ID | Source | 기획 근거 원문 | 구현 계약 | 검증 증거 | 상태 | 형태의 상태 컬럼을 포함한다. 상태 없는 matrix는 무효다.[R1,R2]처럼 닫는 requirement ID를 앞에 붙인다. requirement ID 없는 work map은 큰틀 요약으로 간주한다.요구사항 컬럼 또는 requirementIds를 가져야 한다. requirement ID 없는 layer map은 아키텍처 설명일 뿐 기획 책임 분배표가 아니다.backend_layer_map.mode="boundary-only"라도 반드시 보여준다. 신규 backend 변경이 없다는 이유만으로 triggered:false로 숨기지 않는다.architecture_flow_map.mode="user-flow"로 보여준다. 흐름이 있는데 kind: "architecture-flow" visual이나 이에 준하는 architecture_flow_map이 없으면 source-grounded full frame이 불완전하다.data_model_migration_map과 kind: "data-model-migration-map" visual을 별도 영역으로 보여준다. backend layer/architecture flow에 DB node가 있더라도 DDL/DML 구조 자체는 이 맵으로 분리한다.references/source-grounded-planning.md를 따른다./frame은 티켓의 개별 룰을 나열하기 전에, 그 룰들이 충돌하거나 확장될 정책축을 먼저 스캔한다. 다음 도메인이 보이면 Step 2에서 정책축 스캔을 반드시 수행하고, Step 3/4 질문 후보에 반영한다.
트리거:
필수 스캔 축:
규칙:
정책축 스캔 카드에 적는다.policy_axis_scan에 구조화하거나, 최소한 review_lenses, risk_register, success_criteria, verify_plan.manual_checks에 반영한다.references/policy-axis-scan.md를 따른다./frame은 backend 계층 구조나 기존 action/API boundary가 작업 이해를 좌우하면 구현 plan 전에 레이어 책임 지도를 먼저 그린다. 사용자가 backend 세부 레이어에 익숙하지 않다고 밝혔거나, 작업이 resolver/usecase/service/repository/entity/VO/loader/cache/migration을 건드리거나, FE 요구사항이 기존 action/API/cache/refresh 동작 재사용을 요구하면 이 게이트를 켠다.
트리거:
필수 맵:
규칙:
N/A로 표시한다. 단, source-grounded UI/action 작업에서는 triggered:false로 숨기기보다 mode="boundary-only"로 기존 action/API/refresh 경계와 변경 금지 책임을 보인다.tft-visual fenced block의 kind: "backend-layer-map"으로 Layer Visual Map을 함께 렌더링한다. 특히 사용자가 usecase/entity/service/repository 같은 레이어가 헷갈린다고 밝히면 필수다.requirements/responsibilities/evidence가 우선이고, role/frontendAnalogy/whyHere/ifWrong/beginnerDescription은 부트캠프 수강생도 알 수 있는 설명처럼 프론트 개발자도 이해할 수 있게 돕는 짧은 learning layer로만 둔다.kind: "architecture-flow" tft-visual을 함께 출력한다. 사용자가 명시적으로 원할 때만이 아니라, backend/data/API/DB 흐름이 작업 이해를 좌우하는 source-grounded full frame에서는 필수 surface다.kind:"architecture-flow"로 User/Action Flow Map을 그린다. 이때 DB node가 없을 수 있지만, 화면 → shared action → existing boundary → verification edge가 요구사항 ID와 연결되어야 한다.triggered:false 또는 mode="not-applicable"은 사용자 action/API/data/cache/refresh/verification flow가 정말 없고, 단순 copy/style처럼 구조 흐름 검수가 의미 없는 경우에만 쓴다.backend_layer_map, architecture_flow_map, data_model_migration_map이다.references/backend-layer-map.md를 따른다./frame은 DDL/DML/backfill 또는 DB 관계 변경이 작업 이해를 좌우하면 구현 plan 전에 Data Model / Migration Map을 별도 영역으로 그린다. Backend Layer Map은 “책임 위치”, Architecture Flow는 “런타임 흐름”, Data Model / Migration Map은 “실제 저장 구조와 migration 안전성”을 담당한다.
트리거:
필수 맵:
규칙:
frame.json.data_model_migration_map이 canonical이고, Studio의 kind: "data-model-migration-map" visual은 사람이 읽는 generated view다.entities[].columns[]는 실제 schema/DDL을 읽은 뒤 채운다. 아직 확인 전이면 status:"open_question"이나 verification gap으로 표시한다.migrationOperations[].type으로 DDL, DML, BACKFILL, ROLLBACK, VERIFY를 구분한다.runtimeFlow[]에 “어느 translation/source row를 따르는지”를 명시한다.verificationQueries[]와 verify plan caveat에 남긴다.references/data-model-migration-map.md를 따른다./frame은 Plan Mode나 구현 전에 사용자의 모호한 요청을 실행 가능한 계약으로 좁히는 인터뷰 단계다. 질문을 많이 하는 것이 목적이 아니라, 가장 큰 불확실성 하나를 골라 한 번에 하나씩 푼다.
질문 축은 아래 순서로 스캔한다.
규칙:
질문 제목: {짧은 제목}
현재 이해:
- {코드/문서/사용자 발화로 확인한 사실}
- {아직 가정인 부분은 가정이라고 표시}
막힌 결정:
{지금 풀어야 하는 가장 중요한 불확실성 하나}
왜 중요한가:
{선택에 따라 달라지는 구현 범위, 검증 축, 위험, 롤백 비용}
추천 답안:
{있으면 이유와 함께 제시. 없으면 이 섹션을 생략}
선택 후 달라지는 것:
- {옵션 A를 고르면 달라지는 점}
- {옵션 B를 고르면 달라지는 점}
질문:
{한 가지 질문}
인터뷰는 다음이 정리되면 멈춘다: 목표, 포함 범위, 제외 범위, 제약, 완료 판단 기준, 아직 남은 열린 질문. 마지막에는 전체 대화록이 아니라 결정사항과 열린 질문만 frame draft/canonical에 반영한다.
deep-interview를 별도 명령으로 만들지 않는다. 이 규율은 /frame의 질문 품질을 높이는 내부 규칙이다.
/frame은 긴 설계 문서를 승인받는 절차가 아니다. 목표는 묵시적 합의를 줄이고, 구현 전에 결과가 달라지는 결정을 작게 확인하는 것이다.
규칙:
(명백) 질문 원칙/frame의 목표·범위·성공 기준·검증 축은 후속 계약을 바꾸는 선택이다. AI가 보기에 추천안이 명백해도 묻는다. 대신 질문 앞에 (명백: ...)으로 왜 그렇게 보이는지 표시한다.
(명백: 요청의 핵심은 버튼 노출 조건입니다. 다만 실패 메시지 포함 여부에 따라 검증 범위가 달라집니다.)
질문: 이번 범위를 어디까지 잡을까요?
1. 버튼 노출 조건만 수정 — 최소 범위
2. 버튼 조건 + 실패 메시지까지 수정 — 추천
3. 예약 상태 전환 전체 점검 — 넓은 범위
(명백)은 질문 생략 사유가 아니라 사용자가 “내가 놓친 게 있나?”라고 혼동하지 않게 하는 판단 근거다. 단, 사용자가 선택해도 이후 행동이 달라지지 않는 실행 세부는 질문하지 말고 (명백)으로 보고 후 진행한다.
/frame은 AI가 계획을 예쁘게 써주는 단계가 아니다. 사용자가 놓쳤을 수 있는 질문을 1~2개 던져 계획의 빈틈을 찾는다.
Productive Resistance 질문은 반드시 행동형이어야 한다:
“괜찮나요?” 같은 확신 확인은 금지한다.
/frame은 기능 결과만 맞추는 계약이 아니라, 다음 사람/AI가 변경 지점을 다시 찾을 수 있는 구조인지도 한 번 보게 만든다. 코드 변경이 문서/카피 수준을 넘으면 사고 렌즈나 Productive Resistance에 다음 질문을 seed한다.
이번 변경이 작은 wrapper/분산 조건/shallow module을 늘리는가, 아니면 단순한 interface 뒤에 깊은 구현을 숨기는가?
이 질문은 리팩터링을 강제하지 않는다. 선택 결과는 success_criteria, out_of_scope, risk_register, verify_plan.manual_checks, 또는 follow-up으로 남긴다. 지금 작업의 목표가 빠른 복구라면 구조 개선을 범위 밖으로 명시할 수 있지만, 구조 비용 자체를 보지 않은 척하지 않는다.
저장 시점에는 항상 structured canonical을 먼저 갱신한다.
FrameDoc 객체를 만든다.frame.json.tmp에 쓰고 rename으로 atomic write한다.frame.md는 frame.json을 읽어 재생성한다. 직접 편집 원천이 아니다.provenance.canonicalHash를 제외한 canonical payload hash를 계산해 provenance.canonicalHash와 Studio transcript 마지막 markdown에 남긴다.worktree-meta.json, work_context refresh, TaskCreate는 canonical write 성공 후 수행한다.불일치가 발견되면 frame.json이 우선이다. frame.md/transcript는 mirror/provenance로 다시 생성하거나 경고한다.
Pi UI가 있고 frame_studio tool을 사용할 수 있으면, 번호형 텍스트만 출력하지 말고 Glimpse TFT Studio를 우선 사용한다. 도구 이름은 하위 호환을 위해 frame_studio지만, UI는 Frame/Decide/Verify/Verify Report 탭을 가진 TFT Studio shell이다.
frame_studio action=start tab=frame으로 identity-bound TFT Studio를 연다.frame_studio action=update tab=frame으로 렌더링한 뒤, frame_studio action=ask tab=frame으로 ok 또는 정정 입력을 받는다. 버튼 없는 ok 문장을 markdown에만 남기지 않는다.frame_studio action=ask tab=frame을 호출해 버튼/체크박스/직접입력으로 답을 받는다. 긴 판단 맥락 카드는 직전 update 또는 같은 ask의 markdown에 넣고, question 필드는 짧은 질문 제목 한 줄만 넣는다.ask.question에 현재 이해 / 막힌 결정 / 왜 중요한가 / 추천 답안 / 선택 후 달라지는 것 / 질문 카드 전체를 넣지 않는다. 그런 호출은 Studio가 방어적으로 제목/본문을 분리하더라도 실패한 호출이다.frame_studio action=update tab=frame으로 렌더링한다. 구현 계획은 별도 Plan 탭이 아니라 Frame 탭 마지막의 Implementation plan synthesis 섹션으로 보여준다.frame_studio ask 결과가 unavailable, cancelled, timeout일 때만 허용한다.unavailable, cancelled, timeout이면 ask-user-question-rules의 번호형 text-mode fallback으로 이어간다.frame_studio 결과는 선택값뿐 아니라 contextDigest, tabSnapshot, transcriptRef.openCommand(/archive <transcriptPath>)를 반환한다. 전문 전체를 LLM context에 주입하지 말고, 확정 의미는 canonical에 쓰고 전문은 reference/provenance로 연결한다.transcriptPath는 전체 markdown/update/question/answer 전문 저장 위치다. 사용자가 다시 보고 싶어 하면 같은 identity로 action=open을 호출하거나 transcriptRef.openCommand로 /archive에서 다시 연다.Frame → Verify, Frame → Verify Report, Frame only, 또는 필요한 경우 Verify Report only도 정상 경로다.frame.json, frame.json.decisions[], frame.json.verifications[], verify-report artifact refs)여야 한다. 전 단계 기록이 없다는 이유만으로 현재 탭 사용을 막지 않는다.Self-healing runs / Re-verify result append section으로 남긴다.순서대로 수행:
<worktree>/.pi/worktree-meta.json 읽기<worktree>/.pi/frame.json, <worktree>/.pi/frame.mdFrame · <worktreeName> · <ticket?>~/.pi/agent/frame-planning/planning-ticket-<TICKET>/frame.jsonPlanning · <TICKET> · <sessionTitle?>~/.pi/agent/frame-planning/planning-session-<sessionFileHash>/frame.jsonPlanning · <하단 session title>/Users/...)는 identity로 쓰지 않는다. 홈은 여러 기획 탭이 공유하므로 충돌한다.[A-Z]{2,}-\d+ 티켓 패턴을 추출한다. 발견되면 가능한 issue tracker 도구로 본문/acceptance/status를 가져온다.git status + git log --oneline -5로 진행 상태 파악 (git repo가 아니면 planning mode로 생략 사유 기록)이 단계에선 유저에게 묻지 않는다. 출력은 단 하나: identity + 수집된 컨텍스트 요약 카드.
planning frame은 나중에 worktree가 만들어지면 해당 worktree의 .pi/frame.json으로 승격할 수 있어야 한다. 따라서 ticket, session title, 원래 session file, source cwd를 frame metadata에 남긴다.
수집한 컨텍스트로 AI가 아래를 먼저 보여준다. 코드/문서/티켓/이전 frame으로 확인 가능한 것은 먼저 확인하고, 확인하지 못한 추정만 가정으로 표시한다.
(명백: ...) 근거 포함예:
내가 이해한 목표:
“파트너 예약 취소 흐름에서 권한별 버튼 노출과 실패 메시지를 정렬한다.”
(명백: 요청의 직접 증상은 버튼 미노출입니다. 다만 실패 메시지까지 포함할지에 따라 검증 범위가 달라집니다.)
가정:
1. 대상은 admin 예약 취소 UI다.
2. 성공 판정은 “취소 버튼 노출”이 아니라 “권한별 취소 가능/불가 흐름”이다.
3. DB 스키마 변경은 없다.
4. 검증은 admin UI 캡처 + 관련 mutation 테스트가 필요하다.
같이 볼 렌즈:
1. 권한 경계 — 누가 취소할 수 있고 누가 못 하는가
2. UX 실패 경로 — 취소 실패 시 메시지/복구가 보이는가
3. 검증 증거 — 테스트만으로 충분한가, 화면 캡처가 필요한가
4. 구조 경계 — 조건/모듈이 흩어져 다음 AI가 길을 잃을 구조인가
정책축 스캔:
- 트리거 없음 — 혜택/캠페인/가격/기간/DEFAULT/다중 채널 정책 변경이 아니다.
백엔드 레이어 맵:
- 트리거 없음 — backend resolver/usecase/repository/entity/VO/loader 책임 변경이 아니다.
틀린 가정이 있으면 번호로 정정해주세요. 없으면 `ok`.
이 단계는 자유 텍스트 정정 턴이다. TFT Studio를 쓰면 카드를 update로 보여준 뒤 ask로 ok/정정 입력을 받아야 한다. 아직 draft를 쓰지 않는다.
목표 확인 질문은 추상 카테고리가 아니라 이번 작업의 실제 분기를 옵션화한다. 추천안이 명백해 보여도 질문하고, 질문 앞에 (명백: ...)으로 근거를 쓴다. 단, 질문은 Deep Interview 카드처럼 한 번에 하나의 불확실성만 다룬다.
현재 이해: “파트너 예약 취소 흐름에서 권한별 버튼 노출과 실패 메시지를 정렬한다.”
막힌 결정: 직접 증상만 고칠지, 실패 경로까지 성공 기준에 포함할지
추천 답안: 2번 — 사용자가 보는 실패 경로까지 닫아야 검증이 완결됩니다.
(명백: 요청은 “취소 버튼이 안 보임”이 핵심이라 1번이 최소 목표입니다. 다만 실패 메시지를 포함하면 검증 축이 하나 늘어납니다.)
질문: 목표를 어디까지로 잡을까요?
1. 최소 목표 — 취소 버튼 노출 조건만 수정
2. 표준 목표 — 버튼 조건 + 실패 메시지까지 수정
3. 넓은 목표 — 관련 예약 상태 전환 전체 점검
4. 먼저 탐색 — 기존 예약 상태 모델을 더 읽고 다시 결정
답은 번호로 주세요. 예: `2`
원칙:
성공 기준 수정, 범위 수정 같은 메타 옵션만 쓰지 않는다.막힌 결정 또는 질문 앞 판단 맥락 카드에 표시한다.목표/범위 선택 후, draft 작성 전에 계획을 흔드는 질문을 1~2개 던진다. 단순한 반론 나열이 아니라 frame 계약을 바꾸는 행동 옵션이어야 한다. 여러 리스크가 보여도 한 질문에는 가장 큰 불확실성 하나만 담고, 나머지는 risk seed로 남긴다.
도출 기준:
예:
현재 이해: “버튼 노출 조건 수정이 최소 목표로 선택됐다.”
막힌 결정: 실패 경로를 성공 기준에 넣을지, 이번 범위 밖으로 둘지
추천 답안: 1번 — 화면 증상 수정과 사용자 복구 가능성을 함께 검증합니다.
(명백: 버튼 노출만 고치면 직접 증상은 해결됩니다. 하지만 실패 메시지를 제외하면 사용자는 실패 원인을 모를 수 있습니다.)
질문: 실패 경로를 frame에 어떻게 반영할까요?
1. 성공 기준에 추가 — 실패 메시지/복구까지 확인
2. 범위 밖으로 명시 — 이번엔 버튼 노출만 검증
3. 먼저 탐색 — 기존 실패 처리 구조를 읽고 결정
또 다른 예:
질문: 이번 작업에서 명시적으로 제외할 항목은?
1. 정산 상태 변경 제외 — UI/예약 상태만 다룸
2. 외부 알림 변경 제외 — 알림톡/메일은 건드리지 않음
3. 제외 없음 — 발견되는 연결 흐름까지 포함
4. 먼저 탐색 — 영향 범위를 더 읽고 제외 범위 결정
빈틈 질문을 억지로 만들지 않는다. 정말 아무런 frame 계약 변화가 없으면 (명백: 추가 Productive Resistance 없음 — 목표/범위/검증축이 단일 경로)라고 보고하고 다음 단계로 간다.
사용자가 “뭘 신경 써야 하는지 모르겠다”는 상황을 막기 위해, draft 작성 전에 검증 초점을 좁힌다. 초점이 명백해도 계약을 바꾸는 선택이면 묻고 (명백) 근거를 붙인다. 이 단계도 현재 이해 / 막힌 결정 / 추천 답안 / 질문 구조를 우선 사용한다.
현재 이해: “버튼 조건과 실패 메시지를 표준 목표로 잡았다.”
막힌 결정: draft에서 가장 엄격히 검증할 축 1~2개
추천 답안: 1,4번 — 사용자 흐름 증거와 기존 정상 흐름 회귀를 함께 닫습니다.
(명백: 이번 변경은 화면 노출 이슈라 사용자 흐름 캡처가 1순위입니다. 다만 권한 조건도 함께 바뀌면 회귀 방지가 중요합니다.)
질문: frame draft에서 무엇을 가장 엄격히 볼까요? (최대 2개)
1. 사용자 흐름 — 실제 화면/상태 변화 캡처
2. 데이터 정합성 — 저장값/API 응답/캐시 무효화
3. 권한·보안 — 접근 가능/불가 경계
4. 회귀 방지 — 기존 정상 흐름 유지
5. 구조 비용 — 모듈 경계/인터페이스 복잡도/다음 AI의 탐색 가능성
6. 정책축 — 기준 시간/다중 적용/DEFAULT/채널 매트릭스/마이그레이션 재현성
7. 백엔드 레이어 경계 — resolver/usecase/repository/VO/loader 중 책임 위치
답은 번호로 주세요. 예: `1,4`
선택 결과는 assumptions, success_criteria, verify_plan, risk_register 작성의 우선순위가 된다.
AI가 frame draft를 작성한다. /frame 초반에는 구현 계획을 만들지 않는다. 목표·범위·성공 기준·필요한 결정이 정리된 뒤에만 Frame의 마지막 산출물로 implementation plan을 합성한다.
초반 draft에서 금지:
작성할 것:
success_criteria[]: 각 항목 { id, statement, evidence_locator, verify_command? }
evidence_locator: 코드 경로/함수/엔드포인트/UI 셀렉터 등 검증이 무엇을 가리켜야 하는지verify_command: 가능하면 실행 가능한 명령out_of_scope[]: Step 3/4에서 미룬 항목 + AI가 식별한 명시 제외boundaries: { always[], ask_first[], never[] }
ask_first에 시드risk_register[]: { risk, severity, mitigation, needs_decision }
needs_decision 또는 mitigation으로 남김needs_decision: true 항목은 Step 8에서 task로 큐잉됨source_evidence[]: Jira/Notion/Slack/wireframe/PRD 등 사용한 기획 근거와 provenancerequirement_matrix[]: 기획 근거 원문 ID별 { source, sourceText, implementationContract, verificationEvidence, status }
| ID | Source | 기획 근거 원문 | 구현 계약 | 검증 증거 | 상태 | 컬럼을 사용한다.success_criteria[].statement/evidence_locator, review_lenses, verify_plan.manual_checks에 요구사항 ID를 명시해 fallback한다.decision-needed, blocked, gap, out-of-scope 중 하나로 드러낸다. 또는 동일 UX, 유사 방식, 동등하게 보이게 같은 완화 표현을 PASS 상태 구현 계약으로 쓰지 않는다.domain_work_map[]: FE Web/Admin/Mobile, BE Entry/Application/Domain/Data, DB/Ops, Verification 같은 레인별 task 후보와 requirement refs
[R1,R2] prefix를 붙인다.implementation_plan.slices[]와 TaskCreate area/refs.requirements로 표현한다.policy_axis_scan: 트리거된 작업이면 시간 기준, 적용 대상 수, DEFAULT/fallback, 소비 채널 매트릭스, 데이터/마이그레이션, API/cache identity의 결론과 열린 질문backend_layer_map: 트리거된 작업이면 entry point, application flow, domain rule, data access, cache/batching, persistence, consumers의 책임과 call-flow. source-grounded mode에서는 각 레이어가 닫는 requirement ID도 함께 적고, markdown row에는 요구사항 컬럼을 둔다.architecture_flow_map: 트리거된 작업이면 UI/API/Usecase/Domain/Repository/DB/Ops lane, 주요 node/edge, DB source-of-truth/PK/FK/legacy badge, 각 흐름이 닫는 requirement ID와 verification evidence를 적는다.data_model_migration_map: 트리거된 작업이면 table/entity, column/constraint, relationship/cardinality, DDL/DML/backfill/rollback, runtime fallback/read flow, verification query를 요구사항 ID와 연결한다.edge_case_seeds[]: Step 4/5 초점에 맞춘 3~5개
verify_plan: { commands[], manual_checks[] }implementation_plan: 이 시점에는 blocked_by_decision 또는 draft 상태의 합성 준비 섹션만 둔다.
status="blocked_by_decision"으로 두고, 어떤 결정이 닫혀야 plan이 ready가 되는지 적는다.ready로 합성한다.provenance: Studio transcript path, 사용된 질문/답변 id, canonical hash placeholderDraft를 보여줄 때 맨 위에 반드시 다음을 붙인다:
검수할 때 볼 것:
1. 성공 기준이 실제 사용자/시스템 결과를 말하는가
2. 정확한 기획 근거가 있다면 Requirement Matrix가 원문 요구를 빠짐없이 구현/검증 증거에 매핑했는가
3. Domain Work Map이 FE Web/Admin/Mobile, BE, DB/Ops, Verification 같은 레인별 작업 누락을 드러내는가
4. 이번 작업에서 제외할 범위가 충분히 명시됐는가
5. 검증 증거가 테스트/캡처/로그 중 무엇인지 분명한가
6. claim/slice가 작게 닫히고, 각 slice의 evidence가 분명한가
7. 내가 선택한 답변이 frame 계약에 정확히 반영됐는가
8. 정책축 스캔이 필요한 작업인데 시간 기준/DEFAULT/다중 적용/채널별 규칙이 빠지지 않았는가
9. 백엔드 레이어 맵이 필요한 작업인데 resolver/usecase/repository/VO/loader 책임이 요구사항 ID와 연결됐는가
10. Architecture Flow가 필요한 작업인데 UI/API/Usecase/Domain/Repository/DB/Ops 흐름, source-of-truth, 검증 증거가 요구사항 ID와 연결됐는가
11. Data Model / Migration Map이 필요한 작업인데 DDL/DML/backfill, PK/FK/UNIQUE, fallback source, verification query가 요구사항 ID와 연결됐는가
12. implementation plan이 frame/decide 결정과 matrix/work map에서 파생됐는가
검수 질문은 카테고리 메뉴가 아니라 draft에서 바로 고칠 수 있는 구체 항목으로 만든다. Pi에서는 번호로 답할 수 있게 출력한다.
질문: 저장 전에 무엇을 고칠까요? (복수 선택 가능)
1. SC-2에 “취소 실패 메시지 노출” 추가
2. out_of_scope에 “정산 상태 변경” 추가
3. ask_first에 “예약 상태 enum 변경” 추가
4. verify_plan에 admin 화면 캡처 추가
5. 이대로 저장
답은 번호로 주세요. 예: `1,4` 또는 `5`
원칙:
성공 기준 수정)은 구체 항목을 만들 수 없을 때만 fallback으로 쓴다.이대로 저장은 통과 의례가 아니라 저장 action이다. 선택 시 Step 8로 진행한다.저장은 반드시 아래 순서로 한다.
FrameDoc 객체를 완성한다.requirement_matrix의 모든 ID가 implementation_plan.slices[], domain_work_map, backend_layer_map, architecture_flow_map, data_model_migration_map, verify_plan, out_of_scope, decision_queue, blocked 중 하나에 연결됐는지 확인한다. 미매핑 요구사항, 상태 없는 matrix, requirement ID 없는 work/layer/flow/data map, 또는 원문 요구를 완화한 PASS 계약이 있으면 저장 전에 patch하거나 decision으로 큐잉한다.implementation_plan을 frame/decide 결정에서 합성한다.
decision_queue[]가 남아 있으면 status="blocked_by_decision"으로 저장하고, Plan을 ready로 선언하지 않는다.status="ready"로 두고 slices, firstSafeStep, readiness, gates를 채운다.claim, scope, evidence_needed, done_when이 읽히게 작성한다. 별도 schema 확장이 과하면 기존 slice description/acceptance에 이 네 가지를 넣는다.derivedFrom.frameHash와 derivedFrom.decisionIds로 출처를 남긴다.identity, goal, success_criteria, out_of_scope, boundaries, risk_register, verify_plan, implementation_plan, provenancesource_evidence, requirement_matrix, domain_work_map 또는 이에 준하는 success_criteria/implementation_plan/verify_plan/Task refs 반영 여부policy_axis_scan 또는 이에 준하는 review_lenses/risk_register/verify_plan 반영 여부backend_layer_map 또는 이에 준하는 review_lenses/risk_register/verify_plan 반영 여부. source-grounded UI/action 작업에서 기존 action/API boundary 재사용이 있으면 mode="boundary-only"라도 있어야 한다.architecture_flow_map 또는 이에 준하는 review_lenses/risk_register/verify_plan 반영 여부. source-grounded UI/action 작업에서 화면→action→기존 boundary→검증 흐름이 있으면 mode="user-flow"라도 있어야 한다.data_model_migration_map 또는 이에 준하는 review_lenses/risk_register/verify_plan 반영 여부. DDL/DML/backfill/PK/FK/UNIQUE/fallback source가 있으면 kind:"data-model-migration-map" visual 또는 canonical summary가 있어야 한다.decisions[]는 없으면 빈 배열decision_queue[]는 없으면 빈 배열<worktree>/.pi/frame.json, planning mode면 Step 1에서 정한 planning pathframe.json.tmp → renameprovenance.canonicalHash를 비운 canonical payload의 SHA-256 hash를 계산한다.provenance.canonicalHash에 반영해 frame.json을 한 번 더 atomic write한다.provenance.canonicalHash 필드를 제외한 payload로 재계산한다.frame.md를 frame.json에서 재생성한다.
Generated from frame.json. Do not edit as source. 표시canonicalHash, updatedAt, transcriptPath 표시frame.md의 SC 개수와 frame.json.success_criteria.length가 맞는지 확인frame.md의 requirement/domain work map 요약이 canonical과 맞는지 확인implementation_plan.status와 남은 decision queue 상태가 모순되지 않는지 확인worktree-meta.json에 frame: { path, updatedAt, summary, canonicalHash } 키 추가work_context action=refresh로 work-unit scoped Working Context Card를 만든다.<worktree>/.pi/work-context.json, planning/session이면 identity별 state dirtranscriptRef//archive는 refs로만 남긴다.implementation_plan.slices[] 또는 domain_work_map leaf task → 각 항목당 TaskCreate:kind: "slice", owner: "agent"area: FE Admin, FE Web, FE Mobile, BE, DB/Ops, Verification처럼 사용자가 읽을 수 있는 도메인 레인acceptance: slice validation과 requirement evidencerefs: { sliceId, frame, successCriteria?, requirements? }risk_register 중 needs_decision: true 항목 → 각 항목당 TaskCreate:kind: "decision", owner: "user"subject: 결정 제목description: 리스크 설명 + 후보 옵션metadata: { kind: "frame.decision", riskRef, frameVersion }verify_plan.manual_checks → 각 항목당 TaskCreate:
kind: "verify", owner: "agent"metadata: { kind: "frame.verify_check" }frame_studio action=update tab=frame으로 저장 결과와 Plan synthesis, Working Context Card 요약을 남긴다. 이때 implementation_plan.slices[]가 있으면 “각 slice는 검증 후 work_context commit_plan → auto_commit apply로 닫는 커밋 후보”라는 soft rhythm을 함께 표시한다. Step 9의 다음 단계 질문까지 끝난 뒤 반드시 frame_studio action=finish tab=frame으로 닫는다.
frame.json pathframe.md pathcanonicalHashTFT Studio finish invariant:
frame.json과 frame.md 저장이 성공한 뒤에만 finish한다.unavailable, cancelled, timeout이어도 frame 저장 자체가 끝났다면 “다음 단계 미선택”을 기록하고 finish한다.running으로 남으므로, /frame 완료 보고 전에 반드시 tool result를 확인한다.실패 처리:
frame.md, task, worktree-meta를 만들지 않는다.frame.md 생성만 실패하면 canonical은 성공으로 보고, mirror 재생성 필요를 사용자에게 알린다.provenance.notes[] 또는 사용자 보고에 남긴다.질문: <n>개 결정 큐잉 / verify 명령 <m>개 / plan 상태 <status>. 다음은?
1. /decide — 큐잉된 결정 처리
2. plan 보완 — Frame 안의 implementation_plan만 다듬기
3. /verify dry-run — 검증 계획만 먼저 점검
4. fork해서 시작 — worktree로 옮겨 같은 frame/plan으로 구현
5. 바로 구현 시작 — 현재 worktree에서 진행
6. 여기서 멈춤
답은 번호로 주세요. 예: `4`
사용자의 다음 단계 선택까지 transcript에 남긴 뒤 frame_studio action=finish를 호출한다. fork해서 시작을 선택하면 worktree_fork tool을 호출하지 말고 frame_worktree_fork tool을 호출한다. 이 도구는 /frame command shim이 저장한 command context로 실제 /wt fork 경로를 실행해 현재 패널을 forked worktree session으로 전환하고, 새 세션에서 구현 follow-up을 시작한다. tool이 BLOCKED를 반환하면 worktree를 만들지 않았다는 뜻이므로 현재 세션에서 절대경로로 이어가지 말고 중단해 사용자에게 이유를 보고한다. planning frame은 worktree 생성/전환 시 .pi/frame.json으로 자동 승격되어야 하며, 사용자는 승격 절차를 따로 의식하지 않는다.
| 합리화 | 차단 |
|---|---|
| "frame.json까지 만들 정도는 아니야" | 작은 작업이면 success_criteria 1줄 + verify_command 1개로 30초 안에 끝난다. 그게 안 되는 작업은 작은 게 아니다. |
| "성공 기준은 코드 보면 알아" | verify는 코드를 다시 본다. frame.json은 verify가 코드를 보지 않고도 PASS/FAIL을 정의할 수 있게 만든다. |
| "ticket은 머리에 있으니 메타 안 적어도 됨" | 다음 fork·세션에서 사라진다. 30초 적는 비용 vs 30분 재구성 비용. |
| "엣지 케이스는 verify에서 도출하면 됨" | verify 시점엔 구현이 끝났다. frame이 미리 시드를 박아야 구현 중 처리된다. |
| "명백한데 왜 물어?" | /frame에서는 목표·범위·검증축이 계약을 바꾸므로 묻는다. 대신 (명백) 근거를 보여줘 혼동을 줄인다. |
| "Productive Resistance는 시간 낭비" | 빈틈 질문 1개가 잘못된 성공 기준으로 1시간 구현하는 것을 막는다. |
| "테스트만 통과하면 구조 비용은 나중 문제" | AI가 다시 찾기 어려운 shallow module 증가는 다음 변경 비용이다. 지금 고치지 않아도 risk/out_of_scope/follow-up으로 남긴다. |
| "frame.md만 있으면 충분" | frame.md는 mirror다. /verify와 /decide가 읽는 단일 원천은 frame.json이다. |
| "tasks는 agent 내부 todo라 사용자가 안 봐도 됨" | work-task board는 현재 slice/사용자 결정/검증 대기 상태를 외부화하는 인지 도구다. 사용자에게 필요한 항목(owner=user, kind=decision/blocked)을 먼저 보이게 한다. |
| "Ask first 영역까지 매번 적는 건 과하다" | 결제/보안/PII가 ask_first에 없으면 합리화로 우회된다. 5초로 가장 비싼 사고를 막는다. |
| "AI가 draft를 잘 만들었으니 사용자는 OK만 누르면 됨" | TFT 실패다. draft 전에 사용자가 볼 렌즈와 실제 분기를 번호형 질문으로 좁힌다. |
| "모호하니 질문을 여러 개 한 번에 던지자" | Deep Interview 실패다. 가장 큰 불확실성 하나만 골라 현재 이해 / 막힌 결정 / 왜 중요한가 / 추천 답안 / 선택 후 달라지는 것 / 질문 카드로 묻는다. |
| "사용자에게 물으면 빠르다" | 코드/문서/티켓/이전 frame으로 확인 가능한 사실은 먼저 직접 확인한다. 남은 판단만 묻는다. |
| "처음부터 구현 계획까지 같이 주면 친절하다" | /frame 초반에는 plan을 만들지 않는다. 목표·범위·결정이 닫힌 뒤 Frame의 마지막 산출물로 implementation plan을 합성한다. |
type FrameDoc = {
version: 1;
identity: {
mode: "worktree" | "planning-ticket" | "planning-session";
key: string; // worktree:<hash> | planning:ticket:PROJ-123 | planning:session:<hash>
displayTitle: string; // Glimpse/보고서에 보여줄 이름
sourceSessionFile?: string;
sourceSessionTitle?: string;
promotedToWorktree?: string;
};
workspace: string; // worktree 이름 또는 planning label
worktree?: string; // worktree mode일 때 절대 경로
ticket?: {
key: string;
url: string;
summary: string;
acceptance?: string;
};
goal: string;
scope_size: "small" | "standard" | "risky"; // Non-delegable 감지 시 자동 risky
assumptions: string[];
review_lenses: string[];
source_evidence?: Array<{
id: string; // SRC-1 ...
type: "jira" | "notion" | "slack" | "wireframe" | "prd" | "user" | "code" | "other";
title: string;
url?: string;
excerpt?: string; // raw sensitive text는 public artifact에 넣지 않음
}>;
requirement_matrix?: Array<{
id: string; // R1, R2 ...
sourceId: string;
sourceText: string; // 기획 근거 원문 또는 sanitized excerpt
implementationContract: string;
verificationEvidence: string[];
status: "pending" | "confirmed" | "decision-needed" | "gap" | "blocked" | "out-of-scope";
}>;
domain_work_map?: Array<{
area: string; // FE Admin, FE Web, BE, DB/Ops, Verification ...
tasks: Array<{
title: string;
requirementIds: string[];
implementation?: string;
verification: string[];
owner?: "agent" | "user";
status: "pending" | "confirmed" | "decision-needed" | "gap" | "blocked" | "out-of-scope";
}>;
}>;
policy_axis_scan?: {
triggered: boolean;
triggerDomains: string[];
axes: Array<{
axis: "time_basis" | "application_cardinality" | "default_fallback" | "channel_matrix" | "data_migration" | "api_cache_identity";
decision: string;
source: "code" | "ticket" | "user" | "assumption" | "open_question";
unresolved: boolean;
}>;
channel_matrix?: Array<{
channel: string;
timeBasis: string;
campaignSelection?: string;
defaultPolicy?: string;
displayPolicy?: string;
verification: string;
}>;
};
backend_layer_map?: {
triggered: boolean;
mode?: "full" | "boundary-only" | "not-applicable"; // boundary-only = 신규 BE 구현 없음, 기존 action/API 경계 재사용/보존을 검증
triggerReason: string;
callFlow: string[];
layers: Array<{
layer: "entry_point" | "application_flow" | "domain_rule" | "data_access" | "cache_batching" | "persistence" | "consumer" | "external" | "action_boundary" | "refresh_boundary";
names: string[];
responsibility: string;
requirementIds?: string[];
ownsDecision?: string;
verification?: string;
status: "confirmed" | "assumption" | "open_question" | "not_applicable";
}>;
openQuestions?: string[];
};
architecture_flow_map?: {
triggered: boolean;
mode?: "architecture-flow" | "data-flow" | "user-flow" | "not-applicable"; // user-flow = UI/action/verification 흐름 중심
triggerReason: string;
lanes: string[];
nodes: Array<{
id: string;
lane: string;
type: "screen" | "resolver" | "usecase" | "service" | "domain" | "vo" | "repository" | "table" | "review" | "ops" | "external" | "action" | "cache";
title: string;
description: string;
requirementIds?: string[];
verification?: string;
sourceOfTruth?: boolean;
}>;
edges: Array<{
from: string;
to: string;
label: string;
requirementIds?: string[];
risk?: string;
verification?: string;
}>;
openQuestions?: string[];
};
data_model_migration_map?: {
triggered: boolean;
mode?: "data-model" | "migration-map" | "ddl" | "dml" | "backfill" | "not-applicable";
triggerReason: string;
entities: Array<{
id: string;
name: string; // table/entity/source 이름
status: "new" | "changed" | "removed" | "same" | "open_question";
sourceOfTruth?: boolean;
description?: string;
requirementIds?: string[];
columns: Array<{
name: string;
type?: string;
description?: string;
primaryKey?: boolean;
foreignKey?: boolean;
references?: string;
unique?: boolean;
nullable?: boolean;
defaultValue?: string;
status?: "new" | "changed" | "removed" | "same" | "open_question";
}>;
}>;
relationships?: Array<{
from: string;
to: string;
cardinality: string; // 1:N, 1:0..1 등
description?: string;
requirementIds?: string[];
}>;
migrationOperations?: Array<{
type: "DDL" | "DML" | "BACKFILL" | "ROLLBACK" | "VERIFY";
target: string;
description: string;
sql?: string;
rollback?: string;
idempotency?: string;
requirementIds?: string[];
status: "planned" | "confirmed" | "open_question" | "blocked";
}>;
runtimeFlow?: string[];
verificationQueries?: Array<{ id: string; title: string; sql?: string; description?: string }>;
openQuestions?: string[];
};
productive_resistance: Array<{
question: string;
selected: string;
rationale?: string;
frameImpact: string; // success_criteria/out_of_scope/boundary/risk 중 무엇이 바뀌었는지
}>;
success_criteria: Array<{
id: string; // SC-1, SC-2 ...
statement: string;
evidence_locator: string; // 파일/엔드포인트/셀렉터/메트릭
verify_command?: string;
}>;
out_of_scope: string[];
boundaries: {
always: string[];
ask_first: string[];
never: string[];
};
risk_register: Array<{
id?: string; // RISK-1 ...
risk: string;
severity: "low" | "med" | "high";
mitigation: string;
needs_decision: boolean;
}>;
edge_case_seeds: string[];
verify_plan: {
commands: string[];
manual_checks: string[];
};
implementation_plan: {
status: "blocked_by_decision" | "draft" | "ready";
derivedFrom: {
frameHash?: string;
decisionIds: string[];
};
blockers?: string[];
slices: Array<{
id: string; // SLICE-1 ...
goal: string;
expectedFiles?: string[];
validation: string[];
}>;
firstSafeStep: string;
readiness: {
dependencies?: "unknown" | "running" | "ready" | "blocked";
notes?: string[];
};
gates: string[]; // ask_first/deploy/manual gates that still constrain execution
};
decisions: Array<{
id: string; // DEC-1 ... (/decide가 추가)
title: string;
taskId?: string;
alternatives_considered: string[];
selected: string;
rationale: string;
tradeoffs_accepted: string;
mitigations?: string[];
challenge: {
intensity: "low" | "medium" | "high" | "ask_first";
objection: string;
response: "accepted" | "accepted_with_mitigation" | "reconsidered" | "returned_to_frame";
userSelection: string;
};
challenged: true; // /decide는 항상 challenge 수행
decidedAt: number;
}>;
decision_queue: Array<{
taskId: string;
title: string;
riskRef?: string;
}>;
provenance: {
transcriptPath?: string;
sourceAnswerIds?: string[];
canonicalHash?: string;
generatedMirrors?: {
frame_md?: string;
};
notes?: string[];
};
links: {
jira?: string;
slack_threads?: string[];
notion?: string[];
};
createdAt: number;
updatedAt: number;
};
/verify는 단 하나의 계약을 지킨다: frame.json이 없으면 frame부터 하라고 차단; 있으면 success_criteria의 row 단위로 evidence를 집계.
USER: /frame 결제 취소 시 부분 환불 지원해줘
AI (Step 1, 질문 없음):
컨텍스트:
- worktree: atlanta-PROJ-123 (branch: feat/PROJ-123/partial-refund)
- ticket(자동): PROJ-123 — "부분 환불 지원"
- 변경 없음 (clean)
AI (Step 2):
내가 이해한 목표:
“주문 결제에서 부분 환불을 지원하고 정산/관리자 확인까지 검증한다.”
(명백: ticket acceptance에 정산과 관리자 UI가 함께 언급되어 있어 API만으로는 성공 기준이 닫히지 않습니다.)
가정:
1. 성공 판정은 “부분환불 API 호출 성공”이 아니라 “정산 반영까지 일치”다.
2. DB 스키마 변경 가능성이 있다.
3. 외부 PG는 Toss를 우선 확인한다.
4. 관리자 UI는 범위에 포함될 수 있다.
같이 볼 렌즈:
1. 정산 데이터 정합성 — 환불 금액이 리포트까지 일치하는가
2. 외부 PG 경계 — Toss만 할지, 다른 PG를 제외할지
3. 관리자 UX — 부분환불 상태가 사람이 확인 가능하게 보이는가
틀린 가정이 있으면 번호로 정정해주세요. 없으면 `ok`.
USER: 3번 — Toss만 범위에 포함, PayPal은 제외.
AI (Step 3):
(명백: acceptance가 정산과 관리자 UI까지 요구하므로 3번이 가장 자연스럽습니다. 다만 범위를 줄일 수 있습니다.)
질문: 목표를 어디까지로 잡을까요?
1. Toss 부분환불 API만 지원
2. Toss 부분환불 + 정산 반영까지 포함
3. Toss 부분환불 + 정산 + 관리자 UI까지 포함
4. 먼저 기존 환불 모델을 더 탐색
USER: 3
AI (Step 4 Productive Resistance):
질문: 이번 작업에서 명시적으로 제외할 항목은?
1. PayPal 부분환불 제외 — Toss만 frame에 포함
2. 모바일 앱 표시 제외 — admin UI만 검증
3. 제외 없음 — 연결 흐름 전체 포함
4. 먼저 탐색 — 영향 범위 확인 후 제외 결정
USER: 1,2
AI (Step 5):
질문: frame draft에서 무엇을 가장 엄격히 볼까요? (최대 2개)
1. 정산 데이터 정합성
2. Toss API 실패/재시도 경계
3. 관리자 UI 캡처
4. 기존 전액환불 회귀 방지
USER: 1,3
AI (Step 6 draft):
검수할 때 볼 것:
1. 성공 기준이 정산/관리자 결과까지 말하는가
2. PayPal/모바일 앱 제외 범위가 명확한가
3. 검증 증거가 테스트와 화면 캡처로 나뉘는가
4. 선택한 답변이 frame 계약에 정확히 반영됐는가
AI (Step 7):
질문: 저장 전에 무엇을 고칠까요? (복수 선택 가능)
1. SC-2에 “정산 리포트 금액 일치”를 더 명시
2. out_of_scope에 “PayPal 부분환불” 추가
3. verify_plan에 관리자 UI 캡처 추가
4. edge_case에 “부분환불 후 같은 결제 재시도” 추가
5. 이대로 저장
USER: 4
AI (Step 8):
- implementation_plan.status=`blocked_by_decision` 기록
- frame.json atomic write
- frame.md regenerated from frame.json
- canonicalHash 기록
- frame.decision task 2개 큐잉
- frame.verify_check task 2개 큐잉
AI (Step 9):
질문: 2개 결정 큐잉 / verify 명령 2개 / plan 상태 blocked_by_decision. 다음은?
1. /decide — 큐잉된 결정 처리
2. plan 보완 — Frame 안의 implementation_plan만 다듬기
3. /verify dry-run — 검증 계획만 먼저 점검
4. fork해서 시작 — worktree로 옮겨 같은 frame/plan으로 구현
5. 바로 구현 시작 — 현재 worktree에서 진행
6. 여기서 멈춤