From 77e659119268eb07979325c4503431cfbedc0d1c Mon Sep 17 00:00:00 2001 From: greenhead Date: Sat, 11 Jul 2026 21:36:29 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat(skills):=20finding-unknowns=EB=A5=BC?= =?UTF-8?q?=20Codex=EC=97=90=EB=8F=84=20=EB=85=B8=EC=B6=9C=20=E2=80=94=20?= =?UTF-8?q?=EB=8F=99=EB=93=B1=20=EC=A7=80=ED=9C=98=EC=9E=90=20+=20?= =?UTF-8?q?=ED=96=89=EB=8F=99=20=EA=B3=84=EC=95=BD=20=EC=A4=91=EB=A6=BD?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit grilling 세션 합의 (PR #1082 후속): - 노출 전환: intentionallyNotExposed → exposedCodexSkills (verify-ai-compat EXPECTED_EXPOSED 이동, SKILL_NEUTRAL_LINT_EXCLUDE 제거) - 근거 실측: Codex user 스코프는 ~/.agents/skills — grilling/prototype이 맥북·miniPC 양쪽에서 이미 발견됨 (codex exec 스킬 목록 probe로 확인). 기존 ~/.codex/skills 노출 경로도 인식 확인 - 중립화: 도구명 리터럴(AskUserQuestion/request_user_input)과 runtime-mapping 링크를 제거하고 행동 계약만 유지 — 'blocking 질문 도구로 한 문항씩 답을 기다리고, plain-text로 묻고 지나가거나 가정하고 진행 금지' - Codex 성향 보정: 게이트 A·인터뷰에 명시 지시 (default mode의 make-assumptions-and-only-stop-if-blocked 정책 대응, run-da 선례) - 이식성: grilling/prototype 미설치 환경은 문서 요지로 직접 수행 폴백 Claude-Session: https://claude.ai/code/session_01PbbrsHKxkzkaKn9iJdgYDH --- .../claude/files/skills/finding-unknowns/SKILL.md | 6 +++--- .../files/skills/finding-unknowns/references/tactics.md | 2 +- .../programs/claude/files/skills/finish-pr/SKILL.md | 2 +- modules/shared/programs/codex/default.nix | 6 +++--- scripts/ai/verify-ai-compat.sh | 8 +++----- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/modules/shared/programs/claude/files/skills/finding-unknowns/SKILL.md b/modules/shared/programs/claude/files/skills/finding-unknowns/SKILL.md index 18d80fa7a..c8ce3e523 100644 --- a/modules/shared/programs/claude/files/skills/finding-unknowns/SKILL.md +++ b/modules/shared/programs/claude/files/skills/finding-unknowns/SKILL.md @@ -32,16 +32,16 @@ description: | ## 국면 1 — 구현 전 -각 단계는 프로젝트 성격에 따라 스킵할 수 있으나, 스킵하면 사유 한 줄을 미지 원장에 기록한다. 무단 생략은 스킵이 아니라 unknown unknown의 방치다. +각 단계는 프로젝트 성격에 따라 스킵할 수 있으나, 스킵하면 사유 한 줄을 미지 원장에 기록한다. 무단 생략은 스킵이 아니라 unknown unknown의 방치다. 위임 대상 스킬(`grilling`/`prototype`)이 설치되지 않은 환경이면 이 문서에 적힌 해당 단계의 요지로 직접 수행한다. 1. 영토 정찰 — 관련 소스·테스트·설정·공식 문서를 사용자에게 묻기 전에 직접 읽는다(필요 시 정찰 서브에이전트 병렬). 코드/문서가 답할 수 있는 것을 사용자에게 묻지 않는다. 완료 기준: 정찰한 경로/문서 목록이 미지 원장에 적혀 있음. 2. Blindspot pass — unknown unknowns를 [references/tactics.md](references/tactics.md)의 출력 형식으로 나열한다: 리스크 순위 + 저렴한 해소 수단 + 결정 소유자(사용자/에이전트/문서/프로토타입). 완료 기준: 최고 리스크 미지마다 해소 수단이 지정됨. 3. 프로토타입 — unknown knowns가 많은 영역(시각 디자인, UX 흐름, "보면 아는" 기준)이면 `prototype`으로 의미 있게 대비되는 방향 여러 개를 만들어 반응을 받는다. 완료 기준: 사용자 반응이 명시적 기준 문장으로 원장에 언어화됨. -4. 인터뷰 — `grilling`으로 남은 known unknowns를 좁힌다. 모든 질문은 Material(답이 설계를 바꿈)·Grounded(증거 기반)·Answerable(선택지/기본값/레퍼런스로 답 가능) 3기준을 충족해야 한다 (상세와 블로킹 질문 템플릿: [references/tactics.md](references/tactics.md)). 아키텍처를 바꿀 질문 우선, 한 번에 하나. 저위험 미지는 질문하는 대신 기본값을 선택하고 가정 라벨을 붙인다. +4. 인터뷰 — `grilling`으로 남은 known unknowns를 좁힌다. 모든 질문은 Material(답이 설계를 바꿈)·Grounded(증거 기반)·Answerable(선택지/기본값/레퍼런스로 답 가능) 3기준을 충족해야 한다 (상세와 블로킹 질문 템플릿: [references/tactics.md](references/tactics.md)). 아키텍처를 바꿀 질문 우선, 한 번에 하나 — blocking 질문 도구로 답을 기다리고, 답을 가정하고 진행하지 않는다. 저위험 미지는 질문하는 대신 기본값을 선택하고 가정 라벨을 붙인다. 5. 레퍼런스 — 사용자가 원하는 바를 말로 다 못 하면 레퍼런스를 요청한다. 소스 코드가 최고의 레퍼런스다 — 다른 언어여도 가리키는 폴더를 읽고 의미를 재구현한다. 6. 구현 계획 — 변경 가능성 높은 결정(데이터 모델·타입 인터페이스·권한·사용자 대면 흐름)을 앞에, 기계적 작업을 뒤에 배치한다. 잔존 가정 목록과 "이 계획이 통제하지 못하는 것" 리스크 대장을 포함한다. `run-da` for_plan으로 검증한다. -게이트 A (빌드 전): 사용자가 공유 이해를 확인하기 전에 구현을 시작하지 않는다. 예외는 사용자가 "라벨된 가정과 함께 진행"을 명시 허용한 경우뿐이다. +게이트 A (빌드 전): 사용자가 공유 이해를 확인하기 전에 구현을 시작하지 않는다. 확인은 blocking 질문 도구로 받는다 — 침묵이나 정황을 동의로 간주하거나, 막히지 않았다는 이유로 가정하고 진행하지 않는다. 예외는 사용자가 "라벨된 가정과 함께 진행"을 명시 허용한 경우뿐이다. ## 국면 2 — 구현 중 diff --git a/modules/shared/programs/claude/files/skills/finding-unknowns/references/tactics.md b/modules/shared/programs/claude/files/skills/finding-unknowns/references/tactics.md index 8849a507a..e932b41bc 100644 --- a/modules/shared/programs/claude/files/skills/finding-unknowns/references/tactics.md +++ b/modules/shared/programs/claude/files/skills/finding-unknowns/references/tactics.md @@ -92,7 +92,7 @@ ## 퀴즈 출제 규칙 (finish-pr 게이트가 사용) - 목적: 사용자가 변경의 동작을 이해했는지 확인 — 코드 diff 눈도장이 아니라 "이 입력이면 무슨 일이 일어나나"를 묻는다. -- 출제: 질문 도구로 총 3~5문항(변경 규모 비례)을 한 문항씩 답을 기다려 순차 출제한다. 질문 도구는 blocking tool call이어야 하며 plain-text 질문으로 퇴행하지 않는다 — 런타임별 binding(Claude=AskUserQuestion, Codex=request_user_input)은 [run-da의 런타임 도구 매핑](../../run-da/references/runtime-mapping.md#런타임-도구-매핑)이 정본. 각 문항은 PR 본문(설명자료)만 읽어도 답할 수 있어야 한다 — 본문에 없는 지식을 묻게 되면 퀴즈가 아니라 본문의 결함이므로 본문을 먼저 보강한다. +- 출제: 질문 도구로 총 3~5문항(변경 규모 비례)을 한 문항씩 답을 기다려 순차 출제한다. 질문은 blocking 도구 호출이어야 한다 — plain-text로 묻고 지나가거나, 답을 가정하고 진행하지 않는다. 각 문항은 PR 본문(설명자료)만 읽어도 답할 수 있어야 한다 — 본문에 없는 지식을 묻게 되면 퀴즈가 아니라 본문의 결함이므로 본문을 먼저 보강한다. - 좋은 문항 소재: 경계 조건에서의 동작, 실패 시 폴백, 남아 있는 가정 라벨, Deviations가 생긴 이유, 이 변경이 통제하지 못하는 것. - 오답이면: 해당 부분을 설명하고 그 주제로 재출제한다. 전 문항 정답이 통과다. - 통과 또는 명시적 스킵(사유 기록) 전에는 머지하지 않는다 — 게이트 자체는 finish-pr 절차가 소유한다. diff --git a/modules/shared/programs/claude/files/skills/finish-pr/SKILL.md b/modules/shared/programs/claude/files/skills/finish-pr/SKILL.md index 3589d279e..245b4146b 100644 --- a/modules/shared/programs/claude/files/skills/finish-pr/SKILL.md +++ b/modules/shared/programs/claude/files/skills/finish-pr/SKILL.md @@ -33,7 +33,7 @@ Skip 조건: ### 2. 퀴즈 게이트 (finding-unknowns 방법론 적용 작업) 1. 이 PR이 finding-unknowns 방법론 적용 작업인지 판별한다. 1차 신호는 PR 본문의 durable marker ``다 (기록 주체·정본: create-pr 흡수 계약 — 별도 세션에서도 남는 유일한 신호). 보조 신호는 세션·메모리 컨텍스트의 방법론 적용 선언, 워크트리에 남은 `implementation-notes.md`이며, 보조 신호만으로 판별할 때는 일반 PR 오탐에 주의한다. -2. 해당되면 머지 전에 변경의 동작 이해를 확인하는 퀴즈를 질문 도구로 출제한다 (런타임별 질문 도구 binding: [run-da의 런타임 도구 매핑](../run-da/references/runtime-mapping.md#런타임-도구-매핑) — blocking tool call 필수, plain-text 질문으로 퇴행 금지). 출제 규칙의 SoT는 finding-unknowns 스킬의 `references/tactics.md` — 요지: 변경 규모에 따라 총 3~5문항을 한 문항씩 답을 기다려 순차 출제하고, 모든 문항은 PR 본문만 읽어도 답할 수 있어야 하며, 오답이면 설명 후 그 주제로 재출제한다. +2. 해당되면 머지 전에 변경의 동작 이해를 확인하는 퀴즈를 질문 도구로 출제한다 — blocking 도구 호출로 한 문항씩 답을 기다리고, plain-text로 묻고 지나가거나 답을 가정하고 진행하지 않는다. 출제 규칙의 SoT는 finding-unknowns 스킬의 `references/tactics.md` — 요지: 변경 규모에 따라 총 3~5문항을 한 문항씩 답을 기다려 순차 출제하고, 모든 문항은 PR 본문만 읽어도 답할 수 있어야 하며, 오답이면 설명 후 그 주제로 재출제한다. 3. 전 문항 정답이 통과다. 통과 전에는 squash merge를 진행하지 않는다. 4. 퀴즈 통과 직후 merge 대상을 다시 고정한다: `gh pr view --json headRefOid,body,statusCheckRollup,reviewDecision,mergeStateStatus`를 재조회하고, 퀴즈 시작 시점 대비 head 또는 본문이 바뀌었으면 바뀐 내용 기준으로 퀴즈를 다시 시작한다 (이전 head에 대한 통과로 새 head를 머지하지 않는다). 재확정한 `headRefOid`를 3단계 merge에 전달한다. diff --git a/modules/shared/programs/codex/default.nix b/modules/shared/programs/codex/default.nix index 5aa9e8ab8..8dc2bce59 100644 --- a/modules/shared/programs/codex/default.nix +++ b/modules/shared/programs/codex/default.nix @@ -43,6 +43,9 @@ let "analyzing-da-sessions" "create-issue" "create-pr" + # finding-unknowns: 미지 방법론 오케스트레이터 — Codex도 동등 지휘자 (grilling/prototype은 + # Codex user 스코프 ~/.agents/skills에서 발견됨을 실측 확인; 질문은 blocking 도구 행동 계약으로 중립화) + "finding-unknowns" "finish-pr" "issuing-codex-pairing-code" "playwright-cli" @@ -65,9 +68,6 @@ let # codex-fan-out: Codex 세션은 native subagent fan-out이 기본 경로이므로 자기 참조가 된다. # 이 스킬은 Claude/headless 세션에서 codex exec subprocess를 구동하는 패턴용. "codex-fan-out" - # finding-unknowns: Claude 하네스 전용 오케스트레이터 — grilling/prototype/run-da/create-pr/finish-pr - # 조합과 AskUserQuestion 인터뷰·퀴즈에 결합되어 있어 Codex 단독 세션에선 의미가 없다. - "finding-unknowns" ]; mkCodexSkillEntry = name: { diff --git a/scripts/ai/verify-ai-compat.sh b/scripts/ai/verify-ai-compat.sh index 19e0579eb..99d2e6b7b 100755 --- a/scripts/ai/verify-ai-compat.sh +++ b/scripts/ai/verify-ai-compat.sh @@ -38,6 +38,7 @@ EXPECTED_EXPOSED=( analyzing-da-sessions create-issue create-pr + finding-unknowns finish-pr issuing-codex-pairing-code playwright-cli @@ -50,7 +51,6 @@ SHARED_EXPOSURE_EXCLUDE=( using-claude-p using-codex-exec codex-fan-out - finding-unknowns ) # Split retired names so the public stale-reference scan scope can stay # zero-match while this verifier still checks deployed residue. @@ -62,15 +62,13 @@ RETIRED_EXECUTABLES=( ) # SKILL.md tool-neutral lint has its own exclusion policy. It currently matches -# the shared exposure exclusions (legacy adapters + Claude-harness-only -# orchestrators), but future exposure-only exclusions must be added deliberately. +# the shared exposure exclusions because these four skills are legacy adapters, +# but future exposure-only exclusions must be added deliberately. SKILL_NEUTRAL_LINT_EXCLUDE=( set-icons using-claude-p using-codex-exec codex-fan-out - # finding-unknowns: Claude 하네스 전용 오케스트레이터 — AskUserQuestion 퀴즈 출제 규칙을 명시적으로 소유 - finding-unknowns ) errors=0 From fd5de41092c62b3f7f90a6b196c7841f908128b1 Mon Sep 17 00:00:00 2001 From: greenhead Date: Sat, 11 Jul 2026 21:44:27 +0900 Subject: [PATCH 2/2] =?UTF-8?q?docs(skills):=20=EC=A0=80=EC=9C=84=ED=97=98?= =?UTF-8?q?=20=EA=B8=B0=EB=B3=B8=EA=B0=92=20=EA=B7=9C=EC=B9=99=EA=B3=BC=20?= =?UTF-8?q?=EA=B2=8C=EC=9D=B4=ED=8A=B8=20A=20=EC=A0=95=ED=95=A9=20?= =?UTF-8?q?=E2=80=94=20=EC=9E=A0=EC=A0=95=20=EC=B1=84=ED=83=9D=C2=B7?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D,=20=ED=99=95=EC=9D=B8=20=EC=A0=84=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20=EA=B8=88=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeRabbit 지적 반영: '기본값을 선택하고'가 강화된 게이트 A(가정 직진 금지)와 표면 충돌해 오독 여지 — 기본값은 원장·계획에 잠정 기록되고 게이트 A에서 계획과 함께 확인받는다는 우선순위를 문구로 명시. Claude-Session: https://claude.ai/code/session_01PbbrsHKxkzkaKn9iJdgYDH --- .../programs/claude/files/skills/finding-unknowns/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/shared/programs/claude/files/skills/finding-unknowns/SKILL.md b/modules/shared/programs/claude/files/skills/finding-unknowns/SKILL.md index c8ce3e523..e0dda8ea4 100644 --- a/modules/shared/programs/claude/files/skills/finding-unknowns/SKILL.md +++ b/modules/shared/programs/claude/files/skills/finding-unknowns/SKILL.md @@ -37,7 +37,7 @@ description: | 1. 영토 정찰 — 관련 소스·테스트·설정·공식 문서를 사용자에게 묻기 전에 직접 읽는다(필요 시 정찰 서브에이전트 병렬). 코드/문서가 답할 수 있는 것을 사용자에게 묻지 않는다. 완료 기준: 정찰한 경로/문서 목록이 미지 원장에 적혀 있음. 2. Blindspot pass — unknown unknowns를 [references/tactics.md](references/tactics.md)의 출력 형식으로 나열한다: 리스크 순위 + 저렴한 해소 수단 + 결정 소유자(사용자/에이전트/문서/프로토타입). 완료 기준: 최고 리스크 미지마다 해소 수단이 지정됨. 3. 프로토타입 — unknown knowns가 많은 영역(시각 디자인, UX 흐름, "보면 아는" 기준)이면 `prototype`으로 의미 있게 대비되는 방향 여러 개를 만들어 반응을 받는다. 완료 기준: 사용자 반응이 명시적 기준 문장으로 원장에 언어화됨. -4. 인터뷰 — `grilling`으로 남은 known unknowns를 좁힌다. 모든 질문은 Material(답이 설계를 바꿈)·Grounded(증거 기반)·Answerable(선택지/기본값/레퍼런스로 답 가능) 3기준을 충족해야 한다 (상세와 블로킹 질문 템플릿: [references/tactics.md](references/tactics.md)). 아키텍처를 바꿀 질문 우선, 한 번에 하나 — blocking 질문 도구로 답을 기다리고, 답을 가정하고 진행하지 않는다. 저위험 미지는 질문하는 대신 기본값을 선택하고 가정 라벨을 붙인다. +4. 인터뷰 — `grilling`으로 남은 known unknowns를 좁힌다. 모든 질문은 Material(답이 설계를 바꿈)·Grounded(증거 기반)·Answerable(선택지/기본값/레퍼런스로 답 가능) 3기준을 충족해야 한다 (상세와 블로킹 질문 템플릿: [references/tactics.md](references/tactics.md)). 아키텍처를 바꿀 질문 우선, 한 번에 하나 — blocking 질문 도구로 답을 기다리고, 답을 가정하고 진행하지 않는다. 저위험 미지는 질문하는 대신 기본값을 잠정 채택하고 가정 라벨을 붙여 원장·계획에 기록한다 — 게이트 A에서 계획과 함께 확인받으며, 확인 전에는 구현에 적용하지 않는다. 5. 레퍼런스 — 사용자가 원하는 바를 말로 다 못 하면 레퍼런스를 요청한다. 소스 코드가 최고의 레퍼런스다 — 다른 언어여도 가리키는 폴더를 읽고 의미를 재구현한다. 6. 구현 계획 — 변경 가능성 높은 결정(데이터 모델·타입 인터페이스·권한·사용자 대면 흐름)을 앞에, 기계적 작업을 뒤에 배치한다. 잔존 가정 목록과 "이 계획이 통제하지 못하는 것" 리스크 대장을 포함한다. `run-da` for_plan으로 검증한다.