@dtt_siye/atool 1.3.1 → 1.4.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.
package/lib/common.sh CHANGED
@@ -140,11 +140,9 @@ ensure_dir() {
140
140
  # ── IDE Config Directory Helpers (cross-platform) ─────────────────────────────
141
141
 
142
142
  get_claude_config_dir() {
143
- if is_windows && [[ -n "${APPDATA:-}" ]]; then
144
- cygpath -u "$APPDATA/claude" 2>/dev/null || echo "$HOME/.claude"
145
- else
146
- echo "$HOME/.claude"
147
- fi
143
+ # Claude Code CLI always uses ~/.claude/ on all platforms
144
+ # (APPDATA/claude is the Claude Desktop app, not the CLI)
145
+ echo "$HOME/.claude"
148
146
  }
149
147
 
150
148
  get_cursor_config_dir() {
@@ -861,15 +859,20 @@ scan_skills_catalog() {
861
859
  ;;
862
860
  pdf|docx|pptx|xlsx)
863
861
  office="${office}- ${skill_name}: ${desc}
862
+ "
863
+ ;;
864
+ # Core initialization
865
+ atool-init)
866
+ planning="${planning}- ${skill_name}: ${desc}
864
867
  "
865
868
  ;;
866
869
  # Architecture & Design
867
- software-architecture|ai-project-architecture|ui-ux-pro)
870
+ software-architecture|ai-project-architecture|ui-ux-pro|architecture-guard)
868
871
  arch_design="${arch_design}- ${skill_name}: ${desc}
869
872
  "
870
873
  ;;
871
874
  # Quality & Review
872
- code-review|project-analyze|project-query|verification-before-completion)
875
+ code-review|project-analyze|project-query|verification-before-completion|agent-audit)
873
876
  quality_review="${quality_review}- ${skill_name}: ${desc}
874
877
  "
875
878
  ;;
@@ -879,8 +882,13 @@ scan_skills_catalog() {
879
882
  "
880
883
  ;;
881
884
  # Planning & Dispatch
882
- writing-plans|smart-dispatch|brainstorming|clarify-before-build)
885
+ writing-plans|smart-dispatch|brainstorming|clarify-before-build|using-git-worktrees|find-skills)
883
886
  planning="${planning}- ${skill_name}: ${desc}
887
+ "
888
+ ;;
889
+ # Testing & Automation
890
+ webapp-testing|ci-feedback)
891
+ quality_review="${quality_review}- ${skill_name}: ${desc}
884
892
  "
885
893
  ;;
886
894
  *)
