| name | deep-work-orchestrator |
| description | This skill should be used when the user invokes /deep-work "task", uses cross-platform Skill({ skill: "deep-work:deep-work-orchestrator", args: "task" }), asks to start a new deep-work session, or requests evidence-driven workflow auto-flow across Brainstorm โ Research โ Plan โ Implement โ Test phases. Handles session initialization (profile v3 load, capability detection, session-recommender sub-agent, AskUserQuestion 4-key ask, flag parsing) and dispatches the 5-phase pipeline with Exit Gates between each phase. |
| user-invocable | true |
Step 1: ์ธ์
์ด๊ธฐํ
์ฌ์ฉ์ ์
๋ ฅ: $ARGUMENTS
--resume-from=<phase> ๊ฐ ์ง์ ๋ ๊ฒฝ์ฐ: Step 1์ interactive/setup ๋ํ(ํ๋กํ ์ง๋ฌธ, ์์
๋ชจ๋ ์ ํ ๋ฑ)๋ง ๊ฑด๋๋ด๋ค. SESSION_ID๋ --session์์ ๊ฒฐ์ ๋๊ณ , ๊ธฐ์กด state file์ ์ฌ์ฌ์ฉํ๋ฉฐ ์ ์ธ์
ํ์ผ์ ์ฐ์ง ์๋๋ค.
๋ฐ๋์ ์ํ (NO2 + NP1 fix):
- Step 1-2 state file ๋ก๋:
.claude/deep-work.{SESSION_ID}.md์์ work_dir, task_description, worktree_enabled, worktree_path, team_mode, cross_model_enabled, tdd_mode, iteration_count, skipped_phases, research_approved, research_approved_hash, plan_approved, plan_approved_hash, current_phase ๋ฑ ๋ชจ๋ ์ํ ๋ณ์ ๋ก๋.
$WORK_DIR ๋ณ์ ์ด๊ธฐํ (state์ work_dir์์). ยง3-2/ยง3-3 hash check ๋ฑ ํ์ผ ๊ฒฝ๋ก ์ฐธ์กฐ ์ ํ์.
- Step 2 (์กฐ๊ฑด ๋ณ์ ์กฐ๋ฆฝ โ
ARGS, tdd_mode ๋ฑ) ์ํํ์ฌ Skill ํธ์ถ์ session/worktree/tdd context ๋ณด์กด.
๊ทธ ํ Step 3์ ํด๋น <phase> branch๋ก ์ ํํ๋ค.
Step 1-3: Model Routing Migration (v6.4.0)
State load ์งํ, Step 3 dispatch ์ ์ migration helper ๋ฅผ ํธ์ถํ์ฌ model_routing.{research,implement,test} == "main" ๊ฐ์ "sonnet" ์ผ๋ก atomic ์นํํ๋ค. model_routing.plan ์ migration ๋์์์ ์ ์ธ (Plan phase๋ ๋ํํ ๋ฉ์ธ ์ธ์
์ด ์ค๊ณ์ ํ์ โ spec ยง3 D1 W1).
ํธ์ถ ์กฐ๊ฑด: $STATE_FILE์ด ์ด๋ฏธ ์กด์ฌํ ๋๋ง ํธ์ถ (W-1.1 fix โ ์ ์ธ์
์ ยง1-9์์ state๋ฅผ ์์ฑํ๋ฏ๋ก ์ด ์์ ์ ํ์ผ์ด ์์ ์ ์์).
v6.10.0 ๊ฐ๋: migrateStateFile์ state์ model_routing_meta:๊ฐ ์์ผ๋ฉด skip์ ๋ฐํํ๋ค(์๋ ๊ฒฐ์ ์์ง์ด ์ด fail-safe main ๋ณดํธ โ ์ค๊ณ ยง5). skip ์ ์๋ฆผ ๋ถํ์.
์คํ:
if [ -f "$STATE_FILE" ]; then
result=$(node "${CLAUDE_PLUGIN_ROOT}/scripts/migrate-model-routing.js" "$STATE_FILE" 2>&1 || true)
fi
๋๋ ๋๋ฑํ JS import (orchestrator๊ฐ Node ๋ฐํ์ ๋ด์์ ์คํ ๊ฐ๋ฅํ ๊ฒฝ์ฐ):
const { migrateStateFile } = require('./scripts/migrate-model-routing.js');
const { replaced, warnings } = migrateStateFile(stateFile);
์ถ๋ ฅ ๊ฒฐ๊ณผ:
replaced๊ฐ ๋น์ด์์ง ์์ผ๋ฉด ๊ฐ ํ๋๋ณ๋ก 1ํ ์๋ฆผ:
[migration v6.4.0] model_routing.research='main' deprecated โ 'sonnet' ์ ์ฉ
warnings๊ฐ ์์ผ๋ฉด ๊ทธ๋๋ก stderr์ ์ถ๋ ฅ (์นํ ์์ด ์๋ณธ ์ ์ง).
- ์นํ์ด ๋ฐ์ํ ๊ฒฝ์ฐ atomic
writeFile + rename ์ผ๋ก state file์ persist๋จ.
(spec ยง5.7, ยง6.1 ์ฐธ์กฐ)
1-1. Update Check
SessionStart hook์ update-check.sh ์ถ๋ ฅ ์ฒ๋ฆฌ:
JUST_UPGRADED โ ์
๊ทธ๋ ์ด๋ ์๋ฃ ๋ฉ์์ง, ๊ณ์ ์งํ
UPGRADE_AVAILABLE โ AskUserQuestion์ผ๋ก ์
๊ทธ๋ ์ด๋ ์ ์ (์
๊ทธ๋ ์ด๋ / ๊ฑด๋๋)
1-2. ๊ธฐ์กด ์ธ์
ํ์ธ (Multi-Session)
Legacy ๋ง์ด๊ทธ๋ ์ด์
.claude/deep-work.local.md ์กด์ฌ + active โ migrate_legacy_state ์คํ
Stale ์ธ์
๊ฐ์ง
detect_stale_sessions โ ๊ฐ stale ์ธ์
์ ๋ํด AskUserQuestion:
- ์ด์ด์ ์งํ โ state ์ฝ๊ธฐ + worktree ํ์ธ + artifact ๋ณต์ โ Step 3์ผ๋ก jump
- ์ข
๋ฃ ์ฒ๋ฆฌ โ idle ์ค์ , registry ํด์
- ๋ฌด์ โ ๊ณ์
Active ์ธ์
๋ชฉ๋ก
Registry์์ ํ์ฑ ์ธ์
ํ์. 5๊ฐ ์ด์์ด๋ฉด ๊ฒฝ๊ณ .
์ธ์
ID ์์ฑ
SESSION_ID=$(generate_session_id)
write_session_pointer "$SESSION_ID"
1-3. ํ๋กํ ๋ก๋ + ํ๋๊ทธ ํ์ฑ (v6.4.2)
ํ๋๊ทธ ํ
| ํ๋๊ทธ | ํจ๊ณผ |
|---|
--setup | ํ๋กํ ์ฌ์ค์ ๊ฐ์ |
--team | team_mode โ "team" (ํด๋น ํญ๋ชฉ ask ์ฐํ) |
--zero-base | project_type โ "zero-base" |
--skip-research | start_phase โ "plan" (ํด๋น ํญ๋ชฉ ask ์ฐํ) |
--skip-brainstorm | brainstorm ๊ฑด๋๋ |
--tdd=MODE | strict / relaxed / coaching / spike (ํด๋น ํญ๋ชฉ ask ์ฐํ) |
--skip-review | review_state โ "skipped" |
--no-branch | git โ "current-branch" (ํด๋น ํญ๋ชฉ ask ์ฐํ) |
--skip-to-implement | Plan๊น์ง ์ ๋ถ ๊ฑด๋๋, ์ธ๋ผ์ธ slice |
--skip-integrate | Phase 5 Integrate ๊ฑด๋๋ (v6.3.0) |
--profile=X | ํ๋ฆฌ์
X ์ง์ ์ ํ (ask ๋จ๊ณ๋ ์งํ, v6.4.2 ์๋ฏธ ์ ์ง) |
--no-ask | ์ ๊ท (v6.4.2): ask ๋จ๊ณ ๋ชจ๋ skip + ์ถ์ฒ skip (๊ฐ์ฅ ๋น ๋ฅธ ๊ฒฝ๋ก) |
--recommender=MODEL | ์ ๊ท (v6.4.2): ์ถ์ฒ ๋ชจ๋ธ override. allowlist ^(haiku|sonnet|opus)$, ๊ทธ ์ธ ๊ฑฐ๋ถ + sonnet fallback + 1ํ ๊ฒฝ๊ณ |
--no-recommender | ์ ๊ท (v6.4.2): ์ถ์ฒ sub-agent skip (defaults ๊ฐ์ผ๋ก ask ์ง์
) |
--exec=<inline|delegate> | (v6.4.0) Implement ๋จ๊ณ ์คํ ๋ฐฉ์ override. parser โ state.execution_override โ deep-implement ยง1.5์์ read |
--resume-from=<phase> | Step 1 ์ด๊ธฐํ ๊ฑด๋๋ฐ๊ณ ๊ธฐ์กด state๋ก <phase>(research/plan/implement/test) ํด๋น Step 3-N๋ถํฐ ์ฌ๊ฐ. skills/deep-resume/SKILL.md๊ฐ ์ฌ์ฉ. |
ยง1-3-1. ํ๋๊ทธ ํ์ ํธ์ถ
orchestrator ๋ณธ๋ฌธ์์ ์ง์ ์คํ (process scope ์ผ๊ด โ R3-B):
PARSE_OUT=$(node "${CLAUDE_PLUGIN_ROOT}/scripts/parse-deep-work-flags.js" -- "$ARGUMENTS" 2>/tmp/dw-parse-err.txt)
parse_rc=$?
parse_rc ๋น-zero โ /tmp/dw-parse-err.txt ๋ด์ฉ ํ์ + AskUserQuestion (์ฌ์
๋ ฅ / ์ข
๋ฃ). 2>&1 || true ํจํด ์ฌ์ฉ ๊ธ์ง (R3-C).
PARSE_OUT (JSON) โ TASK_TEXT, FLAGS ๊ฐ์ฒด ์ถ์ถ.
TASK_TEXT ๋น์ด ์์ผ๋ฉด AskUserQuestion("์์
๋ด์ฉ์ ์
๋ ฅํด ์ฃผ์ธ์.").
scripts/parse-deep-work-flags.js๋ Task 4์์ ๊ตฌํ. ๋ณธ task๋ ํธ์ถ step๋ง ๋ฐ์ .
ยง1-3-2. ํ๋กํ v2โv3 ๋ง์ด๊ทธ๋ ์ด์
ํ์ ๊ฒฐ๊ณผ๋ก DEEP_WORK_INITIAL_PRESET(= FLAGS.profile ๋๋ null)์ด ์ฑ์์ง ํ migration ํธ์ถ (R3-W1):
PROFILE_FILE="$PROJECT_ROOT/.claude/deep-work-profile.yaml"
migrate_stderr=$(mktemp)
MIGRATE_OUT=$(DEEP_WORK_INITIAL_PRESET="${FLAGS.profile}" \
node "${CLAUDE_PLUGIN_ROOT}/scripts/migrate-profile-v2-to-v3.js" "$PROFILE_FILE" 2>"$migrate_stderr")
migrate_rc=$?
migrate_rc ๋น-zero โ $migrate_stderr ๋ด์ฉ ํ์ + AskUserQuestion (์๋ ์ด์ / ์ v3 ๊ฐ์ ์์ฑ / ์ข
๋ฃ). 2>&1 || true ํจํด ์ฌ์ฉ ๊ธ์ง (R3-C).
MIGRATE_OUT (JSON stdout):
-
{ "migrated": true, "reason": "v2-to-v3" } โ 1ํ ์๋ด:
"ํ๋กํ์ v3๋ก ๋ง์ด๊ทธ๋ ์ด์
ํ์ต๋๋ค. ์๋ฆผ ์ค์ ์ ์ ๊ฑฐ๋์๊ณ , ๋งค ์ธ์
๋ง๋ค 4๊ฐ ํญ๋ชฉ(team/start/tdd/git)์ ๋ํด LLM ์ถ์ฒ + ํ์ธ์ ๊ฑฐ์นฉ๋๋ค. ๋ชจ๋ธ์ ์ฝ๋๋ฒ ์ด์ค ๊ท๋ชจยท๋์ด๋๋ก ์๋ ์ ํ๋ฉ๋๋ค. ask ํญ๋ชฉ ๋ณ๊ฒฝ: /deep-work --setup. ๋น ๋ฅธ ๊ฒฝ๋ก: /deep-work --profile=X --no-ask."
์ดํ migrate warnings ํ์:
if echo "$MIGRATE_OUT" | node -e 'const r=JSON.parse(require("fs").readFileSync(0,"utf8")); process.exit(r.warnings && r.warnings.length ? 0 : 1)'; then
echo "$MIGRATE_OUT" | node -e '
const r = JSON.parse(require("fs").readFileSync(0, "utf8"));
for (const w of (r.warnings || [])) console.error("[migrate] " + w);
'
fi
-
{ "migrated": false, "reason": "already-v3" } โ silent.
-
{ "migrated": false, "reason": "not-found-created-v3" } โ 1ํ ์๋ด:
"์ ๊ท ํ๋กํ (v3 ํ์)์ ์์ฑํ์ต๋๋ค: $PROFILE_FILE. ๋งค ์ธ์
๋ง๋ค 4๊ฐ ํญ๋ชฉ ask + ์ถ์ฒ์ด ์งํ๋ฉ๋๋ค(๋ชจ๋ธ์ ์๋ ์ ํ). ๋น ๋ฅธ ๊ฒฝ๋ก: --profile=solo-strict --no-ask."
ยง1-3-3. v3 ํ๋กํ ๋ก๋ ํธ์ถ
PROFILE_OUT=$(DEEP_WORK_INITIAL_PRESET="${FLAGS.profile}" \
node "${CLAUDE_PLUGIN_ROOT}/scripts/load-v3-profile.js" "$PROFILE_FILE" 2>/tmp/dw-profile-err.txt)
profile_rc=$?
profile_rc ๋น-zero โ /tmp/dw-profile-err.txt ๋ด์ฉ ํ์ + AskUserQuestion (์ฌ์๋ / ์ข
๋ฃ).
PROFILE_OUT (JSON stdout) โ PROFILE_DATA (presets, default_preset, interactive_each_session, defaults) ์ถ์ถ.
scripts/load-v3-profile.js๋ Task 3.5์์ ๊ตฌํ. ๋ณธ task๋ ํธ์ถ step๋ง ๋ฐ์ .
ยง1-3-4. ํ๋๊ทธ ์ฐ์ ์์ ์ ์ฉ
์๋ ์ฐ์ ์์ ์์๋ก in-memory current_defaults ๊ตฌ์ฑ (๋์ค ๋จ๊ณ๊ฐ ์ ๋จ๊ณ๋ฅผ override):
PROFILE_DATA.defaults (ํ๋ฆฌ์
๊ธฐ๋ณธ๊ฐ)
--profile=X ์ ํ ํ๋ฆฌ์
defaults (๋ช
์ ์ ํ ์)
- CLI ํ๋๊ทธ (
--team, --tdd=MODE, --no-branch, --skip-research ๋ฑ)
--no-ask โ interactive_each_session ์ ํญ๋ชฉ ๊ฑด๋๋ ํ์
current_defaults๋ ยง1-4 ask ํ๋ฆ์ ์
๋ ฅ๊ฐ. --no-ask ์ง์ ์ ยง1-4 ์ ์ฒด skip.
ยง1-3-5. ํ์ฑ ๊ฒฝ๊ณ ํ์
FLAGS.warnings ๋ฐฐ์ด ๋น์ด์์ง ์์ผ๋ฉด ๊ฐ ๊ฒฝ๊ณ ๋ฅผ 1ํ์ฉ ํ์:
- ์ ์ ์๋ ํ๋๊ทธ:
"โ ์ ์ ์๋ ํ๋๊ทธ ๋ฌด์๋จ: --foo"
--recommender= allowlist ์๋ฐ: "โ --recommender=gpt4 ๋ถ์ธ์ โ sonnet fallback"
- ๊ธฐํ ํ์ ๊ฒฝ๊ณ : ๊ทธ๋๋ก ํ์.
--setup ์ฌ์ฉ ์
FLAGS.setup = true โ ๊ธฐ์กด ํ๋กํ ์กด์ฌํ๋ฉด ํ๋ฆฌ์
๊ด๋ฆฌ UI (ํธ์ง / ์๋ก ๋ง๋ค๊ธฐ).
1-4. ํญ๋ชฉ๋ณ ๋ํํ ์ค์ (v6.4.2)
--no-ask ๋๋ --profile=X --no-ask ์ง์ ์ ยง1-4 ์ ์ฒด skip โ ยง1-5๋ก ์งํ.
ยง1-4-1. Assumption auto-adjust ๊ฒฐ๊ณผ ํตํฉ
ยง1-7(Assumption Health Check)์ด ยง1-4 ์ด์ ์ ์คํ๋์ด tdd_mode ๋ฑ์ auto-adjustํ ๊ฒฐ๊ณผ๋ฅผ in-memory current_defaults์ ๋ฐ์. ์ดํ recommender ํธ์ถ์ ์
๋ ฅ current_defaults๊ฐ ๋จ.
(ยง1-7์ ๋ฒํธ ์ ์ง, ยง1-4-1์ด ยง1-7 ๊ฒฐ๊ณผ๋ฅผ consumeํ๋ ๋ฐฉ์์ผ๋ก ์ฐ๊ฒฐ โ ์น์
๋ฒํธ ์ฌ์ ๋ ฌ ํํผ.)
ยง1-4-2. session-recommender sub-agent ํธ์ถ (in-memory only)
์กฐ๊ฑด:
--no-recommender ๋ฏธ์ง์ + sanitize ํ ์
๋ ฅ ํ ํฐ โค 8k์ธ ๊ฒฝ์ฐ๋ง ํธ์ถ
- ๊ทธ ์ธ: ์ถ์ฒ ์์ด ask ์ง์
(์ต์
๋ผ๋ฒจ = "(์๋ ์ถ์ฒ ์คํจ โ ์ง์ ์ ํ)")
capability ๊ฐ์ง:
IS_GIT=$(git rev-parse --is-inside-work-tree 2>/dev/null || echo "false")
WORKTREE_SUPPORTED=$(git worktree list >/dev/null 2>&1 && echo "true" || echo "false")
TEAM_ENV=$([ -n "${CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS:-}" ] && echo "true" || echo "false")
export IS_GIT WORKTREE_SUPPORTED TEAM_ENV
CAP=$(node -e '
const { detectCapability } = require("'"${CLAUDE_PLUGIN_ROOT}"'/scripts/detect-capability.js");
const cap = detectCapability({
is_git: process.env.IS_GIT === "true",
worktree_supported: process.env.WORKTREE_SUPPORTED === "true",
team_env_set: process.env.TEAM_ENV === "true"
});
process.stdout.write(JSON.stringify(cap));
')
ํธ์ถ (deep-work:session-recommender โ 2๋จ๊ณ fallback):
const { sanitizeInput } = require("${CLAUDE_PLUGIN_ROOT}/scripts/recommender-input.js");
const { parseRecommendation } = require("${CLAUDE_PLUGIN_ROOT}/scripts/recommender-parser.js");
const { filterAskItems } = require("${CLAUDE_PLUGIN_ROOT}/runtime/recommender-runtime.js");
const input = sanitizeInput({
task_description: TASK_TEXT,
recent_commits: RECENT_COMMITS,
top_level_dirs: TOP_DIRS,
current_defaults: current_defaults,
capability: CAPABILITY,
ask_items: filterAskItems(PROFILE_DATA.interactive_each_session)
});
let result;
try {
result = await Agent({
subagent_type: "deep-work:session-recommender",
model: RECOMMENDER_MODEL,
prompt: JSON.stringify(input)
});
} catch (e) {
if (/subagent_type.*not found/i.test(e.message || '')) {
result = await Agent({
subagent_type: "session-recommender",
model: RECOMMENDER_MODEL,
prompt: JSON.stringify(input)
});
} else {
throw e;
}
}
const parsed = parseRecommendation(result.text, { capability: input.capability });
const REC_TASK_DIFFICULTY = (parsed.ok && parsed.data.task_difficulty) ? parsed.data.task_difficulty.value : "";
parsed.ok=false ๋๋ 30์ด timeout โ recommender skip + (์๋ ์ถ์ฒ ์คํจ โ ์ง์ ์ ํ) ๋ผ๋ฒจ๋ก ask ์ง์
.
ยง1-4-3. interactive_each_session ํญ๋ชฉ๋ณ AskUserQuestion (in-memory only)
v6.10.0: ์ํ ์ filterAskItems()(recommender-runtime)๋ฅผ ์ ์ฉํ๋ค โ ๊ตฌํ๋กํ interactive_each_session์ model_routing์ด ๋จ์ ์์ด๋ askํ์ง ์๋๋ค(๋ชจ๋ธ์ ยง1-8.5์์ ์๋ ๊ฒฐ์ ).
filterAskItems(PROFILE_DATA.interactive_each_session) ๋ฐฐ์ด์ ์ํํ๋ฉฐ ๊ฐ ํญ๋ชฉ๋ณ AskUserQuestion. CLI ํ๋๊ทธ๋ก ์ด๋ฏธ override๋ ํญ๋ชฉ์ ๊ฑด๋๋.
๊ฐ ask ํญ๋ชฉ๋ณ๋ก ์ต์
๋ผ๋ฒจ ๋น๋:
const { formatOptions, capabilityToDisabled } = require("${CLAUDE_PLUGIN_ROOT}/scripts/format-ask-options.js");
const disabled = capabilityToDisabled(CAP, item);
const opts = formatOptions({
item,
recommendation: REC[item] || null,
default_value: DEFAULTS[item],
enum_values: ENUMS[item],
disabled_values: disabled
});
ยง1-4-4. ๊ฒฐ๊ณผ ๋์
ask ๊ฒฐ๊ณผ๋ orchestrator ๋ณ์์ ๋์ . state file ๋ฏธ์์ฑ. ยง1-9 ์์ ์ ํ ๋ฒ์ atomic write.
ยง1-4-5. ์ผ์์ ์ง ์ ์ฌ์ง์
ask ๋์ค ์ฌ์ฉ์ ์ผ์์ ์ง โ state file ๋ฏธ์์ฑ ์ํ๋ก ์ข
๋ฃ. ๋ณต๊ท(/deep-work ์ฌํธ์ถ) ์ ยง1-1๋ถํฐ ์ฌ์์ (recommender๋ ์ฌํธ์ถ).
1-5. ์์
๋๋ ํ ๋ฆฌ ์์ฑ
mkdir -p .deep-work
TASK_FOLDER="${TIMESTAMP}-${SLUG}"
mkdir -p ".deep-work/${TASK_FOLDER}"
Legacy deep-work/ โ .deep-work/ ๋ง์ด๊ทธ๋ ์ด์
์๋ ์ฒ๋ฆฌ.
1-6. Cross-model ๋๊ตฌ ๊ฐ์ง
codex/gemini ์ค์น ์ฌ๋ถ ํ์ธ โ ํ๋กํ์ cross_model_preference์ ๋ฐ๋ผ ์๋ ํ์ฑํ / AskUserQuestion.
1-7. Assumption Health Check
์ธ์
ํ์คํ ๋ฆฌ ์ถฉ๋ถ ์ (>=5):
- assumption engine auto-adjust ์คํ
- ์๋ ์กฐ์ ๊ฒฐ๊ณผ ํ์ (tdd_mode ๋ฑ)
- ์ฌ์ฉ์ --tdd ํ๋๊ทธ๊ฐ override
1-8. Git Branch + Worktree
Git repository์ธ ๊ฒฝ์ฐ:
- ํ๋กํ/ํ๋๊ทธ์ ๋ฐ๋ผ worktree ๊ฒฉ๋ฆฌ / ์ ๋ธ๋์น / ํ์ฌ ๋ธ๋์น ์ ์ง
- Worktree ์ฑ๊ณต ์:
worktree_enabled: true, worktree_path, worktree_branch state์ ๊ธฐ๋ก
- ์ดํ ๋ชจ๋ ํ์ผ ์์
์ worktree ์ ๋ ๊ฒฝ๋ก ๊ธฐ์ค
1-8.5. Provisional risk-only โ adaptive ๋ชจ๋ธ ๊ฒฐ์ (v6.12.0)
๋ชจ๋ธ ๋ผ์ฐํ
์ ์ ์ ์๊ฒ ๋ฌป์ง ์๋๋ค. ๋์ผํ ์ ํจ ์
๋ ฅ์ ์ฐ๋ ๋ค์ 3๋จ๊ณ๋ฅผ ์์๋๋ก
์คํํ๋ค. REC_TASK_DIFFICULTY๋ ยง1-4-2์ task_difficulty.value์ด๋ฉฐ ๋ถ์ฌ ์ ๋น ๊ฐ์ด๋ค.
1๋จ๊ณ โ provisional risk-only:
RISK_IN=$(mktemp)
node -e 'process.stdout.write(JSON.stringify({task_text:process.argv[1],difficulty:process.argv[2]||null}))' \
"$TASK_TEXT" "${REC_TASK_DIFFICULTY:-}" > "$RISK_IN"
RISK_ONLY_OUT=$(node "${CLAUDE_PLUGIN_ROOT}/scripts/risk-profile-cli.js" \
--stage provisional --risk-only --root "$PROJECT_ROOT" --work-dir "$WORK_DIR" \
--input-file "$RISK_IN")
RISK_CLASS=$(printf '%s' "$RISK_ONLY_OUT" | node -e \
'const r=JSON.parse(require("fs").readFileSync(0,"utf8"));process.stdout.write(r.risk_profile?.class||"")')
RISK_INPUT_REF=$(printf '%s' "$RISK_ONLY_OUT" | node -e \
'const r=JSON.parse(require("fs").readFileSync(0,"utf8"));process.stdout.write(r.input_ref?.path||"")')
FLAGS.risk๊ฐ ์์ผ๋ฉด ํด๋น class๋ฅผ RISK_CLASS์ ์ ์ฉํ๋ค. ์๋/๊ธฐ์กด class๋ณด๋ค ๋ฎ์
override๋ ํ์ธ์ ๋ฐ์ ๋ค์๋ง ์ ์ฉํ๊ณ review_execution_json.risk_acceptances์
{from,to,reason,at,scope:"session"}๋ฅผ appendํ๋ค. ์ํฅ์ ์ฆ์ ์ ์ฉํ๋ค.
2๋จ๊ณ โ risk-aware routing:
POLICY_MODE="${FLAGS.policy:-adaptive}"
MR_OUT=$(node "${CLAUDE_PLUGIN_ROOT}/scripts/model-routing-cli.js" \
--root "$PROJECT_ROOT" --task "$TASK_TEXT" \
--difficulty "${REC_TASK_DIFFICULTY:-}" --pinned "${FLAGS.model_routing:-}" \
--risk-class "$RISK_CLASS" --policy-mode "$POLICY_MODE")
ํ๋กํ์ per-phase concrete pin์ --pinned์ ๋ณํฉํ๋ CLI pin์ด ์ฐ์ ํ๋ค. MR_OUT.meta.policy.floor_overridden_by_pin์ true๊ฐ ์๊ณ risk class๊ฐ
high ๋๋ critical์ด๋ฉด โ ๏ธ ์ฌ์ฉ์ pin์ด <phase> policy floor๋ณด๋ค ๋ฎ์ต๋๋ค๋ฅผ phase๋ณ
1ํ ํ๋ฉดํํ๋ค. pin์ ์ต์ข
์ฐ์ ์ด๋ฉฐ ์ด ๊ฒฝ๊ณ ๊ฐ ์คํ์ ์ฐจ๋จํ์ง๋ ์๋๋ค.
1-8.6. Provisional policy snapshot (v6.12.0)
3๋จ๊ณ โ ๊ธฐ์กด policy snapshot, signals ์ฌ์ฌ์ฉ: 2๋จ๊ณ ๊ฒฐ๊ณผ์ routing์ ์ ์ ํ๊ฒ
์
๋ ฅ์ ์ถ๊ฐํ๊ณ 1๋จ๊ณ artifact์ signals๋ง ์ฌ์ฌ์ฉํ๋ค.
node -e '
const mr=JSON.parse(process.argv[1]);
process.stdout.write(JSON.stringify({task_text:process.argv[2],
model_routing:mr.model_routing,tiers:mr.meta?.tiers??{},pinned:mr.meta?.pinned??{},
difficulty:process.argv[3]||null,runtime:mr.meta?.runtime??"unknown"}));
' "$MR_OUT" "$TASK_TEXT" "${REC_TASK_DIFFICULTY:-}" > "$RISK_IN"
RISK_OUT=$(node "${CLAUDE_PLUGIN_ROOT}/scripts/risk-profile-cli.js" \
--stage provisional --root "$PROJECT_ROOT" --work-dir "$WORK_DIR" \
--input-file "$RISK_IN" --reuse-input "$RISK_INPUT_REF")
rm -f "$RISK_IN"
- ๋ risk ํธ์ถ์ ๊ตฌ์กฐํ
errors๋ฅผ risk_profile_json.errors์ ๋ณด์กดํ๋ค. ์คํจ๋ ๊ฒฝ๊ณ ํ
fail-openํ๋ฉฐ ์ธ์
์ ์ค๋จํ์ง ์๋๋ค.
RISK_OUT.policy_snapshot์ policy_shadow_json.provisional๋ก ๊ธฐ์กด ๊ด์ฐฐ ์ฐ์์ฑ์
์ ์งํ๋ค.
MR_OUT.meta.policy์ MR_OUT.meta.efforts๋ก ์ค์ ์ ์ฉ ์ ์ฑ
์ธ
methodology_policy_json์ ๊ตฌ์ฑํ๋ค. mode, risk_class, profile, based_on,
floors_applied, floors_effective, floor_overridden_by_pin, efforts, decided_at์
๊ธฐ๋กํ๊ณ FLAGS.review์ review_mode_override๋ก ๊ธฐ๋กํ๋ค.
1-9. State ํ์ผ + Registry ์์ฑ (atomic + ๊ถํ 600)
.claude/deep-work.{SESSION_ID}.md ์์ฑ (YAML frontmatter):
- session_id, current_phase, task_description, work_dir
- team_mode, tdd_mode, worktree_, cross_model_
model_routing_json: JSON.stringify(MR_OUT.model_routing)๋ก ๋ง๋ ํ ์ค JSON-string ์ค์นผ๋ผ
model_routing_meta_json: JSON.stringify(MR_OUT.meta)๋ก ๋ง๋ ํ ์ค JSON-string ์ค์นผ๋ผ
risk_profile_json, policy_shadow_json, slice_risk_shadow_json (์ต์
๋, v6.11.0 โ frontmatter JSON-string ์ค์นผ๋ผ, shadow ๊ด์ฐฐ ์ ์ฉ. phase-guard/gate enforcement์ ์ํฅ ์์)
methodology_policy_json, review_execution_json (์ต์
๋, v6.12.0). --policy/--risk/--review ๊ฒฐ์ ๊ณผ ํํฅ ์น์ธ risk_acceptances๋ฅผ ์ ยง1-8.5/8.6 shape๋ก ๊ธฐ๋กํ๋ค.
- ๊ฐ phase timestamp, test_retry_count, max_test_retries ๋ฑ
recommendations: { ... } (v6.4.2 ์ ๊ท) โ ยง1-4-2 sub-agent ์๋ต + ยง1-4-3 ์ฌ์ฉ์ ์ต์ข
์ ํ (์ต์
๋ ํ๋, phase-guard enforcement์๋ ์ํฅ ์์)
execution_override: {FLAGS.exec_mode | null} โ v6.4.0 ํธํ, deep-implement Section 1.5์์ read
์์ฑ ์ ์ฐจ (atomic + ๊ถํ 600):
state_tmp="${state_path}.tmp"
write_yaml_to "$state_tmp"
chmod 600 "$state_tmp"
sync_file "$state_tmp"
mv -f "$state_tmp" "$state_path"
ยง1-4-2/ยง1-4-3์ in-memory ๊ฒฐ๊ณผ๋ ์ด ์์ ์ recommendations ํ๋๋ก ์ง๋ ฌํ. phase-guard๋ current_phase, *_completed_at, *_approved ํ๋๋ง ๊ฒ์ฌํ๋ฉฐ recommendations ํ๋๋ enforcement์ ์ํฅ์ ๋ฏธ์น์ง ์๋๋ค.
Registry ๋ฑ๋ก: register_session "$SESSION_ID" ...
1-10. ํ๋กํ ์ ์ฅ (์ฒซ ์คํ ์)
ํ๋กํ ๋ฏธ์กด์ฌ ์ .claude/deep-work-profile.yaml์ v3 ํ์์ผ๋ก ์ ์ฅ (v2 ํ์ ์ฌ์ฉ ๊ธ์ง). ยง1-3-2์ migration ๋จ๊ณ๊ฐ not-found-created-v3 ์๋ต ์ ์ด๋ฏธ v3 ํ์ผ์ด ์์ฑ๋๋ฏ๋ก, ๋ณธ ๋จ๊ณ์์๋ ยง1-4-3 ask ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ํ์ฌ ํด๋น ํ๋ฆฌ์
defaults๋ฅผ ์
๋ฐ์ดํธํ๋ค.
1-11. ์ธ์
ํ์ธ ํ์
๊ทผ๊ฑฐ ๋ผ์ธ ๋ถ๊ธฐ: MR_OUT.meta.error === true(CLI ์๋ ๊ฒฐ์ ์คํจ โ fail-safe)์ด๋ฉด ์๋ "๊ทผ๊ฑฐ" ๋ผ์ธ ๋์
๊ทผ๊ฑฐ: ์๋ ์ ํ ์คํจ โ ์ phase main(ํ์ฌ ์ธ์
๋ชจ๋ธ)๋ก fallback์ ํ์ํ๊ณ MR_OUT.warnings์ ์ฌ์ ๋ ํจ๊ป ๋ณด์ฌ์ค๋ค.
์ ์ meta({tiers, scale, signals_summary, difficulty, ...})์ผ ๋๋ง ์๋ scale/tracked_files/difficulty ๊ทผ๊ฑฐ๋ฅผ ํ์ํ๋ค
(fallback meta๋ {runtime, tiers, error} ํํ๋ฟ์ด๋ผ scale/signals_summary/difficulty ์ฐธ์กฐ ์ undefined ๋ ๋ โ final review #2).
Deep Work ์ธ์
์ด ์์๋์์ต๋๋ค!
์์
: $ARGUMENTS
์์
ํด๋: $WORK_DIR
ํ๋ฆฌ์
: [preset_name]
์์
๋ชจ๋: Solo / Team
TDD ๋ชจ๋: strict / relaxed / coaching / spike
๋ชจ๋ธ ๋ผ์ฐํ
(์๋): R=[model] P=main I=[model] T=[model]
๊ทผ๊ฑฐ: [meta.scale] ์ฝ๋๋ฒ ์ด์ค([meta.signals_summary.tracked_files] files) ยท ๋์ด๋ [meta.difficulty ?? "๊ธฐ์ค์ "]
(๋๋ meta.error === true ์: ๊ทผ๊ฑฐ: ์๋ ์ ํ ์คํจ โ ์ phase main(ํ์ฌ ์ธ์
๋ชจ๋ธ)๋ก fallback)
์กฐ์ : --model-routing=implement=deep ํ์ ๋๋ /deep-slice model
์ํฌํ๋ก์ฐ:
Phase 0: deep-brainstorm [โ ํ์ฌ / โ
๊ฑด๋๋]
Phase 1: deep-research
Phase 2: deep-plan
Phase 3: deep-implement
Phase 4: deep-test
Phase 5: deep-integrate [skippable]
๊ฐ phase ์๋ฃ ์ ์งํ ํ์ธ์ ๋ฐ์ผ๋ฉฐ ์์ฐจ ์คํํฉ๋๋ค. "๋ค์ phase๋ก ์งํ" ์ ํ ์ ์ถ๊ฐ ํ์ธ ์์ด ์ฆ์ ๋ค์ ๋จ๊ณ๋ฅผ ์์ํฉ๋๋ค.
Step 2: ์กฐ๊ฑด ๋ณ์ ์กฐ๋ฆฝ
ARGS="--session={SESSION_ID}"
if worktree_enabled: ARGS += " --worktree={worktree_path}"
if team_mode=team: ARGS += " --team"
if cross_model_enabled: ARGS += " --cross-model"
if tdd_mode: ARGS += " --tdd={tdd_mode}"
Step 3: Auto-flow Dispatch
State์ current_phase์์ ์์์ ๊ฒฐ์ :
- brainstorm โ 3-1 | research โ 3-2 | plan โ 3-3 | implement โ 3-4 | test โ 3-5
3-1. Brainstorm (skip ๊ฐ๋ฅ)
skipped_phases / start_phase ํ์ธ. ๊ฑด๋๋ฐ๋ฉด Exit Gate ์๋ตํ๊ณ current_phase: research๋ก ์ง์ ์ ํ โ 3-2.
Skill("deep-brainstorm", args=ARGS)
Brainstorm skill์ Section 3 ์๋ฃ ๋ฉ์์ง ์ถ๋ ฅ ํ:
Exit Gate (Phase 0 โ Phase 1)
AskUserQuestion:
- header: "Phase 0 (Brainstorm) ์๋ฃ. ์ด๋ป๊ฒ ์งํํ ๊น์?"
- multiSelect: false
- options:
- label: "๋ค์ phase๋ก ์งํ", description: "์ฆ์ Phase 1 Research๋ฅผ ์์ํฉ๋๋ค"
- label: "์ด phase ์ฌ์คํ/์์ ", description: "Brainstorm์ ์ฌ์คํํ๊ฑฐ๋ brainstorm.md๋ฅผ ํธ์งํฉ๋๋ค"
- label: "์ผ์์ ์ง", description: "์ธ์
์ ์ง. /deep-resume์ผ๋ก ๋ณต๊ท ์ ์ด Exit Gate๋ก ๋์์ต๋๋ค"
๋ถ๊ธฐ:
- option 1 โ ์ฆ์
current_phase: research ์ค์ (F1 Option A) โ ยง3-2 Research๋ก dispatch (ยง3-2 body๊ฐ Resume check + Skill ํธ์ถ ๋ด๋น). ๋ณธ branch์์ Skill์ ์ง์ ํธ์ถํ์ง ์๋๋ค โ ยง3-2 ๋ณธ๋ฌธ๊ณผ ์ค๋ณต ์คํ ๋ฐฉ์ง (v6.3.1 NO1 fix).
- option 2 โ ์ฌ์คํ ์ completion marker clear (v6.3.1 NC2 symmetric):
brainstorm_completed_at: null ์ค์ โ ์ดํ ์ฌ์ฉ์ ์์ธ ์ง์ ์ฒญ์ทจ. brainstorm.md ์ง์ ํธ์ง(phase-guard ํ์ฉ) ๋๋ Skill("deep-brainstorm", args=ARGS + " --force-rerun") ์ฌํธ์ถ. ์ฌ์คํ์ด ์๋ฃ๋ ๋ค์๋ง brainstorm_completed_at์ด ๋ค์ ๊ธฐ๋ก๋์ด Resume fast-path๊ฐ ์ ์ ๋์.
- option 3 โ current_phase๋
brainstorm ์ ์ง. "์ธ์
์ ์ง๋จ. /deep-resume {SESSION_ID}๋ก ๋ณต๊ท ์ Exit Gate๊ฐ ์ฌํ์๋ฉ๋๋ค." ์ถ๋ ฅ ํ ํด ์ข
๋ฃ.
3-2. Research
skipped_phases์ "research" ํฌํจ ์ Exit Gate ์๋ตํ๊ณ current_phase: plan์ผ๋ก ์ง์ ์ ํ โ 3-3.
Spec resume ์ฐ์ ๋ถ๊ธฐ (v6.13): current_phase: research + subphase: spec์ด๋ฉด
deep-research๋ฅผ ์ฌ์คํํ์ง ์๋๋ค. ํ์ฌ $WORK_DIR/spec.md bytes์
spec_approved_hash๋ฅผ ์ฌ๋์กฐํ๊ณ , ๋ถ์ผ์น/๋ฏธ์น์ธ์ด๋ฉด
Skill("deep-spec", args=ARGS)๋ก spec gate์์ ๋ณต๊ตฌํ๋ค. ์ผ์นํ๊ณ
spec_gate_result_json.pass:true์ด๋ฉด ์๋ Research Exit Gate๋ง ์ฌํ์ํ๋ค.
Resume ๋ถ๊ธฐ (v6.3.1 F1 + NW5 integrity check): state์ research_approved: true๊ฐ ์ด๋ฏธ ์๊ณ $ARGUMENTS์ --force-rerun์ด ์์ผ๋ฉด paused-after-approval ๋ณต๊ท ํ๋ณด ๊ฒฝ๋ก์ด๋ค. ๋จ, approval integrity check๊ฐ ์ถ๊ฐ๋ก ํ์:
-
research_approved_hash (state) ์ ํ์ฌ $WORK_DIR/research.md์ sha256์ ๋น๊ต:
Bash({ command: "shasum -a 256 \"$WORK_DIR/research.md\" | awk '{print $1}'" }) (or sha256sum on Linux)
- ํด์ ์ผ์น โ approval์ ์ ํจ. Skill ํธ์ถ๊ณผ review+approval์ ๊ฑด๋๋ฐ๊ณ ๋ฐ๋ก ์๋ Exit Gate ์คํ.
- ํด์ ๋ถ์ผ์น โ out-of-band ํธ์ง ๊ฐ์ง โ data preservation + in-place review (v6.3.1 NO3 fix + NP3 collision fix):
- ํ์ฌ
$WORK_DIR/research.md๋ฅผ $WORK_DIR/research.v{iteration_count+1}-edit.md๋ก ๋ณต์ฌ (ํธ์ง ๋ด์ฉ ๋ฐฑ์
). -edit ์ ๋ฏธ์ฌ ์ฌ์ฉ โ deep-research skill์ ๊ธฐ์กด research.v{iteration_count}.md backup๊ณผ ํ์ผ๋ช
์ถฉ๋ ๋ฐฉ์ง (NP3).
iteration_count์ 1 ์ฆ๊ฐ.
- Approval state invalidate:
research_approved: false, research_approved_at: null, research_approved_hash: null.
- ๊ฒฝ๊ณ : "โ ๏ธ research.md๊ฐ ์น์ธ ์ดํ ์ธ๋ถ์์ ์์ ๋์์ต๋๋ค. ํธ์ง ๋ด์ฉ์ research.v{N}-edit.md๋ก ๋ฐฑ์
๋์์ต๋๋ค. ํธ์ง๋ ํ์ฌ ๋ฌธ์๋ฅผ ๋์์ผ๋ก Review+Approval์ ์ฌ์คํํฉ๋๋ค."
- Skill ์ฌํธ์ถ ์์ด ์๋ Review+Approval workflow (Step 1-6)๋ก ์ง์ ์ง์
โ ํ์ฌ ์์ ๋ ๋ฌธ์๋ฅผ in-place review. template ๊ธฐ๋ฐ ์ฌ์์ฑ path๋ ์คํตํ์ฌ ์ฌ์ฉ์ ํธ์ง ๋ณด์กด.
- ์ต์ข
์น์ธ ์ ์
research_approved_hash ๊ธฐ๋ก (ํ์ฌ ํธ์ง๋ ํ์ผ์ sha256).
- ์ฌ์ฉ์๊ฐ ๊ฑฐ๋ถ ์ ์ต์
์ ๊ณต: ์ง์ ์์ /
Skill("deep-research", args + " --force-rerun")๋ก ์์ ์ฌ์์ฑ. -edit ์ ๋ฏธ์ฌ ๋๋ถ์ force-rerun ๊ฒฝ๋ก์์ skill์ ์์ฒด backup(v{N}.md)๊ณผ collision ์์ด ์๋ณธ ํธ์ง backup ๋ณด์กด๋จ.
research_approved_hash ํ๋ ๋ถ์ฌ (pre-v6.3.1 ์ธ์
๋๋ ์ฌ์คํ ํ ๋ฏธ์น์ธ) โ Skill ์ฌ์คํ + review+approval. pre-v6.3.1 ์ธ์
์ fresh approval flow๋ก ๊ฐ๋ ๊ฒ์ด safer default.
- ํ์ผ missing โ ๋ณต๊ตฌ ๋ถ๊ฐ๋ฅ. Skill ์ฌ์คํ + review+approval (edited doc ์์ค ์์ ์ ๊ฐ์ถ ์ ์์).
-
research.md๊ฐ ์๋ state๋ง ๊ฐ์ง drift ์ํ ๋ํ invalidate (๋ณต๊ตฌ ๋ถ๊ฐ๋ฅ ์ํ๋ฅผ ๊ฐ์ถ ์ฑ ์งํํ์ง ์์).
์ฃผ์: research_completed_at / research_complete๋ skill Section 3์์ ๊ธฐ๋กํ๋ marker์ด๋ฉฐ review+approval ์ด์ ์ set๋๋ค. Resume fast-path์ ์กฐ๊ฑด์ผ๋ก ์ฌ์ฉ ๊ธ์ง โ Orchestrator review+approval Step 6๊ฐ ์ฑ๊ณตํ ๋ค์๋ง set๋๋ research_approved: true + research_approved_hash ํ ์์ด ์ ํํ approval-state ์ฆ๊ฑฐ์ด๋ค.
๊ทธ ์ธ ๊ฒฝ์ฐ:
Skill("deep-research", args=ARGS)
์๋ฃ ํ: Review + Approval Workflow ์คํ (๋ฌธ์ ์์ ์น์ธ ๋จ๊ณ).
Phase Skill ์๋ฃ ํ ๋จ์ผ ๋ฆฌ๋ทฐ ์ง์
์ ๋ง ์คํํ๋ค:
- Read(
../shared/references/adaptive-review-protocol.md) ํ document ์
๋ ฅ์ ์กฐ๋ฆฝํ๋ค.
compileReviewPlan ๊ฒฐ๊ณผ๋๋ก reviewers ์คํ๊ณผ execution/finding ํ์ ์ ์ํํ๋ค.
- ํต๊ณผ ํ์๋ง Read(
../shared/references/review-approval-workflow.md)์ Step 4-6 ์น์ธ UX๋ก
์ด๋ํ๋ค. ์ด workflow๋ ์๋ ๋ฆฌ๋ทฐ๋ฅผ ๋ค์ ์คํํ์ง ์๋๋ค.
๋ฌธ์ ์ต์ข
์น์ธ ํ โ State ๋ถ๋ถ ์
๋ฐ์ดํธ:
research_approved: true (Resume fast-path baseline โ v6.3.1 NC1 fix)
research_approved_at: current ISO timestamp
research_approved_hash: Bash({ command: "shasum -a 256 \"$WORK_DIR/research.md\" | awk '{print $1}'" }) ๊ฒฐ๊ณผ (v6.3.1 NW5 integrity snapshot)
Spec Subphase Gate (v6.13)
authoritative risk_profile_json์ class๊ฐ medium|high|critical์ด๋ฉด Exit
Gate ์ ์ ๋ฐ๋์ runtime phase spec enter๋ฅผ ํธ์ถํ๊ณ
Skill("deep-spec", args=ARGS)๋ฅผ dispatchํ๋ค. Low๋ ๋ช
์์ opt-in์ผ ๋๋ง
๊ฐ์ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ๋ค.
current_phase๋ research๋ก ์ ์งํ๊ณ runtime๋ง subphase: spec์ ๊ธฐ๋กํ๋ค.
deep-spec ๋ฐํ ํ ํ์ฌ spec.md bytes, validator pass:true, document
review ์น์ธ, spec_approved_hash, spec_contract_json,
spec_gate_result_json์ runtime phase spec approve๋ก ๊ฒฐ๋ฐํ๋ค.
- unresolved marker, blocking question, validator/runtime ์ค๋ฅ, stale whole-file
hash๊ฐ ํ๋๋ผ๋ ์์ผ๋ฉด Medium+๋ fail-closedํ๋ฉฐ Research Exit Gate๋ฅผ
ํ์ํ์ง ์๋๋ค.
- ์ฑ๊ณตํ
research + spec resume์ research๋ฅผ ์ฌ์คํํ์ง ์๋๋ค. ์ ํจํ
runtime phase advance --from research --to plan๋ง subphase๋ฅผ null๋ก
clearํ๋ค.
โ ์๋ Exit Gate ์คํ.
Exit Gate (Phase 1 โ Phase 2)
AskUserQuestion:
- header: "Phase 1 (Research) ์๋ฃ. ์ด๋ป๊ฒ ์งํํ ๊น์?"
- options:
- "๋ค์ phase๋ก ์งํ" โ ์ฆ์ Phase 2 Plan ์์
- "์ด phase ์ฌ์คํ/์์ "
- "์ผ์์ ์ง"
๋ถ๊ธฐ:
- option 1 โ runtime
phase advance --from research --to plan์ผ๋ก fresh spec
admission์ ์ฌ๊ฒ์ฆํ ๋ค ยง3-3 Plan์ผ๋ก dispatchํ๋ค. state ์ง์ ์ ํ์
๊ธ์งํ๋ค.
- option 2 โ ์ฌ์คํ ์ approval state clear (NC2 ๊ท์น + NW5):
research_approved: false, research_approved_at: null, research_approved_hash: null๋ก state ์
๋ฐ์ดํธ โ ์ดํ Skill("deep-research", args=ARGS + " --force-rerun") ์ฌํธ์ถ ๋๋ ์ฌ์ฉ์ ์ง์ ํธ์ง (phase-guard ํ์ฉ ๋ฒ์). ํฌ๊ธฐ์ ๊ด๊ณ์์ด post-approval ํธ์ง์ด๋ฉด approval clear ํ์.
- option 3 โ current_phase๋
research ์ ์ง. ์ฌ๊ฐ ์๋ด ํ ํด ์ข
๋ฃ.
3-3. Plan
skipped_phases / --skip-to-implement ํฌํจ ์ Exit Gate ์๋ตํ๊ณ current_phase: implement + plan_approved: true + plan_approved_at ์ค์ ์ผ๋ก ์ง์ ์ ํ โ 3-4.
Resume ๋ถ๊ธฐ (v6.3.1 F1 + NW5 integrity check): state์ plan_approved: true๊ฐ ์ด๋ฏธ ์๊ณ $ARGUMENTS์ --force-rerun์ด ์์ผ๋ฉด paused-after-approval ๋ณต๊ท ํ๋ณด ๊ฒฝ๋ก์ด๋ค. ๋จ, approval integrity check๊ฐ ์ถ๊ฐ๋ก ํ์:
-
plan_approved_hash (state) ์ ํ์ฌ $WORK_DIR/plan.md์ sha256์ ๋น๊ต:
Bash({ command: "shasum -a 256 \"$WORK_DIR/plan.md\" | awk '{print $1}'" }) (or sha256sum)
- ํด์ ์ผ์น โ approval ์ ํจ. Skill ํธ์ถ๊ณผ review+approval์ ๊ฑด๋๋ฐ๊ณ ๋ฐ๋ก ์๋ Exit Gate ์คํ.
- ํด์ ๋ถ์ผ์น โ out-of-band ํธ์ง ๊ฐ์ง โ data preservation + in-place review (v6.3.1 NO3 fix + NP3 collision fix):
- ํ์ฌ
$WORK_DIR/plan.md๋ฅผ $WORK_DIR/plan.v{iteration_count+1}-edit.md๋ก ๋ณต์ฌ. -edit ์ ๋ฏธ์ฌ ์ฌ์ฉ โ deep-plan skill์ ๊ธฐ์กด plan.v{iteration_count}.md backup(Pre-steps Backup ๋จ๊ณ)๊ณผ ํ์ผ๋ช
์ถฉ๋ ๋ฐฉ์ง (NP3).
iteration_count์ 1 ์ฆ๊ฐ.
- Approval state invalidate:
plan_approved: false, plan_approved_at: null, plan_approved_hash: null.
- ๊ฒฝ๊ณ : "โ ๏ธ plan.md๊ฐ ์น์ธ ์ดํ ์ธ๋ถ์์ ์์ ๋์์ต๋๋ค. ํธ์ง ๋ด์ฉ์ plan.v{N}-edit.md๋ก ๋ฐฑ์
๋์์ต๋๋ค. ํธ์ง๋ ํ์ฌ ๋ฌธ์๋ฅผ ๋์์ผ๋ก Review+Approval์ ์ฌ์คํํฉ๋๋ค."
- Skill ์ฌํธ์ถ ์์ด ์๋ Review+Approval workflow๋ก ์ง์ ์ง์
โ ํธ์ง๋ ๋ฌธ์ in-place review.
- ์ต์ข
์น์ธ ์ ์
plan_approved_hash + plan_approved_at ๊ธฐ๋ก (drift baseline ์ ์ ).
- ๊ฑฐ๋ถ ์ ์ฌ์ฉ์ ์ ํ: ์ง์ ์์ /
Skill("deep-plan", args + " --force-rerun")๋ก ์์ ์ฌ์์ฑ. -edit ์ ๋ฏธ์ฌ ๋๋ถ์ collision ์์.
plan_approved_hash ํ๋ ๋ถ์ฌ (pre-v6.3.1 ์ธ์
๋๋ ์ฌ์คํ ํ ๋ฏธ์น์ธ) โ Skill ์ฌ์คํ + review+approval.
- ํ์ผ missing โ ๋ณต๊ตฌ ๋ถ๊ฐ๋ฅ. Skill ์ฌ์คํ.
-
drift gate์ plan_approved_at์ด ์ค์ ์ต์ข
plan๊ณผ ์ผ์นํ๋๋ก hash check๊ฐ ์ถ๊ฐ ๊ฐ๋ ์ญํ .
๊ทธ ์ธ ๊ฒฝ์ฐ:
Skill("deep-plan", args=ARGS)
์๋ฃ ํ Read(../shared/references/adaptive-review-protocol.md)์ document ๋จ์ผ ์ง์
์์
compileReviewPlan ๊ฒฐ๊ณผ๋ฅผ ์คํํ๋ค. ์คํ ํ์ ๊ณผ finding verdict ํต๊ณผ ํ์๋ง
Read(../shared/references/review-approval-workflow.md) Step 4-6 ์น์ธ UX๋ก ์ด๋ํ๋ค.
๋ฌธ์ ์ต์ข
์น์ธ ํ โ State ๋ถ๋ถ ์
๋ฐ์ดํธ:
plan_approved: true
plan_approved_at: current ISO timestamp (drift baseline)
plan_approved_hash: Bash({ command: "shasum -a 256 \"$WORK_DIR/plan.md\" | awk '{print $1}'" }) ๊ฒฐ๊ณผ (v6.3.1 NW5 integrity snapshot)
current_phase๋ ์ด ์์ ์์๋ ๋ณ๊ฒฝํ์ง ์๋๋ค. Exit Gate "์งํ" ์์ implement๋ก ์ ํ.
Exit Gate (Phase 2 โ Phase 3)
AskUserQuestion:
- header: "Phase 2 (Plan) ์๋ฃ. ์ด๋ป๊ฒ ์งํํ ๊น์?"
- options:
- "๋ค์ phase๋ก ์งํ"
- "์ด phase ์ฌ์คํ/์์ "
- "์ผ์์ ์ง"
๋ถ๊ธฐ:
- option 1 โ ์ฆ์
current_phase: implement ์ค์ โ ยง3-4 Implement๋ก dispatch (ยง3-4 body๊ฐ Skill ํธ์ถ ๋ด๋น). ๋ณธ branch์์ Skill ์ง์ ํธ์ถํ์ง ์์ (NO1 fix).
- option 2 โ ์ฌ์คํ ์ approval state clear (NC2 fix + NW5):
plan_approved: false, plan_approved_at: null, plan_approved_hash: null๋ก state ์
๋ฐ์ดํธ โ ์ดํ Skill("deep-plan", args=ARGS + " --force-rerun") ์ฌํธ์ถ ๋๋ ์ฌ์ฉ์ ์ง์ ํธ์ง. ๋ชจ๋ ํธ์ง์ Step 6 re-approval์ ๊ฑฐ์น๋ฉฐ, approval clear๊ฐ ์์ผ๋ฉด Resume fast-path๊ฐ stale approval์ ์ฌ์ฌ์ฉํจ. ํฌ๊ธฐ์ ๊ด๊ณ์์ด post-approval ํธ์ง์ด๋ฉด approval clear ํ์ โ drift gate baseline์ plan_approved_at + plan_approved_hash๊ฐ ์ค์ ์ต์ข
plan๊ณผ ์ผ์นํ๋๋ก.
- option 3 โ current_phase๋
plan ์ ์ง. ์ฌ๊ฐ ์๋ด ํ ํด ์ข
๋ฃ.
3-4. Implement
skipped_phases์ "implement" ํฌํจ ์ Exit Gate ์๋ตํ๊ณ current_phase: test๋ก ์ง์ ์ ํ โ 3-5. (๋๋ฌธ ๊ฒฝ๋ก์ด์ง๋ง spike ์ธ์
๋ฑ์์ ํ์ฉ)
Skill("deep-implement", args=ARGS + " --tdd={tdd_mode}")
Implement skill์ Section 3 ์๋ฃ ํ:
Exit Gate (Phase 3 โ Phase 4)
AskUserQuestion:
- header: "Phase 3 (Implement) ์๋ฃ. ์ด๋ป๊ฒ ์งํํ ๊น์?"
- options:
- "๋ค์ phase๋ก ์งํ"
- "์ด phase ์ฌ์คํ/์์ "
- "์ผ์์ ์ง"
๋ถ๊ธฐ:
- option 1 โ ์ฆ์
current_phase: test ์ค์ (F1 Option A) โ ยง3-5 Test๋ก dispatch (ยง3-5 body๊ฐ Skill ํธ์ถ ๋ด๋น). ๋ณธ branch์์ Skill ์ง์ ํธ์ถํ์ง ์์ (NO1 fix).
- option 2 โ ์ฌ์คํ/์์ ์ completion state clear (v6.3.1 NC3 fix): completion marker + receipts + slice checklist ๋ชจ๋ invalidateํด์ผ resume ์ stale evidence๋ฅผ ์ฌ์ฌ์ฉํ์ง ์๋๋ค.
implement_completed_at: null ์ค์
- ์ํฅ ๋ฐ๋ slice์ receipt (
$WORK_DIR/receipts/SLICE-NNN.json) status๋ฅผ "invalidated"๋ก ๊ธฐ๋ก
- plan.md์ ํด๋น slice
[x] โ [ ]๋ก ํด์ (Implement skill Resume Detection์ด ๋ฏธ์๋ฃ๋ก ์ธ์ํ๋๋ก)
- ๊ทธ ํ ์ฌ์ฉ์ ์์ธ ์ง์ ์ฒญ์ทจ ๋๋
Skill("deep-implement", args=ARGS + " --tdd={tdd_mode} --force-rerun") ์ฌํธ์ถ. ์ฌ๊ตฌํ ์๋ฃ ์ ์ receipt + implement_completed_at ๊ธฐ๋ก.
- option 3 โ current_phase๋
implement ์ ์ง. ์ฌ๊ฐ ์๋ด ํ ํด ์ข
๋ฃ.
3-5. Test
Skill("deep-test", args=ARGS)
/deep-test๊ฐ ๋ด๋ถ์ ์ผ๋ก implement-test retry loop ๊ด๋ฆฌ (max 3ํ).
Retry exhausted: auto-flow ์ค๋จ. ์ฌ์ฉ์ ์๋ ๊ฐ์
. Exit Gate ์คํํ์ง ์์. current_phase๋ implement ์ ์ง (์๋ ์์ ๊ฒฝ๋ก).
All pass (test_passed: true): ์๋ Exit Gate ์คํ.
Exit Gate (Phase 4 โ Phase 5 / Finish)
$ARGUMENTS์ --skip-integrate ํฌํจ ์ Exit Gate ์๋ตํ๊ณ ๋ฐ๋ก ยง3-6 Finish ์ง์
.
AskUserQuestion:
- header: "Phase 4 (Test) ์๋ฃ. ์ด๋ป๊ฒ ์งํํ ๊น์?"
- options:
- "๋ค์ phase๋ก ์งํ" โ Phase 5 Integrate
- "Integrate ๊ฑด๋๋ฐ๊ณ Finish"
- "Test ์ฌ์คํ"
- "์ผ์์ ์ง"
๋ถ๊ธฐ:
- option 1 โ current_phase๋
test ์ ์ง (Integrate๋ idle๋ก ์ ํํจ) โ ยง3-5b Integrate๋ก dispatch (ยง3-5b body๊ฐ Skill ํธ์ถ ๋ด๋น). ๋ณธ branch์์ Skill ์ง์ ํธ์ถํ์ง ์์ (NO1 fix).
- option 2 โ
$ARGUMENTS์ ์ค์ ๋ก --skip-integrate ํ๋๊ทธ ์ถ๊ฐ (ARGS mutation) โ ยง3-5b๋ฅผ ๊ฑด๋๋ฐ๊ณ ยง3-6 Finish๋ก ์ง์ ๋ถ๊ธฐ. --skip-integrate ๋ฏธ์ค์ ๋ ์ฑ ยง3-5b ์ง์
ํ๋ฉด skip์ด ๋ฐ์๋์ง ์์ผ๋ฏ๋ก ๋ฐ๋์ ์ค์ ARGS ๋ณ๊ฒฝ ํ์ (NO1 fix).
- option 3 โ ์ฌ์คํ ์ Test state clear (v6.3.1 NW4 fix):
test_passed: false, test_completed_at: null, test_retry_count: 0 ์ค์ โ ๊ทธ ํ Skill("deep-test", args=ARGS + " --force-rerun") ์ฌํธ์ถ. ์ด๋ ๊ฒ ํด์ผ ์ฌ์คํ ๋์ค ์ธ์
์ค๋จ ์ /deep-resume์ด stale test_passed: true marker๋ฅผ ์ฌ์ฌ์ฉํด quality gate๋ฅผ ๊ฑด๋๋ฐ๋ ๊ฒ์ ๋ฐฉ์งํ๋ค (failing rerun์ "passed"๋ก ๊ธฐ๋งํ๋ ๊ฒฝ๋ก ์ฐจ๋จ).
- option 4 โ current_phase๋
test ์ ์ง. ์ฌ๊ฐ ์๋ด ํ ํด ์ข
๋ฃ.
3-5b. Integrate (v6.3.0, skippable)
Phase 5: ์ค์น๋ deep-suite ํ๋ฌ๊ทธ์ธ ์ํฐํฉํธ๋ฅผ ์ฝ์ด AI๊ฐ ๋ค์ ๋จ๊ณ๋ฅผ ์ถ์ฒํ๋ ๋ํํ ๋ฃจํ.
$ARGUMENTS์ --skip-integrate ํฌํจ ์ โ 3-6๋ก ์ง์ง (state ๋ณ๊ฒฝ ์์).
- ์์ผ๋ฉด โ
Skill("deep-integrate", args=ARGS) ํธ์ถ.
- ์คํฌ์ด ์ ์ ์ข
๋ฃํ๋ฉด โ 3-6๋ก ์งํ.
- ์คํฌ์ด ์๋ฌ๋ก ์ข
๋ฃํ๋ฉด ๊ฒฝ๊ณ ๋ฉ์์ง ์ถ๋ ฅ ํ
--skip-integrate๋ฅผ ์ถ๊ฐํ์ฌ 3-6๋ก ์งํํ๋ค. Phase 5๋ ์ง์
์ phase5_entered_at์ ๊ธฐ๋กํ์ง๋ง phase5_completed_at์ด ์์ผ๋ฏ๋ก, --skip-integrate ์์ด /deep-finish๋ฅผ ํธ์ถํ๋ฉด "Phase 5 ์ค๋จ" ๋ถ๊ธฐ์ ๊ฑธ๋ ค ์ธ์
์ด idle-but-unfinishable ์ํ์ ๊ณ ์ฐฉ๋๋ค(v6.3.0 review C2). --skip-integrate๊ฐ ์ด ๋ถ๊ธฐ๋ฅผ ์ฐํํ์ฌ ์ ์ finish ๊ฒฝ๋ก๋ฅผ ๋ณด์ฅํ๋ค.
- ์คํฌ์ด
terminated_by: "interrupted" ์ํ๋ก ๋จ๊ธฐ๊ณ ์ข
๋ฃํ๋ฉด auto-flow ์ค๋จ (์ฌ์ง์
๋๊ธฐ).
current_phase ๋ณ๊ฒฝ ์ฃผ์ฒด: deep-integrate Skill์ด Phase 5 ์ง์
์ idle๋ก ์ ํํ๊ณ phase5_entered_at + phase5_work_dir_snapshot(v6.3.0 review RC3-1) ํ๋๋ฅผ ๊ธฐ๋กํ๋ค. Phase 5 ์ข
๋ฃ ์ skills/deep-integrate/phase5-finalize.sh๋ก phase5_completed_at๋ง atomically ๊ธฐ๋กํ๋ค. current_phase ์์ฒด๋ idle ์ ์ง (phase-guard Phase 5 mode์ ํธํ). phase5_work_dir_snapshot์ phase-guard๊ฐ enforcement ๊ธฐ์ค์ผ๋ก ์ฌ์ฉํ๋ ๋ถ๋ณ snapshot โ state file์ work_dir์ด ๋ฐํ์์ ๋ณ์กฐ๋ผ๋ snapshot ๊ฐ์ผ๋ก ๋ฐฉ์ด๋๋ค. finished ๊ฐ์ ์ ๊ท state๋ ๋์
ํ์ง ์๋๋ค.
3-6. Finish
Read skills/deep-finish/SKILL.md โ ์๋ฃ ์ต์
์ ์:
- Merge: worktree๋ฅผ base branch์ merge
- PR: GitHub PR ์์ฑ
- Keep: branch/worktree ์ ์ง, ๋์ค์ ์ฒ๋ฆฌ
- Discard: branch/worktree ์ญ์
์ธ์
ํ์คํ ๋ฆฌ ๊ธฐ๋ก (JSONL), Session Quality Score ๊ณ์ฐ.
Finish ์๋ฃ ํ: current_phase: idle ์ค์ .
Registry ํด์ : unregister_session "$SESSION_ID".
current_phase ๋ณ๊ฒฝ ์ฃผ์ฒด ์ ๋ฆฌ (v6.3.1 Option A โ ์ผ์ํ)
| Phase | Review | ์ฌ์ฉ์ ์น์ธ | current_phase ๋ณ๊ฒฝ ์ฃผ์ฒด | ๋ณ๊ฒฝ ์์ |
|---|
| Brainstorm | ์ ํ์ | Exit Gate ํ์ | Orchestrator | Exit Gate "์งํ" ์ ํ ์ |
| Research | ํ์ | review+approval + Exit Gate ํ์ | Orchestrator | Exit Gate "์งํ" ์ ํ ์ |
| Plan | ํ์ | review+approval + Exit Gate ํ์ | Orchestrator | Exit Gate "์งํ" ์ ํ ์ |
| Implement | Phase Review | Exit Gate ํ์ | Orchestrator | Exit Gate "์งํ" ์ ํ ์ |
| Test | ์๋ | Exit Gate ํ์ | Orchestrator (์ ์ง: test โ test; Integrate ์ง์
์์๋ test ์ ์ง, Integrate skill์ด idle๋ก ์ ํ) | Exit Gate "์งํ" ์ ํ ์ |
| Integrate (v6.3.0) | ์ ํ์ | ๋ถํ์ | Integrate Phase Skill (idle + phase5_*_at ํ๋) | ๊ธฐ์กด ๋์ ์ ์ง |
ํต์ฌ ๋ณํ (v6.3.0 โ v6.3.1):
- ๊ธฐ์กด์๋ Brainstorm/Implement phase skill์ด Section 3์์ ์ง์ current_phase๋ฅผ ๋ค์ ๊ฐ์ผ๋ก ์ ํ โ Exit Gate ์ด์ ์ state๊ฐ ์ด๋๋์ด pause/resume ์ Exit Gate ์ฌํ์ ๋ถ๊ฐ
- v6.3.1: ๋ชจ๋ phase skill์
*_completed_at marker๋ง ๊ธฐ๋กํ๊ณ current_phase ๋ณ๊ฒฝ์ Orchestrator์ ์์
- pause ์ ํ ์ current_phase๋ ํ์ฌ ๊ฐ ์ ์ง โ resume ์ Orchestrator๊ฐ ํด๋น phase๋ฅผ ์ฌํธ์ถ โ skill์ Section 1 ์๋ฃ-marker ๊ฐ์ง ๋ถ๊ธฐ๊ฐ Orchestrator๋ก ์ ์ด ๋ฐํ โ Exit Gate ์ฌํ์