원클릭으로
explore
에이전트들이 코드베이스를 백그라운드로 자율 탐색해 원하는 정보를 찾아옵니다. 사용자가 '탐색', '코드 찾아줘', '어디 있어'를 말하거나 /mst:explore를 호출할 때 사용.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
에이전트들이 코드베이스를 백그라운드로 자율 탐색해 원하는 정보를 찾아옵니다. 사용자가 '탐색', '코드 찾아줘', '어디 있어'를 말하거나 /mst:explore를 호출할 때 사용.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
프로젝트 목표 + 설계 문서(objective.md)를 JTBD 기반 Q&A로 생성하고, 실행 전 검토 가능한 플래닝 세션을 초기화합니다.
프로젝트 목표를 제공하면 JTBD+프로젝트 DoD 기반 자율 실행을 수행합니다. Step 1은 agile-plan 서브스킬로 objective.md를 준비하고 Sprint 0 → Sprint N(프로젝트 건강 우선) 루프 → 스티어링 체크포인트를 반복합니다.
스펙을 승인하고 실행을 시작합니다. 사용자가 '승인', '진행해', 'OK 진행'을 말하거나 /mst:approve를 호출할 때 사용. Gran Maestro 워크플로우 내에서만 의미 있으며, 일반적인 확인 응답에는 사용하지 않음.
Claude provider 전용 native-first delegation entrypoint. 사용자가 '클로드로 실행', '클로드 서브에이전트'를 말하거나 /mst:claude를 호출할 때 사용한다. 같은 Claude host에서는 Task/Agent를 우선하고 route=external일 때만 managed wrapper를 사용한다.
Codex provider 작업을 native-first로 위임합니다. 사용자가 '코덱스 실행', '코덱스로', '코드 작업'을 말하거나 /mst:codex를 호출할 때 사용. 같은 Codex host에서는 collaboration agent를 우선하고, 중앙 route가 external일 때만 Codex CLI adapter를 사용합니다.
설정된 AI 에이전트들이 병렬로 버그를 조사하고 종합 리포트를 생성합니다. 사용자가 '디버그', '버그 찾아줘', '문제 분석'을 말하거나 /mst:debug를 호출할 때 사용. 1회성 의견 수집은 /mst:ideation을, 합의 토론은 /mst:discussion을 사용.
| name | explore |
| description | 에이전트들이 코드베이스를 백그라운드로 자율 탐색해 원하는 정보를 찾아옵니다. 사용자가 '탐색', '코드 찾아줘', '어디 있어'를 말하거나 /mst:explore를 호출할 때 사용. |
| user-invocable | true |
| argument-hint | {탐색 목표 설명} [--focus {파일패턴|관점키워드}] [--from EXP-NNN] |
설정된 AI 팀원들이 병렬로 코드베이스를 탐색하고 PM(Claude)이 결과를 합쳐 종합 탐색 리포트를 생성합니다.
| 항목 | debug | explore |
|---|---|---|
| 조사자 키 | investigators | explorers |
| 개별 산출물 | finding-{key}.md | explore-{key}.md |
| 종합 리포트 | debug-report.md | explore-report.md |
| claude 참여 방식 | investigator로 직접 참여 가능 | explorers에서 제외, claude_synthesis로만 종합 |
경로 규칙 (MANDATORY): 이 스킬의 모든
.gran-maestro/경로는 절대경로로 사용합니다. 스킬 실행 시작 시PROJECT_ROOT를 취득하고, 이후 모든 경로에{PROJECT_ROOT}/접두사를 붙입니다.PROJECT_ROOT=$(pwd)
{PLUGIN_ROOT}는 이 스킬의 "Base directory"에서skills/{스킬명}/을 제거한 절대경로입니다. 상대경로(.claude/...)는 절대 사용하지 않습니다.
이 프로토콜은 이 스킬 아래의 모든 provider 실행 예시보다 우선한다. provider 작업을 시작하기 전에 parent host가 route와 lifecycle evidence를 소유하고, child는 실제 할당 작업만 수행한다.
python3 {PLUGIN_ROOT}/scripts/mst.py host context --json을 실행하고 JSON의 host를 읽는다. 이 호출 실패, 잘못된 JSON, 알 수 없는 host는 임의 추정하지 말고 blocked로 종료한다.
이어서 반드시 아래 중앙 planner를 호출한다. {scope}는 현재 작업의 실제 scope(implementation, review, exploration, ideation, discussion, debug, analysis)이고, {provider}는 선택된 codex | claude | agy다.
python3 {PLUGIN_ROOT}/scripts/mst.py delegation route \
--host "{host}" \
--provider "{provider}" \
--scope "{scope}" \
--capability-status "{available|unknown|unavailable}"
route 결과 외의 근거로 transport를 바꾸지 않는다.
route=native_candidate: 같은 host/provider의 native bridge만 사용한다. handshake_required=true이면 실제 host tool 가용성을 확인한 뒤 진행한다.route=external: 이 경우에만 아래에 남아 있는 managed wrapper, dispatch build, provider CLI adapter 예시를 사용할 수 있다.route=blocked, CLI non-zero, lifecycle 응답의 status=blocked, 또는 현재 attempt의 phase=reconciling: 즉시 fail closed 한다. 같은 task/worktree에 새 agent나 external process를 시작하지 않는다.native_candidate 실행과 evidenceNative spawn 전 parent가 delegation start를 호출하고 반환된 attempt_id를 이후 모든 CAS 호출에 사용한다. start는 lifecycle 준비만 하며, 신규 응답이나 exact replay 모두 그 자체로 spawn 권한을 주지 않는다(spawn_allowed=false).
python3 {PLUGIN_ROOT}/scripts/mst.py delegation start \
--task-id "{task_id}" \
--idempotency-key "{task_id}:start:{stable_key}" \
--host "{host}" \
--provider "{provider}" \
--capability-status available \
--route-reason "{route.reason_code}" \
--worktree-dir "{worktree_path}" \
--model "{model}" \
--scope "{scope}" \
--prompt-file "{prompt_file}" \
--output-path "{output_path}"
analysis|review|exploration|ideation|discussion|debug가 실제 read-only 작업이고 별도 linked worktree를 쓰지 않는 경우에만 --read-only를 추가한다. 구현·수정 작업에는 이 예외를 사용하지 않는다.
그 다음 parent invocation별 고유한 {claimant_id}로 single-use spawn claim을 요청한다. 오직 이 호출에서 spawn_allowed=true와 non-empty private claim_token_file을 함께 받은 단 한 caller만 native host tool을 한 번 호출할 수 있다. raw bearer token은 CLI JSON, argv, process listing, tool transcript, child prompt에 노출하지 않는다.
python3 {PLUGIN_ROOT}/scripts/mst.py delegation claim-spawn \
--task-id "{task_id}" \
--attempt-id "{attempt_id}" \
--claimant-id "{claimant_id}" \
--idempotency-key "{task_id}:claim:{claimant_id}"
spawn_allowed=false, claim_status=claim_replay|already_claimed|reconciling|provider_task_in_flight|terminal, 빈 claim_token_file, 또는 claim 응답 유실/불명확 상태에서는 host tool을 호출하지 않는다. claim_replay|already_claimed는 winner의 claim lease가 살아 있는 동안 wait만 하며 recover/cancel로 ownership을 빼앗지 않는다. lease 만료 뒤에만 delegation recover로 reconcile하고, 그 외에는 next_action에 따라 기존 provider task에 attach/wait한다. claim exact replay는 bearer token/파일을 다시 발급하지 않는다. 따라서 claim 결과를 잃은 caller도 외부 fallback이나 중복 native spawn을 시도하지 않는다.
host=codex, provider=codex: Codex collaboration native tools를 사용한다. collaboration.spawn_agent로 spawn하고, host가 제공하는 attach/follow-up 수단으로 같은 task에 연결하며, collaboration.wait_agent로 대기한 뒤 전달된 completion result를 수집한다. 병렬 fan-out은 독립 task마다 native agent를 하나씩 spawn한다.host=claude, provider=claude: Claude의 Task(...) 또는 Agent(...) native tool로 spawn한다. background task는 host의 TaskOutput/resume 결과로 대기·수집한다.codex exec, claude CLI, mst.py run --provider {same_provider}, 같은 provider의 managed wrapper, 또는 nested /mst:claude//mst:codex를 호출하지 않는다.Native tool 응답마다 claim winner parent가 다음 순서로 evidence를 기록한다. {claim_token_file}은 winner 응답의 mode 0400 private one-shot handle이며 acknowledge 성공 시 삭제된다. 내용을 읽거나 복사하거나 child/user/log에 전달하지 않는다. 각 명령의 JSON 응답에서 status/phase를 확인하고 blocked/reconciling이면 더 진행하지 않는다.
delegation acknowledge --task-id "{task_id}" --attempt-id "{attempt_id}" --claim-token-file "{claim_token_file}" --spawn-status created_with_task_id --provider-task-id "{provider_task_id}" --idempotency-key "{task_id}:ack:{stable_key}"delegation attach --task-id "{task_id}" --attempt-id "{attempt_id}" --attach-status attached --idempotency-key "{task_id}:attach:{stable_key}"delegation heartbeat --task-id "{task_id}" --attempt-id "{attempt_id}" --provider-state running --idempotency-key "{task_id}:heartbeat:{sequence}"{output_path}의 sibling temp file에 먼저 쓰고 atomic replace한 뒤, fresh hash/size를 확인한다. child에게 이 파일 쓰기를 맡기거나 기존 파일을 재사용하지 않는다.delegation complete --task-id "{task_id}" --attempt-id "{attempt_id}" --completion-signal "{succeeded|failed|timeout|unknown}" --output-path "{output_path}" --idempotency-key "{task_id}:complete:{stable_key}"Native spawn이 task 생성 전에 명확히 실패한 경우에만 claim winner가 같은 --claim-token-file "{claim_token_file}"로 spawn-status=definitive_not_created를 acknowledge한 뒤 delegation fallback --expected-attempt-id "{attempt_id}" ...를 요청할 수 있다. 그 후 capability를 unavailable로 route planner에 다시 전달해 route=external을 받은 경우에만 external lane을 실행한다. claim 결과 유실, accepted, task ID 발급, attach 실패/timeout, child 실패, unknown/indeterminate 결과 뒤에는 external fallback을 금지하고 reconcile 상태를 유지한다.
route=external 판정만으로 provider command를 직접 만들지 않는다. Fresh headless/cross-provider external lane은 command 생성 전에 중앙 planner 결과를 state에 고정한다.
python3 {PLUGIN_ROOT}/scripts/mst.py dispatch authorize-external \
--provider "{provider}" \
--task-id "{task_id}" \
--prompt-file "{prompt_file}" \
--worktree-dir "{worktree_path}" \
--running-log-path "{running_log}" \
--trace-path "{trace_path}" \
--output-path "{output_path}" \
--model "{model}" \
--scope "{scope}" \
--idempotency-key "{task_id}:external-authorize:{stable_key}" \
{read_only_flag}
이 명령은 실제 host를 다시 확인하고 중앙 route가 여전히 external일 때만 current external attempt와 model/running/trace/output binding을 저장한다. 구현·수정 lane은 registered linked worktree를 사용하고 {read_only_flag}를 비운다. 실제 read-only scope만 --read-only를 사용한다. 반환된 attempt_id와 동일한 artifact binding을 external wrapper에 전달한다.
python3 {PLUGIN_ROOT}/scripts/mst.py dispatch build \
--provider "{provider}" \
--task-id "{task_id}" \
--prompt-file "{prompt_file}" \
--worktree-dir "{worktree_path}" \
--log-file "{running_log}" \
--model "{model}" \
--expected-attempt-id "{external_attempt_id}"
Native definitive non-creation fallback이면 새 authorization을 만들지 않고 delegation fallback이 반환한 external attempt_id를 --expected-attempt-id로 사용한다. Builder는 current attempt의 task/provider/resolved worktree/prompt hash/route를 재검증하므로 native, reconciling, stale attempt, 또는 mismatch 상태에서는 command를 만들지 않는다. Codex/Claude 보호 wrapper는 provider command나 split claim/finalize shell을 포함하지 않고 dispatch run-external 단일 감독자만 호출한다. 감독자는 먼저 side effect가 없는 anonymous exec gate를 띄워 PID/PGID/start identity를 CAS로 attach하고, 같은 task lock 안에서 취소보다 먼저 exec 권한이 확정된 경우에만 실제 provider를 release한다. claim에서 캡처한 정확한 prompt bytes를 stdin으로 전달하고, provider process group을 회수한 뒤 fresh single-link inode로 claim해 계속 보유한 non-following output descriptor로 결과를 게시한다. prompt/snapshot/running/trace/output alias와 MST state·lock·history reserved path alias는 provider spawn 전에 차단한다. claim-external/heartbeat-external/finalize-external을 별도로 호출하거나 prompt snapshot/output pathname을 shell에서 다시 열지 않는다. Prompt 본문·snapshot path·claim secret·descriptor number는 argv/state/history에 확장하지 않는다.
모든 native child prompt에는 다음 제약을 그대로 포함한다.
DELEGATION BOUNDARY (MANDATORY)
- Complete the assigned task yourself; do not delegate or spawn another provider agent.
- Do not invoke codex/claude provider CLIs, /mst:codex, /mst:claude, or a same-provider managed wrapper.
- Do not call `mst.py delegation` lifecycle commands and do not edit `.gran-maestro/run`, session, or history state; the parent owns routing and evidence.
- Work only in the assigned worktree/scope and return the result/evidence to the parent.
아래 skill별 dispatch 예시는 이 protocol의 route로 gate한다. Provider CLI/managed wrapper 예시는 오직 route=external일 때만 사용한다. Task/Agent/Codex collaboration 예시는 host와 provider가 일치하는 route=native_candidate일 때만 사용하고 child boundary와 native lifecycle evidence를 함께 적용한다.
~/.claude/user-profile.json (AskUserQuestion 컨텍스트, 비차단)~/.claude/user-profile.json을 Read한다.
user_profile_context = null로 처리하고 기존 동작을 유지한다 (graceful fallback).role (string)experience_level (string)domain_knowledge (string[])communication_style (string)user_profile_context = null로 처리한다 (워크플로우 차단 금지).communication_style을 최우선 반영한다.experience_level/domain_knowledge에 맞춰 용어 수준과 설명 깊이를 조절한다.archive.auto_archive_on_create=true 시 EXP-* 세션 수 확인 → max_active_sessions 초과 시 완료 세션 아카이브 후 진행
{PROJECT_ROOT}/.gran-maestro/explore/ 디렉토리 존재 확인, 없으면 생성python3 {PLUGIN_ROOT}/scripts/mst.py counter next --type expEXP-EXP- 이중 접두사 감지 시 sanitize → 단일 EXP-만 유지 (최우선)EXP-NNN 형태면 유효성 확인 후 그대로 사용EXP-{zero-padded}로 1회만 접두사 부여mst.py counter next --type exp는 이미 EXP- 접두사를 포함하여 반환합니다. 반환값에 수동으로 EXP-를 추가하면 EXP-EXP- 이중 접두사가 발생합니다. 반환값을 그대로 사용하되, 위 검증만 수행하세요.{PROJECT_ROOT}/.gran-maestro/explore/counter.json Readnext_id = last_id + 1EXP-* 디렉토리/아카이브를 스캔해 max 번호를 복구하고 counter.json 생성{PROJECT_ROOT}/.gran-maestro/explore/EXP-NNN/ 디렉토리 생성session.json 작성⏱️ 타임스탬프 취득 (MANDATORY):
TS=$(python3 {PLUGIN_ROOT}/scripts/mst.py timestamp now)위 명령 실패 시 폴백:python3 -c "from datetime import datetime, timezone; print(datetime.now(timezone.utc).isoformat())"출력값을created_at필드에 기입한다. 날짜만 기입 금지.
{
"schema_version": "1.0",
"id": "EXP-NNN",
"goal": "{사용자 탐색 목표}",
"focus": "{--focus 값 또는 null}",
"status": "exploring",
"created_at": "{TS — mst.py timestamp now 출력값}",
"dispatch_started_at": null,
"merge_completed_at": null,
"completed_at": null,
"failed_at": null,
"explorers": {
"codex": {
"role": "",
"status": "pending",
"provider": "codex",
"tier": "default",
"started_at": null,
"completed_at": null,
"output_file": "explore-codex.md",
"task_id": null,
"exit_code": null
},
"agy": {
"role": "",
"status": "pending",
"provider": "agy",
"tier": "default",
"started_at": null,
"completed_at": null,
"output_file": "explore-agy.md",
"task_id": null,
"exit_code": null
}
},
"claude_synthesis": {
"status": "pending",
"started_at": null,
"completed_at": null,
"output_file": "explore-report.md"
},
"participant_config": {
"codex": { "count": 1, "tier": "default" },
"agy": { "count": 1, "tier": "default" },
"claude": { "count": 1, "tier": "default" }
},
"merge_wait_ms": 60000,
"error": null
}
explorers는 config의 explore.agents를 읽어 동적 생성합니다.
codex, agy, claude)별 count/tier를 읽어 participant_config를 {provider: {count, tier}} 구조로 기록claude는 explorers 생성 대상에서 항상 제외하고 claude_synthesis로만 사용{provider}{provider}, {provider}-2, {provider}-3... 순으로 생성provider 및 tier 필드를 기록 (tier는 config의 explore.agents.{provider}.tier 값을 전파, 미설정 시 "default")explore.agents가 없으면 기본값 { codex:1, agy:1, claude:1 }을 사용합니다.
schema_version이 없는 세션은 legacy로 간주하고, Read 시 canonical 형태로 normalize한다.schema_version, explorers=object, participant_config={provider:{count,tier}})로만 수행한다.필드별 변환 테이블:
| 레거시 형태 | canonical 변환 |
|---|---|
participant_config.{provider}: number (예: "codex": 2) | { "count": 2, "tier": "default" } |
participant_config.{provider}: string (예: "codex_model": "...") | { "count": 1, "tier": "default" } (모델명은 무시) |
claude_synthesis: true | { "status": "done", "started_at": null, "completed_at": null, "output_file": "explore-report.md" } |
claude_synthesis: false | { "status": "pending", "started_at": null, "completed_at": null, "output_file": "explore-report.md" } |
claude_synthesis: { ... } (object, 필드 누락) | 누락 필드를 기본값으로 보정 (status: "pending", output_file: "explore-report.md") |
explorers: [array] (배열 형태) | 각 항목의 key 필드를 object 키로 사용하여 object로 변환 |
explorers[].tier 필드 누락 | "tier": "default" 보정 |
세션 구조:
EXP-NNN/session.jsonEXP-NNN/prompts/explore-{explorerKey}-prompt.mdEXP-NNN/prompts/synthesis-prompt.mdEXP-NNN/explore-{explorerKey}.mdEXP-NNN/explore-report.mdPM(Claude)이 탐색 목표를 분석하여 explorers 수만큼 역할을 배정합니다.
session.json 업데이트:
explorers[key].role 기록status: "dispatching"으로 전이이 스킬의 모든 Step은 사용자 입력 없이 자율적으로 진행합니다.
- 백그라운드 작업 완료 시 사용자 확인 질문 금지
- Step 2~5는 완전 자동 진행
- 작업 실패 시에도 가능한 범위까지 자동 복구/합성 후 상태를 종료(
completed또는failed)한다- 단, Step 5 종료 보고 직후 다음 단계 선택은
AskUserQuestion으로 처리한다 (AUTO-CONTINUE 예외)
독립 파일 Write는 하나의 응답에서 동시에 수행합니다.
session.json + 여러 프롬프트 파일 동시 생성/업데이트explorers 키를 순회하여 provider별로 동시 실행합니다.
Claude 모델 결정:
Bash(python3 {PLUGIN_ROOT}/scripts/mst.py config get explore.agents.claude.tier models.providers.claude.default_tier)로 tier를 구한 뒤models.providers.claude[{tier}]로 resolve (미설정 시"sonnet"폴백).
config 확인:
python3 {PLUGIN_ROOT}/scripts/mst.py config get prompt_builder.enabled prompt_builder.fallback_on_error
.gran-maestro/tmp/ctx-{session_id}.md로 Writedispatch-input.json Write:
{
"format": "mst.dispatch",
"schema_version": 1,
"common": {
"topic": "{EXP-NNN 탐색 목표}",
"constraints": ["읽기 전용 탐색만 수행, 파일 수정/생성 금지", "..."],
"reference_context_file": ".gran-maestro/tmp/ctx-{session_id}.md"
},
"tasks": [
{"role": "explore-{explorerKey}", "angle": "{role}", "ask": "탐색 지침 ≤200자 또는 ask_file"}
]
}
tasks[]는 explorers 키를 순회하여 작성role 값은 "explore-{explorerKey}"로 설정 (split 결과 파일이 explore-{explorerKey}-prompt.md로 생성되어 기존 dispatch 경로 호환)ask_file 경로로 분리python3 {PLUGIN_ROOT}/scripts/mst.py prompt build --input {absolute_path}/dispatch-input.json --out-dir {absolute_path}/prompts --sid {session_id}python3 {PLUGIN_ROOT}/scripts/mst.py session split-prompts --dir {absolute_path}/prompts 호출 → prompts/explore-{explorerKey}-prompt.md 개별 파일 생성 → 기존 dispatch (2b 단계) 그대로 실행fallback_on_error=true일 때)fallback_on_error=false이면 워크플로우 중단 + 사용자 에스컬레이션mst.py prompt build는 오류 반환만 담당, repair 1회/fallback 전환은 본 스킬(explore)의 책임이다explorers 키를 순회하여 prompts/explore-{explorerKey}-prompt.md를 하나의 메시지에서 동시에 Write합니다.
프롬프트에는 반드시 **"읽기 전용 탐색만 수행, 파일 수정/생성 금지"**를 명시하고 결과를 explore-{explorerKey}.md에 작성하도록 지정합니다.
--from EXP-NNN 요약 주입 규칙 (옵션)--from EXP-NNN이 지정되면 {PROJECT_ROOT}/.gran-maestro/explore/EXP-NNN/explore-report.md에서 후속 탐색용 요약 섹션만 추출한다.이전 세션 요약 컨텍스트 블록으로 삽입하고, 없거나 추출 실패 시 해당 블록을 생략한다.# 코드베이스 탐색 요청
## 탐색 목표
{사용자 탐색 목표 전체 내용}
## 당신의 역할
당신은 {provider} 탐색자입니다. 담당 각도: **{role}**
## 조사 지침
1. 코드베이스를 읽기 전용으로 탐색하고 증거를 수집한다.
2. 파일 경로, 심볼명, 라인 번호를 가능한 한 구체적으로 제시한다.
3. 추론과 사실을 구분해 작성한다.
4. 의심 지점은 확인이 필요한 이유를 함께 적는다.
5. 파일 수정/생성/삭제는 절대 수행하지 않는다.
## 집중 영역
{--focus 값이 있으면 해당 패턴, 없으면 "코드베이스 전체"}
## 이전 세션 요약 컨텍스트 (선택)
{--from이 있으면 EXP-NNN의 "후속 탐색용 요약"만 500토큰 이내로 주입, 없으면 이 섹션 생략}
## 출력 형식
응답을 `{output_file}`에 마크다운으로 작성하고 아래 섹션을 포함한다.
- **탐색 범위**: 실제로 확인한 파일/모듈/심볼 범위
- **발견 사항**: 확인된 사실/패턴 목록 (`파일:라인` 표기)
- **구조적 관계**: 모듈/호출/데이터 흐름 관계
- **미탐색 영역**: 아직 확인하지 못했거나 증거가 부족한 영역
- **후속 탐색 제안**: 다음 탐색 우선순위와 제안 경로
글자 수 제한: `{config.collaborative_explore.finding_char_limit}`자 이내
explorer별 shared route/lifecycle을 먼저 적용한다. Same-host Codex는 collaboration agent로 병렬화하고, 아래 provider process는
route=external일 때만 실행한다.
provider: "codex", external lane only (same-host native candidate는 collaboration agent):
Bash(
run_in_background: true,
command: "codex exec --full-auto -m $(python3 {PLUGIN_ROOT}/scripts/mst.py resolve-model codex explore 2>/dev/null || echo \"gpt-5.3-codex\") -C $(pwd) \"$(cat {absolute_path}/prompts/explore-{explorerKey}-prompt.md)\" > {absolute_path}/explore-{explorerKey}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/explore-{explorerKey}.md; exit $EC"
)
provider: "agy":
Bash(
run_in_background: true,
command: "agy --print \"$(cat {absolute_path}/prompts/explore-{explorerKey}-prompt.md)\" --dangerously-skip-permissions > {absolute_path}/explore-{explorerKey}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/explore-{explorerKey}.md; exit $EC"
)
각 호출의 background task ID를 session.json에 기록합니다.
⏱️ 타임스탬프 취득 (MANDATORY):
TS=$(python3 {PLUGIN_ROOT}/scripts/mst.py timestamp now)실패 시 UTC ISO 폴백으로 생성한다.
session.json 업데이트:
status: "waiting"dispatch_started_at: "{TS}"explorers[key].status: "in_progress"explorers[key].started_at: "{TS}"explorers를 순회하여 explore-{explorerKey}.md 존재 여부/내용을 확인:
EXIT_CODE: 존재 → 후보 상태 done 또는 failed(exit code 기반)EXIT_CODE: 미기록 → in_progress모든 explorer가 완료 상태면 즉시 Step 3c로 진행.
in_progress explorer가 있으면 아래 명령으로 대기:
python3 {PLUGIN_ROOT}/scripts/mst.py wait-files \
--timeout {config.collaborative_explore.merge_wait_ms를 1000으로 나눈 값, 기본 60} \
{in_progress explorer들의 {absolute_path}/explore-{explorerKey}.md 절대 경로 목록}
분기 처리:
ALL_READY면 즉시 Step 3c 진행TIMEOUT이면 완료된 결과만 사용하고 미완료 explorer는 timeout으로 기록 후 Step 3c 진행⏱️ 타임스탬프 취득 (MANDATORY):
TS=$(python3 {PLUGIN_ROOT}/scripts/mst.py timestamp now)위 명령 실패 시 폴백:python3 -c "from datetime import datetime, timezone; print(datetime.now(timezone.utc).isoformat())"출력값을merge_completed_at필드에 기입한다. 날짜만 기입 금지.
{
"status": "synthesizing",
"explorers": {
"codex": { "status": "done", "completed_at": "{TS}", "exit_code": 0 },
"agy": { "status": "timeout", "completed_at": null, "exit_code": null }
},
"merge_completed_at": "{TS — mst.py timestamp now 출력값}"
}
status in ["done"]인 explore-{explorerKey}.md만 입력으로 사용prompts/synthesis-prompt.md 생성 후 Claude로 종합 실행explore-report.md로 저장 (아래 표준 섹션을 반드시 유지)claude_synthesis.status 갱신:
donefailed + 원인 기록explore-report.md 표준 섹션:
--from 주입 전용 요약)status: "completed"status: "failed"completed면 completed_at 필수failed면 failed_at 필수explore-report.md 요약과 경로를 표시표시 포맷:
## EXP-NNN 탐색 리포트
### 참여 탐색자
- {explorerKey} ({role}, {provider}): {status}
### 핵심 발견
{신뢰도 높은 발견 1~3개}
### 참고 경로
- 상세 리포트: {PROJECT_ROOT}/.gran-maestro/explore/EXP-NNN/explore-report.md
AskUserQuestion으로 다음 단계를 안내한다.
Skill(skill: "mst:explore", args: "--from {EXP-NNN} {사용자 후속 탐색 질문}")--from에 자동 포함한다.Skill(skill: "mst:request", args: "--from-explore {EXP-NNN} {탐색 목표 앞 50자}")Skill(skill: "mst:plan", args: "--from-explore {EXP-NNN} {탐색 목표 앞 50자}")exploring → dispatching → waiting → synthesizing → completed
→ failed
| 현재 상태 | 허용 전이 대상 |
|---|---|
exploring | dispatching, failed |
dispatching | waiting, failed |
waiting | synthesizing, failed |
synthesizing | completed, failed |
completed | (터미널 — 전이 불가) |
failed | (터미널 — 전이 불가) |
failed로 전이 가능: * → failedfailed 전이 시 반드시 failed_at 타임스탬프를 기록한다.completed → (any non-terminal): 절대 금지. 완료된 세션을 다시 열 수 없다.failed → (any non-terminal): 절대 금지. 실패한 세션을 다시 열 수 없다.completed, failed)는 불변이다. 재시도가 필요하면 새 세션을 생성한다.중간 실패가 있어도 상태를 열린 채로 두지 않습니다. 반드시 completed 또는 failed로 닫습니다.
explore-* 결과로 정상 합성 진행completed 가능completed, 합성 실패 시 failedstatus: "failed" + failed_at + error 기록skipped로 표시하고 계속 진행failedmst.py counter next --type exp 실패
EXP-EXP 방지failed로 종료failed 종료.gran-maestro/explore/EXP-NNN/
├── session.json
├── prompts/
│ ├── explore-{explorerKey}-prompt.md
│ └── synthesis-prompt.md
├── explore-{explorerKey}.md
└── explore-report.md
--focus {파일패턴|관점키워드}: 탐색 범위를 파일 패턴 또는 관점 키워드로 지정 (예: src/auth/**/*.ts, architecture, data-flow, security-surface)--from EXP-NNN: 이전 탐색 세션의 후속 탐색용 요약만(최대 500토큰) 주입해 연속 탐색을 수행/mst:explore "로그인 흐름에서 토큰 검증 경로를 찾아줘"
/mst:explore --focus src/api/**/*.ts "API 라우팅과 에러 처리 흐름을 정리해줘"
/mst:explore --from EXP-012 --focus data-flow "결제 승인 이후 정산까지 데이터 흐름을 이어서 추적해줘"
/mst:explore "이 저장소에서 결제 모듈이 어디서 시작되는지 추적해줘"
--from, 산출물 표준화, 다음 단계 안내, --focus 관점 키워드)을 추가 포함합니다.explorers는 object canonical 스키마를 사용하며 배열 표현을 금지합니다.