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.
- package/dist/cli/index.js +449 -40
- package/dist/index.js +95 -5
- package/package.json +1 -1
- package/templates/.claude/output-styles/korean-engineer.md +1 -1
- package/templates/.claude/rules/MUST-agent-design.md +2 -2
- package/templates/.claude/rules/MUST-agent-teams.md +18 -7
- package/templates/.claude/rules/MUST-orchestrator-coordination.md +46 -29
- package/templates/.claude/rules/MUST-permissions.md +15 -10
- package/templates/.claude/settings.json +0 -3
- package/templates/.claude/skills/action-validator/SKILL.md +2 -2
- package/templates/.claude/skills/adaptive-harness/SKILL.md +2 -2
- package/templates/.claude/skills/adversarial-review/SKILL.md +1 -1
- package/templates/.claude/skills/agent-eval-framework/SKILL.md +2 -2
- package/templates/.claude/skills/de-lead-routing/SKILL.md +2 -2
- package/templates/.claude/skills/deep-plan/SKILL.md +4 -4
- package/templates/.claude/skills/deep-verify/SKILL.md +3 -3
- package/templates/.claude/skills/design-shotgun/SKILL.md +1 -1
- package/templates/.claude/skills/dev-lead-routing/SKILL.md +2 -2
- package/templates/.claude/skills/dev-review/SKILL.md +2 -2
- package/templates/.claude/skills/evaluator-optimizer/SKILL.md +1 -1
- package/templates/.claude/skills/fsd/SKILL.md +48 -10
- package/templates/.claude/skills/harness-eval/SKILL.md +1 -1
- package/templates/.claude/skills/harness-synthesizer/SKILL.md +1 -1
- package/templates/.claude/skills/homework/SKILL.md +3 -3
- package/templates/.claude/skills/idea/SKILL.md +4 -2
- package/templates/.claude/skills/instinct-extractor/SKILL.md +8 -8
- package/templates/.claude/skills/intent-detection/SKILL.md +1 -1
- package/templates/.claude/skills/multi-model-verification/SKILL.md +2 -2
- package/templates/.claude/skills/omcustom-release-notes/SKILL.md +1 -1
- package/templates/.claude/skills/pipeline/SKILL.md +1 -1
- package/templates/.claude/skills/pipeline/scripts/trusted-issue-filter.jq +37 -0
- package/templates/.claude/skills/pipeline/workflows/auto-dev.yaml +128 -38
- package/templates/.claude/skills/post-release-followup/SKILL.md +2 -2
- package/templates/.claude/skills/professor-triage/SKILL.md +10 -10
- package/templates/.claude/skills/profile/SKILL.md +4 -4
- package/templates/.claude/skills/qa-lead-routing/SKILL.md +2 -2
- package/templates/.claude/skills/release-plan/SKILL.md +1 -1
- package/templates/.claude/skills/research/SKILL.md +8 -6
- package/templates/.claude/skills/result-aggregation/SKILL.md +1 -1
- package/templates/.claude/skills/roundtable-debate/SKILL.md +2 -2
- package/templates/.claude/skills/scout/SKILL.md +3 -8
- package/templates/.claude/skills/sec-agentshield-wrapper/SKILL.md +1 -1
- package/templates/.claude/skills/secretary-routing/SKILL.md +2 -2
- package/templates/.claude/skills/skill-extractor/SKILL.md +1 -1
- package/templates/.claude/skills/structured-dev-cycle/SKILL.md +1 -1
- package/templates/.claude/skills/task-decomposition/SKILL.md +1 -1
- package/templates/.claude/skills/worker-reviewer-pipeline/SKILL.md +5 -1
- package/templates/guides/claude-code/15-version-compatibility.md +20 -4
- package/templates/guides/deep-plan/phases.md +11 -9
- package/templates/guides/harness-engineering/README.md +2 -1
- package/templates/guides/professor-triage/README.md +1 -1
- package/templates/guides/professor-triage/phases.md +1 -1
- package/templates/manifest.json +1 -1
- 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.
|
|
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
|
@@ -56,7 +56,7 @@ ecomode 활성 시 자동으로 concise 모드로 전환 (R013).
|
|
|
56
56
|
|
|
57
57
|
## 위임 모델 (R010)
|
|
58
58
|
|
|
59
|
-
오케스트레이터(메인 대화)는 파일 수정 금지 → 서브에이전트에 위임. Agent
|
|
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
|
|
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,
|
|
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`(
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
600
|
-
1. **유효 permission mode
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
(
|
|
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? →
|
|
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
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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+**:
|
|
176
|
-
>
|
|
177
|
-
> permission
|
|
178
|
-
>
|
|
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
|
-->
|
|
@@ -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
|
|
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 (
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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.
|