@@ -890,26 +898,31 @@ scan_skills_catalog() {
890
898
  esac
891
899
  done
892
900
 
893
- # Check for Superpowers skills
901
+ # Check for Superpowers skills (only if Superpowers directory exists and is separate from skills_dir)
894
902
  local sp_dir="$skills_dir"
895
903
  if [[ -d "$skills_dir/_superpowers/skills" ]]; then
896
904
  sp_dir="$skills_dir/_superpowers/skills"
897
905
  fi
898
- for skill_dir in "$sp_dir"/*/; do
899
- [[ ! -d "$skill_dir" ]] && continue
900
- local skill_name
901
- skill_name=$(basename "$skill_dir")
902
- [[ -L "$skill_dir" ]] && continue
903
- local sp_md="$skill_dir/SKILL.md"
904
- [[ ! -f "$sp_md" ]] && continue
905
- local desc=""
906
- desc=$(head -10 "$sp_md" | sed -n '/^---$/,/^---$/p' | grep '^description:' | head -1 | sed 's/^description:[[:space:]]*//')
907
- if [[ -z "$desc" ]]; then
908
- desc=$(head -10 "$sp_md" | grep -i '^#' | head -1 | sed 's/^#*\s*//' || echo "$skill_name")
909
- fi
910
- superpowers_list="${superpowers_list}- ${skill_name}: ${desc}
906
+
907
+ # Only scan Superpowers directory if it exists and is NOT the same as skills_dir
908
+ # (prevents double-scanning skills already categorized in first loop)
909
+ if [[ "$sp_dir" != "$skills_dir" ]] && [[ -d "$sp_dir" ]]; then
910
+ for skill_dir in "$sp_dir"/*/; do
911
+ [[ ! -d "$skill_dir" ]] && continue
912
+ local skill_name
913
+ skill_name=$(basename "$skill_dir")
914
+ [[ -L "$skill_dir" ]] && continue
915
+ local sp_md="$skill_dir/SKILL.md"
916
+ [[ ! -f "$sp_md" ]] && continue
917
+ local desc=""
918
+ desc=$(head -10 "$sp_md" | sed -n '/^---$/,/^---$/p' | grep '^description:' | head -1 | sed 's/^description:[[:space:]]*//')
919
+ if [[ -z "$desc" ]]; then
920
+ desc=$(head -10 "$sp_md" | grep -i '^#' | head -1 | sed 's/^#*\s*//' || echo "$skill_name")
921
+ fi
922
+ superpowers_list="${superpowers_list}- ${skill_name}: ${desc}
911
923
  "
912
- done
924
+ done
925
+ fi
913
926
 
914
927
  # Output catalog
915
928
  if [[ -n "$conventions" ]]; then
@@ -591,6 +591,79 @@ compute_importance() {
591
591
  rm -rf "$tmpdir"
592
592
  }
593
593
 
594
+ # === Batch Processing (for pre-scan manifest.json) ===
595
+
596
+ # Update manifest.json modules array with importance scores
597
+ # Args: MANIFEST_PATH - path to manifest.json
598
+ # PROJECT_ROOT - project root directory (parent of .atool-docs)
599
+ # Updates: manifest.json modules[].importance field in-place
600
+ compute_importance_batch() {
601
+ local manifest_path="${1:-.atool-docs/pre-scan/manifest.json}"
602
+ local project_root="${2:-.}"
603
+
604
+ if [[ ! -f "$manifest_path" ]]; then
605
+ log_error "Manifest not found: $manifest_path"
606
+ return 1
607
+ fi
608
+
609
+ log_info "Computing importance scores for modules in manifest..."
610
+
611
+ # Get inventory directory from project_root
612
+ local inventory_dir="${project_root}/.atool-docs/inventory"
613
+
614
+ # Read modules from manifest
615
+ local modules_json
616
+ modules_json=$(jq -r '.modules[] | .slug' "$manifest_path" 2>/dev/null)
617
+
618
+ if [[ -z "$modules_json" ]]; then
619
+ log_warn "No modules found in manifest"
620
+ return 0
621
+ fi
622
+
623
+ # Build module path map: slug -> importance_score
624
+ local tmpdir
625
+ tmpdir=$(mktemp -d)
626
+
627
+ # Discover all modules in project and compute importance
628
+ local all_modules
629
+ all_modules=$(discover_modules "$project_root")
630
+
631
+ if [[ -z "$all_modules" ]]; then
632
+ log_warn "No source modules found in project"
633
+ echo "{}" > "$tmpdir/importance_map"
634
+ else
635
+ # Compute importance for all discovered modules
636
+ log_info "Computing importance factors for discovered modules..."
637
+ local importance_output
638
+ importance_output=$(compute_importance "$project_root" --inventory-dir "$inventory_dir" 2>/dev/null || true)
639
+
640
+ # Build slug-to-importance map from output (module_path<tab>score<tab>tier)
641
+ # Convert module path to slug: extract last path component
642
+ {
643
+ while IFS=$'\t' read -r module_path score tier; do
644
+ [[ -z "$module_path" ]] && continue
645
+ local slug
646
+ slug=$(basename "$module_path")
647
+ printf '%s\t%s\n' "$slug" "$score"
648
+ done <<< "$importance_output"
649
+ } > "$tmpdir/importance_map"
650
+ fi
651
+
652
+ # Update manifest.json with importance scores
653
+ log_info "Updating manifest with importance scores..."
654
+ jq --slurpfile importance_data <(cat "$tmpdir/importance_map" | jq -R 'split("\t") | {key: .[0], value: (.[1] | tonumber)}' | jq -s 'from_entries') \
655
+ '.modules |= map(.importance = ($importance_data[0][.slug] // 0))' \
656
+ "$manifest_path" > "$tmpdir/manifest_updated.json"
657
+
658
+ # Atomically replace manifest
659
+ mv "$tmpdir/manifest_updated.json" "$manifest_path"
660
+
661
+ # Cleanup
662
+ rm -rf "$tmpdir"
663
+
664
+ log_success "Importance scores computed and manifest updated"
665
+ }
666
+
594
667
  # === Standalone Execution ===
595
668
  # When run directly (not sourced), execute compute_importance with CLI args
596
669
  if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
@@ -79,8 +79,8 @@ should_always_apply() {
79
79
  project-analyze) return 0 ;;
80
80
  # Workflow skill with no good glob match - must be always-on
81
81
  using-git-worktrees) return 0 ;;
