oh-my-customcode 1.1.102 → 1.1.104

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/cli/index.js +449 -40
  2. package/dist/index.js +95 -5
  3. package/package.json +1 -1
  4. package/templates/.claude/output-styles/korean-engineer.md +1 -1
  5. package/templates/.claude/rules/MUST-agent-design.md +2 -2
  6. package/templates/.claude/rules/MUST-agent-teams.md +18 -7
  7. package/templates/.claude/rules/MUST-orchestrator-coordination.md +46 -29
  8. package/templates/.claude/rules/MUST-permissions.md +15 -10
  9. package/templates/.claude/settings.json +0 -3
  10. package/templates/.claude/skills/action-validator/SKILL.md +2 -2
  11. package/templates/.claude/skills/adaptive-harness/SKILL.md +2 -2
  12. package/templates/.claude/skills/adversarial-review/SKILL.md +1 -1
  13. package/templates/.claude/skills/agent-eval-framework/SKILL.md +2 -2
  14. package/templates/.claude/skills/de-lead-routing/SKILL.md +2 -2
  15. package/templates/.claude/skills/deep-plan/SKILL.md +4 -4
  16. package/templates/.claude/skills/deep-verify/SKILL.md +3 -3
  17. package/templates/.claude/skills/design-shotgun/SKILL.md +1 -1
  18. package/templates/.claude/skills/dev-lead-routing/SKILL.md +2 -2
  19. package/templates/.claude/skills/dev-review/SKILL.md +2 -2
  20. package/templates/.claude/skills/evaluator-optimizer/SKILL.md +1 -1
  21. package/templates/.claude/skills/fsd/SKILL.md +48 -10
  22. package/templates/.claude/skills/harness-eval/SKILL.md +1 -1
  23. package/templates/.claude/skills/harness-synthesizer/SKILL.md +1 -1
  24. package/templates/.claude/skills/homework/SKILL.md +3 -3
  25. package/templates/.claude/skills/idea/SKILL.md +4 -2
  26. package/templates/.claude/skills/instinct-extractor/SKILL.md +8 -8
  27. package/templates/.claude/skills/intent-detection/SKILL.md +1 -1
  28. package/templates/.claude/skills/multi-model-verification/SKILL.md +2 -2
  29. package/templates/.claude/skills/omcustom-release-notes/SKILL.md +1 -1
  30. package/templates/.claude/skills/pipeline/SKILL.md +1 -1
  31. package/templates/.claude/skills/pipeline/scripts/trusted-issue-filter.jq +37 -0
  32. package/templates/.claude/skills/pipeline/workflows/auto-dev.yaml +128 -38
  33. package/templates/.claude/skills/post-release-followup/SKILL.md +2 -2
  34. package/templates/.claude/skills/professor-triage/SKILL.md +10 -10
  35. package/templates/.claude/skills/profile/SKILL.md +4 -4
  36. package/templates/.claude/skills/qa-lead-routing/SKILL.md +2 -2
  37. package/templates/.claude/skills/release-plan/SKILL.md +1 -1
  38. package/templates/.claude/skills/research/SKILL.md +8 -6
  39. package/templates/.claude/skills/result-aggregation/SKILL.md +1 -1
  40. package/templates/.claude/skills/roundtable-debate/SKILL.md +2 -2
  41. package/templates/.claude/skills/scout/SKILL.md +3 -8
  42. package/templates/.claude/skills/sec-agentshield-wrapper/SKILL.md +1 -1
  43. package/templates/.claude/skills/secretary-routing/SKILL.md +2 -2
  44. package/templates/.claude/skills/skill-extractor/SKILL.md +1 -1
  45. package/templates/.claude/skills/structured-dev-cycle/SKILL.md +1 -1
  46. package/templates/.claude/skills/task-decomposition/SKILL.md +1 -1
  47. package/templates/.claude/skills/worker-reviewer-pipeline/SKILL.md +5 -1
  48. package/templates/guides/claude-code/15-version-compatibility.md +20 -4
  49. package/templates/guides/deep-plan/phases.md +11 -9
  50. package/templates/guides/harness-engineering/README.md +2 -1
  51. package/templates/guides/professor-triage/README.md +1 -1
  52. package/templates/guides/professor-triage/phases.md +1 -1
  53. package/templates/manifest.json +1 -1
  54. package/templates/workflows/auto-dev.yaml +128 -38
