@dtt_siye/atool 1.3.0 → 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/VERSION +1 -1
- package/hooks/doc-sync-reminder +4 -4
- package/hooks/hooks-cursor.json +20 -0
- package/hooks/hooks.json +21 -1
- package/hooks/pre-commit +191 -0
- package/hooks/prompt-guard +84 -35
- package/hooks/session-start +34 -12
- package/hooks/task-state-tracker +145 -0
- package/lib/common.sh +36 -23
- package/lib/compute-importance.sh +73 -0
- package/lib/install-cursor.sh +2 -2
- package/lib/install-hooks.sh +64 -0
- package/lib/install-skills.sh +19 -0
- package/lib/knowledge-graph.sh +483 -81
- package/lib/pre-scan.sh +81 -6
- package/package.json +1 -1
- package/skills/agent-audit/SKILL.md +180 -0
- package/skills/architecture-guard/SKILL.md +164 -0
- package/skills/architecture-guard/rules/violation-detection.md +90 -0
- package/skills/ci-feedback/SKILL.md +165 -0
- package/skills/project-analyze/SKILL.md +131 -23
- package/skills/project-analyze/phases/phase1-setup.md +15 -1
- package/skills/project-analyze/phases/phase2-understand.md +17 -2
- package/skills/project-analyze/phases/phase2.5-refine.md +293 -0
- package/skills/project-analyze/phases/phase3-graph.md +7 -1
- package/skills/project-analyze/phases/phase4-synthesize.md +117 -120
- package/skills/project-analyze/phases/phase5-export.md +117 -33
- package/skills/project-analyze/prompts/understand-agent.md +17 -0
- package/skills/project-analyze/rules/android.md +61 -260
- package/skills/project-analyze/rules/devops.md +61 -421
- package/skills/project-analyze/rules/generic.md +53 -221
- package/skills/project-analyze/rules/go.md +60 -275
- package/skills/project-analyze/rules/harmony.md +64 -237
- package/skills/project-analyze/rules/java.md +47 -485
- package/skills/project-analyze/rules/mobile-flutter.md +57 -292
- package/skills/project-analyze/rules/mobile-react-native.md +65 -262
- package/skills/project-analyze/rules/mobile-swift.md +58 -303
- package/skills/project-analyze/rules/python.md +50 -296
- package/skills/project-analyze/rules/rust-tauri.md +51 -217
- package/skills/project-analyze/rules/rust.md +50 -274
- package/skills/project-analyze/rules/web-nextjs.md +61 -335
- package/skills/project-analyze/rules/web-react.md +50 -272
- package/skills/project-analyze/rules/web-vue.md +58 -352
- package/skills/project-analyze/rules/web.md +55 -347
- package/skills/project-query/SKILL.md +681 -120
- package/skills/requirements-writer/SKILL.md +48 -1
- package/skills/software-architecture/SKILL.md +73 -3
package/lib/pre-scan.sh
CHANGED
|
@@ -426,7 +426,7 @@ _extract_typescript() {
|
|
|
426
426
|
local lang="typescript"
|
|
427
427
|
[[ "$rel_path" == *.js || "$rel_path" == *.jsx ]] && lang="javascript"
|
|
428
428
|
|
|
429
|
-
# --- Imports ---
|
|
429
|
+
# --- Imports (enhanced with named symbols for cross-reference) ---
|
|
430
430
|
local imports_json="[]"
|
|
431
431
|
imports_json=$({ grep -n -E '^(import |const .* = require)' "$file" 2>/dev/null || true; } | awk -F: '
|
|
432
432
|
{
|
|
@@ -435,20 +435,47 @@ _extract_typescript() {
|
|
|
435
435
|
if (content ~ /^import /) {
|
|
436
436
|
# ES module import
|
|
437
437
|
source = ""
|
|
438
|
+
syms = "[]"
|
|
439
|
+
# Extract source path
|
|
438
440
|
if (match(content, /from "[^"]*"/)) {
|
|
439
441
|
source = substr(content, RSTART+6, RLENGTH-7)
|
|
440
442
|
} else if (match(content, /"[^"]*"/)) {
|
|
441
443
|
source = substr(content, RSTART+1, RLENGTH-2)
|
|
442
444
|
}
|
|
445
|
+
# Extract named symbols from destructured import: import { X, Y } from ...
|
|
446
|
+
if (match(content, /\{[^}]+\}/)) {
|
|
447
|
+
brace = substr(content, RSTART+1, RLENGTH-2)
|
|
448
|
+
gsub(/^[[:space:]]+/, "", brace)
|
|
449
|
+
gsub(/[[:space:]]+$/, "", brace)
|
|
450
|
+
n = split(brace, parts, ",")
|
|
451
|
+
sym_arr = "["
|
|
452
|
+
for (i = 1; i <= n; i++) {
|
|
453
|
+
gsub(/^[[:space:]]+/, "", parts[i])
|
|
454
|
+
gsub(/[[:space:]]+$/, "", parts[i])
|
|
455
|
+
gsub(/[[:space:]]+as[[:space:]]+.*/, "", parts[i])
|
|
456
|
+
gsub(/=.*/, "", parts[i])
|
|
457
|
+
if (parts[i] != "") {
|
|
458
|
+
if (length(sym_arr) > 1) sym_arr = sym_arr ","
|
|
459
|
+
sym_arr = sym_arr "\"" parts[i] "\""
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
syms = sym_arr "]"
|
|
463
|
+
} else if (content ~ /^import [a-zA-Z_]/ && content !~ /^import type/ && content !~ /^import \*/) {
|
|
464
|
+
# Default import: import X from '"'"'Z'"'"'
|
|
465
|
+
tmp = content
|
|
466
|
+
gsub(/^import /, "", tmp)
|
|
467
|
+
gsub(/ .*$/, "", tmp)
|
|
468
|
+
syms = "[\"" tmp "\"]"
|
|
469
|
+
}
|
|
443
470
|
is_local = (source ~ /^\./ || source ~ /^@/) ? "true" : "false"
|
|
444
|
-
printf "{\"from\":\"%s\",\"import\":null,\"line\":%s,\"is_local\":%s}\n", source, line, is_local
|
|
471
|
+
printf "{\"from\":\"%s\",\"import\":null,\"line\":%s,\"is_local\":%s,\"symbols\":%s}\n", source, line, is_local, syms
|
|
445
472
|
} else if (index(content, "require(") > 0) {
|
|
446
473
|
source = ""
|
|
447
474
|
if (match(content, /"[^"]*"/)) {
|
|
448
475
|
source = substr(content, RSTART+1, RLENGTH-2)
|
|
449
476
|
}
|
|
450
477
|
is_local = (source ~ /^\./ || source ~ /^@/) ? "true" : "false"
|
|
451
|
-
printf "{\"from\":\"%s\",\"import\":null,\"line\":%s,\"is_local\":%s}\n", source, line, is_local
|
|
478
|
+
printf "{\"from\":\"%s\",\"import\":null,\"line\":%s,\"is_local\":%s,\"symbols\":[]}\n", source, line, is_local
|
|
452
479
|
}
|
|
453
480
|
}' | jq -s '.' 2>/dev/null || echo '[]')
|
|
454
481
|
|
|
@@ -687,7 +714,7 @@ _extract_rust() {
|
|
|
687
714
|
hash=$(file_checksum "$file")
|
|
688
715
|
line_count=$(wc -l < "$file" | tr -d ' ')
|
|
689
716
|
|
|
690
|
-
# --- Imports ---
|
|
717
|
+
# --- Imports (enhanced with symbols from use paths) ---
|
|
691
718
|
local imports_json="[]"
|
|
692
719
|
imports_json=$({ grep -n -E '^use ' "$file" 2>/dev/null || true; } | awk '
|
|
693
720
|
{
|
|
@@ -697,7 +724,45 @@ _extract_rust() {
|
|
|
697
724
|
gsub(/^use /, "", content)
|
|
698
725
|
gsub(/;.*$/, "", content)
|
|
699
726
|
gsub(/ *$/, "", content)
|
|
700
|
-
|
|
727
|
+
|
|
728
|
+
# Detect local imports: crate::, self::, super::, or crate-relative paths
|
|
729
|
+
is_local = "false"
|
|
730
|
+
if (content ~ /^crate::/ || content ~ /^super::/ || content ~ /^self::/) is_local = "true"
|
|
731
|
+
|
|
732
|
+
# Extract symbols from {A, B, C} grouped imports: use path::{A, B}
|
|
733
|
+
syms = "[]"
|
|
734
|
+
if (match(content, /\{[^}]+\}/)) {
|
|
735
|
+
brace = substr(content, RSTART+1, RLENGTH-2)
|
|
736
|
+
gsub(/^[[:space:]]+/, "", brace)
|
|
737
|
+
gsub(/[[:space:]]+$/, "", brace)
|
|
738
|
+
n = split(brace, parts, ",")
|
|
739
|
+
sym_arr = "["
|
|
740
|
+
for (i = 1; i <= n; i++) {
|
|
741
|
+
gsub(/^[[:space:]]+/, "", parts[i])
|
|
742
|
+
gsub(/[[:space:]]+$/, "", parts[i])
|
|
743
|
+
gsub(/[[:space:]]+as[[:space:]]+.*/, "", parts[i])
|
|
744
|
+
gsub(/ .*$/, "", parts[i])
|
|
745
|
+
if (parts[i] != "") {
|
|
746
|
+
if (length(sym_arr) > 1) sym_arr = sym_arr ","
|
|
747
|
+
sym_arr = sym_arr "\"" parts[i] "\""
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
syms = sym_arr "]"
|
|
751
|
+
} else {
|
|
752
|
+
# Single import: extract the last segment as symbol
|
|
753
|
+
n = split(content, seg, "::")
|
|
754
|
+
if (n > 0 && seg[n] != "" && seg[n] !~ /^\{/ && seg[n] !~ /\}$/) {
|
|
755
|
+
gsub(/[[:space:]]+as[[:space:]]+.*/, "", seg[n])
|
|
756
|
+
gsub(/ .*/, "", seg[n])
|
|
757
|
+
if (seg[n] != "*") {
|
|
758
|
+
syms = "[\"" seg[n] "\"]"
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
# Escape double quotes in content for JSON
|
|
764
|
+
gsub(/"/, "\\\"", content)
|
|
765
|
+
printf "{\"from\":\"%s\",\"import\":null,\"line\":%s,\"is_local\":%s,\"symbols\":%s}\n", content, line, is_local, syms
|
|
701
766
|
}' | jq -s '.' 2>/dev/null || echo '[]')
|
|
702
767
|
|
|
703
768
|
# --- Structs/Enums/Traits ---
|
|
@@ -1033,7 +1098,17 @@ pre_scan_project() {
|
|
|
1033
1098
|
generated_at: (now | todate),
|
|
1034
1099
|
total_modules: length,
|
|
1035
1100
|
scan_duration_seconds: null,
|
|
1036
|
-
modules: [.[]
|
|
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
|
+
})]
|
|
1037
1112
|
}' "$output_dir"/*.json 2>/dev/null || echo '{}')
|
|
1038
1113
|
|
|
1039
1114
|
# Add duration to manifest
|
package/package.json
CHANGED
|
@@ -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 | 建议运行架构重构 |
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Architecture Violation Detection Rules
|
|
2
|
+
|
|
3
|
+
## Dependency Direction Rules
|
|
4
|
+
|
|
5
|
+
### Rule 1: Strict Layer Ordering
|
|
6
|
+
Each layer may only depend on layers below it in the hierarchy. A dependency pointing upward is a violation.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
ALLOWED: Presentation → Application → Domain → Infrastructure
|
|
10
|
+
VIOLATION: Domain → Application (upward dependency)
|
|
11
|
+
VIOLATION: Infrastructure → Domain (skipping layers or upward)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Rule 2: No Cross-Skip Dependencies
|
|
15
|
+
A layer may not skip intermediate layers unless the intermediate layer has no relevant abstraction.
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
ALLOWED: Controller → Repository (if Service is just a pass-through)
|
|
19
|
+
VIOLATION: Page → API (skipping Service layer with business logic)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## API Boundary Rules
|
|
23
|
+
|
|
24
|
+
### Rule 3: No DTO Leakage
|
|
25
|
+
Response/DTO/ViewModel types must NOT appear in Service or Repository layers.
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
VIOLATION: PaymentService.java imports OrderResponse
|
|
29
|
+
VIOLATION: UserRepository.java returns UserDTO instead of UserEntity
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Rule 4: No Domain Logic in Presentation
|
|
33
|
+
Business logic must NOT appear in Controller/Handler/Page layers.
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
VIOLATION: UserController.java contains validation logic (should be in Service)
|
|
37
|
+
VIOLATION: OrderPage.vue contains price calculation (should be in Service)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Circular Dependency Rules
|
|
41
|
+
|
|
42
|
+
### Rule 5: No Import Cycles
|
|
43
|
+
No circular import chains are allowed between modules.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
VIOLATION: A imports B, B imports C, C imports A
|
|
47
|
+
ALLOWED: A imports B, A imports C, B imports C (DAG)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Rule 6: No Mutual Dependencies
|
|
51
|
+
Two modules must not directly import from each other.
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
VIOLATION: UserService imports OrderService, OrderService imports UserService
|
|
55
|
+
FIX: Extract shared logic into a third module or use events
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Module Boundary Rules
|
|
59
|
+
|
|
60
|
+
### Rule 7: Bounded Context Isolation
|
|
61
|
+
Modules from different bounded contexts should not directly import each other's internal types.
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
VIOLATION: billing/internal/invoice.go imports shipping/internal/package.go
|
|
65
|
+
ALLOWED: billing/invoice.go imports shipping/api.go (public API)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Rule 8: No God Modules
|
|
69
|
+
A module importing from more than 50% of other modules may be a god module.
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
WARNING: CommonUtils imports from 15 out of 20 modules
|
|
73
|
+
FIX: Split into focused utility modules
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Detection Priority
|
|
77
|
+
|
|
78
|
+
1. **Critical** (blocks commit): Circular dependencies, reverse dependencies
|
|
79
|
+
2. **Warning** (should fix): API boundary leaks, cross-module imports
|
|
80
|
+
3. **Info** (consider): God modules, new unknown modules
|
|
81
|
+
|
|
82
|
+
## Output Format
|
|
83
|
+
|
|
84
|
+
Each violation includes:
|
|
85
|
+
- `file`: The file containing the violation
|
|
86
|
+
- `line`: Line number of the problematic import/usage
|
|
87
|
+
- `rule`: Which rule was violated (1-8)
|
|
88
|
+
- `severity`: Critical / Warning / Info
|
|
89
|
+
- `detail`: Human-readable explanation
|
|
90
|
+
- `suggestion`: How to fix
|