82
- # Conventions skills - always relevant for their file types (via globs too)
83
- *-conventions) return 0 ;;
82
+ # Conventions skills - globs handle triggering by file type (no need for alwaysApply)
83
+ *-conventions) return 1 ;;
84
84
  # All other skills: use globs or on-demand (reduces context token consumption)
85
85
  *) return 1 ;;
86
86
  esac
@@ -132,6 +132,58 @@ install_hooks() {
132
132
  fi
133
133
  fi
134
134
 
135
+ # Install pre-commit hook (PreToolUse - checks before git commit)
136
+ local pre_commit_src="$atool_root/hooks/pre-commit"
137
+ if [[ -f "$pre_commit_src" ]]; then
138
+ local pre_commit_name="atool-pre-commit"
139
+ local dest_pre_commit="$hooks_dir/$pre_commit_name"
140
+
141
+ if [[ -f "$dest_pre_commit" ]] && [[ "${ATOOL_FORCE:-0}" != "1" ]]; then
142
+ local pc_existing pc_source
143
+ pc_existing=$(file_checksum "$dest_pre_commit")
144
+ pc_source=$(file_checksum "$pre_commit_src")
145
+ if [[ "$pc_existing" == "$pc_source" ]]; then
146
+ log_info "Hook '$pre_commit_name' already up to date, skipping"
147
+ else
148
+ log_info "Hook '$pre_commit_name' exists but differs - backing up"
149
+ backup_file "$dest_pre_commit"
150
+ run_cmd cp "$pre_commit_src" "$dest_pre_commit"
151
+ run_cmd chmod +x "$dest_pre_commit"
152
+ log_success "Hook installed: $dest_pre_commit"
153
+ fi
154
+ else
155
+ run_cmd cp "$pre_commit_src" "$dest_pre_commit"
156
+ run_cmd chmod +x "$dest_pre_commit"
157
+ log_success "Hook installed: $dest_pre_commit"
158
+ fi
159
+ fi
160
+
161
+ # Install task-state-tracker hook (PostToolUse - tracks session state)
162
+ local task_state_src="$atool_root/hooks/task-state-tracker"
163
+ if [[ -f "$task_state_src" ]]; then
164
+ local task_state_name="atool-task-state-tracker"
165
+ local dest_task_state="$hooks_dir/$task_state_name"
166
+
167
+ if [[ -f "$dest_task_state" ]] && [[ "${ATOOL_FORCE:-0}" != "1" ]]; then
168
+ local ts_existing ts_source
169
+ ts_existing=$(file_checksum "$dest_task_state")
170
+ ts_source=$(file_checksum "$task_state_src")
171
+ if [[ "$ts_existing" == "$ts_source" ]]; then
172
+ log_info "Hook '$task_state_name' already up to date, skipping"
173
+ else
174
+ log_info "Hook '$task_state_name' exists but differs - backing up"
175
+ backup_file "$dest_task_state"
176
+ run_cmd cp "$task_state_src" "$dest_task_state"
177
+ run_cmd chmod +x "$dest_task_state"
178
+ log_success "Hook installed: $dest_task_state"
179
+ fi
180
+ else
181
+ run_cmd cp "$task_state_src" "$dest_task_state"
182
+ run_cmd chmod +x "$dest_task_state"
183
+ log_success "Hook installed: $dest_task_state"
184
+ fi
185
+ fi
186
+
135
187
  # Install hooks config JSON
136
188
  local config_file
137
189
  case "$ide_type" in
@@ -224,6 +276,18 @@ install_hooks_global() {
224
276
  run_cmd chmod +x "$claude_hooks_dir/atool-doc-sync-reminder"
225
277
  fi
226
278
 
279
+ # Copy pre-commit hook (PreToolUse)
280
+ if [[ -f "$atool_root/hooks/pre-commit" ]]; then
281
+ run_cmd cp "$atool_root/hooks/pre-commit" "$claude_hooks_dir/atool-pre-commit"
282
+ run_cmd chmod +x "$claude_hooks_dir/atool-pre-commit"
283
+ fi
284
+
285
+ # Copy task-state-tracker hook (PostToolUse)
286
+ if [[ -f "$atool_root/hooks/task-state-tracker" ]]; then
287
+ run_cmd cp "$atool_root/hooks/task-state-tracker" "$claude_hooks_dir/atool-task-state-tracker"
288
+ run_cmd chmod +x "$claude_hooks_dir/atool-task-state-tracker"
289
+ fi
290
+
227
291
  # 2. Register hooks config in settings.json
228
292
  # Claude Code reads hooks from settings.json, NOT from files on disk
229
293
  local settings_file="$claude_config_dir/settings.json"
@@ -122,8 +122,11 @@ install_skills() {
122
122
  # Skills reference scripts via "source lib/X.sh" relative to the skill dir
123
123
  local skill_lib_dir="$target_skill/lib"
124
124
  local referenced_libs
125
- referenced_libs=$(find "$target_skill/phases" "$target_skill" -maxdepth 2 -name '*.md' -exec grep -roh 'source lib/[^ ]*\.sh' {} + 2>/dev/null \
126
- | sed 's/source lib\///' | sort -u)
125
+ local _find_paths=()
126
+ [[ -d "$target_skill/phases" ]] && _find_paths+=("$target_skill/phases")
127
+ _find_paths+=("$target_skill")
128
+ referenced_libs=$(find "${_find_paths[@]}" -maxdepth 2 -name '*.md' -exec grep -roh 'source lib/[^ ]*\.sh' {} + 2>/dev/null \
129
+ | sed 's/source lib\///' | sort -u || true)
127
130
  if [[ -n "$referenced_libs" ]]; then
128
131
  run_cmd mkdir -p "$skill_lib_dir"
129
132
  for lib_name in $referenced_libs; do
package/lib/pre-scan.sh CHANGED
@@ -1098,7 +1098,17 @@ pre_scan_project() {
1098
1098
  generated_at: (now | todate),
1099
1099
  total_modules: length,
1100
1100
  scan_duration_seconds: null,
1101
- modules: [.[].module_summary // {} | {total_files, total_classes, total_functions, total_api_endpoints, total_data_models}]
1101
+ modules: [.[] | {
1102
+ slug: .module,
1103
+ name: .module,
1104
+ importance: 0
1105
+ } + (.module_summary // {} | {
1106
+ total_files,
1107
+ total_classes,
1108
+ total_functions,
1109
+ total_api_endpoints,
1110
+ total_data_models
1111
+ })]
1102
1112
  }' "$output_dir"/*.json 2>/dev/null || echo '{}')
1103
1113
 
1104
1114
  # Add duration to manifest
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dtt_siye/atool",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "AI Developer Toolkit - 一键配置 AI IDE 的工具集",
5
5
  "bin": {
6
6
  "atool": "bin/atool.js"
@@ -0,0 +1,180 @@
1
+ ---
2
+ name: agent-audit
3
+ description: "Use when multiple agents or parallel tasks are running — tracks each agent's modifications, detects file conflicts, and provides audit trail. 在多Agent并行工作时使用 — 追踪每个Agent的修改、检测文件冲突、提供审计记录."
4
+ version: 0.1.0
5
+ category: quality
6
+ ---
7
+
8
+ # Agent Audit — Multi-Agent Modification Tracking
9
+
10
+ Tracks file modifications across multiple AI agents or parallel tasks, detects conflicts, and provides a complete audit trail for coordination.
11
+
12
+ ## When to Use
13
+
14
+ - When using `/smart-dispatch` for parallel agent execution
15
+ - When using `/dispatching-parallel-agents` for independent tasks
16
+ - When using `/subagent-driven-development` for implementation plans
17
+ - After parallel agents complete, before merging results
18
+ - When reviewing what changes each agent made
19
+
20
+ ## How It Works
21
+
22
+ ### Audit Log Format
23
+
24
+ Each agent's modifications are recorded in `.claude/agent-audit.json`:
25
+
26
+ ```json
27
+ {
28
+ "audit_entries": [
29
+ {
30
+ "agent_id": "agent-1",
31
+ "task": "Implement user authentication",
32
+ "started_at": 1712649600,
33
+ "completed_at": 1712649900,
34
+ "files_modified": [
35
+ {
36
+ "path": "src/auth/UserService.java",
37
+ "action": "modified",
38
+ "lines_added": 45,
39
+ "lines_removed": 12,
40
+ "intent": "Add JWT token generation"
41
+ }
42
+ ],
43
+ "files_planned": ["src/auth/UserService.java", "src/auth/AuthController.java"],
44
+ "files_unexpected": [],
45
+ "impact_scope": ["auth", "api"],
46
+ "status": "completed"
47
+ }
48
+ ],
49
+ "conflicts": [],
50
+ "summary": {
51
+ "total_agents": 3,
52
+ "total_files_modified": 8,
53
+ "conflicts_detected": 0
54
+ }
55
+ }
56
+ ```
57
+
58
+ ### Step 1: Agent Registration
59
+
60
+ Before dispatching an agent, register it:
61
+
62
+ ```
63
+ Read: agent-audit.json (or create if not exists)
64
+ Add entry:
65
+ {
66
+ "agent_id": "{agent-N}",
67
+ "task": "{task description}",
68
+ "files_planned": [{list of expected files}],
69
+ "started_at": {timestamp}
70
+ }
71
+ ```
72
+
73
+ ### Step 2: Modification Tracking
74
+
75
+ Each agent should record its modifications. Use git diff or task-state data:
76
+
77
+ ```
78
+ After agent completes:
79
+ git diff --stat HEAD → extract file list and line changes
80
+ Compare with files_planned → flag unexpected files
81
+ Cross-reference with knowledge-graph → compute impact_scope
82
+ ```
83
+
84
+ ### Step 3: Conflict Detection
85
+
86
+ After all agents complete, detect file-level conflicts:
87
+
88
+ ```
89
+ For each pair of agents (A, B):
90
+ overlap = A.files_modified ∩ B.files_modified
91
+ if overlap is not empty:
92
+ CONFLICT: agents A and B both modified: {overlap}
93
+ severity = check if changes are in same lines (git merge-base)
94
+ ```
95
+
96
+ Conflict severity levels:
97
+ - **Critical**: Same file, same lines → merge conflict likely
98
+ - **Warning**: Same file, different sections → manual review needed
99
+ - **Info**: Different files, same module → review for logical consistency
100
+
101
+ ### Step 4: Impact Analysis
102
+
103
+ Using knowledge-graph.json (from project-analyze):
104
+
105
+ ```
106
+ For each agent's modified files:
107
+ 1. Find the module each file belongs to
108
+ 2. Find upstream dependents (who depends on this module)
109
+ 3. Find downstream dependencies (what this module depends on)
110
+ 4. Compute impact scope = module + direct dependents
111
+ ```
112
+
113
+ ### Step 5: Consolidated Audit Report
114
+
115
+ ```
116
+ ## Agent Audit Report
117
+
118
+ ### Execution Summary
119
+ | Agent | Task | Files | Status | Duration |
120
+ |-------|------|-------|--------|----------|
121
+ | agent-1 | User auth | 3 | completed | 5m |
122
+ | agent-2 | Payment API | 4 | completed | 7m |
123
+ | agent-3 | Tests | 5 | completed | 4m |
124
+
125
+ ### File Overlap
126
+ | File | Agent-1 | Agent-2 | Agent-3 |
127
+ |------|---------|---------|---------|
128
+ | src/common/Utils.java | modified | - | modified |
129
+
130
+ ### Conflicts
131
+ | Severity | File | Details |
132
+ |----------|------|---------|
133
+ | Warning | src/common/Utils.java | Both agent-1 and agent-3 modified this file |
134
+
135
+ ### Impact Scope
136
+ | Agent | Modules Affected | Downstream Impact |
137
+ |-------|-----------------|-------------------|
138
+ | agent-1 | auth, api | gateway, frontend |
139
+ | agent-2 | payment, billing | notification, reporting |
140
+
141
+ ### Recommendations
142
+ 1. Review src/common/Utils.java for merge conflicts before integrating
143
+ 2. Run integration tests after merging all agent changes
144
+ 3. Update documentation for auth and payment modules
145
+ ```
146
+
147
+ ## Integration with task-state
148
+
149
+ The agent-audit reads from and writes to `.claude/task-state.json`:
150
+
151
+ ```json
152
+ {
153
+ "active_agents": 3,
154
+ "completed_agents": 2,
155
+ "agent_conflicts": ["src/common/Utils.java"],
156
+ "pending_actions": ["resolve_conflict:Utils.java", "run_integration_tests", "update_docs"]
157
+ }
158
+ ```
159
+
160
+ ## Smart-Dispatch Integration
161
+
162
+ When using `/smart-dispatch`:
163
+
164
+ 1. **Before dispatch**: Register each chunk as an agent entry
165
+ 2. **During execution**: Each agent records its modifications
166
+ 3. **After all complete**: Run conflict detection
167
+ 4. **Review phase**: Present consolidated audit report
168
+ 5. **Integration**: User resolves conflicts, then merge
169
+
170
+ ## Skill 协作
171
+
172
+ | 协作 Skill | 触发条件 | 交互方式 |
173
+ |-----------|---------|---------|
174
+ | smart-dispatch | Parallel execution | 每个chunk注册为agent,完成后审计 |
175
+ | dispatching-parallel-agents | Independent tasks | 跟踪每个后台agent的修改 |
176
+ | subagent-driven-development | Implementation plans | 追踪sub-agent修改范围 |
177
+ | project-analyze | Knowledge-graph available | 使用图谱计算impact scope |
178
+ | architecture-guard | Conflicts detected | 检查冲突是否违反架构约束 |
179
+ | verification-before-completion | After agent merge | 合并后验证整体完整性 |
180
+ | ci-feedback | After merge | 运行集成测试验证 |
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: architecture-guard
3
+ description: "Use when reviewing or modifying code in analyzed projects — detects architectural violations in real-time using knowledge-graph data. 在修改代码时使用 — 实时检测架构违规(分层违反/依赖方向/循环依赖/边界泄漏)."
4
+ version: 0.1.0
5
+ category: quality
6
+ ---
7
+
8
+ # Architecture Guard
9
+
10
+ Real-time architectural violation detection using knowledge-graph data. Prevents AI and developers from degrading system structure.
11
+
12
+ ## When to Use
13
+
14
+ - After modifying source files in a previously analyzed project (has `atool-analysis/` or `.atool-docs/`)
15
+ - Before committing changes to verify architectural compliance
16
+ - When reviewing code changes for structural correctness
17
+ - Auto-triggered by verification-before-completion for analyzed projects
18
+
19
+ ## How It Works
20
+
21
+ Architecture-guard reads the knowledge-graph.json produced by `/project-analyze` and checks:
22
+
23
+ 1. **Dependency Direction** — Enforces layer ordering (e.g., Controller → Service → DAO). Reverse dependencies are violations.
24
+ 2. **Package Structure** — New files must belong to recognized package paths.
25
+ 3. **API Boundary Leaks** — Response/DTO types should not appear in Service/DAO layers.
26
+ 4. **Circular Dependencies** — New imports must not introduce cycles.
27
+
28
+ ## Guard Process
29
+
30
+ ### Step 1: Load Architecture Data
31
+
32
+ ```
33
+ Read: atool-analysis/knowledge-graph.json (or .atool-docs/knowledge-graph.json)
34
+ Extract:
35
+ - architectural_layers: {layer_name: [module_names]}
36
+ - edges: [{source, target, edge_type}]
37
+ - nodes: [{id, type, layer}]
38
+ ```
39
+
40
+ If no knowledge-graph.json exists, warn the user and suggest running `/project-analyze` first.
41
+
42
+ ### Step 2: Detect Violations in Changed Files
43
+
44
+ For each modified source file, check:
45
+
46
+ #### 2a. Dependency Direction Check
47
+
48
+ ```
49
+ For each import/dependency in the modified file:
50
+ source_layer = lookup layer of the modified file's module
51
+ target_layer = lookup layer of the imported module
52
+ if source_layer is lower than target_layer in the layer ordering:
53
+ VIOLATION: "Reverse dependency: {source} ({source_layer}) imports {target} ({target_layer})"
54
+ ```
55
+
56
+ Common layer ordering (adjustable per project):
57
+ - **Java/Spring**: Controller → Service → Repository → Entity
58
+ - **Web/React**: Page → Component → Hook → Service → API
59
+ - **Go**: Handler → Service → Repository → Model
60
+ - **Python**: Route → Service → Repository → Model
61
+
62
+ #### 2b. API Boundary Leak Check
63
+
64
+ ```
65
+ For each import in the modified file:
66
+ if the file is in Service/Repository layer:
67
+ check if imported type is a Response/DTO/ViewModel (belongs to API/Presentation layer)
68
+ if yes: VIOLATION: "API type {type} leaked into {layer} layer"
69
+ ```
70
+
71
+ #### 2c. Circular Dependency Check
72
+
73
+ ```
74
+ Build dependency graph from knowledge-graph edges + new imports
75
+ Run cycle detection (DFS)
76
+ if cycle found: VIOLATION: "Circular dependency: {cycle_path}"
77
+ ```
78
+
79
+ #### 2d. Module Boundary Check
80
+
81
+ ```
82
+ For each new file or moved file:
83
+ Check if it belongs to a recognized module boundary
84
+ if it crosses module boundaries (imports from unrelated modules):
85
+ WARNING: "Cross-module import: {source_module} → {target_module}"
86
+ ```
87
+
88
+ ### Step 3: Report Results
89
+
90
+ Output a structured violation report:
91
+
92
+ ```
93
+ ## Architecture Guard Report
94
+
95
+ ### Summary
96
+ - Files checked: {n}
97
+ - Violations: {n} (Critical: {n}, Warning: {n})
98
+ - Status: PASS / FAIL
99
+
100
+ ### Violations
101
+
102
+ | Severity | Type | File | Details |
103
+ |----------|------|------|---------|
104
+ | Critical | Reverse Dependency | UserService.java | Imports UserController (Controller→Service violation) |
105
+ | Critical | Circular Dependency | OrderService.java | Cycle: OrderService → UserService → OrderService |
106
+ | Warning | API Boundary Leak | PaymentService.java | Uses OrderResponse (DTO in Service layer) |
107
+ | Warning | Cross-Module | notification.go | Imports billing/invoice.go (unrelated domain) |
108
+ ```
109
+
110
+ ### Step 4: Suggest Fixes
111
+
112
+ For each violation, provide:
113
+ 1. The specific line/import causing the issue
114
+ 2. Why it violates the architecture
115
+ 3. Suggested fix (e.g., "Move logic to OrderService", "Use OrderEntity instead of OrderResponse")
116
+
117
+ ## Integration Points
118
+
119
+ ### With verification-before-completion
120
+ When the project has been analyzed, verification-before-completion should invoke architecture-guard as an additional check before claiming complete.
121
+
122
+ ### With code-review
123
+ Architecture violations detected here feed into the `architecture` dimension of `/code-review` with specific line-level details.
124
+
125
+ ### With project-analyze
126
+ Reads the knowledge-graph.json output from `/project-analyze`. If the graph is stale (older than source files), suggest re-running analysis.
127
+
128
+ ## Layer Definition Patterns
129
+
130
+ The guard auto-detects layer patterns from the knowledge-graph:
131
+
132
+ | Pattern | Layers |
133
+ |---------|--------|
134
+ | **Spring Boot** | controller → service → repository → entity |
135
+ | **Clean Architecture** | presentation → application → domain → infrastructure |
136
+ | **Hexagonal** | adapter/in → port/in → application → port/out → adapter/out |
137
+ | **Generic Web** | page → component → service → data |
138
+ | **DDD** | ui → application → domain → infrastructure |
139
+
140
+ If no layers are detected, fall back to directory-based heuristics:
141
+ - `controller/` / `handler/` / `api/` → Presentation
142
+ - `service/` / `usecase/` / `application/` → Application
143
+ - `repository/` / `dao/` / `store/` / `data/` → Data
144
+ - `model/` / `entity/` / `domain/` → Domain
145
+
146
+ ## Severity Classification
147
+
148
+ | Type | Severity | Auto-fixable |
149
+ |------|----------|-------------|
150
+ | Reverse dependency | Critical | Sometimes (move import) |
151
+ | Circular dependency | Critical | Often (extract interface) |
152
+ | API boundary leak | Warning | Yes (use internal type) |
153
+ | Cross-module import | Warning | Context-dependent |
154
+ | New unknown module | Info | No (may need new layer) |
155
+
156
+ ## Skill 协作
157
+
158
+ | 协作 Skill | 触发条件 | 交互方式 |
159
+ |-----------|---------|---------|
160
+ | project-analyze | No knowledge-graph.json found | 建议运行 `/project-analyze` 生成图谱 |
161
+ | code-review | Architecture dimension scoring | 提供层违反数据给 code-review |
162
+ | verification-before-completion | Analyzed project, before claiming done | 作为额外检查步骤 |
163
+ | {stack}-conventions | Stack-specific layer patterns | 加载栈级分层规范 |
164
+ | software-architecture | Architecture score < 60 | 建议运行架构重构 |