package/dist/index.js CHANGED
@@ -404,6 +404,7 @@ var MESSAGES = {
404
404
  "lockfile.component_dir_missing": "Component directory missing: {{path}}",
405
405
  "lockfile.hash_failed": "Failed to hash file: {{path}} — {{error}}",
406
406
  "lockfile.entry_added": "Lockfile entry added: {{path}} ({{component}})",
407
+ "lockfile.entry_git_excluded": "Lockfile entry skipped (not in git listing): {{path}}",
407
408
  "update.start": "Checking for updates...",
408
409
  "update.success": "Updated from {{from}} to {{to}}",
409
410
  "update.components_synced": "Components synced (version {{version}}): {{components}}",
@@ -525,6 +526,7 @@ var MESSAGES = {
525
526
  "lockfile.component_dir_missing": "컴포넌트 디렉토리 없음: {{path}}",
526
527
  "lockfile.hash_failed": "파일 해시 실패: {{path}} — {{error}}",
527
528
  "lockfile.entry_added": "잠금 파일 항목 추가: {{path}} ({{component}})",
529
+ "lockfile.entry_git_excluded": "잠금 파일 항목 제외 (git 목록에 없음): {{path}}",
528
530
  "update.start": "업데이트 확인 중...",
529
531
  "update.success": "{{from}}에서 {{to}}로 업데이트 완료",
530
532
  "update.components_synced": "컴포넌트 동기화 완료 (버전 {{version}}): {{components}}",
@@ -2035,10 +2037,12 @@ function getComponentPath(component) {
2035
2037
 
2036
2038
  // src/core/lockfile.ts
2037
2039
  init_fs();
2040
+ import { execFile } from "node:child_process";
2038
2041
  import { createHash } from "node:crypto";
2039
2042
  import { createReadStream } from "node:fs";
2040
- import { readdir, stat } from "node:fs/promises";
2043
+ import { readdir, realpath, stat } from "node:fs/promises";
2041
2044
  import { join as join4, relative as relative2 } from "node:path";
2045
+ import { promisify } from "node:util";
2042
2046
  var LOCKFILE_NAME = ".omcustom.lock.json";
2043
2047
  var LOCKFILE_VERSION = 1;
2044
2048
  var LOCKFILE_COMPONENTS = [
@@ -2051,6 +2055,87 @@ var LOCKFILE_COMPONENTS = [
2051
2055
  "guides"
2052
2056
  ];
2053
2057
  var COMPONENT_PATHS = LOCKFILE_COMPONENTS.map((component) => [getComponentPath(component), component]);
2058
+ var execFileAsync = promisify(execFile);
2059
+ var GIT_LOCATION_ENV_KEYS = [
2060
+ "GIT_DIR",
2061
+ "GIT_WORK_TREE",
2062
+ "GIT_INDEX_FILE",
2063
+ "GIT_PREFIX",
2064
+ "GIT_COMMON_DIR"
2065
+ ];
2066
+ var GIT_INJECTED_CONFIG_ENV_KEYS = ["GIT_CONFIG_PARAMETERS", "GIT_CONFIG_COUNT"];
2067
+ var GIT_INJECTED_CONFIG_ENV_PREFIXES = ["GIT_CONFIG_KEY_", "GIT_CONFIG_VALUE_"];
2068
+ var GIT_REQUIRED_HINT = "build from a git checkout: excluding ignored local files from the lockfile requires git (#1819)";
2069
+ function gitChildEnv() {
2070
+ const env = { ...process.env };
2071
+ for (const key of [...GIT_LOCATION_ENV_KEYS, ...GIT_INJECTED_CONFIG_ENV_KEYS]) {
2072
+ delete env[key];
2073
+ }
2074
+ for (const key of Object.keys(env)) {
2075
+ if (GIT_INJECTED_CONFIG_ENV_PREFIXES.some((prefix) => key.startsWith(prefix))) {
2076
+ delete env[key];
2077
+ }
2078
+ }
2079
+ return env;
2080
+ }
2081
+ async function runGit(targetDir, args, env) {
2082
+ try {
2083
+ const { stdout } = await execFileAsync("git", args, {
2084
+ cwd: targetDir,
2085
+ env,
2086
+ encoding: "utf-8",
2087
+ maxBuffer: 256 * 1024 * 1024
2088
+ });
2089
+ return stdout;
2090
+ } catch (err) {
2091
+ const detail = err instanceof Error ? err.message.trim() : String(err);
2092
+ throw new Error(`git ${args[0]} failed in ${targetDir}: ${detail} — ${GIT_REQUIRED_HINT}`);
2093
+ }
2094
+ }
2095
+ function foldCase(nfcPath) {
2096
+ return nfcPath.toLowerCase();
2097
+ }
2098
+ function isGitVisible(visible, relativePath) {
2099
+ if (visible.exact.has(relativePath)) {
2100
+ return true;
2101
+ }
2102
+ const nfc = relativePath.normalize("NFC");
2103
+ if (visible.nfc.has(nfc)) {
2104
+ return true;
2105
+ }
2106
+ return visible.folded?.has(foldCase(nfc)) ?? false;
2107
+ }
2108
+ function stripFinalNewline(output) {
2109
+ return output.endsWith(`
2110
+ `) ? output.slice(0, -1) : output;
2111
+ }
2112
+ async function assertGitWorkTreeRoot(targetDir, env) {
2113
+ const topLevel = stripFinalNewline(await runGit(targetDir, ["rev-parse", "--show-toplevel"], env));
2114
+ let realTop;
2115
+ let realTarget;
2116
+ try {
2117
+ [realTop, realTarget] = await Promise.all([realpath(topLevel), realpath(targetDir)]);
2118
+ } catch (err) {
2119
+ const detail = err instanceof Error ? err.message : String(err);
2120
+ throw new Error(`cannot resolve the git work tree root of ${targetDir}: ${detail} — ${GIT_REQUIRED_HINT}`);
2121
+ }
2122
+ if (realTop !== realTarget) {
2123
+ throw new Error(`${targetDir} is not the root of its git work tree (root: ${topLevel}) — ${GIT_REQUIRED_HINT}`);
2124
+ }
2125
+ }
2126
+ async function listGitVisiblePaths(targetDir) {
2127
+ const env = gitChildEnv();
2128
+ await assertGitWorkTreeRoot(targetDir, env);
2129
+ const pathspecs = COMPONENT_PATHS.map(([prefix]) => prefix);
2130
+ const [listing, ignoreCase] = await Promise.all([
2131
+ runGit(targetDir, ["ls-files", "-z", "--cached", "--others", "--exclude-standard", "--", ...pathspecs], env),
2132
+ runGit(targetDir, ["config", "--type=bool", "--default=false", "--get", "core.ignorecase"], env)
2133
+ ]);
2134
+ const exact = new Set(listing.split("\x00").filter((entry) => entry.length > 0));
2135
+ const nfc = new Set([...exact].map((entry) => entry.normalize("NFC")));
2136
+ const folded = stripFinalNewline(ignoreCase) === "true" ? new Set([...nfc].map(foldCase)) : null;
2137
+ return { exact, nfc, folded };
2138
+ }
2054
2139
  function computeFileHash(filePath) {
2055
2140
  return new Promise((resolve, reject) => {
2056
2141
  const hash = createHash("sha256");
@@ -2136,8 +2221,9 @@ function sortFilesByPath(files) {
2136
2221
  const sorted = Object.keys(files).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
2137
2222
  return Object.fromEntries(sorted.map((key) => [key, files[key]]));
2138
2223
  }
2139
- async function generateLockfile(targetDir, generatorVersion, templateVersion) {
2224
+ async function generateLockfile(targetDir, generatorVersion, templateVersion, options = {}) {
2140
2225
  const files = {};
2226
+ const gitVisible = options.excludeGitIgnored ? await listGitVisiblePaths(targetDir) : null;
2141
2227
  const componentRoots = COMPONENT_PATHS.map(([prefix]) => join4(targetDir, prefix));
2142
2228
  for (const componentRoot of componentRoots) {
2143
2229
  const exists = await fileExists(componentRoot);
@@ -2148,6 +2234,10 @@ async function generateLockfile(targetDir, generatorVersion, templateVersion) {
2148
2234
  const allFiles = await collectFiles(componentRoot, targetDir, false);
2149
2235
  for (const absolutePath of allFiles) {
2150
2236
  const relativePath = relative2(targetDir, absolutePath).replace(/\\/g, "/");
2237
+ if (gitVisible !== null && !isGitVisible(gitVisible, relativePath)) {
2238
+ debug("lockfile.entry_git_excluded", { path: relativePath });
2239
+ continue;
2240
+ }
2151
2241
  let hash;
2152
2242
  let size;
2153
2243
  try {
@@ -2208,12 +2298,12 @@ function preserveGeneratedAt(next, previous) {
2208
2298
  }
2209
2299
  return { ...next, generatedAt: previous.generatedAt };
2210
2300
  }
2211
- async function generateAndWriteLockfileForDir(targetDir) {
2301
+ async function generateAndWriteLockfileForDir(targetDir, options = {}) {
2212
2302
  try {
2213
2303
  const packageRoot = getPackageRoot();
2214
2304
  const manifest = await readJsonFile(join4(packageRoot, "templates", "manifest.json"));
2215
2305
  const { version: generatorVersion } = await readJsonFile(join4(packageRoot, "package.json"));
2216
- const generated = await generateLockfile(targetDir, generatorVersion, manifest.version);
2306
+ const generated = await generateLockfile(targetDir, generatorVersion, manifest.version, options);
2217
2307
  const previous = await readLockfile(targetDir);
2218
2308
  const lockfile = preserveGeneratedAt(generated, previous);
2219
2309
  await writeLockfile(targetDir, lockfile);
@@ -2853,7 +2943,7 @@ var package_default = {
2853
2943
  workspaces: [
2854
2944
  "packages/*"
2855
2945
  ],
2856
- version: "1.1.102",
2946
+ version: "1.1.104",
2857
2947
  description: "Batteries-included agent harness for Claude Code",
2858
2948
  type: "module",
2859
2949
  bin: {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "workspaces": [
4
4
  "packages/*"
5
5
  ],
6
- "version": "1.1.102",
6
+ "version": "1.1.104",
7
7
  "description": "Batteries-included agent harness for Claude Code",
8
8
  "type": "module",
9
9
  "bin": {
@@ -56,7 +56,7 @@ ecomode 활성 시 자동으로 concise 모드로 전환 (R013).
56
56
 
57
57
  ## 위임 모델 (R010)
58
58
 
59
- 오케스트레이터(메인 대화)는 파일 수정 금지 → 서브에이전트에 위임. Agent tool 호출 시 항상 `mode: "bypassPermissions"` 명시.
59
+ 오케스트레이터(메인 대화)는 파일 수정 금지 → 서브에이전트에 위임. CC < 2.1.212에서는 Agent 도구 호출 시 `mode: "bypassPermissions"`가 필요하므로 호환을 위해 명시합니다. 2.1.212+에서는 `mode`가 무시되고 서브에이전트가 부모 세션의 권한 모드를 상속합니다(frontmatter `permissionMode`로 조정 가능). 무인 실행 전 유효 모드는 R010 「Universal bypassPermissions」 절차로 실측합니다.
60
60
 
61
61
  ## 작업 완료 검증 (R020)
62
62
 
@@ -371,7 +371,7 @@ RETIRED (은퇴 릴리즈 v1.1.50, 보존 기준 v2.1.230 미만): > **v2.1.204+
371
371
 
372
372
  ## Permission Mode Guidance
373
373
 
374
- > Canonical source for the bypassPermissions requirement: R010 (MUST-orchestrator-coordination.md) "Universal bypassPermissions". CC defaults `mode` to `acceptEdits` if not specified — always pass `mode: "bypassPermissions"` explicitly in Agent tool calls. See R010 for the full requirement, rationale, and self-check. Note: as of v2.1.212+, the Agent tool's `mode` parameter is ignored — subagents inherit the parent session's permission mode instead (canonical: R010 Self-Check).
374
+ > Canonical source: R010 (MUST-orchestrator-coordination.md) "Universal bypassPermissions". Below CC 2.1.212, CC defaults per-call `mode` to `acceptEdits` — pass `mode: "bypassPermissions"` explicitly. From 2.1.212 the parameter is ignored: subagents inherit the parent session's mode, and frontmatter `permissionMode` (modes in the table below) may override it. Keep passing `mode` for compatibility; see R010 for the version table and self-check.
375
375
 
376
376
  | Mode | Behavior |
377
377
  |------|----------|
@@ -390,7 +390,7 @@ RETIRED (은퇴 릴리즈 v1.1.50, 보존 기준 v2.1.230 미만): > **v2.1.204+
390
390
  > **v2.1.212+**: Agent(구 Task) tool의 `mode` 파라미터가 **deprecated되어 무시됩니다** — subagent는 **기본적으로** 부모(오케스트레이터) 세션의 permission mode를 상속합니다. 위 "CC defaults `mode` to `acceptEdits`" 서술과 R010 Universal bypassPermissions의 per-call `mode: "bypassPermissions"` 지정은 플랫폼 레벨에서 no-op가 됩니다(명시 지정 자체는 무해). 무인 실행의 실제 bypass 여부는 이제 부모 세션 mode가 결정하므로, 오케스트레이터 세션을 bypassPermissions로 유지하는 것이 핵심입니다. Canonical owner는 R010.
391
391
  -->
392
392
 
393
- <!-- DETAIL: Permission Mode Guidance (reasoning)
393
+ <!-- DETAIL (applies to CC < 2.1.212 only, #1818): Permission Mode Guidance (reasoning)
394
394
  When spawning agents via the Agent tool, CC applies a default `mode` of `acceptEdits` if not explicitly specified. To maintain consistent permission behavior:
395
395
 
396
396
  1. **Agent frontmatter `permissionMode`**: Declares the agent's intended permission level. CC respects this when the agent is spawned via Agent tool.
@@ -19,10 +19,10 @@ Agent Teams is active only when the **team-creation path actually exists** — `
19
19
  | Observed state | Teams active? |
20
20
  |----------------|---------------|
21
21
  | `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` **and** `TeamCreate` present | Yes |
22
- | env var set, `TeamCreate` **absent** | **No** — no team creatable, no member spawnable |
22
+ | env var set, `TeamCreate` **absent** | **No** — no team creatable. A named `Agent` spawn (`name:`) still creates a teammate of the session's implicit team (CC 2.1.289 measured), but without `TeamCreate`/`TeamDelete` in the session (main or teammate) it is governed by R009/R010 as a subagent |
23
23
  | `SendMessage` present, `TeamCreate` absent | **No** — peer/cross-session messaging is separate (see Scope), not Teams evidence |
24
24
 
25
- <!-- DETAIL: Detection table rows, original wording
25
+ <!-- DETAIL: Detection table rows, original wording — superseded by #1827 (CC 2.1.289 measured) — do not restore as-is
26
26
  | env var set, `TeamCreate` **absent** | **No** — a team cannot be created, so no member can be spawned |
27
27
  | `SendMessage` present, `TeamCreate` absent | **No** — peer/cross-session messaging is a separate capability (see Scope below), not evidence of Teams |
28
28
  -->
@@ -33,7 +33,7 @@ Rationale: v2.1.233+부터 `TeamCreate`/`TeamDelete`가 부재하다(R002). env
33
33
  Rationale: since v2.1.233, `TeamCreate`/`TeamDelete` are absent from the tool list in this runtime (measured — R002 "Todo/Task 도구 기본 제거"), so a set env var cannot make teams creatable. Detection therefore rests on the tools actually being present, not on the env var alone — "the tool exists" is itself a claim requiring measurement (R020).
34
34
  -->
35
35
 
36
- When Detection resolves to **No**, this entire rule is dormant and R009/R010 govern.
36
+ When Detection resolves to **No**, this entire rule is dormant and R009/R010 govern (the named-spawn note in 「멤버 도구 부재 시 대체 규약」 restates R010 policy and applies under R010).
37
37
 
38
38
  ## Decision Matrix
39
39
 
@@ -65,9 +65,9 @@ When Detection resolves to **No**, this entire rule is dormant and R009/R010 gov
65
65
 
66
66
  ### Scope: Intra-Session vs Cross-Session
67
67
 
68
- Intra-session: `SendMessage`(Agent Teams), peer-to-peer, `TeamCreate` 필요. Cross-session: `send_message`(claude-peers-mcp), broker 경유, 별도 프로세스 간.
68
+ Intra-session: `SendMessage`. 메인→이름 붙인 멤버 전달은 `TeamCreate` 없이 동작(CC 2.1.289 실측, general-purpose 팀원 1건); 멤버→멤버 peer-to-peer는 `[가설]` 미관측. Cross-session: `send_message`(claude-peers-mcp), broker 경유, 별도 프로세스 간.
69
69
 
70
- <!-- DETAIL: Scope table and mechanism-distinction paragraph, original wording
70
+ <!-- DETAIL: Scope table and mechanism-distinction paragraph, original wording — superseded by #1827 (CC 2.1.289 measured) — do not restore as-is
71
71
  | Scope | Tool | Protocol | Use Case |
72
72
  |-------|------|----------|----------|
73
73
  | Intra-session | `SendMessage` (Agent Teams) | Peer-to-peer within team | Multi-agent collaboration in one session |
@@ -448,10 +448,10 @@ Agent Teams 멤버는 long-running 작업 중 TaskUpdate 로 진행 상태를
448
448
  Agent Teams 멤버는 long-running 작업 중 진행 상태를 TaskUpdate 로 명시적으로 알려야 한다. 침묵은 코디네이터가 죽었거나 멤버가 막혔다고 오인하게 만든다.
449
449
  -->
450
450
 
451
- `TaskCreate/Get/Update/List`는 현행 모델(Opus 4.8 / Sonnet 5 / Fable 5 / Mythos 5 이상)에서 기본 미제공(R002) — 가용 시 아래 표, 부재 시 「대체 규약」을 따른다.
451
+ `TaskCreate/Get/Update/List`는 현행 모델(Opus 4.8 / Sonnet 5 / Fable 5 / Mythos 5 이상)에서 기본 미제공(R002) — 가용 시 아래 표, 부재 시 「Task 도구 부재 시 대체 규약」을 따른다. 가용성은 모델을 따른다 — haiku 팀원 1건은 `ToolSearch`로 로드, sonnet-5-5 팀원 1건과 `claude-opus-5-5` 메인은 불가(CC 2.1.289 실측).
452
452
 
453
453
  <!-- DETAIL: Task tool availability measurement note, original wording
454
- > **도구 가용성 선확인 (v2.1.233+)**: `TaskCreate/Get/Update/List`는 현행 모델(Opus 4.8 / Sonnet 5 / Fable 5 / Mythos 5 이상)에서 기본 제거되어 이 저장소 실행 환경에 **존재하지 않는다** — 실측은 R002 「Todo/Task 도구 기본 제거」. 아래 표는 Task 도구가 가용할 때(구모델 또는 `CLAUDE_CODE_ENABLE_TODO_TOOLS=1`)의 규정이며, **부재 시 아래 대체 규약을 따른다**. 없는 도구의 호출을 의무로 남겨두면 실행 불가능한 규정이 된다.
454
+ > **도구 가용성 선확인 (v2.1.233+)**: `TaskCreate/Get/Update/List`는 현행 모델(Opus 4.8 / Sonnet 5 / Fable 5 / Mythos 5 이상)에서 기본 제거되어 이 저장소 실행 환경에 **존재하지 않는다** — 실측은 R002 「Todo/Task 도구 기본 제거」. 아래 표는 Task 도구가 가용할 때(구모델 또는 `CLAUDE_CODE_ENABLE_TODO_TOOLS=1`)의 규정이며, **부재 시 아래 「Task 도구 부재 시 대체 규약」을 따른다**. 없는 도구의 호출을 의무로 남겨두면 실행 불가능한 규정이 된다.
455
455
  -->
456
456
 
457
457
  | 시점 | 호출 |
@@ -487,6 +487,17 @@ Reference issue: #1087.
487
487
  `TaskList` 부재로 **공유 작업 목록이라는 조율 기반 자체가 사라지므로**, 아래 Member Completion Verification의 "보고는 신호일 뿐, 판정은 실측"이 보조 원칙이 아니라 **유일한 방어선**이 된다.
488
488
  -->
489
489
 
490
+ ### 멤버 도구 부재 시 대체 규약 (Origin: #1817)
491
+
492
+ 멤버의 도구 구성은 그 에이전트의 frontmatter `tools:`와 실행 환경에 좌우되는 것으로 추정된다(#1817 "추정 원인 (미검증)") — `SendMessage`·`Agent`·`ToolSearch`가 있다고 가정하지 않는다(#1817: 멤버 3종에서 일부 부재 관측). 전용 `Glob`/`Grep`은 실측됐다(R002 ‡, CC 2.1.289): frontmatter `tools:`에 명시한 `qa-writer`는 받았고, 명시 목록이 없는 메인 세션에는 없었다 — 명시되지 않은 쪽은 부재로 전제한다. Detection = No일 때 이름 붙인 멤버(general-purpose 팀원 1건 실측)는 직접 도구에 `Agent`가 있어도(CC 2.1.289) R010 Core Rule상 서브에이전트를 스폰하지 않는다 — 이는 도구 부재가 아니라 프로젝트 정책이며(Detection = Yes 멤버는 R010의 Agent Teams 예외를 따른다), `SendMessage`는 직접 목록에는 없으나 `ToolSearch`(query "select:SendMessage")로 지연 로드해 `team-lead`에게 전달됐다(CC 2.1.289 실측) — 따라서 `SendMessage` 부재를 전제하지 말고 먼저 로드를 시도한다. 멤버→멤버 메시징은 `[가설]` 미관측이다. 멤버 측 `SendMessage` 지시(위 「Task 도구 부재 시 대체 규약」 표, TaskUpdate 표의 "차단 시" 행, 「Blocked Agent Behavior」의 "Post-completion: SendMessage + wait silently")는 모두 `SendMessage` 부재 시 아래 표를 따른다.
493
+
494
+ | 부재 도구 | 대체 수단 |
495
+ |-----------|-----------|
496
+ | `SendMessage` | 아티팩트 파일 채널(R006 Artifact Channel Protocol) — 오케스트레이터가 경로를 중계 |
497
+ | `Agent` | 멤버는 필요한 스폰(예: R017 `mgr-sauron:watch`)을 보고하고 오케스트레이터가 스폰 |
498
+ | `ToolSearch` | 로드할 수 없는 지연 도구는 부재로 취급하고 이 표의 해당 행을 따른다(R002 §) |
499
+ | 전용 `Glob`/`Grep` (명시 목록에 없음) | 읽기 전용 Bash(`git grep`·`find`, R002 Tier 4 승인 정책 적용). Bash도 없으면 오케스트레이터가 사전 수집해 내용으로 전달(R010 「Known Limitations (Active Cache)」) |
500
+
490
501
  ## Member Completion Verification (deterministic ground-truth)
491
502
 
492
503
  Agent Teams member completion MUST be verified by deterministic ground-truth — NOT by SendMessage reports or TaskList status alone. Members may edit files without updating task status (task stays `pending`) or go idle without executing at all.
@@ -11,11 +11,12 @@ The main conversation is the **sole orchestrator**. It uses routing skills to de
11
11
  -->
12
12
 
13
13
  <!-- DETAIL: Agent Teams Exception detail (restated in ARCHIVED note below)
14
- **Agent Teams Exception**: Agent Teams members are peers, not hierarchical subagents. Teams members CAN spawn sub-agents via the Agent tool to execute complex workflows (e.g., research teams, verification teams). This enables Teams-compatible skills like `/research` and `/deep-plan` to run inside Team members. The Teams member acts as a local orchestrator for its own sub-tasks.
14
+ **Agent Teams Exception** (conditional, #1817): Agent Teams members are peers, not hierarchical subagents. A member MAY spawn sub-agents via the Agent tool only when `Agent` is actually in its tool list (presumably decided by its frontmatter `tools:` and the execution environment — #1817 "추정 원인 (미검증)"; the documented cause of dedicated Glob/Grep absence is CC 2.1.117, which replaces them with Bash-embedded bfs/ugrep on native builds — #1817 observed members without `Agent`/`SendMessage`/`ToolSearch`). When present, the member acts as a local orchestrator for its own sub-tasks (e.g., `/research`, `/deep-plan` inside a member). When absent, use the R018 「멤버 도구 부재 시 대체 규약」: file channel + orchestrator relay/spawn.
15
+ Original wording (pre-#1817): "Teams members CAN spawn sub-agents via the Agent tool to execute complex workflows (e.g., research teams, verification teams)."
15
16
  -->
16
17
 
17
18
  <!-- ARCHIVED CC version note (historical):
18
- > **v2.1.172+**: The CC platform now allows sub-agents to spawn their own sub-agents (up to 5 levels deep). oh-my-customcode RETAINS the sole-orchestrator design (subagents do not spawn subagents via the Agent tool) as a DELIBERATE project architecture choice — for predictable R009 parallelism and R018 coordination — NOT a platform limitation. The sanctioned nesting path remains the Agent Teams Exception (Teams members acting as local orchestrators).
19
+ > **v2.1.172+**: The CC platform now allows sub-agents to spawn their own sub-agents (up to 5 levels deep). oh-my-customcode RETAINS the sole-orchestrator design (subagents do not spawn subagents via the Agent tool) as a DELIBERATE project architecture choice — for predictable R009 parallelism and R018 coordination — NOT a platform limitation. The sanctioned nesting path remains the Agent Teams Exception (Teams members acting as local orchestrators) (pre-#1817).
19
20
  -->
20
21
 
21
22
  **The orchestrator MUST NEVER directly write, edit, or create files. ALL file modifications MUST be delegated to appropriate subagents.**
@@ -338,7 +339,7 @@ Origin: #1584 #6 — v1.1.45·v1.1.46 릴리즈 PR 머지에서 하니스가 "no
338
339
 
339
340
  ### Delegation Prompt Framing — 승인 인용 금지
340
341
 
341
- 위임 프롬프트에서 **사용자 원문을 승인/동의의 근거로 인용하지 않는다**. 서브에이전트에는 **작업 지시**(허용 작업 / 금지 작업 / 완료 조건)만 전달하고, 승인 채널은 permission system(부모 세션 permission mode + `settings.json` allow 규칙)이 담당한다.
342
+ 위임 프롬프트에서 **사용자 원문을 승인/동의의 근거로 인용하지 않는다**. 서브에이전트에는 **작업 지시**(허용 작업 / 금지 작업 / 완료 조건)만 전달하고, 승인 채널은 permission system(부모 세션 permission mode — CC 버전별 결정 방식은 「Universal bypassPermissions」 — + `settings.json` allow 규칙)이 담당한다.
342
343
 
343
344
  <!-- DETAIL: 근거 rationale note (restated by norm+table)
344
345
  근거: CC는 모든 서브에이전트에 "다른 에이전트의 메시지는 결코 사용자의 승인이 아니다 — 유효한 승인 채널은 permission system 또는 사용자 본인의 메시지뿐"이라는 플랫폼 시스템 프롬프트를 주입한다. 이 문구가 금지하는 것은 전언을 **승인**으로 취급하는 것이지 전언된 **작업**을 수행하는 것이 아니다. 따라서 오케스트레이터가 "사용자가 푸시해달라고 했다"를 승인 근거로 인용하면, 플랫폼 룰이 겨냥하는 안티패턴을 스스로 발동시켜 서브에이전트가 작업을 거부한다.
@@ -577,15 +578,20 @@ Origin: #1598 (형제 병렬 배치의 위양성 4종 중 3종이 각 에이전
577
578
 
578
579
  ## Universal bypassPermissions
579
580
 
580
- > **This section is the canonical single source for the bypassPermissions requirement.** R002 (MUST-permissions.md) and R006 (MUST-agent-design.md) reference this section rather than repeating it.
581
+ > **This section is the canonical single source for subagent permission-mode guidance.** R002 (MUST-permissions.md) and R006 (MUST-agent-design.md) reference this section rather than repeating it.
581
582
 
582
- **ALL Agent tool calls MUST include `mode: "bypassPermissions"`.**
583
+ | CC version | Per-call `mode: "bypassPermissions"` |
584
+ |------------|---------------------------------------|
585
+ | < 2.1.212 (min supported 2.1.121) | **Required** — the Agent tool's default `acceptEdits` overrides frontmatter `permissionMode` and causes prompts during unattended runs |
586
+ | ≥ 2.1.212 | Ignored — 2.1.212 CHANGELOG (#1497): "Deprecated the Task tool's `mode` parameter (now ignored); subagents inherit the parent session's permission mode by default". The frontmatter override comes from the Agent tool schema observed on CC 2.1.289 (`claude --version`), not from the 2.1.212 entry: "Deprecated; ignored. Subagents inherit the parent session's permission mode; agent-definition frontmatter may override it." |
583
587
 
584
- <!-- DETAIL: Agent tool default explanation (restated by table)
588
+ Keep passing `mode` on every Agent call for compatibility (harmless on 2.1.212+), but never treat its presence as evidence of unattended execution. On 2.1.212+ the inherited parent mode comes from the `permissions.defaultMode` settings (managed, local, project, user) or a launch flag such as `--permission-mode`. Since 2.1.257 the `bypassPermissions` value is narrower: project (`.claude/settings.json`) and local (`.claude/settings.local.json`) `defaultMode: "bypassPermissions"` is ignored, like `"auto"` (2.1.257 CHANGELOG), and an ignored project/local `bypassPermissions` is dropped, so that scope resolves to `default` and overrides a non-bypass user value (user `plan`/`auto`/`acceptEdits` → `default`), whereas with user `bypassPermissions` the result stays `bypassPermissions` (no ignore WARN observed); other values there (measured: `default`, `acceptEdits`; `auto` is ignored per the same CHANGELOG entry, unmeasured `[가설]`; `plan`/`dontAsk` unmeasured) still apply and override the user value, with precedence local > project > user (a project `"default"` overrides a user `auto`/`bypassPermissions`; an absent key leaves the user value in effect) — measured via `claude -p` init `permissionMode` (#1828 comments 5997497206 (E1–E8) / 5998595610 (C0–C9), CC 2.1.289, 2026-10-06). `[가설]` (unobserved): interactive TTY sessions (the 2026-09-02 DETAIL record below, user=auto + project·local=bypass → "auto mode is active", is not reconciled with the `-p` result; a launch flag such as an alias's `--enable-auto-mode` is only a hypothesis), whether `default` actually prompts, managed policy/`--settings` scopes, other CC versions, subagent inheritance. Bypass can still be granted elsewhere, e.g. user or managed settings, `--permission-mode`, or `--dangerously-skip-permissions` (`claude --help` on 2.1.289: "Bypass all permission checks.") (#1644).
589
+
590
+ <!-- DETAIL (applies to CC < 2.1.212 only, #1818): Agent tool default explanation
585
591
  The Agent tool defaults to `mode: "acceptEdits"`, which overrides agent frontmatter `permissionMode` and causes permission prompts during unattended execution. This is a CC platform behavior, not a configuration error.
586
592
  -->
587
593
 
588
- <!-- DETAIL: bypassPermissions Aspect/Detail table
594
+ <!-- DETAIL (applies to CC < 2.1.212 only, #1818): bypassPermissions Aspect/Detail table
589
595
  | Aspect | Detail |
590
596
  |--------|--------|
591
597
  | Scope | Every Agent tool call, without exception |
@@ -594,32 +600,42 @@ The Agent tool defaults to `mode: "acceptEdits"`, which overrides agent frontmat
594
600
  | Enforcement | Prompt-based (R021); all agent-spawning skills include instruction |
595
601
  -->
596
602
 
597
- ### Self-Check
598
-
599
- Before spawning any agent:
600
- 1. **유효 permission mode 확인** — per-call `mode` 파라미터는 v2.1.212+ 에서 무시되고,
601
- **프로젝트 scope `permissions.defaultMode` 는 v2.1.257+ 에서도 무시된다(#1644)**.
602
- 무인 실행 전 실측할 것: `jq -r '.permissions.defaultMode // "unset"' ~/.claude/settings.json`
603
- (user scope) — 이 값 또는 `--permission-mode` 실행 플래그만이 유효하다.
603
+ ### Self-Check (MUST)
604
+
605
+ Before unattended execution (item 1) and when authoring a skill that spawns agents (item 2):
606
+ 1. **유효 permission mode 실측** — CC ≥ 2.1.212: 부모 모드는 `permissions.defaultMode`(managed·local·
607
+ project·user 범위)와 실행 플래그(`--permission-mode` 등)가 정한다. 2.1.257+에서 무시되는 것은
608
+ project/local의 `bypassPermissions` 값(CHANGELOG상 `auto`도, 미측정 `[가설]`)이며 그 범위의 다른 값(예: 사용자가 project에 둔 `"default"`)은
609
+ 여전히 원천이다(위 문단). 세 파일을 함께 실측한다 —
610
+ `jq -r '.permissions.defaultMode // "unset"' ~/.claude/settings.json .claude/settings.json .claude/settings.local.json`
611
+ (출력 순서 user·project·local) — managed 설정과 실행 플래그도 원천이므로 별도로 확인한다. 범위 간
612
+ 우선순위는 local > project > user이며 project의 `"default"`는 user의 `auto`/`bypassPermissions`를 덮는다
613
+ (#1828 comments 5997497206 (E1–E8) / 5998595610 (C0–C9), CC 2.1.289, 2026-10-06, `claude -p` init `permissionMode` 실측). 키가 없으면 user 값이 유지되고,
614
+ project/local `bypassPermissions`는 무시되어 그 범위는 `default`로 귀결되고 bypass가 아닌 user 값
615
+ (`plan`/`auto`/`acceptEdits`)을 덮는다; user가 `bypassPermissions`이면 결과는 `bypassPermissions`다.
616
+ TTY 세션(2026-09-02 DETAIL 기록과 미조정)·`default`의 실제 프롬프트 여부·managed/`--settings`·다른 버전·
617
+ 서브에이전트 상속은 `[가설]` — 미관측.
618
+ 대상 에이전트 frontmatter `permissionMode`가 위에서 실측한 유효 부모 모드를 덮어쓸 수 있다 — 근거는 CHANGELOG 항목이 아니라
619
+ CC 2.1.289에서 관측한 Agent tool 스키마("agent-definition frontmatter may override it")다. 이 구간에서
620
+ per-call `mode` 값은 무인 실행의 증거가 아니다(R020 "actual outcome ≠ attempt").
621
+ CC < 2.1.212: per-call `mode`가 서브에이전트 모드를 정한다 — 생략하면 기본값 `acceptEdits`가
622
+ frontmatter `permissionMode`를 덮어쓴다(위 버전 표). 어느 구간이든 유효 모드가
604
623
  bypassPermissions 가 아니면 프롬프트 발생을 전제로 계획한다.
605
- 하위 호환을 위해 per-call `mode: "bypassPermissions"` 는 계속 포함하되,
606
- **그 존재를 무인 실행의 증거로 삼지 않는다**(R020 "attempt ≠ outcome").
607
624
  <!-- DETAIL: defaultMode ignored measurement evidence
608
625
  실측(2026-09-03, `claude -p --debug-file`): `[WARN] settings defaultMode "bypassPermissions"
609
626
  ignored — only policy/user/flag settings may grant bypass mode (projectSettings and
610
627
  localSettings are repo-controllable)` — 무시 동작이 직접 실증되었다. 프로젝트 settings에는
611
628
  `permissions._comment_defaultMode` 안내 키가 추가되었다(v1.1.59).
612
629
  -->
613
- 2. Is this a new skill that spawns agents? → Add Permission Mode section
630
+ 2. Is this a new skill that spawns agents? → Include `mode: "bypassPermissions"` in its Agent calls (required below 2.1.212) and point to this section for the version split
614
631
 
615
632
  ### Common Violation
616
633
 
617
634
  ```
618
- ❌ WRONG: Agent tool call without mode parameter
619
- Agent(subagent_type: "lang-golang-expert", prompt: "...")
620
-
621
- ✓ CORRECT: Always include mode
622
- Agent(subagent_type: "lang-golang-expert", mode: "bypassPermissions", prompt: "...")
635
+ ❌ WRONG (CC < 2.1.212): Agent call without mode → acceptEdits default, prompts mid-run
636
+ ❌ WRONG (CC ≥ 2.1.212): Prompt appears → assume a missing mode is the cause
637
+ ✓ CORRECT: Always pass mode, and diagnose 2.1.212+ prompts via the parent's effective mode
638
+ and the agent's frontmatter permissionMode
623
639
  ```
624
640
 
625
641
 
@@ -637,7 +653,7 @@ Before spawning any agent:
637
653
  | >= v2.1.141 | Preserves current permission mode — `/bg` flows no longer need extra workaround |
638
654
  -->
639
655
 
640
- `mode: "bypassPermissions"` on every Agent tool call is still required (applies to Agent tool, not `/bg` shell command).
656
+ Background agents (`/bg`, `←←`) keep the current session's permission mode (v2.1.141+); Agent tool calls still follow the CC-version table at the top of 「Universal bypassPermissions」 (per-call `mode` required below 2.1.212, ignored from 2.1.212).
641
657
 
642
658
  <!-- ARCHIVED CC version note (historical):
643
659
  > **v2.1.172+**: Fixed background agents potentially reading another directory's project settings (`.mcp.json` approvals, trust) when dispatched onto a pre-warmed worker. Strengthens background-agent isolation — a `/bg`-dispatched agent now reads the correct project's settings.
@@ -737,7 +753,7 @@ Before delegating a task to a subagent, MUST verify the target agent's tool capa
737
753
  | `Read` external files | `tools:` includes Read |
738
754
  | `Write` files | `tools:` includes Write (and target path not in `disallowedTools` scope) |
739
755
  | MCP server calls | `mcpServers:` includes the required server |
740
- | Task targets a specific file path | The path EXISTS (`Glob`/`ls`) — capability check alone does not catch a missing/renamed file |
756
+ | Task targets a specific file path | The path EXISTS (`ls`/`find`, or `Glob` when present — not `git ls-files`, which reports an existing untracked path as absent; tracked status is the next row) — capability check alone does not catch a missing/renamed file |
741
757
  | Task targets an EXISTING file for editing/commit (not a newly-created file) | The path is git-tracked (`git ls-files <path>` non-empty) — an existing-but-untracked target needs an explicit scope decision before delegation |
742
758
 
743
759
  <!-- DETAIL: path-existence clarification (restated by Required Checks row)
@@ -797,6 +813,7 @@ Before delegating a task to a subagent, MUST verify the target agent's tool capa
797
813
  | Agent | Limitation | Workaround |
798
814
  |-------|-----------|-----------|
799
815
  | `arch-documenter` | `disallowedTools: [Bash]` — cannot run `gh`, shell scripts, `diff`/`md5`/`verify-*.sh` | Pre-collect data via orchestrator, pass as content; OR use `general-purpose` for the Bash-needing portion. **Completion-condition guard (#1593 #1)**: do NOT put `diff` / `md5` / `verify-*.sh` execution into arch-documenter's completion criteria — the orchestrator must run these itself, or split off a `general-purpose` agent for the Bash-needing verification |
816
+ | `arch-documenter`, `fe-design-expert`, `mgr-supplier`, `qa-planner`, `qa-writer`, `sys-naggy` (frontmatter parse: `Bash` in `disallowedTools`) | No Bash, so every search path is the dedicated `Grep`/`Glob` listed in their `tools:` (`sys-naggy` lists `Grep` only). Measured 2026-10-05 on CC 2.1.289: a spawned `qa-writer` received `Read`, `Write`, `Edit`, `Grep`, `Glob` — consistent with 2.1.162 ("explicitly listing Grep/Glob now provides the dedicated search tools on native builds with embedded search"); the main session, which has no explicit list, lacks them (2.1.117). The other five were not spawned to measure | Do not remove `Grep`/`Glob` from these agents' `tools:` — without Bash they would have no search path left |
800
817
  | `qa-engineer` | (verify each invocation) | — |
801
818
 
802
819
  ### Common Violation
@@ -818,9 +835,7 @@ Reference issues: #1202 item #2, `feedback_arch_documenter_no_bash.md`.
818
835
  > **Status**: Deprecated as of CC v2.1.121 (2026-04-28) and further relaxed in v2.1.126 (2026-05-01). Direct Write/Edit/Bash on `.claude/`, `.git/`, `.vscode/` works without prompts under `bypassPermissions` mode in CC v2.1.121+ (issue #1101).
819
836
  -->
820
837
 
821
- Current CC versions (>=2.1.121): direct Write/Edit/Bash on `.claude/**` paths are permitted under `mode: "bypassPermissions"`. The `/tmp/*.sh` script wrapping pattern previously required is no longer necessary. Catastrophic operations (e.g., `rm -rf /`) remain blocked by independent safety guards.
822
-
823
- `mode: "bypassPermissions"` on every Agent tool call is still required (see "Universal bypassPermissions" above).
838
+ Current CC versions (>=2.1.121): direct Write/Edit/Bash on `.claude/**` paths are permitted when the effective permission mode is `bypassPermissions`. The `/tmp/*.sh` script wrapping pattern previously required is no longer necessary. Catastrophic operations (e.g., `rm -rf /`) remain blocked by independent safety guards.
824
839
 
825
840
  <!-- DETAIL: legacy /tmp bypass pointer (historical)
826
841
  **For CC < v2.1.121 only**: see git history of this rule for the legacy `/tmp/*.sh` bypass pattern (commit before v0.126.0).
@@ -861,7 +876,7 @@ After restart/compaction: re-read CLAUDE.md, all delegation rules still apply. N
861
876
  | Unmatched specialized task | mgr-creator → dynamic agent creation |
862
877
 
863
878
  **Rules:**
864
- - All file modifications MUST be delegated (orchestrator only uses Read/Glob/Grep)
879
+ - All file modifications MUST be delegated (orchestrator only uses read-only tools — Read, Glob/Grep when present, otherwise read-only Bash such as `git grep`/`find`)
865
880
  - Use specialized agents, not general-purpose, when one exists
866
881
  - general-purpose only for truly generic tasks (file moves, simple scripts)
867
882
  - No exceptions for "small" or "quick" changes
@@ -926,7 +941,7 @@ The following paths MUST be created or structurally modified ONLY through `mgr-c
926
941
  ## Exception: Simple Tasks
927
942
 
928
943
  Subagent NOT required for:
929
- - Reading files for analysis (Read, Glob, Grep only)
944
+ - Reading files for analysis (read-only tools only — see Rules above; dedicated Glob/Grep may be absent)
930
945
  - Simple file searches
931
946
  - Direct questions answered by main conversation
932
947
 
@@ -1053,6 +1068,8 @@ See **R018 (MUST-agent-teams.md)** for the Detection table, complete decision ma
1053
1068
  **Quick rule** (applies only when active): 3+ agents OR review cycle OR 2+ issues in same batch → use Agent Teams.
1054
1069
  Using Agent tool when Agent Teams criteria are met needs correction per R018.
1055
1070
 
1071
+ Exception to the Core Rule ("Subagents MUST NOT spawn other subagents"), only when R018 Detection = Yes: Agent Teams members are peers, not hierarchical subagents (Agent Teams Exception — narrowed by #1817). When Detection = No, every agent spawned via the Agent tool is treated as a subagent under the Core Rule by policy (even if a named spawn appears as a Teammate in `ListAgents`). Members spawn sub-agents or message peers only if `Agent`/`SendMessage` are available to them (directly or loadable via `ToolSearch`); otherwise the orchestrator relays via files and spawns on their behalf (R018 「멤버 도구 부재 시 대체 규약」).
1072
+
1056
1073
  <!-- DETAIL: Announcement Format
1057
1074
  ```
1058
1075
  [Routing] Using {routing-skill} for {task}
@@ -6,15 +6,19 @@
6
6
 
7
7
  | Tier | Tools | Policy |
8
8
  |------|-------|--------|
9
- | 1: Always | Read, Glob, Grep, ToolSearch | Free use, read-only |
9
+ | 1: Always | Read, Glob‡, Grep‡, ToolSearch§ | Free use, read-only |
10
10
  | 2: Default | Write, Edit, NotebookEdit | State changes explicitly, notify before modifying important files |
11
11
  | 3: Context | Agent, Skill, EnterPlanMode, ExitPlanMode, EnterWorktree, ExitWorktree, LSP, Monitor, TodoWrite†, AskUserQuestion, PushNotification | Context-dependent, no user approval needed |
12
12
  | 4: Approval | Bash, PowerShell, WebFetch, WebSearch | Request user approval on first use |
13
- | 5: Conditional | TeamCreate†, TeamDelete†, SendMessage, TaskCreate†, TaskGet†, TaskList†, TaskUpdate†, TaskStop | Available when Agent Teams enabled (TaskOutput 제거됨, v2.1.277+ — 아래 참조) |
13
+ | 5: Conditional | TeamCreate†, TeamDelete†, SendMessage, TaskCreate†, TaskGet†, TaskList†, TaskUpdate†, TaskStop | Available when Agent Teams enabled; `SendMessage` to a named agent also delivered without `TeamCreate` (CC 2.1.289 measured) (TaskOutput 제거됨, v2.1.277+ — 아래 참조) |
14
14
  | 6: MCP | ListMcpResourcesTool, ReadMcpResourceTool, CronCreate, CronDelete, CronList, RemoteTrigger | MCP/extension tools, available when servers configured |
15
15
 
16
16
  > **†** 현행 모델의 기본 실행 환경에 **존재하지 않는다** — 아래 v2.1.233 노트 참조. 이 표는 **도구 카탈로그**이지 가용성 보증이 아니므로, 규칙이 특정 도구 호출을 의무화하기 전에 실측(도구 목록 / `ToolSearch`)으로 존재를 확인한다.
17
17
 
18
+ > **‡** 네이티브 빌드(macOS/Linux)에서는 전용 `Glob`/`Grep`이 Bash 내장 `bfs`/`ugrep`으로 대체되고(CHANGELOG 2.1.117: "the `Glob` and `Grep` tools are replaced by embedded `bfs` and `ugrep` available through the Bash tool"), `--tools`로 명시하면 전용 도구가 제공된다(2.1.162: "explicitly listing Grep/Glob now provides the dedicated search tools on native builds with embedded search"). 실측(CC 2.1.289, 2026-10-05): frontmatter `tools:`에 Grep/Glob을 명시한 `qa-writer`는 전용 `Grep`/`Glob`을 받았고(Bash 없음), 명시 목록이 없는 메인 세션에는 없었다 — frontmatter 명시가 `--tools` 명시와 같은 효과라는 일반화는 이 1건에 근거한 추정이다. 전용 도구가 없으면 읽기 전용 Bash(`git grep`·`find`)로 대체한다(R005: 가용성 미확인 시 Bash 우선 #1307, 전수조사 `git grep` 표준 #1590). 이 대체는 Tier 1 작업을 Tier 4로 옮기므로 Tier 4 정책("Request user approval on first use")이 적용된다. Bash도, frontmatter에 명시된 해당 검색 도구도 없는 경우(예: `sys-naggy`는 Grep만 명시 — Glob 검색)에만 오케스트레이터가 사전 수집해 내용으로 전달한다(R010 「Known Limitations (Active Cache)」).
19
+
20
+ > **§** `ToolSearch`도 멤버 실행 환경에 없을 수 있다(#1817 QA teammate 관측) — 없으면 지연 도구를 로드할 수 없으므로 그 지연 도구는 부재로 취급한다(R018 「멤버 도구 부재 시 대체 규약」).
21
+
18
22
  ## File Access
19
23
 
20
24
  | Operation | Allowed | Prohibited |
@@ -147,6 +151,8 @@ CHANGELOG v2.1.233 원문: *"Todo/task-tracking tools (TaskCreate/Get/Update/Lis
147
151
  | 잔존 | `TaskStop`, `SendMessage` |
148
152
  | 제거됨 (v2.1.277+) | `TaskOutput` — background task output은 Read로 직접 읽는다; `taskOutputMaxChars`/`TASK_MAX_OUTPUT_LENGTH` 무효 |
149
153
 
154
+ 이 표(2026-08-15, `claude-opus-5[1m]`/`claude-sonnet-5`)는 2026-10-06 재측정 `claude-opus-5-5` 메인에서도 같았다 — haiku 팀원 1건은 `ToolSearch`로 `TaskCreate`/`TaskList`/`TaskUpdate`/`TaskGet`을 로드했고 sonnet-5-5 팀원 1건은 불가였으며, `TeamCreate`/`TeamDelete`는 측정한 셋 모두 불가였다(CC 2.1.289 실측).
155
+
150
156
  <!-- DETAIL: TaskOutput 2026-08-15 측정 당시 잔존 표기(v2.1.233 기준) — CC v2.1.277 CHANGELOG: "Removed the deprecated TaskOutput tool; Claude reads a background task's output file with Read instead, and the `taskOutputMaxChars` setting and `TASK_MAX_OUTPUT_LENGTH` no longer have any effect" Origin: #1714.
151
157
  -->
152
158
 
@@ -157,25 +163,24 @@ CHANGELOG v2.1.233 원문: *"Todo/task-tracking tools (TaskCreate/Get/Update/Lis
157
163
 
158
164
  `CLAUDE_CODE_ENABLE_TODO_TOOLS=1`은 복구 수단이나 **환경 설정 사안**이므로 규칙이 그 설정을 전제하지 않는다. 공식 settings 문서(`code.claude.com/docs/en/settings`)에는 2026-08-15 기준 미수록 — 현재 근거는 CHANGELOG 원문 + 위 실측이다.
159
165
 
160
- Origin: #1582. Cross-ref: R018(Member TaskUpdate Discipline 대체 규약), R020("도구가 있다"는 가정도 실측 대상).
166
+ Origin: #1582. Cross-ref: R018 「Task 도구 부재 시 대체 규약」(Member TaskUpdate Discipline 하위 절), R020("도구가 있다"는 가정도 실측 대상).
161
167
  -->
162
168
  `TeamCreate`/`TeamDelete`도 별도로 부재 — R018은 이 환경에서 비활성입니다(R018 Detection). 규칙은 **존재하지 않는 도구의 호출을 의무화하지 않으며**, 도구 의존 의무를 쓸 때는 부재 시 대체 규약을 함께 규정합니다(R018 Member TaskUpdate Discipline이 그 예). `CLAUDE_CODE_ENABLE_TODO_TOOLS=1`은 환경 설정 사안이므로 규칙이 전제하지 않습니다. Origin: #1582.
163
169
 
164
170
  ## Agent Tool Permission Mode
165
171
 
166
- > Canonical source: R010 (MUST-orchestrator-coordination.md) "Universal bypassPermissions" owns the full requirement, rationale, self-check, and version history. Core rule: always pass `mode: "bypassPermissions"` explicitly on every Agent tool call — the Agent tool's default `mode` (`acceptEdits`) overrides agent frontmatter `permissionMode` and causes prompts during unattended execution. Skills that spawn agents MUST include this in their Agent tool call instructions. See R010 for details.
167
-
168
- **주의**: v2.1.212+부터 `mode` 파라미터는 무시되며 유효 모드는 부모 세션이 결정합니다 — 실측은 R010 Self-Check를 참조합니다.
172
+ > Canonical source: R010 (MUST-orchestrator-coordination.md) "Universal bypassPermissions" owns the guidance, self-check, and version history. Core: below CC 2.1.212, per-call `mode: "bypassPermissions"` is required (the Agent tool's default `acceptEdits` overrides frontmatter `permissionMode`); from 2.1.212 it is ignored and subagents inherit the parent session's mode, which frontmatter `permissionMode` may override. Keep passing `mode` for compatibility, but measure the effective mode before unattended runs (R010 Self-Check 1).
169
173
 
170
174
  <!-- DETAIL: Agent tool mode deprecation rationale (canonical: R010)
171
175
  > **v2.1.212+**: CC가 Agent(구 Task) tool의 `mode` 파라미터를 deprecated 처리했습니다(이제 무시) — subagent는 부모 세션의 permission mode를 기본 상속합니다. 위 canonical 요약의 default `mode`(`acceptEdits`)가 frontmatter `permissionMode`를 override한다는 서술 및 항상 `mode: "bypassPermissions"`를 넘기라는 요건은 이 버전부터 stale이며(파라미터가 무시됨), 무인 실행의 실질 게이트는 부모 세션의 permission mode입니다. 요건 재조정은 R010 "Universal bypassPermissions"가 canonical — R002는 이 flag만 유지합니다.
172
176
  -->
173
177
 
174
178
  <!-- DETAIL: defaultMode project-scope-ignored rationale (canonical: R010)
175
- > **v2.1.257+**: 프로젝트 scope `permissions.defaultMode` 가 무시됩니다(user/managed scope 또는
176
- > `--permission-mode` 플래그만 유효). 위 v2.1.212 노트가 "무인 실행의 실질 게이트는 부모 세션의
177
- > permission mode"라고 정정했는데, **그 부모 세션 모드를 프로젝트 settings로 지정하는 경로가 이
178
- > 버전에서 끊겼습니다** — 이 파일 상단 「Deny Rule Glob Patterns」의 v2.1.214 노트(allow 규칙만
179
+ > **v2.1.257+**: `.claude/settings.json`·`.claude/settings.local.json`의 `defaultMode: "bypassPermissions"`
180
+ > 값이 `"auto"`처럼 무시됩니다(CHANGELOG 2.1.257 — 다른 값은 이 항목의 대상이 아님; bypass는 user/managed
181
+ > settings 또는 `--permission-mode`로 지정). 위 v2.1.212 노트가 "무인 실행의 실질 게이트는 부모 세션의
182
+ > permission mode"라고 정정했는데, **그 부모 세션 모드를 프로젝트 settings로 `bypassPermissions`로
183
+ > 지정하는 경로가 이 버전에서 끊겼습니다** — 이 파일 상단 「Deny Rule Glob Patterns」의 v2.1.214 노트(allow 규칙만
179
184
  > `<cwd>`로 좁아진 비대칭)와 같은 계열의 **project-scope 축소** 흐름입니다. Canonical owner 는
180
185
  > R010 "Universal bypassPermissions" — 상세와 실측 절차는 그쪽을 참조합니다. Origin: #1644.
181
186
  -->
@@ -1,7 +1,4 @@
1
1
  {
2
- "permissions": {
3
- "defaultMode": "default"
4
- },
5
2
  "hooks": {
6
3
  "PreToolUse": [
7
4
  {
@@ -109,11 +109,11 @@ When a synthesized harness exists for an agent (`.claude/outputs/harnesses/{agen
109
109
 
110
110
  ### Tool: Writing artifacts under .claude/outputs/
111
111
 
112
- Under `mode: "bypassPermissions"`, direct Write/Edit/Bash on `.claude/**` paths is permitted (CC v2.1.121+, #1101) — no `/tmp/*.sh` wrapping is needed.
112
+ Under the `bypassPermissions` permission mode, direct Write/Edit/Bash on `.claude/**` paths is permitted (CC v2.1.121+, #1101) — no `/tmp/*.sh` wrapping is needed.
113
113
 
114
114
  To write action-validator results under `.claude/outputs/sessions/`:
115
115
 
116
- 1. Write the artifact body directly to `.claude/outputs/sessions/$(date +%Y-%m-%d)/action-validator-$(date +%H%M%S).md` with the Write tool (every Agent tool call includes `mode: "bypassPermissions"`, R010)
116
+ 1. Write the artifact body directly to `.claude/outputs/sessions/$(date +%Y-%m-%d)/action-validator-$(date +%H%M%S).md` with the Write tool (under the `bypassPermissions` permission mode, R010)
117
117
  2. Read-only Bash on `.claude/outputs/` (e.g., `cat`, `head`, `wc`) is allowed for verification
118
118
 
119
119
  Reference: R006/R010 sensitive-path handling (CC v2.1.121+), #1101.
@@ -187,11 +187,11 @@ Append a record to `.claude/outputs/harness-adaptations/YYYY-MM-DD.md`:
187
187
 
188
188
  ### Tool: Writing artifacts under .claude/outputs/
189
189
 
190
- Under `mode: "bypassPermissions"`, direct Write/Edit/Bash on `.claude/**` paths is permitted (CC v2.1.121+, #1101) — no `/tmp/*.sh` wrapping is needed.
190
+ Under the `bypassPermissions` permission mode, direct Write/Edit/Bash on `.claude/**` paths is permitted (CC v2.1.121+, #1101) — no `/tmp/*.sh` wrapping is needed.
191
191
 
192
192
  To write adaptive-harness results under `.claude/outputs/`:
193
193
 
194
- 1. Write the artifact body directly to `.claude/outputs/harness-adaptations/$(date +%Y-%m-%d).md` with the Write tool (every Agent tool call includes `mode: "bypassPermissions"`, R010)
194
+ 1. Write the artifact body directly to `.claude/outputs/harness-adaptations/$(date +%Y-%m-%d).md` with the Write tool (under the `bypassPermissions` permission mode, R010)
195
195
  2. Read-only Bash on `.claude/outputs/` (e.g., `cat`, `head`, `wc`) is allowed for verification
196
196
 
197
197
  Reference: R006/R010 sensitive-path handling (CC v2.1.121+), #1101.
@@ -102,4 +102,4 @@ Refs: #1171 (CRG 통합), #1180 (본 cross-ref 추가)
102
102
 
103
103
  ## Permission Mode
104
104
 
105
- When spawning agents via the Agent tool during this skill's execution, always pass `mode: "bypassPermissions"`. The Agent tool default (`acceptEdits`) overrides agent frontmatter `permissionMode`, causing permission prompts during unattended execution.
105
+ Pass `mode: "bypassPermissions"` on Agent calls for compatibility: it is required on CC < 2.1.212 (the per-call default, `acceptEdits`, overrides agent frontmatter `permissionMode`) and ignored on 2.1.212+, where subagents inherit the parent session's permission mode (adjustable via agent frontmatter `permissionMode`). Verify the effective mode before unattended runs: see R010 "Universal bypassPermissions".
@@ -75,11 +75,11 @@ Use this taxonomy to **select representative tasks per category** when building
75
75
 
76
76
  ### Tool: Writing artifacts under .claude/outputs/
77
77
 
78
- Under `mode: "bypassPermissions"`, direct Write/Edit/Bash on `.claude/**` paths is permitted (CC v2.1.121+, #1101) — no `/tmp/*.sh` wrapping is needed.
78
+ Under the `bypassPermissions` permission mode, direct Write/Edit/Bash on `.claude/**` paths is permitted (CC v2.1.121+, #1101) — no `/tmp/*.sh` wrapping is needed.
79
79
 
80
80
  To write eval trajectories or result reports under `.claude/outputs/evals/`:
81
81
 
82
- 1. Write the artifact body directly to `.claude/outputs/evals/{trajectories,sessions}/...` with the Write tool (every Agent tool call includes `mode: "bypassPermissions"`, R010)
82
+ 1. Write the artifact body directly to `.claude/outputs/evals/{trajectories,sessions}/...` with the Write tool (under the `bypassPermissions` permission mode, R010)
83
83
  2. Read-only Bash on `.claude/outputs/` (e.g., `cat`, `head`, `wc`) is allowed for verification
84
84
 
85
85
  Reference: R006/R010 sensitive-path handling (CC v2.1.121+), #1101.