all-for-claudecode 2.8.1 → 2.9.0

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.
@@ -6,14 +6,14 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Automated pipeline for Claude Code — spec → plan → implement → review → clean",
9
- "version": "2.8.1"
9
+ "version": "2.9.0"
10
10
  },
11
11
  "plugins": [
12
12
  {
13
13
  "name": "afc",
14
14
  "source": "./",
15
15
  "description": "Automated pipeline for Claude Code. Automates the full development cycle: spec → plan → implement → review → clean.",
16
- "version": "2.8.1",
16
+ "version": "2.9.0",
17
17
  "category": "automation",
18
18
  "tags": ["pipeline", "automation", "spec", "plan", "implement", "review", "critic-loop"]
19
19
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "afc",
3
- "version": "2.8.1",
3
+ "version": "2.9.0",
4
4
  "description": "Automated pipeline for Claude Code. Automates the full development cycle: spec → plan → implement → review → clean.",
5
5
  "author": { "name": "jhlee0409", "email": "relee6203@gmail.com" },
6
6
  "homepage": "https://github.com/jhlee0409/all-for-claudecode",
@@ -23,12 +23,10 @@ model: sonnet
23
23
 
24
24
  ## Config Load
25
25
 
26
- **Always** read `.claude/afc.config.md` first. This file contains free-form markdown sections:
27
- - `## Architecture` architecture pattern, layers, import rules (primary reference for structural analysis)
28
- - `## Code Style` — language, naming conventions, lint rules
29
- - `## Project Context` — framework, state management, testing, etc.
26
+ Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
27
+ Read `.claude/afc.config.md` if CI commands are needed.
30
28
 
31
- If config file is missing: read `CLAUDE.md` for architecture info. Proceed without config if neither exists.
29
+ If neither rules file nor config exists: read `CLAUDE.md` for architecture info. Proceed without config if neither exists.
32
30
 
33
31
  ## Execution Steps
34
32
 
@@ -26,12 +26,10 @@ model: sonnet
26
26
 
27
27
  ## Config Load
28
28
 
29
- **Always** read `.claude/afc.config.md` first. This file contains free-form markdown sections:
30
- - `## Architecture` architecture pattern, layers, import rules (primary reference for this command)
31
- - `## Code Style` — language, naming conventions, lint rules
32
- - `## Project Context` — framework, state management, testing, etc.
29
+ Read `.claude/afc.config.md` if CI commands are needed.
30
+ Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
33
31
 
34
- If config file is missing: read `CLAUDE.md` for architecture info. Assume "Layered Architecture" if neither source has it.
32
+ If neither rules file nor config exists: read `CLAUDE.md` for architecture info. Assume "Layered Architecture" if no source has it.
35
33
 
36
34
  ## Execution Steps
37
35
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: afc:consult
3
- description: "Expert consultation — use when the user asks for expert advice, wants to consult a specialist, or needs domain-specific guidance on backend, infra, PM, design, marketing, legal, or tech decisions"
3
+ description: "Expert consultation — use when the user asks for expert advice, wants to consult a specialist, needs domain-specific guidance on backend, infra, PM, design, marketing, legal, or tech decisions, or wants to think together, brainstorm, discuss ideas, or have a structured dialogue"
4
4
  argument-hint: "[domain?] \"[question]\" [brief|deep]"
5
5
  model: sonnet
6
6
  ---
@@ -14,7 +14,7 @@ model: sonnet
14
14
  ## Arguments
15
15
 
16
16
  - `$ARGUMENTS` — (optional) Format: `[domain] "[question]" [brief|deep]`
17
- - `domain` — one of: `backend`, `infra`, `pm`, `design`, `marketing`, `legal`, `security`, `advisor` (optional, auto-detected if omitted)
17
+ - `domain` — one of: `backend`, `infra`, `pm`, `design`, `marketing`, `legal`, `security`, `advisor`, `peer` (optional, auto-detected if omitted)
18
18
  - `question` — the consultation question (optional, enters exploratory mode if omitted)
19
19
  - `brief|deep` — depth hint (optional, default: `auto`)
20
20
 
@@ -45,6 +45,7 @@ If `$ARGUMENTS` is empty → go to Step 2 (domain selection).
45
45
  | legal | GDPR, CCPA, privacy, cookie, consent, license, GPL, MIT, compliance, terms of service, data protection, PII, HIPAA, regulation, policy |
46
46
  | security | XSS, CSRF, injection, OWASP, vulnerability, attack, exploit, encryption, secret, credential, CORS, CSP, rate limit, brute force, penetration |
47
47
  | advisor | library, framework, stack, tool, package, which to use, alternative, compare, choose, select, recommend, what exists, ecosystem, best option, switch to |
48
+ | peer | think together, brainstorm, discuss, explore idea, talk through, figure out, pros and cons, what if, should I, direction, approach, trade-off, opinion, weigh options |
48
49
 
49
50
  Match rules:
50
51
  - Case-insensitive keyword matching against the question
@@ -65,9 +66,79 @@ Options:
65
66
  6. Legal — GDPR, privacy, licenses, compliance, terms of service
66
67
  7. Security — application security, OWASP, threat modeling, secure coding
67
68
  8. Advisor — technology/library/framework selection, ecosystem navigation, stack decisions
69
+ 9. Peer — think together, brainstorm, discuss ideas, explore directions as equals
68
70
  ```
69
71
 
70
- ### 3. Construct Expert Prompt
72
+ ### 3. Peer Mode (if domain is `peer`)
73
+
74
+ If the detected domain is `peer`, **do not delegate to a subagent**. Run the dialogue directly in the main context.
75
+
76
+ #### Behavior Principles
77
+
78
+ You are a thinking partner, not an expert giving answers. Follow these rules:
79
+
80
+ 1. **Ask before answering.** Default to questions that deepen the user's thinking, not solutions. "What would happen if...?", "What are you optimizing for?"
81
+ 2. **Challenge, don't agree.** Apply the Anti-Sycophancy Rules from `expert-protocol.md`. When the user states a direction, probe its weaknesses before supporting it.
82
+ 3. **Present the strongest counter-argument.** Steel-man the opposing view: "The best case for NOT doing this is..."
83
+ 4. **Name what's been decided and what hasn't.** Periodically summarize: "So far we've landed on X. Still open: Y and Z."
84
+ 5. **Suggest convergence, don't force it.** When the discussion feels circular or key decisions are made, say so: "I think we have enough to move forward. Want to wrap up?"
85
+
86
+ #### Coaching Techniques
87
+
88
+ Use these as appropriate — not all at once, not in order:
89
+
90
+ - **5 Whys** — repeat "why?" to reach the root motivation
91
+ - **Pre-mortem** — "If this fails in 6 months, what went wrong?"
92
+ - **Constraint flip** — "What if you had half the time?" / "What if cost didn't matter?"
93
+ - **Steel-manning** — present the strongest version of the opposing view
94
+ - **Bisection** — "Is the core question A or B?" to narrow scope
95
+
96
+ #### Codebase Context
97
+
98
+ If the discussion involves the current project:
99
+ - Read relevant files (Read/Glob/Grep) to ground the conversation in reality
100
+ - Reference actual code, not hypothetical structures
101
+ - Note existing patterns that constrain or enable options
102
+
103
+ #### Wrapping Up
104
+
105
+ When the user signals completion (or agrees to your convergence suggestion):
106
+
107
+ 1. Write `.claude/afc/discuss.md` with:
108
+
109
+ ```markdown
110
+ # Discussion: {topic}
111
+
112
+ > Date: {YYYY-MM-DD}
113
+ > Seed: {original question/topic}
114
+
115
+ ## Key Decisions
116
+ - [DECIDED] {decision} — {rationale}
117
+
118
+ ## Open Questions
119
+ - [OPEN] {unresolved item}
120
+
121
+ ## Summary
122
+ {3-5 sentence synthesis of what was discussed and concluded}
123
+
124
+ ## Next Steps
125
+ - {recommended action, e.g., → /afc:spec "...", → /afc:plan "...", → /afc:research "..."}
126
+ ```
127
+
128
+ 2. Output:
129
+ ```
130
+ Discussion complete
131
+ ├─ .claude/afc/discuss.md
132
+ ├─ Decisions: {count}
133
+ ├─ Open questions: {count}
134
+ └─ Suggested next: {command}
135
+ ```
136
+
137
+ **Skip Steps 4-6 and end here.**
138
+
139
+ ---
140
+
141
+ ### 3b. Construct Expert Prompt (non-peer domains)
71
142
 
72
143
  Build the prompt for the expert agent:
73
144
 
@@ -146,6 +217,12 @@ Follow-up options:
146
217
  # With depth hint
147
218
  /afc:consult infra "How should I set up CI/CD?" deep
148
219
 
220
+ # Peer mode — think together (explicit)
221
+ /afc:consult peer "Should we split this into a monorepo or keep it separate?"
222
+
223
+ # Peer mode — auto-detected from keywords
224
+ /afc:consult "Let's think through the onboarding flow together"
225
+
149
226
  # No arguments (domain selection prompt)
150
227
  /afc:consult
151
228
  ```
@@ -158,3 +235,4 @@ Follow-up options:
158
235
  - **Domain adapters**: Industry-specific guardrails (fintech, ecommerce, healthcare) auto-loaded based on project profile.
159
236
  - **Pipeline-independent**: Works anytime, no active pipeline required. If a pipeline is active, experts consider the current phase context.
160
237
  - **Cross-referral**: Experts may suggest consulting another domain expert when a question crosses boundaries.
238
+ - **Peer mode**: Unlike other domains, `peer` runs directly in the main context (no subagent). It produces `.claude/afc/discuss.md` on wrap-up. Overwritten on each new peer session — rename to preserve.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: afc:doctor
3
- description: "Diagnose project health and plugin setup — use when the user asks for a health check, wants to diagnose project issues, or verify plugin installation"
3
+ description: "Diagnose afc plugin setup and configuration — use when the user asks for a health check, wants to verify plugin installation, or check if afc is properly configured"
4
4
  argument-hint: "[--verbose]"
5
5
  allowed-tools:
6
6
  - Read
@@ -10,10 +10,13 @@ allowed-tools:
10
10
  model: haiku
11
11
  ---
12
12
 
13
- # /afc:doctor — Project Health Diagnosis
13
+ # /afc:doctor — Plugin Setup Diagnosis
14
14
 
15
- > Runs a comprehensive health check on the all-for-claudecode setup for the current project.
15
+ > Checks whether the all-for-claudecode plugin is correctly installed and configured in the current project.
16
+ > Like `brew doctor` or `flutter doctor` — verifies the **tool's setup**, NOT the project's code quality.
16
17
  > Read-only — never modifies files. Reports issues with actionable fix commands.
18
+ >
19
+ > **IMPORTANT: Do NOT analyze project source code, architecture, or code quality. Only check afc plugin configuration, hooks, state, and environment as defined in the check tables below.**
17
20
 
18
21
  ## Arguments
19
22
 
@@ -32,136 +35,21 @@ Each failing check includes a **Fix:** line with the exact command to resolve it
32
35
 
33
36
  ---
34
37
 
35
- ## Checks
36
-
37
- Run ALL checks regardless of earlier failures. Do not short-circuit.
38
-
39
- ### Category 1: Environment
40
-
41
- | Check | How | Pass | Fail |
42
- |-------|-----|------|------|
43
- | git installed | `which git` | git found in PATH | Fix: install git |
44
- | jq installed | `which jq` | jq found in PATH | ⚠ Warning: jq not found. Hook scripts will use grep/sed fallback (slower, less reliable). Fix: `brew install jq` or `apt install jq` |
45
-
46
- ### Category 2: Project Config
47
-
48
- | Check | How | Pass | Fail |
49
- |-------|-----|------|------|
50
- | Config file exists | Read `.claude/afc.config.md` | File exists | Fix: run `/afc:init` |
51
- | Required sections present | Grep for `## CI Commands`, `## Architecture`, `## Code Style` | All 3 sections found | Fix: add missing section to `.claude/afc.config.md` or re-run `/afc:init` |
52
- | Gate command defined | Grep for `gate:` inside `## CI Commands` section | `gate:` field found | Fix: add `gate:` field to `## CI Commands` section |
53
- | CI command runnable | Extract CI command from config, run it | Exits 0 | ⚠ Warning: CI command failed. Check `{config.ci}` in afc.config.md |
54
- | Gate command runnable | Extract gate command from config, run it | Exits 0 | ⚠ Warning: gate command failed. Check `{config.gate}` in afc.config.md |
55
-
56
- ### Category 3: CLAUDE.md Integration
57
-
58
- | Check | How | Pass | Fail |
59
- |-------|-----|------|------|
60
- | Global CLAUDE.md exists | Read `~/.claude/CLAUDE.md` | File exists | ⚠ Warning: no global CLAUDE.md. all-for-claudecode skills won't auto-trigger from intent. Fix: run `/afc:init` |
61
- | all-for-claudecode block present | Grep for `<!-- AFC:START -->` and `<!-- AFC:END -->` in `~/.claude/CLAUDE.md` | Both markers found | Fix: run `/afc:init` to inject all-for-claudecode block |
62
- | all-for-claudecode block version | Extract version from `<!-- AFC:VERSION:X.Y.Z -->` in CLAUDE.md. Read `${CLAUDE_PLUGIN_ROOT}/package.json` (`.version`) to get the actual plugin version. Compare the two. | Block version = plugin version | ⚠ Warning: all-for-claudecode block is outdated (found {block_version}, current {plugin_version}). Fix: run `/afc:init` to update |
63
- | No conflicting routing | Grep for conflicting agent patterns (`executor`, `deep-executor`, `debugger`, `code-reviewer`) outside all-for-claudecode block that could intercept afc intents | No conflicts or conflicts are inside other tool blocks | ⚠ Warning: found agent routing that may conflict with afc skills. Review `~/.claude/CLAUDE.md` |
64
-
65
- ### Category 4: Legacy Migration (v1.x → v2.0)
66
-
67
- > Detects leftover artifacts from the old `selfish-pipeline` (v1.x) plugin. If none found, print `✓ No legacy artifacts` and skip this category.
68
-
69
- | Check | How | Pass | Fail |
70
- |-------|-----|------|------|
71
- | No legacy CLAUDE.md block | Grep `~/.claude/CLAUDE.md` for `<!-- SELFISH:START -->` | Marker not found | ⚠ Warning: legacy `SELFISH:START` block found in `~/.claude/CLAUDE.md`. Fix: run `/afc:init` (will replace with all-for-claudecode block) |
72
- | No legacy config file | Check `.claude/selfish.config.md` | File does not exist | ⚠ Warning: legacy config `.claude/selfish.config.md` found. Fix: `mv .claude/selfish.config.md .claude/afc.config.md` |
73
- | No legacy state files | Glob `.claude/.selfish-*` | No files found | ⚠ Warning: legacy state files `.claude/.selfish-*` found. Fix: `cd .claude && for f in .selfish-*; do mv "$f" "${f/.selfish-/.afc-}"; done` |
74
- | No legacy artifact dir | Check `.claude/selfish/` directory | Directory does not exist | ⚠ Warning: legacy artifact directory `.claude/selfish/` found. Fix: `mv .claude/selfish .claude/afc` |
75
- | No legacy git tags | `git tag -l 'selfish/pre-*' 'selfish/phase-*'` | No tags found | ⚠ Warning: legacy git tags found. Fix: `git tag -l 'selfish/*' \| xargs git tag -d` |
76
- | No legacy plugin installed | Check if `selfish@selfish-pipeline` appears in installed plugins (grep settings.json for `selfish-pipeline`) | Not found | ⚠ Warning: old `selfish-pipeline` plugin still installed. Fix: `claude plugin uninstall selfish@selfish-pipeline && claude plugin marketplace remove jhlee0409/selfish-pipeline` |
77
-
78
- ### Category 5: Pipeline State
79
-
80
- | Check | How | Pass | Fail |
81
- |-------|-----|------|------|
82
- | No stale pipeline state | Check `.claude/.afc-state.json` via `afc-pipeline-manage.sh status` | File does not exist (no active pipeline) | ⚠ Warning: stale pipeline state found (feature: {name}, phase: {phase}). This may block normal operations. Fix: `"${CLAUDE_PLUGIN_ROOT}/scripts/afc-pipeline-manage.sh" end --force` or run `/afc:resume` |
83
- | No orphaned artifacts | Glob `.claude/afc/specs/*/spec.md` | No specs directories, or all are from active pipeline | ⚠ Warning: orphaned `.claude/afc/specs/{name}/` found. Left over from a previous pipeline. Fix: `rm -rf .claude/afc/specs/{name}/` |
84
- | No lingering safety tags | `git tag -l 'afc/pre-*'` | No tags, or tags match active pipeline | ⚠ Warning: lingering safety tag `afc/pre-{x}` found. Fix: `git tag -d afc/pre-{x}` |
85
- | Checkpoint state | Read `.claude/afc/memory/checkpoint.md` if exists | No checkpoint (clean), or checkpoint is from current session | ⚠ Warning: stale checkpoint from {date}. Fix: run `/afc:resume` to continue or delete `.claude/afc/memory/checkpoint.md` |
86
-
87
- ### Category 6: Memory Health
88
-
89
- > Checks `.claude/afc/memory/` subdirectory sizes and agent memory file sizes. If memory directory does not exist, print `✓ No memory directory` and skip this category.
90
-
91
- | Check | How | Pass | Fail |
92
- |-------|-----|------|------|
93
- | quality-history count | Count files in `.claude/afc/memory/quality-history/` | ≤ 30 files | ⚠ Warning: {N} files in quality-history/ (threshold: 30). Oldest files should be pruned. Fix: run a pipeline with `/afc:auto` (Clean phase auto-prunes) or manually delete oldest files |
94
- | reviews count | Count files in `.claude/afc/memory/reviews/` | ≤ 40 files | ⚠ Warning: {N} files in reviews/ (threshold: 40). Fix: run a pipeline or manually delete oldest files |
95
- | retrospectives count | Count files in `.claude/afc/memory/retrospectives/` | ≤ 30 files | ⚠ Warning: {N} files in retrospectives/ (threshold: 30). Fix: run a pipeline or manually delete oldest files |
96
- | research count | Count files in `.claude/afc/memory/research/` | ≤ 50 files | ⚠ Warning: {N} files in research/ (threshold: 50). Fix: run a pipeline or manually delete oldest files |
97
- | decisions count | Count files in `.claude/afc/memory/decisions/` | ≤ 60 files | ⚠ Warning: {N} files in decisions/ (threshold: 60). Fix: run a pipeline or manually delete oldest files |
98
- | afc-architect MEMORY.md size | Count lines in `.claude/agent-memory/afc-architect/MEMORY.md` (if exists) | ≤ 100 lines | ⚠ Warning: afc-architect MEMORY.md is {N} lines (limit: 100). Fix: invoke `/afc:architect` to trigger self-pruning, or manually edit the file |
99
- | afc-security MEMORY.md size | Count lines in `.claude/agent-memory/afc-security/MEMORY.md` (if exists) | ≤ 100 lines | ⚠ Warning: afc-security MEMORY.md is {N} lines (limit: 100). Fix: invoke `/afc:security` to trigger self-pruning, or manually edit the file |
100
-
101
- ### Category 7: Hook Health
102
-
103
- | Check | How | Pass | Fail |
104
- |-------|-----|------|------|
105
- | hooks.json valid | Parse plugin's hooks.json with jq (or manual validation) | Valid JSON with `hooks` key | ✗ Fix: reinstall plugin — `claude plugin install afc@all-for-claudecode` |
106
- | All scripts exist | For each script referenced in hooks.json, check file exists | All scripts found | ✗ Fix: reinstall plugin |
107
- | Scripts executable | Check execute permission on each script in plugin's scripts/ | All have +x | Fix: `chmod +x` on the missing scripts, or reinstall plugin |
108
-
109
- ### Category 8: Version Sync (development only)
110
-
111
- > Only run if current directory is the all-for-claudecode source repo (check for `package.json` with `"name": "all-for-claudecode"`).
112
-
113
- | Check | How | Pass | Fail |
114
- |-------|-----|------|------|
115
- | Version triple match | Compare versions in `package.json` (`.version`), `.claude-plugin/plugin.json` (`.version`), `.claude-plugin/marketplace.json` (`.metadata.version` and `.plugins[0].version`) | All identical | ✗ Fix: update mismatched files to the same version |
116
- | Cache in sync | Compare `commands/auto.md` content between source and `~/.claude/plugins/cache/all-for-claudecode/afc/{version}/commands/auto.md` | Content matches | ⚠ Warning: plugin cache is stale. Fix: copy source files to cache directory |
117
-
118
- ### Category 9: Command Definitions (development only)
119
-
120
- > Only run if current directory is the all-for-claudecode source repo (same condition as Category 8).
121
-
122
- | Check | How | Pass | Fail |
123
- |-------|-----|------|------|
124
- | Frontmatter exists | Each `commands/*.md` file has opening and closing `---` block | All files have frontmatter | ✗ Fix: add YAML frontmatter block to `commands/{file}.md` |
125
- | Required fields | Each command frontmatter contains `name:` and `description:` | All files have both fields | ✗ Fix: add missing `name:` or `description:` to `commands/{file}.md` |
126
- | Name-filename match | `name:` value follows `afc:{filename}` pattern (e.g. `auto.md` → `name: afc:auto`) | All names match filenames | ✗ Fix: rename `name:` field in `commands/{file}.md` to `afc:{filename}` |
127
- | Fork-agent reference | Commands with `context: fork` and `agent:` field reference a file that exists in `agents/` (e.g. `agent: afc-architect` → `agents/afc-architect.md` exists) | All agent references resolve | ✗ Fix: create missing agent file `agents/{name}.md` or fix `agent:` field in `commands/{file}.md` |
128
-
129
- ### Category 10: Agent Definitions (development only)
130
-
131
- > Only run if current directory is the all-for-claudecode source repo (same condition as Category 8).
132
-
133
- | Check | How | Pass | Fail |
134
- |-------|-----|------|------|
135
- | Frontmatter exists | Each `agents/*.md` file has opening and closing `---` block | All files have frontmatter | ✗ Fix: add YAML frontmatter block to `agents/{file}.md` |
136
- | Required fields | Each agent frontmatter contains `name:`, `description:`, and `model:` | All files have all 3 fields | ✗ Fix: add missing field to `agents/{file}.md` |
137
- | Name-filename match | `name:` value equals the filename without extension (e.g. `afc-architect.md` → `name: afc-architect`) | All names match filenames | ✗ Fix: rename `name:` field in `agents/{file}.md` to match filename |
138
- | Expert memory | All 8 expert consultation agents (`afc-backend-expert`, `afc-infra-expert`, `afc-pm-expert`, `afc-design-expert`, `afc-marketing-expert`, `afc-legal-expert`, `afc-appsec-expert`, `afc-tech-advisor`) have `memory: project` | All experts have memory field | ✗ Fix: add `memory: project` to `agents/{name}.md` frontmatter |
139
- | Worker maxTurns | `afc-impl-worker` and `afc-pr-analyst` have `maxTurns:` field | Both workers have maxTurns | ✗ Fix: add `maxTurns:` to `agents/{name}.md` frontmatter |
140
-
141
- ### Category 11: Doc References (development only)
142
-
143
- > Only run if current directory is the all-for-claudecode source repo (same condition as Category 8).
144
-
145
- | Check | How | Pass | Fail |
146
- |-------|-----|------|------|
147
- | Referenced docs exist | Scan commands and agents for file references to `docs/` (e.g. `docs/critic-loop-rules.md`, `docs/phase-gate-protocol.md`). Each referenced file must exist. | All referenced docs found | ✗ Fix: create missing `docs/{file}.md` or fix the reference |
148
- | Domain adapters exist | `docs/domain-adapters/` directory contains at least one `.md` file | ≥ 1 adapter file found | ✗ Fix: add domain adapter files to `docs/domain-adapters/` |
149
-
150
- ---
151
-
152
38
  ## Execution
153
39
 
154
- 1. Run the automated health check script:
40
+ 1. Run the health check script (covers ALL categories — no manual checks needed):
155
41
  ```
156
42
  "${CLAUDE_PLUGIN_ROOT}/scripts/afc-doctor.sh" $ARGUMENTS
157
43
  ```
158
- This covers Categories 1-8 automatically.
159
44
 
160
- 2. Print the script's stdout output as-is (already formatted with pass/warn/fail markers).
45
+ 2. Print the script's stdout output as-is. Do not reformat, summarize, or interpret.
161
46
 
162
- 3. If in the source repo (package.json `name` = `"all-for-claudecode"`), continue with Categories 9-11 manually using the check tables above.
47
+ 3. **Stop.** Output nothing after the script output. No analysis, no suggestions, no follow-up actions.
163
48
 
164
- 4. Print combined summary (script summary + any additional findings from Categories 9-11).
49
+ **Rules:**
50
+ - The ONLY Bash command you may run is the `afc-doctor.sh` script above. No other Bash calls.
51
+ - Do NOT execute Fix commands. They are for the user to run manually.
52
+ - Do NOT analyze project source code, git history, branches, or architecture.
165
53
 
166
54
  ## Example Output
167
55
 
@@ -226,7 +114,8 @@ Results: 28 passed, 2 warnings, 0 failures
226
114
 
227
115
  ## Notes
228
116
 
229
- - **Read-only**: this command never modifies any files. It only reads and reports.
117
+ - **Read-only**: this command NEVER modifies any files, deletes tags, changes permissions, or executes fix commands. It only reads and reports. The `Fix:` lines are instructions for the USER to run manually — do NOT execute them.
118
+ - **No project analysis**: after printing the summary, STOP. Do not analyze project source code, git history, branches, or suggest next steps about the project. Doctor's scope ends at the summary line.
230
119
  - **Always run all checks**: do not stop on first failure. The full picture is the value.
231
120
  - **Actionable fixes**: every non-pass result must include a Fix line. Never report a problem without a solution.
232
121
  - **Fast execution**: skip CI/gate command checks if `--fast` is in arguments (these are the slowest checks).
@@ -313,9 +313,14 @@ This enables granular rollback: `git reset --hard afc/phase-{N}` restores state
313
313
  For each task:
314
314
 
315
315
  1. **Read files**: always read files before modifying them
316
- 2. **Implement**: write code following the design in plan.md
317
- 3. **Type/Lint check**: verify new code passes `{config.gate}`
318
- 4. **Update tasks.md**: mark completed tasks as `[x]`
316
+ 2. **TDD cycle** (when plan.md Test Strategy classifies the task's target file as "required"):
317
+ - **Red**: write the test file first (failing test that defines expected behavior)
318
+ - **Green**: implement the minimum code to pass the test
319
+ - **Refactor**: clean up while keeping tests green
320
+ - If `{config.tdd}` is `strict` or `guide`: always follow this order. If `off` or unset: recommended but not enforced.
321
+ 3. **Implement**: write code following the design in plan.md
322
+ 4. **Type/Lint check**: verify new code passes `{config.gate}`
323
+ 5. **Update tasks.md**: mark completed tasks as `[x]`
319
324
  ```markdown
320
325
  - [x] T001 {description} ← complete
321
326
  - [ ] T002 {description} ← incomplete
package/commands/init.md CHANGED
@@ -125,7 +125,25 @@ Write sections as natural descriptions — **no YAML code blocks** except for CI
125
125
  For items that cannot be inferred: note `TODO: Adjust for your project` inline.
126
126
  Save to `.claude/afc.config.md`.
127
127
 
128
- ### 4.5. Generate Project Profile
128
+ ### 4.5. Generate Project Rules File
129
+
130
+ Generate `.claude/rules/afc-project.md` — a concise summary of project rules that Claude Code auto-loads for all conversations and sub-agents.
131
+
132
+ 1. Create `.claude/rules/` directory if it does not exist
133
+ 2. If `.claude/rules/afc-project.md` already exists:
134
+ - If it contains `<!-- afc:auto-generated` marker: overwrite silently (auto-generated file, safe to regenerate)
135
+ - If it does NOT contain the marker: ask user "Project rules file exists (user-managed). Overwrite with auto-generated version?" — skip if declined
136
+ 3. Reference `${CLAUDE_PLUGIN_ROOT}/templates/afc-project.template.md` for section structure
137
+ 4. Fill in from the analysis performed in Step 3:
138
+ - **Architecture**: pattern, key layers, import rules, path alias — concise bullet points
139
+ - **Code Style**: language, naming conventions, lint rules — concise bullet points
140
+ - **Project Context**: framework, state management, styling, testing, DB/ORM — concise bullet points
141
+ 5. Include `<!-- afc:auto-generated — do not edit manually; regenerate with /afc:init -->` as the first line
142
+ 6. Keep total length **under 30 lines** (excluding the marker comment) — rules only, no explanations
143
+ 7. Save to `.claude/rules/afc-project.md`
144
+ 8. Print: `Project rules: .claude/rules/afc-project.md (auto-loaded by Claude Code)`
145
+
146
+ ### 4.6. Generate Project Profile
129
147
 
130
148
  Generate `.claude/afc/project-profile.md` for expert consultation agents:
131
149
 
@@ -302,6 +320,7 @@ The following rules were auto-generated to resolve conflicts:
302
320
  ```
303
321
  all-for-claudecode initialization complete
304
322
  ├─ Config: .claude/afc.config.md
323
+ ├─ Rules: .claude/rules/afc-project.md (auto-loaded)
305
324
  ├─ Framework: {detected framework}
306
325
  ├─ Architecture: {detected style}
307
326
  ├─ Package Manager: {detected manager}
package/commands/plan.md CHANGED
@@ -26,7 +26,8 @@ model: sonnet
26
26
 
27
27
  ## Config Load
28
28
 
29
- **Always** read `.claude/afc.config.md` first (read manually if not auto-loaded above).
29
+ **Always** read `.claude/afc.config.md` first (read manually if not auto-loaded above) — needed for CI Commands (YAML).
30
+ Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
30
31
 
31
32
  If config file is missing:
32
33
  1. Ask the user: "`.claude/afc.config.md` not found. Run `/afc:init` to set up the project?"
@@ -40,7 +41,7 @@ If config file is missing:
40
41
  1. Check **current branch** → `BRANCH_NAME`
41
42
  2. Find **.claude/afc/specs/{feature}/spec.md**:
42
43
  - Search under `.claude/afc/specs/` for a directory matching the current branch name or `$ARGUMENTS`
43
- - If not found: print "spec.md not found. Run `/afc:spec` first." then **abort**
44
+ - If not found: print "spec.md not found. Running `/afc:spec` to create it first." then **execute `/afc:spec`** with `$ARGUMENTS`. After spec completes, **restart this command** from the beginning with the original `$ARGUMENTS`
44
45
  3. Read full **spec.md**
45
46
  4. Read **.claude/afc/memory/principles.md** (if present)
46
47
  5. Read **CLAUDE.md** project context
@@ -109,7 +110,7 @@ Create `.claude/afc/specs/{feature}/plan.md`. **Must** follow the structure belo
109
110
  {summary of core requirements from spec + technical approach, 3-5 sentences}
110
111
 
111
112
  ## Technical Context
112
- {Summarize key project settings from afc.config.md Architecture, Code Style, and Project Context sections}
113
+ {Summarize key project settings from .claude/rules/afc-project.md (auto-loaded) and afc.config.md}
113
114
  - **Constraints**: {constraints extracted from spec}
114
115
 
115
116
  ## Principles Check
@@ -131,6 +132,35 @@ Create `.claude/afc/specs/{feature}/plan.md`. **Must** follow the structure belo
131
132
  ### API Design (omit if not applicable)
132
133
  {plan for new API endpoints or use of existing APIs}
133
134
 
135
+ ## Test Strategy
136
+
137
+ > Written alongside the File Change Map. Classify each implementation file and decide test coverage level.
138
+ > Determines which files need test coverage and at what level.
139
+
140
+ ### Code Classification
141
+
142
+ | File | Code Type | Test Need | Reason |
143
+ |------|-----------|:---------:|--------|
144
+ | {path} | {business-logic / pure-function / side-effect / framework / config / UI} | {required / optional / unnecessary} | {brief justification} |
145
+
146
+ > Classification guide:
147
+ > - **business-logic / pure-function**: Required — unit tests (AAA pattern)
148
+ > - **side-effect code** (external API, DB, file I/O): Required — integration tests with mocks
149
+ > - **framework / config / getter-setter / boilerplate**: Unnecessary — no test
150
+ > - **UI rendering** (no state logic): Optional — minimal snapshot or skip
151
+
152
+ ### Test Pyramid
153
+
154
+ - **Unit tests**: {count} files ({which files})
155
+ - **Integration tests**: {count} files ({which files}, if applicable)
156
+ - **E2E tests**: {count} (if applicable, only for critical user flows)
157
+
158
+ ### Required Test Cases (derived from spec EARS requirements)
159
+
160
+ {For each spec EARS requirement with `→ TC:` mapping, list the test case here}
161
+ - `should_{behavior}_when_{trigger}` → covers FR-{NNN}
162
+ - `should_{behavior}_while_{state}` → covers FR-{NNN}
163
+
134
164
  ## File Change Map
135
165
 
136
166
  | File | Action | Description | Depends On | Phase |
@@ -139,6 +169,7 @@ Create `.claude/afc/specs/{feature}/plan.md`. **Must** follow the structure belo
139
169
 
140
170
  > - **Depends On**: list file(s) that must be created/modified first (enables dependency-aware task generation in /afc:implement).
141
171
  > - **Phase**: implementation phase number. Same-phase + no dependency + different file = parallelizable.
172
+ > - **Test files**: For each implementation file classified as "required" in Code Classification, include a corresponding test file in the same Phase. Test files are first-class citizens in the File Change Map.
142
173
 
143
174
  ## Implementation Context
144
175
 
@@ -215,7 +246,7 @@ Run the critic loop until convergence. Safety cap: 5 passes.
215
246
 
216
247
  | Criterion | Validation |
217
248
  |-----------|------------|
218
- | **COMPLETENESS** | Are all requirements (FR-*) from spec.md reflected in the plan? |
249
+ | **COMPLETENESS** | Are all requirements (FR-*) from spec.md reflected in the plan? For each implementation file classified as "required" in Test Strategy Code Classification, does the File Change Map include a corresponding test file? Report: `{M}/{N} test pairs present`. |
219
250
  | **FEASIBILITY** | Is it compatible with the existing codebase? Are dependencies available? |
220
251
  | **ARCHITECTURE** | Does it comply with {config.architecture} rules? |
221
252
  | **CROSS_CONSISTENCY** | Spec↔Plan cross-artifact validation (see checklist below) |
package/commands/qa.md CHANGED
@@ -28,11 +28,8 @@ model: sonnet
28
28
 
29
29
  ## Config Load
30
30
 
31
- **Always** read `.claude/afc.config.md` first. This file contains free-form markdown sections:
32
- - `## Architecture` architecture pattern, layers, import rules
33
- - `## Code Style` — language, naming conventions, lint rules
34
- - `## CI Commands` — test, lint, gate commands (YAML)
35
- - `## Project Context` — framework, state management, testing strategy
31
+ **Always** read `.claude/afc.config.md` first needed for CI Commands (YAML: ci, gate, test).
32
+ Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
36
33
 
37
34
  If config file is missing: read `CLAUDE.md` for project info. Proceed without config if neither exists.
38
35
 
@@ -9,6 +9,7 @@ allowed-tools:
9
9
  - Glob
10
10
  - Bash
11
11
  - Task
12
+ - LSP
12
13
  model: sonnet
13
14
  ---
14
15
 
@@ -28,7 +29,8 @@ model: sonnet
28
29
 
29
30
  ## Config Load
30
31
 
31
- **Always** read `.claude/afc.config.md` first (read manually if not auto-loaded above).
32
+ **Always** read `.claude/afc.config.md` first (read manually if not auto-loaded above) — needed for CI Commands (YAML).
33
+ Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
32
34
 
33
35
  If config file is missing:
34
36
  1. Ask the user: "`.claude/afc.config.md` not found. Run `/afc:init` to set up the project?"
@@ -48,6 +50,33 @@ If config file is missing:
48
50
  3. Read **full content** of each changed file (not just the diff — full context)
49
51
  4. **Load spec context** (if available): Check for `.claude/afc/specs/{feature}/context.md` and `.claude/afc/specs/{feature}/spec.md`. If found, load them for SPEC_ALIGNMENT validation in the Critic Loop. If neither exists, SPEC_ALIGNMENT criterion is skipped with note "no spec artifacts available"
50
52
 
53
+ ### 1.5. Reverse Impact Analysis
54
+
55
+ Before reviewing, identify **files affected by the changes** (not just the changed files themselves):
56
+
57
+ 1. **For each changed file**, find files that depend on it:
58
+ - **LSP (preferred)**: `LSP(findReferences)` on exported symbols — tracks type references, function calls, re-exports
59
+ - **Grep (fallback)**: `Grep` for `import.*{filename}`, `require.*{filename}`, `source.*{filename}` patterns across the codebase
60
+ - LSP and Grep are complementary — use both when LSP is available (LSP catches type-level references Grep misses; Grep catches dynamic patterns LSP misses)
61
+
62
+ 2. **Build impact map**:
63
+ ```
64
+ Impact Map:
65
+ ├─ src/auth/login.ts (changed)
66
+ │ └─ affected: src/pages/LoginPage.tsx, src/middleware/auth.ts
67
+ ├─ scripts/afc-state.sh (changed)
68
+ │ └─ affected: scripts/afc-stop-gate.sh, scripts/afc-drift.sh (grep: source.*afc-state)
69
+ └─ Total: {N} changed files → {M} affected files
70
+ ```
71
+
72
+ 3. **Scope decision**:
73
+ - Affected files are NOT full review targets (that would explode scope)
74
+ - Instead, include them as **cross-reference context** in Step 2 and Step 3.5
75
+ - If an affected file has >3 references to a changed symbol → flag for closer inspection
76
+
77
+ 4. **Limitations** (include in review output):
78
+ > ⚠ Dynamic dependencies not covered: runtime dispatch (`obj[method]()`), reflection, cross-language calls, config/env-driven branching. Manual verification recommended for these patterns.
79
+
51
80
  ### 2. Parallel Review (scaled by file count)
52
81
 
53
82
  Choose review orchestration based on the number of changed files:
@@ -58,7 +87,8 @@ Before distributing files to review agents, collect cross-boundary context:
58
87
 
59
88
  1. For each changed file, identify **outbound calls** to other changed files (imports + function calls)
60
89
  2. For each outbound call target, extract: function signature + 1-line side-effect summary (e.g., "mutates playlist state", "triggers async cascade")
61
- 3. Include this context in each review agent's prompt:
90
+ 3. Include the **Impact Map** from Step 1.5 — each agent receives the list of affected (non-changed) files that depend on its assigned files
91
+ 4. Include this context in each review agent's prompt:
62
92
  ```
63
93
  ## Cross-File Context
64
94
  This file calls:
@@ -176,6 +206,8 @@ After individual/parallel reviews complete, the **orchestrator** MUST perform a
176
206
 
177
207
  **For 11+ file reviews**: This is especially critical because individual review agents cannot see cross-file interactions. The orchestrator MUST read callee implementations directly.
178
208
 
209
+ 0. **Impact Map integration**: Use the Impact Map from Step 1.5 to prioritize verification. Affected files with >3 references to changed symbols should be read and checked for breakage — even if no finding was raised against them.
210
+
179
211
  1. **Filter**: From all collected findings, select those involving:
180
212
  - Call order changes (function A now calls B before C)
181
213
  - Error handling modifications (try/catch scope changes, error propagation changes)
@@ -212,6 +244,13 @@ This step runs in the orchestrator context (not delegated), as it requires readi
212
244
  | Warning | {N} | {summary} |
213
245
  | Info | {N} | {summary} |
214
246
 
247
+ ### Impact Analysis
248
+ | Changed File | Affected Files | Method |
249
+ |---|---|---|
250
+ | {path} | {affected file list} | LSP / Grep |
251
+
252
+ > ⚠ Dynamic dependencies (runtime dispatch, reflection, cross-language calls) require manual verification.
253
+
215
254
  ### Detailed Findings
216
255
 
217
256
  #### C-{N}: {title}
@@ -26,12 +26,10 @@ model: sonnet
26
26
 
27
27
  ## Config Load
28
28
 
29
- **Always** read `.claude/afc.config.md` first. This file contains free-form markdown sections:
30
- - `## Project Context` framework, state management, testing, etc. (primary source for framework info)
31
- - `## Architecture` — architecture pattern, layers, import rules
32
- - `## Code Style` — language, naming conventions, lint rules
29
+ Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
30
+ Read `.claude/afc.config.md` if CI commands are needed.
33
31
 
34
- If config file is missing: read `CLAUDE.md` for framework info. Assume "unknown" if neither source has it.
32
+ If neither rules file nor config exists: read `CLAUDE.md` for framework info. Assume "unknown" if no source has it.
35
33
 
36
34
  For dependency audit command: infer from `packageManager` field in `package.json` or the lockfile (e.g., `npm audit`, `yarn audit`, `pnpm audit`).
37
35
 
package/commands/spec.md CHANGED
@@ -99,8 +99,19 @@ Create `.claude/afc/specs/{feature-name}/spec.md`:
99
99
  - [ ] Given {precondition}, When {action}, Then {result}
100
100
 
101
101
  #### System Requirements (EARS notation)
102
- - [ ] WHEN {trigger}, THE System SHALL {behavior}
103
- - [ ] WHILE {state}, THE System SHALL {behavior}
102
+
103
+ > Use one of the 5 EARS patterns for each requirement. Each requirement must map to at least one expected test case (TC).
104
+
105
+ | Pattern | Template | Use When |
106
+ |---------|----------|----------|
107
+ | Ubiquitous | `THE System SHALL {behavior}` | Always-on property (no trigger needed) |
108
+ | Event-driven | `WHEN {trigger}, THE System SHALL {response}` | Specific event triggers a response |
109
+ | State-driven | `WHILE {state}, THE System SHALL {behavior}` | Behavior depends on system state |
110
+ | Unwanted | `IF {condition}, THE System SHALL {handling}` | Error/failure handling |
111
+ | Optional | `WHERE {feature/config active}, THE System SHALL {behavior}` | Feature flag or conditional capability |
112
+
113
+ - [ ] WHEN {trigger}, THE System SHALL {behavior} → TC: `should_{behavior}_when_{trigger}`
114
+ - [ ] WHILE {state}, THE System SHALL {behavior} → TC: `should_{behavior}_while_{state}`
104
115
 
105
116
  ### US2: {story title} [P2]
106
117
  {same format}
@@ -172,6 +183,7 @@ Run the critic loop until convergence. Safety cap: 5 passes.
172
183
  | **MEASURABILITY** | Are the success criteria measurable, not subjective? |
173
184
  | **INDEPENDENCE** | Are implementation details (code, library names) absent from the spec? |
174
185
  | **EDGE_CASES** | Are at least 2 edge cases identified? Any missing boundary conditions? |
186
+ | **TESTABILITY** | Does every System Requirement follow one of the 5 EARS patterns (WHEN/WHILE/IF/WHERE/SHALL)? Does each EARS requirement have a mapped TC (`→ TC: should_...`)? If not → FAIL and auto-fix: rewrite to EARS + generate TC mapping. |
175
187
 
176
188
  **On FAIL**: auto-fix and continue to next pass.
177
189
  **On ESCALATE**: pause, present options to user, apply choice, resume.
package/hooks/hooks.json CHANGED
@@ -45,6 +45,16 @@
45
45
  "statusMessage": "Checking spec immutability..."
46
46
  }
47
47
  ]
48
+ },
49
+ {
50
+ "matcher": "Edit|MultiEdit|Write|NotebookEdit",
51
+ "hooks": [
52
+ {
53
+ "type": "command",
54
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/afc-tdd-guard.sh\"",
55
+ "statusMessage": "Checking TDD compliance..."
56
+ }
57
+ ]
48
58
  }
49
59
  ],
50
60
  "PostToolUse": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "all-for-claudecode",
3
- "version": "2.8.1",
3
+ "version": "2.9.0",
4
4
  "description": "Claude Code plugin that automates the full dev cycle — spec, plan, implement, review, clean.",
5
5
  "bin": {
6
6
  "all-for-claudecode": "bin/cli.mjs"
@@ -2,7 +2,7 @@
2
2
  set -euo pipefail
3
3
 
4
4
  # afc-doctor.sh — Automated health check for all-for-claudecode plugin
5
- # Runs categories 1-9 deterministically. Categories 10-12 require LLM analysis.
5
+ # Runs ALL categories deterministically. No LLM judgment required.
6
6
  # Output: human-readable text (no JSON), directly printable.
7
7
  # Read-only: never modifies files.
8
8
 
@@ -122,6 +122,18 @@ else
122
122
  fail ".claude/afc.config.md not found" "run /afc:init"
123
123
  fi
124
124
 
125
+ # Project rules file
126
+ RULES_FILE="$PROJECT_DIR/.claude/rules/afc-project.md"
127
+ if [ -f "$RULES_FILE" ]; then
128
+ if grep -q '<!-- afc:auto-generated' "$RULES_FILE" 2>/dev/null; then
129
+ pass "Project rules file exists (auto-generated)"
130
+ else
131
+ pass "Project rules file exists (user-managed)"
132
+ fi
133
+ else
134
+ warn "No .claude/rules/afc-project.md — project rules not auto-loaded" "run /afc:init to generate"
135
+ fi
136
+
125
137
  # --- Category 3: CLAUDE.md Integration ---
126
138
  section "CLAUDE.md Integration"
127
139
 
@@ -459,6 +471,224 @@ if [ "$IS_DEV" = true ]; then
459
471
  else
460
472
  warn "Plugin cache directory not found" "install plugin first, then npm run sync:cache"
461
473
  fi
474
+
475
+ # --- Category 10: Command Definitions (dev only) ---
476
+ section "Command Definitions (dev)"
477
+
478
+ CMD_DIR="$PROJECT_DIR/commands"
479
+ if [ -d "$CMD_DIR" ]; then
480
+ CMD_COUNT=0
481
+ CMD_FM_MISSING=""
482
+ CMD_FIELD_MISSING=""
483
+ CMD_NAME_MISMATCH=""
484
+ CMD_AGENT_MISSING=""
485
+
486
+ for cmd_file in "$CMD_DIR"/*.md; do
487
+ [ -f "$cmd_file" ] || continue
488
+ CMD_COUNT=$((CMD_COUNT + 1))
489
+ BASENAME=$(basename "$cmd_file" .md)
490
+
491
+ # Check frontmatter exists (--- ... ---)
492
+ if ! head -1 "$cmd_file" | grep -q '^---' 2>/dev/null; then
493
+ CMD_FM_MISSING="${CMD_FM_MISSING:+$CMD_FM_MISSING, }$BASENAME"
494
+ continue
495
+ fi
496
+
497
+ # Extract frontmatter (between first and second ---)
498
+ FM=$(sed -n '2,/^---$/p' "$cmd_file" 2>/dev/null | sed '$d')
499
+
500
+ # Check required fields: name and description
501
+ if ! printf '%s\n' "$FM" | grep -q '^name:' 2>/dev/null || ! printf '%s\n' "$FM" | grep -q '^description:' 2>/dev/null; then
502
+ CMD_FIELD_MISSING="${CMD_FIELD_MISSING:+$CMD_FIELD_MISSING, }$BASENAME"
503
+ fi
504
+
505
+ # Check name-filename match (afc:{basename})
506
+ FM_NAME=$(printf '%s\n' "$FM" | grep '^name:' | head -1 | sed 's/name:[[:space:]]*//' | tr -d '"' | tr -d "'" | tr -d ' ')
507
+ EXPECTED_NAME="afc:$BASENAME"
508
+ if [ -n "$FM_NAME" ] && [ "$FM_NAME" != "$EXPECTED_NAME" ]; then
509
+ CMD_NAME_MISMATCH="${CMD_NAME_MISMATCH:+$CMD_NAME_MISMATCH, }$BASENAME (got $FM_NAME)"
510
+ fi
511
+
512
+ # Check fork-agent reference
513
+ if printf '%s\n' "$FM" | grep -q 'context:.*fork' 2>/dev/null; then
514
+ AGENT_NAME=$(printf '%s\n' "$FM" | grep '^agent:' | head -1 | sed 's/agent:[[:space:]]*//' | tr -d '"' | tr -d "'" | tr -d ' ' || true)
515
+ if [ -n "$AGENT_NAME" ] && [ ! -f "$PROJECT_DIR/agents/$AGENT_NAME.md" ]; then
516
+ CMD_AGENT_MISSING="${CMD_AGENT_MISSING:+$CMD_AGENT_MISSING, }$BASENAME → $AGENT_NAME"
517
+ fi
518
+ fi
519
+ done
520
+
521
+ if [ -z "$CMD_FM_MISSING" ]; then
522
+ pass "Frontmatter exists ($CMD_COUNT files)"
523
+ else
524
+ fail "Missing frontmatter: $CMD_FM_MISSING" "add YAML frontmatter block"
525
+ fi
526
+
527
+ if [ -z "$CMD_FIELD_MISSING" ]; then
528
+ pass "Required fields present"
529
+ else
530
+ fail "Missing name/description: $CMD_FIELD_MISSING" "add missing fields"
531
+ fi
532
+
533
+ if [ -z "$CMD_NAME_MISMATCH" ]; then
534
+ pass "Name-filename match"
535
+ else
536
+ fail "Name mismatch: $CMD_NAME_MISMATCH" "rename name: field to afc:{filename}"
537
+ fi
538
+
539
+ if [ -z "$CMD_AGENT_MISSING" ]; then
540
+ pass "Fork-agent references valid"
541
+ else
542
+ fail "Missing agent: $CMD_AGENT_MISSING" "create missing agent file or fix agent: field"
543
+ fi
544
+ fi
545
+
546
+ # --- Category 11: Agent Definitions (dev only) ---
547
+ section "Agent Definitions (dev)"
548
+
549
+ AGENT_DIR="$PROJECT_DIR/agents"
550
+ if [ -d "$AGENT_DIR" ]; then
551
+ AGENT_COUNT=0
552
+ AGENT_FM_MISSING=""
553
+ AGENT_FIELD_MISSING=""
554
+ AGENT_NAME_MISMATCH=""
555
+ EXPERT_MEMORY_MISSING=""
556
+ WORKER_TURNS_MISSING=""
557
+
558
+ EXPERT_AGENTS="afc-backend-expert afc-infra-expert afc-pm-expert afc-design-expert afc-marketing-expert afc-legal-expert afc-appsec-expert afc-tech-advisor"
559
+ WORKER_AGENTS="afc-impl-worker afc-pr-analyst"
560
+
561
+ for agent_file in "$AGENT_DIR"/*.md; do
562
+ [ -f "$agent_file" ] || continue
563
+ AGENT_COUNT=$((AGENT_COUNT + 1))
564
+ BASENAME=$(basename "$agent_file" .md)
565
+
566
+ # Check frontmatter exists
567
+ if ! head -1 "$agent_file" | grep -q '^---' 2>/dev/null; then
568
+ AGENT_FM_MISSING="${AGENT_FM_MISSING:+$AGENT_FM_MISSING, }$BASENAME"
569
+ continue
570
+ fi
571
+
572
+ FM=$(sed -n '2,/^---$/p' "$agent_file" 2>/dev/null | sed '$d')
573
+
574
+ # Check required fields: name, description, model
575
+ if ! printf '%s\n' "$FM" | grep -q '^name:' 2>/dev/null || ! printf '%s\n' "$FM" | grep -q '^description:' 2>/dev/null || ! printf '%s\n' "$FM" | grep -q '^model:' 2>/dev/null; then
576
+ AGENT_FIELD_MISSING="${AGENT_FIELD_MISSING:+$AGENT_FIELD_MISSING, }$BASENAME"
577
+ fi
578
+
579
+ # Check name-filename match
580
+ FM_NAME=$(printf '%s\n' "$FM" | grep '^name:' | head -1 | sed 's/name:[[:space:]]*//' | tr -d '"' | tr -d "'" | tr -d ' ')
581
+ if [ -n "$FM_NAME" ] && [ "$FM_NAME" != "$BASENAME" ]; then
582
+ AGENT_NAME_MISMATCH="${AGENT_NAME_MISMATCH:+$AGENT_NAME_MISMATCH, }$BASENAME (got $FM_NAME)"
583
+ fi
584
+
585
+ # Expert memory check
586
+ for expert in $EXPERT_AGENTS; do
587
+ if [ "$BASENAME" = "$expert" ]; then
588
+ if ! printf '%s\n' "$FM" | grep -q '^memory:' 2>/dev/null; then
589
+ EXPERT_MEMORY_MISSING="${EXPERT_MEMORY_MISSING:+$EXPERT_MEMORY_MISSING, }$BASENAME"
590
+ fi
591
+ fi
592
+ done
593
+
594
+ # Worker maxTurns check
595
+ for worker in $WORKER_AGENTS; do
596
+ if [ "$BASENAME" = "$worker" ]; then
597
+ if ! printf '%s\n' "$FM" | grep -q '^maxTurns:' 2>/dev/null; then
598
+ WORKER_TURNS_MISSING="${WORKER_TURNS_MISSING:+$WORKER_TURNS_MISSING, }$BASENAME"
599
+ fi
600
+ fi
601
+ done
602
+ done
603
+
604
+ if [ -z "$AGENT_FM_MISSING" ]; then
605
+ pass "Frontmatter exists ($AGENT_COUNT files)"
606
+ else
607
+ fail "Missing frontmatter: $AGENT_FM_MISSING" "add YAML frontmatter block"
608
+ fi
609
+
610
+ if [ -z "$AGENT_FIELD_MISSING" ]; then
611
+ pass "Required fields present"
612
+ else
613
+ fail "Missing name/description/model: $AGENT_FIELD_MISSING" "add missing fields"
614
+ fi
615
+
616
+ if [ -z "$AGENT_NAME_MISMATCH" ]; then
617
+ pass "Name-filename match"
618
+ else
619
+ fail "Name mismatch: $AGENT_NAME_MISMATCH" "rename name: field to match filename"
620
+ fi
621
+
622
+ # Count experts found
623
+ EXPERT_TOTAL=0
624
+ EXPERT_WITH_MEM=0
625
+ for expert in $EXPERT_AGENTS; do
626
+ if [ -f "$AGENT_DIR/$expert.md" ]; then
627
+ EXPERT_TOTAL=$((EXPERT_TOTAL + 1))
628
+ FM=$(sed -n '2,/^---$/p' "$AGENT_DIR/$expert.md" 2>/dev/null | sed '$d')
629
+ if printf '%s\n' "$FM" | grep -q '^memory:' 2>/dev/null; then
630
+ EXPERT_WITH_MEM=$((EXPERT_WITH_MEM + 1))
631
+ fi
632
+ fi
633
+ done
634
+ if [ -z "$EXPERT_MEMORY_MISSING" ]; then
635
+ pass "Expert memory configured ($EXPERT_WITH_MEM/$EXPERT_TOTAL)"
636
+ else
637
+ fail "Missing memory: field: $EXPERT_MEMORY_MISSING" "add memory: project to agent frontmatter"
638
+ fi
639
+
640
+ WORKER_TOTAL=0
641
+ WORKER_WITH_TURNS=0
642
+ for worker in $WORKER_AGENTS; do
643
+ if [ -f "$AGENT_DIR/$worker.md" ]; then
644
+ WORKER_TOTAL=$((WORKER_TOTAL + 1))
645
+ FM=$(sed -n '2,/^---$/p' "$AGENT_DIR/$worker.md" 2>/dev/null | sed '$d')
646
+ if printf '%s\n' "$FM" | grep -q '^maxTurns:' 2>/dev/null; then
647
+ WORKER_WITH_TURNS=$((WORKER_WITH_TURNS + 1))
648
+ fi
649
+ fi
650
+ done
651
+ if [ -z "$WORKER_TURNS_MISSING" ]; then
652
+ pass "Worker maxTurns configured ($WORKER_WITH_TURNS/$WORKER_TOTAL)"
653
+ else
654
+ fail "Missing maxTurns: $WORKER_TURNS_MISSING" "add maxTurns: to agent frontmatter"
655
+ fi
656
+ fi
657
+
658
+ # --- Category 12: Doc References (dev only) ---
659
+ section "Doc References (dev)"
660
+
661
+ # Scan commands and agents for docs/ references
662
+ DOC_REFS_MISSING=""
663
+ for src_file in "$CMD_DIR"/*.md "$AGENT_DIR"/*.md; do
664
+ [ -f "$src_file" ] || continue
665
+ while IFS= read -r ref; do
666
+ [ -z "$ref" ] && continue
667
+ DOC_PATH="$PROJECT_DIR/$ref"
668
+ if [ ! -f "$DOC_PATH" ]; then
669
+ DOC_REFS_MISSING="${DOC_REFS_MISSING:+$DOC_REFS_MISSING, }$ref (in $(basename "$src_file"))"
670
+ fi
671
+ done < <(grep -oE 'docs/[a-zA-Z0-9_/-]+\.md' "$src_file" 2>/dev/null | sort -u)
672
+ done
673
+
674
+ if [ -z "$DOC_REFS_MISSING" ]; then
675
+ pass "Referenced docs exist"
676
+ else
677
+ fail "Missing docs: $DOC_REFS_MISSING" "create missing doc files or fix references"
678
+ fi
679
+
680
+ # Domain adapters
681
+ ADAPTER_DIR="$PROJECT_DIR/docs/domain-adapters"
682
+ if [ -d "$ADAPTER_DIR" ]; then
683
+ ADAPTER_COUNT=$(find "$ADAPTER_DIR" -maxdepth 1 -name '*.md' -type f 2>/dev/null | wc -l | tr -d ' ')
684
+ if [ "$ADAPTER_COUNT" -ge 1 ]; then
685
+ pass "Domain adapters exist ($ADAPTER_COUNT files)"
686
+ else
687
+ fail "No domain adapter files" "add .md files to docs/domain-adapters/"
688
+ fi
689
+ else
690
+ fail "docs/domain-adapters/ directory missing" "create docs/domain-adapters/ with at least one .md file"
691
+ fi
462
692
  fi
463
693
 
464
694
  # --- Summary ---
@@ -474,9 +704,5 @@ else
474
704
  printf '%d issues need attention. Run the Fix commands above.\n' "$FAIL"
475
705
  fi
476
706
 
477
- # Signal dev-only categories to caller
478
- if [ "$IS_DEV" = true ]; then
479
- printf '\nNote: Categories 10-12 (Command/Agent/Doc validation) require LLM analysis.\n'
480
- fi
481
707
 
482
708
  exit 0
@@ -15,8 +15,6 @@ cleanup() {
15
15
  }
16
16
  trap cleanup EXIT
17
17
 
18
- PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
19
-
20
18
  # Consume stdin (required -- pipe breaks if not consumed)
21
19
  cat > /dev/null
22
20
 
@@ -34,31 +32,8 @@ PHASE=$(afc_state_read phase || echo "unknown")
34
32
  # 3. Build context string
35
33
  CONTEXT="[AFC PIPELINE] Feature: $FEATURE | Phase: $PHASE | [AFC] When this task matches an AFC skill (analyze, implement, review, debug, test, plan, spec, research, ideate), use the Skill tool to invoke it. Do not substitute with raw Task agents. When analyzing external systems, verify against official documentation."
36
34
 
37
- # 4. Extract config sections from afc.config.md
38
- CONFIG_FILE="$PROJECT_DIR/.claude/afc.config.md"
39
-
40
- if [ -f "$CONFIG_FILE" ]; then
41
- # Extract Architecture section (## Architecture to next ##)
42
- # shellcheck disable=SC2001
43
- ARCH=$(sed -n '/^## Architecture/,/^## /p' "$CONFIG_FILE" 2>/dev/null | sed '1d;/^## /d;/^$/d' | head -15 | tr '\n' ' ' | sed 's/ */ /g;s/^ *//;s/ *$//')
44
- if [ -n "$ARCH" ]; then
45
- CONTEXT="$CONTEXT | Architecture: $ARCH"
46
- fi
47
-
48
- # Extract Code Style section (## Code Style to next ##)
49
- # shellcheck disable=SC2001
50
- STYLE=$(sed -n '/^## Code Style/,/^## /p' "$CONFIG_FILE" 2>/dev/null | sed '1d;/^## /d;/^$/d' | head -15 | tr '\n' ' ' | sed 's/ */ /g;s/^ *//;s/ *$//')
51
- if [ -n "$STYLE" ]; then
52
- CONTEXT="$CONTEXT | Code Style: $STYLE"
53
- fi
54
-
55
- # Extract Project Context section (## Project Context to next ## or EOF)
56
- # shellcheck disable=SC2001
57
- PROJ_CTX=$(sed -n '/^## Project Context/,/^## /p' "$CONFIG_FILE" 2>/dev/null | sed '1d;/^## /d;/^$/d' | head -15 | tr '\n' ' ' | sed 's/ */ /g;s/^ *//;s/ *$//')
58
- if [ -n "$PROJ_CTX" ]; then
59
- CONTEXT="$CONTEXT | Project Context: $PROJ_CTX"
60
- fi
61
- fi
35
+ # 4. Architecture/Code Style/Project Context are auto-loaded via .claude/rules/afc-project.md
36
+ # No need to extract from afc.config.md — Claude Code loads rules files automatically
62
37
 
63
38
  # 5. Output as hookSpecificOutput JSON (required for SubagentStart context injection)
64
39
  if command -v jq &>/dev/null; then
@@ -0,0 +1,108 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ # PreToolUse Hook: TDD Guard — blocks non-test file writes during implement phase
4
+ # Only active when: pipeline active + phase=implement + tdd=strict (or warns on guide)
5
+ # tdd setting read from afc.config.md CI Commands YAML
6
+
7
+ # shellcheck source=afc-state.sh
8
+ . "$(dirname "$0")/afc-state.sh"
9
+
10
+ # shellcheck disable=SC2329
11
+ cleanup() {
12
+ :
13
+ }
14
+ trap cleanup EXIT
15
+
16
+ ALLOW='{"hookSpecificOutput":{"permissionDecision":"allow"}}'
17
+
18
+ # Consume stdin immediately (prevents SIGPIPE if exiting early)
19
+ INPUT=$(cat)
20
+
21
+ # If pipeline is inactive -> allow
22
+ if ! afc_state_is_active; then
23
+ printf '%s\n' "$ALLOW"
24
+ exit 0
25
+ fi
26
+
27
+ # Read current phase — only guard during implement
28
+ PHASE="$(afc_state_read phase || echo '')"
29
+ if [ "$PHASE" != "implement" ]; then
30
+ printf '%s\n' "$ALLOW"
31
+ exit 0
32
+ fi
33
+
34
+ # Read tdd setting from afc.config.md (YAML in markdown — grep/sed parse)
35
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
36
+ CONFIG_FILE="$PROJECT_DIR/.claude/afc.config.md"
37
+ TDD_MODE="off"
38
+
39
+ if [ -f "$CONFIG_FILE" ]; then
40
+ TDD_MODE=$(grep -E '^tdd:' "$CONFIG_FILE" | head -1 | sed 's/^tdd:[[:space:]]*"//;s/".*$//' 2>/dev/null || echo "off")
41
+ fi
42
+
43
+ # Normalize: empty or missing -> off
44
+ TDD_MODE="${TDD_MODE:-off}"
45
+
46
+ # If tdd is off -> allow immediately (0ms overhead goal)
47
+ if [ "$TDD_MODE" = "off" ]; then
48
+ printf '%s\n' "$ALLOW"
49
+ exit 0
50
+ fi
51
+
52
+ if [ -z "$INPUT" ]; then
53
+ printf '%s\n' "$ALLOW"
54
+ exit 0
55
+ fi
56
+
57
+ # Extract file_path from tool_input
58
+ FILE_PATH=""
59
+ if command -v jq &> /dev/null; then
60
+ FILE_PATH=$(printf '%s\n' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null || true)
61
+ else
62
+ FILE_PATH=$(printf '%s\n' "$INPUT" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*:[[:space:]]*"//;s/"$//' 2>/dev/null || true)
63
+ fi
64
+
65
+ if [ -z "$FILE_PATH" ]; then
66
+ printf '%s\n' "$ALLOW"
67
+ exit 0
68
+ fi
69
+
70
+ # Check if the file is a test file — always allow test file edits
71
+ # Patterns: *.test.*, *.spec.*, *_test.*, *_spec.*, *_test.go, spec/*, __tests__/*, test/*, tests/*
72
+ BASENAME=$(basename "$FILE_PATH")
73
+ if printf '%s' "$BASENAME" | grep -qE '\.(test|spec)\.[^.]+$'; then
74
+ printf '%s\n' "$ALLOW"
75
+ exit 0
76
+ fi
77
+ if printf '%s' "$BASENAME" | grep -qE '_(test|spec)\.[^.]+$'; then
78
+ printf '%s\n' "$ALLOW"
79
+ exit 0
80
+ fi
81
+ if printf '%s' "$FILE_PATH" | grep -qE '(^|/)(spec|__tests__|tests?)/'; then
82
+ printf '%s\n' "$ALLOW"
83
+ exit 0
84
+ fi
85
+
86
+ # Non-code files (markdown, json, yaml, config) — always allow
87
+ if printf '%s' "$BASENAME" | grep -qE '\.(md|json|ya?ml|toml|txt|csv|lock|gitignore)$'; then
88
+ printf '%s\n' "$ALLOW"
89
+ exit 0
90
+ fi
91
+
92
+ # At this point: implement phase + tdd is strict or guide + file is not a test file + file is code
93
+ # Sanitize BASENAME for JSON safety (remove double quotes and backslashes)
94
+ SAFE_BASENAME=$(printf '%s' "$BASENAME" | tr -d '"\\')
95
+
96
+ if [ "$TDD_MODE" = "strict" ]; then
97
+ printf '{"hookSpecificOutput":{"permissionDecision":"deny","permissionDecisionReason":"[afc:tdd-guard] TDD strict mode: write test file first before implementing. Target: %s"}}\n' "$SAFE_BASENAME"
98
+ exit 0
99
+ fi
100
+
101
+ if [ "$TDD_MODE" = "guide" ]; then
102
+ printf '{"hookSpecificOutput":{"permissionDecision":"allow","additionalContext":"[afc:tdd-guard] TDD guide: consider writing tests first for %s"}}\n' "$SAFE_BASENAME"
103
+ exit 0
104
+ fi
105
+
106
+ # Fallback: unknown tdd value -> allow
107
+ printf '%s\n' "$ALLOW"
108
+ exit 0
@@ -41,13 +41,17 @@ if ! afc_state_is_active; then
41
41
  # Normalize: lowercase + truncate for matching
42
42
  LOWER=$(printf '%s' "$USER_TEXT" | tr '[:upper:]' '[:lower:]' | cut -c1-500)
43
43
 
44
+ # Compact skill catalog: injected when regex misses, so the model classifies semantically
45
+ FALLBACK_HINT="[afc] Route via Skill tool if applicable — debug(bug/에러/수정/fix) | review(코드검토/리뷰/PR) | test(테스트/coverage) | spec(요구사항/스펙) | plan(설계/계획) | implement(구현/리팩터) | auto(새기능/feature) | consult(조언/상의/discuss) | analyze(분석/trace) | research(조사/리서치) | security(보안/취약점) | architect(아키텍처/설계) | qa(품질감사) | launch(릴리스/배포) | triage(PR정리/이슈분류) | clean(정리/cleanup) | ideate(아이디어/brainstorm) | doctor(진단/health) | release-notes(변경이력)"
46
+
44
47
  # Early exit for empty prompts (context-only messages, malformed JSON)
45
48
  if [ -z "$LOWER" ]; then
46
49
  if command -v jq >/dev/null 2>&1; then
47
- jq -n --arg c "[afc] If this request matches an afc skill, invoke it via Skill tool. See CLAUDE.md routing table." \
48
- '{"hookSpecificOutput":{"additionalContext":$c}}'
50
+ jq -n --arg c "$FALLBACK_HINT" '{"hookSpecificOutput":{"additionalContext":$c}}'
49
51
  else
50
- printf '{"hookSpecificOutput":{"additionalContext":"[afc] If this request matches an afc skill, invoke it via Skill tool. See CLAUDE.md routing table."}}\n'
52
+ SAFE_FALLBACK="${FALLBACK_HINT//\\/\\\\}"
53
+ SAFE_FALLBACK="${SAFE_FALLBACK//\"/\\\"}"
54
+ printf '{"hookSpecificOutput":{"additionalContext":"%s"}}\n' "$SAFE_FALLBACK"
51
55
  fi
52
56
  exit 0
53
57
  fi
@@ -55,43 +59,55 @@ if ! afc_state_is_active; then
55
59
  # Intent detection: priority-ordered if/elif chain.
56
60
  # Each pattern targets strong-signal phrases to minimize false positives.
57
61
  # The model retains final authority — this is a hint, not enforcement.
62
+ # Patterns include Korean (한국어) variants for natural language coverage.
58
63
  SKILL=""
59
64
  # High confidence: distinctive multi-word or rare keywords
60
- if printf '%s' "$LOWER" | grep -qE '(bug|broken|debug|not working|crash|exception)' 2>/dev/null; then
65
+ if printf '%s' "$LOWER" | grep -qE '(bug|broken|debug|not working|crash|exception|에러|버그|오류|안.?됨|안.?돼|안.?되|고장)' 2>/dev/null; then
61
66
  SKILL="afc:debug"
62
- elif printf '%s' "$LOWER" | grep -qE '(code review|pr review)' 2>/dev/null; then
67
+ elif printf '%s' "$LOWER" | grep -qE '(code review|pr review|코드.?리뷰|pr.?리뷰|코드.?검토)' 2>/dev/null; then
63
68
  SKILL="afc:review"
64
- elif printf '%s' "$LOWER" | grep -qE '(write test|add test|test coverage|improve coverage)' 2>/dev/null; then
69
+ elif printf '%s' "$LOWER" | grep -qE '(write test|add test|test coverage|improve coverage|unit test|integration test|e2e test|테스트.?작성|테스트.?추가|커버리지)' 2>/dev/null; then
65
70
  SKILL="afc:test"
66
- elif printf '%s' "$LOWER" | grep -qE '(security scan|security review|security audit|vulnerabilit)' 2>/dev/null; then
71
+ elif printf '%s' "$LOWER" | grep -qE '(security scan|security review|security audit|vulnerabilit|보안.?검사|보안.?스캔|보안.?리뷰|취약점)' 2>/dev/null; then
67
72
  SKILL="afc:security"
68
- elif printf '%s' "$LOWER" | grep -qE '(architecture|architect|system design)' 2>/dev/null; then
73
+ elif printf '%s' "$LOWER" | grep -qE '(architecture|architect|system design|아키텍처|시스템.?설계|구조.?설계)' 2>/dev/null; then
69
74
  SKILL="afc:architect"
70
- elif printf '%s' "$LOWER" | grep -qE '(doctor|health check|diagnose.*project)' 2>/dev/null; then
75
+ elif printf '%s' "$LOWER" | grep -qE '(doctor|health check|diagnose.*project|진단|상태.?확인|헬스.?체크)' 2>/dev/null; then
71
76
  SKILL="afc:doctor"
72
- elif printf '%s' "$LOWER" | grep -qE '(quality audit|qa audit|project quality)' 2>/dev/null; then
77
+ elif printf '%s' "$LOWER" | grep -qE '(quality audit|qa audit|project quality|품질.?감사|품질.?점검|qa.?점검)' 2>/dev/null; then
73
78
  SKILL="afc:qa"
74
- elif printf '%s' "$LOWER" | grep -qE '(new release|version bump|changelog|publish.*package)' 2>/dev/null; then
79
+ # NOTE: release-notes MUST come before launch 릴리스.?노트 vs 릴리스 순서 의존
80
+ elif printf '%s' "$LOWER" | grep -qE '(release note|릴리스.?노트|변경.?이력|release.?note)' 2>/dev/null; then
81
+ SKILL="afc:release-notes"
82
+ elif printf '%s' "$LOWER" | grep -qE '(new release|version bump|changelog|publish.*package|릴리스|버전.?업|배포.?준비)' 2>/dev/null; then
75
83
  SKILL="afc:launch"
84
+ elif printf '%s' "$LOWER" | grep -qE '(triage|pr.?정리|이슈.?정리|백로그.?정리|pr.?분류|이슈.?분류)' 2>/dev/null; then
85
+ SKILL="afc:triage"
76
86
  # Medium confidence: still distinctive but broader
77
- elif printf '%s' "$LOWER" | grep -qE '(specification|requirements|acceptance criteria)' 2>/dev/null; then
87
+ elif printf '%s' "$LOWER" | grep -qE '(specification|requirements|acceptance criteria|요구.?사항|기능.?정의|인수.?조건)' 2>/dev/null; then
78
88
  SKILL="afc:spec"
79
- elif printf '%s' "$LOWER" | grep -qE '(brainstorm|ideate|what to build|product brief)' 2>/dev/null; then
89
+ elif printf '%s' "$LOWER" | grep -qE '(brainstorm|ideate|what to build|product brief|아이디어|브레인스토밍|뭘.*만들)' 2>/dev/null; then
80
90
  SKILL="afc:ideate"
81
- elif printf '%s' "$LOWER" | grep -qE '(expert advice)' 2>/dev/null; then
91
+ elif printf '%s' "$LOWER" | grep -qE '(expert advice|discuss|advice|think together|같이.*생각|함께.*생각|상의|조언|의견.*구|자문|상담)' 2>/dev/null; then
82
92
  SKILL="afc:consult"
83
- elif printf '%s' "$LOWER" | grep -qE '(analyz|trace.*flow|how does.*work)' 2>/dev/null; then
93
+ elif printf '%s' "$LOWER" | grep -qE '(analyz|trace.*flow|how does.*work|분석|추적|어떻게.*동작|흐름.*파악)' 2>/dev/null; then
84
94
  SKILL="afc:analyze"
85
- elif printf '%s' "$LOWER" | grep -qE '(research|investigat|compare.*lib)' 2>/dev/null; then
95
+ elif printf '%s' "$LOWER" | grep -qE '(research|investigat|compare.*lib|조사|리서치|비교.*라이브러리|탐색)' 2>/dev/null; then
86
96
  SKILL="afc:research"
87
- # Lower confidence: common verbs
88
- elif printf '%s' "$LOWER" | grep -qE '(implement|add feature|refactor|modify.*code)' 2>/dev/null; then
97
+ elif printf '%s' "$LOWER" | grep -qE '(clean.*up|cleanup|아티팩트.?정리|파이프라인.?정리|산출물.?정리)' 2>/dev/null; then
98
+ SKILL="afc:clean"
99
+ # Lower confidence: common verbs — auto for non-trivial feature scopes
100
+ elif printf '%s' "$LOWER" | grep -qE '(새.*기능|신규.*기능|기능.*개발|기능.*만들|feature.*develop|build.*feature|develop.*feature|create.*feature)' 2>/dev/null; then
101
+ SKILL="afc:auto"
102
+ elif printf '%s' "$LOWER" | grep -qE '(implement|add feature|refactor|modify.*code|리팩터|리팩토링|코드.?수정)' 2>/dev/null; then
89
103
  SKILL="afc:implement"
90
- elif printf '%s' "$LOWER" | grep -qE '(review)' 2>/dev/null; then
104
+ elif printf '%s' "$LOWER" | grep -qE '(fix|error|issue|problem|failing|수정|고쳐|문제)' 2>/dev/null; then
105
+ SKILL="afc:debug"
106
+ elif printf '%s' "$LOWER" | grep -qE '(review|검토|리뷰)' 2>/dev/null; then
91
107
  SKILL="afc:review"
92
- elif printf '%s' "$LOWER" | grep -qE '(spec[^a-z]|spec$)' 2>/dev/null; then
108
+ elif printf '%s' "$LOWER" | grep -qE '(spec[^a-z]|spec$|스펙)' 2>/dev/null; then
93
109
  SKILL="afc:spec"
94
- elif printf '%s' "$LOWER" | grep -qE '(plan[^a-z]|plan$)' 2>/dev/null; then
110
+ elif printf '%s' "$LOWER" | grep -qE '(plan[^a-z]|plan$|계획|설계)' 2>/dev/null; then
95
111
  SKILL="afc:plan"
96
112
  fi
97
113
 
@@ -99,13 +115,15 @@ if ! afc_state_is_active; then
99
115
  if [ -n "$SKILL" ]; then
100
116
  HINT="[afc:route -> ${SKILL}] Detected intent from user prompt. Invoke /${SKILL} via Skill tool."
101
117
  else
102
- HINT="[afc] If this request matches an afc skill, invoke it via Skill tool. See CLAUDE.md routing table."
118
+ HINT="$FALLBACK_HINT"
103
119
  fi
104
120
 
105
121
  if command -v jq >/dev/null 2>&1; then
106
122
  jq -n --arg c "$HINT" '{"hookSpecificOutput":{"additionalContext":$c}}'
107
123
  else
108
- printf '{"hookSpecificOutput":{"additionalContext":"%s"}}\n' "$HINT"
124
+ SAFE_HINT="${HINT//\\/\\\\}"
125
+ SAFE_HINT="${SAFE_HINT//\"/\\\"}"
126
+ printf '{"hookSpecificOutput":{"additionalContext":"%s"}}\n' "$SAFE_HINT"
109
127
  fi
110
128
  exit 0
111
129
  fi
@@ -0,0 +1,27 @@
1
+ <!-- afc:auto-generated — do not edit manually; regenerate with /afc:init -->
2
+ # Project Rules
3
+
4
+ > Auto-generated by /afc:init. Claude Code loads this file automatically for all conversations.
5
+ > For CI/gate/test commands, see .claude/afc.config.md.
6
+
7
+ ## Architecture
8
+
9
+ - **Pattern**: (e.g., FSD, Clean Architecture, Layered, Modular, Flat)
10
+ - **Key layers**: (e.g., app, pages, widgets, features, entities, shared)
11
+ - **Import rule**: (e.g., upper layers may import lower only, no cross-feature imports)
12
+ - **Path alias**: (e.g., @/ → src/)
13
+
14
+ ## Code Style
15
+
16
+ - **Language**: (e.g., TypeScript strict, JavaScript ESM, Python 3.12)
17
+ - **Naming**: (e.g., PascalCase components, camelCase functions, UPPER_SNAKE constants)
18
+ - **Lint**: (e.g., ESLint flat config + Prettier, Biome)
19
+ - **Key rules**: (e.g., import type separated, no any, prefer const)
20
+
21
+ ## Project Context
22
+
23
+ - **Framework**: (e.g., Next.js 14 App Router, FastAPI, Express)
24
+ - **State**: (e.g., Zustand + TanStack Query, Redux Toolkit, Pinia)
25
+ - **Styling**: (e.g., Tailwind CSS, styled-components, CSS Modules)
26
+ - **Testing**: (e.g., Vitest + Playwright, Jest + Cypress)
27
+ - **DB/ORM**: (e.g., PostgreSQL + Prisma, MongoDB + Mongoose)
@@ -1,8 +1,8 @@
1
1
  # Project Configuration
2
2
 
3
- > afc commands reference this file to determine project-specific behavior.
4
- > CI Commands are parsed by scripts keep the YAML format intact.
5
- > All other sections are free-form markdown write whatever best describes your project.
3
+ > CI Commands are parsed by hook scripts keep the YAML format intact.
4
+ > Architecture, Code Style, and Project Context sections below are detailed references.
5
+ > A concise summary is also generated in `.claude/rules/afc-project.md` (auto-loaded by Claude Code).
6
6
 
7
7
  ## CI Commands
8
8
 
@@ -11,6 +11,7 @@
11
11
  ci: "npm run ci"
12
12
  gate: "npm run typecheck && npm run lint"
13
13
  test: "npm test"
14
+ tdd: "off" # TDD mode: "strict" (block impl without tests), "guide" (warn only), "off" (disabled)
14
15
  ```
15
16
 
16
17
  ## Architecture