@harness-engineering/cli 1.2.0 → 1.3.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.
Files changed (52) hide show
  1. package/dist/bin/harness.js +1 -1
  2. package/dist/{chunk-IXT3KLVN.js → chunk-APYEWOCR.js} +355 -19
  3. package/dist/index.js +1 -1
  4. package/package.json +6 -4
  5. package/dist/agents/commands/claude-code/harness/add-component.md +0 -34
  6. package/dist/agents/commands/claude-code/harness/align-documentation.md +0 -33
  7. package/dist/agents/commands/claude-code/harness/architecture-advisor.md +0 -41
  8. package/dist/agents/commands/claude-code/harness/brainstorming.md +0 -42
  9. package/dist/agents/commands/claude-code/harness/check-mechanical-constraints.md +0 -32
  10. package/dist/agents/commands/claude-code/harness/cleanup-dead-code.md +0 -33
  11. package/dist/agents/commands/claude-code/harness/code-review.md +0 -33
  12. package/dist/agents/commands/claude-code/harness/debugging.md +0 -43
  13. package/dist/agents/commands/claude-code/harness/detect-doc-drift.md +0 -32
  14. package/dist/agents/commands/claude-code/harness/diagnostics.md +0 -43
  15. package/dist/agents/commands/claude-code/harness/enforce-architecture.md +0 -32
  16. package/dist/agents/commands/claude-code/harness/execution.md +0 -43
  17. package/dist/agents/commands/claude-code/harness/git-workflow.md +0 -32
  18. package/dist/agents/commands/claude-code/harness/initialize-project.md +0 -33
  19. package/dist/agents/commands/claude-code/harness/onboarding.md +0 -32
  20. package/dist/agents/commands/claude-code/harness/parallel-agents.md +0 -35
  21. package/dist/agents/commands/claude-code/harness/planning.md +0 -41
  22. package/dist/agents/commands/claude-code/harness/pre-commit-review.md +0 -38
  23. package/dist/agents/commands/claude-code/harness/refactoring.md +0 -35
  24. package/dist/agents/commands/claude-code/harness/skill-authoring.md +0 -35
  25. package/dist/agents/commands/claude-code/harness/state-management.md +0 -35
  26. package/dist/agents/commands/claude-code/harness/tdd.md +0 -42
  27. package/dist/agents/commands/claude-code/harness/validate-context-engineering.md +0 -32
  28. package/dist/agents/commands/claude-code/harness/verification.md +0 -38
  29. package/dist/agents/commands/gemini-cli/harness/add-component.toml +0 -240
  30. package/dist/agents/commands/gemini-cli/harness/align-documentation.toml +0 -238
  31. package/dist/agents/commands/gemini-cli/harness/architecture-advisor.toml +0 -469
  32. package/dist/agents/commands/gemini-cli/harness/brainstorming.toml +0 -326
  33. package/dist/agents/commands/gemini-cli/harness/check-mechanical-constraints.toml +0 -249
  34. package/dist/agents/commands/gemini-cli/harness/cleanup-dead-code.toml +0 -258
  35. package/dist/agents/commands/gemini-cli/harness/code-review.toml +0 -461
  36. package/dist/agents/commands/gemini-cli/harness/debugging.toml +0 -436
  37. package/dist/agents/commands/gemini-cli/harness/detect-doc-drift.toml +0 -215
  38. package/dist/agents/commands/gemini-cli/harness/diagnostics.toml +0 -401
  39. package/dist/agents/commands/gemini-cli/harness/enforce-architecture.toml +0 -222
  40. package/dist/agents/commands/gemini-cli/harness/execution.toml +0 -381
  41. package/dist/agents/commands/gemini-cli/harness/git-workflow.toml +0 -325
  42. package/dist/agents/commands/gemini-cli/harness/initialize-project.toml +0 -257
  43. package/dist/agents/commands/gemini-cli/harness/onboarding.toml +0 -316
  44. package/dist/agents/commands/gemini-cli/harness/parallel-agents.toml +0 -221
  45. package/dist/agents/commands/gemini-cli/harness/planning.toml +0 -405
  46. package/dist/agents/commands/gemini-cli/harness/pre-commit-review.toml +0 -294
  47. package/dist/agents/commands/gemini-cli/harness/refactoring.toml +0 -209
  48. package/dist/agents/commands/gemini-cli/harness/skill-authoring.toml +0 -350
  49. package/dist/agents/commands/gemini-cli/harness/state-management.toml +0 -354
  50. package/dist/agents/commands/gemini-cli/harness/tdd.toml +0 -247
  51. package/dist/agents/commands/gemini-cli/harness/validate-context-engineering.toml +0 -186
  52. package/dist/agents/commands/gemini-cli/harness/verification.toml +0 -334
@@ -1,401 +0,0 @@
1
- # Generated by harness generate-slash-commands. Do not edit.
2
- description = "Classify errors into taxonomy categories and route to resolution strategies"
3
- prompt = """
4
- <context>
5
- Cognitive mode: diagnostic-investigator
6
- Type: rigid
7
- State: persistent (files: .harness/diagnostics/)
8
- </context>
9
-
10
- <objective>
11
- Classify errors into taxonomy categories and route to resolution strategies
12
-
13
- Phases:
14
- - classify: Categorize the error into one of 7 taxonomy categories
15
- - route: Apply the resolution strategy for the error category
16
- - resolve: Execute the resolution and verify the fix
17
- - record: Record findings in anti-pattern log if initial approach failed (optional)
18
- </objective>
19
-
20
- <execution_context>
21
- --- SKILL.md (agents/skills/claude-code/harness-diagnostics/SKILL.md) ---
22
- # Harness Diagnostics
23
-
24
- > Cognitive mode: **diagnostic-investigator**. Classify errors into taxonomy categories and route to deterministic resolution strategies. Evidence first, classification second, action third.
25
-
26
- ## When to Use
27
-
28
- - When an error occurs and the root cause category is unclear
29
- - When a bug fix attempt failed and you need a structured re-approach
30
- - When `on_bug_fix` triggers fire and the error does not match a known pattern
31
- - When you need to decide whether to fix locally or escalate
32
- - NOT for obvious typos or syntax errors with clear fixes (just fix them)
33
- - NOT for feature development (use harness-tdd instead)
34
- - NOT for deep multi-phase debugging (use harness-debugging instead — this skill classifies and routes)
35
-
36
- ## Error Taxonomy
37
-
38
- Every error falls into one of 7 categories. Each category has distinct signals and a distinct resolution strategy. Misclassification leads to wasted effort — a Logic error treated as Syntax will never be fixed by reading the compiler output.
39
-
40
- ### Category 1: Syntax/Type
41
-
42
- **Signals:** Compilation failures, type errors, parse errors, import resolution failures, "cannot find name", "expected X but got Y" from the compiler or type checker.
43
-
44
- **Resolution strategy:** Read the error message. It tells you exactly what is wrong and where. Fix mechanically — match the type, fix the import, correct the syntax. No investigation needed. Run the type checker to confirm.
45
-
46
- **Time budget:** Under 5 minutes. If it takes longer, you have misclassified.
47
-
48
- ### Category 2: Logic
49
-
50
- **Signals:** Tests fail with wrong output values, unexpected behavior at runtime, "expected X but received Y" from test assertions, correct types but incorrect results.
51
-
52
- **Resolution strategy:** Write a failing test FIRST that isolates the incorrect behavior. Then trace the data flow from input to incorrect output. Find the exact line where the actual value diverges from the expected value. Fix that line. Run the test to confirm.
53
-
54
- **Time budget:** 5-30 minutes. If it takes longer, consider reclassifying as Design.
55
-
56
- ### Category 3: Design
57
-
58
- **Signals:** Multiple related failures, fixes that break other things, circular dependencies, "everything is tangled", you cannot write a clean test because the code is not testable, the fix requires changing many files.
59
-
60
- **Resolution strategy:** STOP. Do not attempt to fix locally. This is an architectural issue that requires human judgment. Document the symptoms, the attempted fixes, and the structural problem. Escalate to the human architect with a clear summary and 2-3 options.
61
-
62
- **Time budget:** 15 minutes maximum for classification and documentation. Do not spend time attempting fixes.
63
-
64
- ### Category 4: Performance
65
-
66
- **Signals:** Slow responses, timeouts, high memory usage, "heap out of memory", operations that used to be fast are now slow, N+1 query patterns.
67
-
68
- **Resolution strategy:** Profile FIRST. Do not guess at the bottleneck. Use the appropriate profiling tool for the runtime (browser devtools, `node --prof`, `py-spy`, database `EXPLAIN`). Identify the actual hotspot. Optimize only that hotspot. Measure again to confirm improvement.
69
-
70
- **Time budget:** 15-60 minutes. Profiling takes time but prevents optimizing the wrong thing.
71
-
72
- ### Category 5: Security
73
-
74
- **Signals:** Vulnerability scanner findings, injection possibilities, authentication/authorization failures, exposed secrets, CORS issues, unsafe deserialization.
75
-
76
- **Resolution strategy:** Check OWASP Top 10 for the vulnerability class. Apply the minimal fix that closes the vulnerability without changing unrelated behavior. Do not refactor surrounding code during a security fix — minimize the blast radius. Verify with a test that the vulnerability is closed.
77
-
78
- **Time budget:** Variable, but the fix itself should be minimal. If the fix requires large changes, reclassify as Design and escalate.
79
-
80
- ### Category 6: Environment
81
-
82
- **Signals:** "Module not found" at runtime (not compile time), version mismatch errors, "connection refused", works on one machine but not another, Docker/CI failures that pass locally, missing environment variables.
83
-
84
- **Resolution strategy:** Check versions first — runtime, dependencies, OS. Compare the failing environment to a working environment. Look at: Node/Python/Java version, dependency lock file freshness, environment variables, file permissions, network connectivity. Fix the environment, not the code.
85
-
86
- **Time budget:** 5-30 minutes. Environment issues are usually fast once you compare configurations.
87
-
88
- ### Category 7: Flaky
89
-
90
- **Signals:** Test passes sometimes and fails sometimes, "works on retry", timing-dependent failures, failures that disappear when you add logging, race conditions, order-dependent test results.
91
-
92
- **Resolution strategy:** Isolate the timing dependency. Run the failing test in isolation — does it still flake? Run it 20 times in a loop — what is the failure rate? Look for: shared mutable state between tests, missing `await` on async operations, time-dependent assertions (`setTimeout`, `Date.now()`), external service dependencies without mocking. Fix the non-determinism, do not add retries.
93
-
94
- **Time budget:** 15-60 minutes. Flaky tests are deceptively hard. If you cannot isolate the timing dependency in 60 minutes, escalate.
95
-
96
- ## Process
97
-
98
- ### Phase 1: CLASSIFY — Collect Evidence and Categorize
99
-
100
- **This phase must complete before any fix is attempted.**
101
-
102
- #### Step 1: Run Deterministic Checks (Baseline)
103
-
104
- Capture the current state before any changes:
105
-
106
- ```bash
107
- # Run type checker (adapt to project language)
108
- npx tsc --noEmit 2>&1 | tail -50
109
-
110
- # Run test suite
111
- npm test 2>&1 | tail -100
112
-
113
- # Record results
114
- echo "Baseline captured at $(date)" >> .harness/diagnostics/current.md
115
- ```
116
-
117
- Record exact counts: how many type errors, how many test failures, which tests fail.
118
-
119
- #### Step 2: Read the Complete Error
120
-
121
- Read the ENTIRE error output. Not the first line. Not the summary. The complete message including:
122
-
123
- - Error type/code
124
- - Stack trace (every frame)
125
- - Warnings that preceded the error
126
- - Context about what operation was being attempted
127
-
128
- #### Step 3: Match Signals to Category
129
-
130
- Compare the error signals against the 7 categories above. Ask:
131
-
132
- - Is this a compile-time or runtime error? (Compile-time -> likely Syntax/Type)
133
- - Is the code syntactically valid but producing wrong results? (-> Logic)
134
- - Does the error involve multiple components or layers? (-> Design)
135
- - Is it about speed or resource consumption? (-> Performance)
136
- - Is it about unauthorized access or unsafe data handling? (-> Security)
137
- - Does it work in one environment but not another? (-> Environment)
138
- - Does it fail intermittently? (-> Flaky)
139
-
140
- #### Step 4: State the Classification Explicitly
141
-
142
- ```
143
- CLASSIFICATION: [Category Name]
144
- CONFIDENCE: [High/Medium/Low]
145
- SIGNALS: [List the specific signals that led to this classification]
146
- ALTERNATIVE: [If confidence is Medium or Low, what other category could it be?]
147
- ```
148
-
149
- **Gate: Classification must be explicit and written down before proceeding. "I think it's a type error" is not sufficient. State the category, confidence, and signals.**
150
-
151
- ---
152
-
153
- ### Phase 2: ROUTE — Apply Category-Specific Strategy
154
-
155
- Follow the resolution strategy for the classified category exactly. Do not mix strategies. Each category has a specific approach because each category has a specific failure mode.
156
-
157
- If the category is **Design**, STOP HERE. Do not proceed to Phase 3. Document and escalate.
158
-
159
- For all other categories, execute the resolution strategy as described in the taxonomy above.
160
-
161
- ---
162
-
163
- ### Phase 3: RESOLVE — Execute and Verify
164
-
165
- #### Step 1: Apply the Fix
166
-
167
- Implement the fix according to the resolution strategy for the classified category.
168
-
169
- #### Step 2: Run Deterministic Checks (Verification)
170
-
171
- Run the same checks from Phase 1 Step 1:
172
-
173
- ```bash
174
- # Run type checker
175
- npx tsc --noEmit 2>&1 | tail -50
176
-
177
- # Run test suite
178
- npm test 2>&1 | tail -100
179
- ```
180
-
181
- Compare results to the baseline:
182
-
183
- - Type errors: must be equal or fewer than baseline
184
- - Test failures: the target failure must be resolved, no new failures introduced
185
- - If new failures appeared, the fix is wrong. Revert and re-examine.
186
-
187
- #### Step 3: Confirm Resolution
188
-
189
- The error is resolved when:
190
-
191
- 1. The original error no longer occurs
192
- 2. No new errors were introduced
193
- 3. The type checker count is equal or better than baseline
194
- 4. The test suite count is equal or better than baseline
195
-
196
- ---
197
-
198
- ### Phase 4: RECORD — Capture Anti-Patterns (Optional)
199
-
200
- This phase triggers only when the initial classification was wrong or the first fix attempt failed.
201
-
202
- #### Step 1: Document What Went Wrong
203
-
204
- ```markdown
205
- # Diagnostic Record: <brief description>
206
-
207
- Date: <timestamp>
208
- Initial Classification: <what you thought it was>
209
- Actual Classification: <what it turned out to be>
210
- Misclassification Reason: <why the signals were misleading>
211
- Resolution: <what actually fixed it>
212
- Anti-Pattern: <what to watch for next time>
213
- ```
214
-
215
- #### Step 2: Save to Anti-Pattern Log
216
-
217
- ```bash
218
- # Append to diagnostics log
219
- cat >> .harness/diagnostics/anti-patterns.md << 'ENTRY'
220
- <the record from Step 1>
221
- ENTRY
222
- ```
223
-
224
- This log accumulates over time and helps improve future classifications.
225
-
226
- ## Harness Integration
227
-
228
- - Follows Principle 7 — runs deterministic checks (typecheck, tests) before and after LLM reasoning
229
- - Builds on harness-debugging but adds structured classification layer
230
- - Writes to `.harness/anti-patterns.md` per Group B3 convention
231
- - Category 3 (Design) escalates to human architect per human-architect model
232
-
233
- ## Success Criteria
234
-
235
- - [ ] Error is classified into exactly one of the 7 categories
236
- - [ ] Resolution strategy matches the category playbook
237
- - [ ] Post-execution checks pass (typecheck + tests)
238
- - [ ] If initial approach failed, it is recorded in anti-pattern log
239
-
240
- ## Gates
241
-
242
- - **Classification must be explicit.** You must write down the category, confidence level, and signals before any fix attempt. Implicit classification ("I'll just fix this type error") skips the evidence step and leads to misclassification.
243
- - **Design category MUST escalate.** If the error is classified as Design, you must stop and escalate to the human. Do not attempt a local fix for an architectural problem. Local fixes for architectural problems create more architectural problems.
244
- - **Deterministic checks before AND after.** You must run the type checker and test suite both before and after the fix. Without a baseline, you cannot prove the fix helped and did not hurt.
245
- - **No category mixing.** Follow the resolution strategy for one category. If you find yourself profiling (Performance) while also tracing data flow (Logic), you have not committed to a classification. Pick one.
246
- - **Reclassify, do not force.** If the resolution strategy is not working, the classification is probably wrong. Go back to Phase 1 and reclassify. Do not force a Logic fix on what turns out to be an Environment issue.
247
-
248
- ## Escalation
249
-
250
- - **Design errors:** Always escalate. Provide: symptom summary, files affected, 2-3 architectural options if you can identify them.
251
- - **Confidence is Low:** Escalate if you cannot decide between two categories after examining all signals. Present both possibilities and let the human decide.
252
- - **Fix introduced new failures:** Revert the fix. Re-examine. If you cannot fix without side effects after 2 attempts, escalate.
253
- - **Flaky test not isolated in 60 minutes:** The non-determinism source may be outside the codebase (infrastructure, external service). Escalate with your findings.
254
- - **Security vulnerability with large blast radius:** If the minimal fix requires changing more than 3 files, reclassify as Design and escalate.
255
-
256
- ## Examples
257
-
258
- ### Example 1: Type Error in API Handler
259
-
260
- **Phase 1 — CLASSIFY:**
261
-
262
- ```
263
- Error: src/handlers/users.ts(42,15): error TS2345:
264
- Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
265
-
266
- Baseline: 1 type error, 0 test failures.
267
-
268
- CLASSIFICATION: Syntax/Type
269
- CONFIDENCE: High
270
- SIGNALS: Compile-time error, TypeScript error code TS2345, exact file and line provided
271
- ALTERNATIVE: None — this is unambiguously a type error
272
- ```
273
-
274
- **Phase 2 — ROUTE:**
275
- Following Syntax/Type strategy: read the error, fix mechanically.
276
-
277
- The function `getUserById(id: string)` is called with `req.params.id` which is `string | undefined`. Add a guard or use non-null assertion after validation.
278
-
279
- **Phase 3 — RESOLVE:**
280
-
281
- ```typescript
282
- // Fix: add guard before call
283
- const id = req.params.id;
284
- if (!id) {
285
- return res.status(400).json({ error: 'id parameter is required' });
286
- }
287
- const user = await getUserById(id);
288
- ```
289
-
290
- Verification: 0 type errors (was 1), 0 test failures (unchanged). Fix confirmed.
291
-
292
- ### Example 2: Flaky Integration Test
293
-
294
- **Phase 1 — CLASSIFY:**
295
-
296
- ```
297
- Error: test/integration/queue.test.ts
298
- "should process message within timeout"
299
- Passes 7 out of 10 runs. Fails with: "Timeout — message not processed within 2000ms"
300
-
301
- Baseline: 0 type errors, 1 flaky test failure (intermittent).
302
-
303
- CLASSIFICATION: Flaky
304
- CONFIDENCE: High
305
- SIGNALS: Intermittent failure, timing-dependent assertion (2000ms timeout),
306
- passes on retry, failure rate ~30%
307
- ALTERNATIVE: Could be Environment if CI has different resource constraints,
308
- but it also flakes locally
309
- ```
310
-
311
- **Phase 2 — ROUTE:**
312
- Following Flaky strategy: isolate the timing dependency.
313
-
314
- Run in isolation: still flakes (not order-dependent).
315
- Run 20 times: fails 6/20 times (~30% failure rate, consistent).
316
- Examine the test: it publishes a message and asserts it is processed within 2000ms.
317
- Examine the handler: processing involves a database write that sometimes takes >2000ms under load.
318
- Root cause: the timeout is too tight for the actual processing time, and there is no mechanism to signal completion — the test polls on a timer.
319
-
320
- **Phase 3 — RESOLVE:**
321
-
322
- ```typescript
323
- // Before: polling with fixed timeout
324
- await new Promise((resolve) => setTimeout(resolve, 2000));
325
- const result = await db.query('SELECT * FROM processed WHERE id = ?', [msgId]);
326
- expect(result.rows).toHaveLength(1);
327
-
328
- // After: event-driven wait with generous timeout
329
- const result = await waitForCondition(
330
- () => db.query('SELECT * FROM processed WHERE id = ?', [msgId]).then((r) => r.rows.length > 0),
331
- { timeout: 10000, interval: 100 }
332
- );
333
- expect(result).toBe(true);
334
- ```
335
-
336
- Verification: 0 type errors (unchanged), 20/20 test runs pass. Fix confirmed.
337
-
338
- **Phase 4 — RECORD:**
339
- Not needed — initial classification was correct and first fix attempt succeeded.
340
-
341
-
342
- --- skill.yaml (agents/skills/claude-code/harness-diagnostics/skill.yaml) ---
343
- name: harness-diagnostics
344
- version: "1.0.0"
345
- description: Classify errors into taxonomy categories and route to resolution strategies
346
- cognitive_mode: diagnostic-investigator
347
- triggers:
348
- - manual
349
- - on_bug_fix
350
- platforms:
351
- - claude-code
352
- - gemini-cli
353
- tools:
354
- - Bash
355
- - Read
356
- - Glob
357
- - Grep
358
- - Edit
359
- - Write
360
- cli:
361
- command: harness skill run harness-diagnostics
362
- args:
363
- - name: path
364
- description: Project root path
365
- required: false
366
- - name: error
367
- description: Error message or description to diagnose
368
- required: false
369
- mcp:
370
- tool: run_skill
371
- input:
372
- skill: harness-diagnostics
373
- path: string
374
- type: rigid
375
- phases:
376
- - name: classify
377
- description: Categorize the error into one of 7 taxonomy categories
378
- required: true
379
- - name: route
380
- description: Apply the resolution strategy for the error category
381
- required: true
382
- - name: resolve
383
- description: Execute the resolution and verify the fix
384
- required: true
385
- - name: record
386
- description: Record findings in anti-pattern log if initial approach failed
387
- required: false
388
- state:
389
- persistent: true
390
- files:
391
- - .harness/diagnostics/
392
- depends_on: []
393
-
394
- </execution_context>
395
-
396
- <process>
397
- 1. Try: invoke mcp__harness__run_skill with skill: "harness-diagnostics"
398
- 2. If MCP unavailable: follow the SKILL.md workflow provided above directly
399
- 3. Pass through any arguments provided by the user
400
- </process>
401
- """
@@ -1,222 +0,0 @@
1
- # Generated by harness generate-slash-commands. Do not edit.
2
- description = "Validate architectural layer boundaries and detect circular dependencies"
3
- prompt = """
4
- <context>
5
- Cognitive mode: meticulous-verifier
6
- Type: rigid
7
- </context>
8
-
9
- <objective>
10
- Validate architectural layer boundaries and detect circular dependencies
11
- </objective>
12
-
13
- <execution_context>
14
- --- SKILL.md (agents/skills/claude-code/enforce-architecture/SKILL.md) ---
15
- # Enforce Architecture
16
-
17
- > Validate architectural layer boundaries and detect dependency violations. No code may violate layer constraints — this is a hard gate, not a suggestion.
18
-
19
- ## When to Use
20
-
21
- - Before approving any pull request or merge
22
- - After writing new imports or module references
23
- - When adding a new module or package to the project
24
- - When `on_pre_commit` or `on_architecture_check` triggers fire
25
- - After refactoring that moves code between layers or modules
26
- - NOT when editing documentation, configuration, or non-code files
27
- - NOT when the violation is intentional and requires a constraint update (escalate instead)
28
-
29
- ## Process
30
-
31
- ### Phase 1: Load Constraints
32
-
33
- 1. **Read `harness.config.json`** to understand the project's architectural constraints. The config defines:
34
- - **Layers** — ordered list of architectural layers (e.g., `ui -> service -> repository -> domain`)
35
- - **Dependency rules** — which layers may import from which (typically: layers may only import from layers below them)
36
- - **Forbidden imports** — specific import paths that are never allowed in certain contexts
37
- - **Boundary definitions** — which directories/packages belong to which layer
38
-
39
- 2. **Understand the layer model.** In a typical layered architecture:
40
- - Higher layers depend on lower layers (UI depends on Service, Service depends on Repository)
41
- - Lower layers NEVER depend on higher layers (Repository must not import from UI)
42
- - Same-layer imports may or may not be allowed depending on project config
43
- - Cross-cutting concerns (logging, config) have their own rules
44
-
45
- ### Phase 2: Run Dependency Checks
46
-
47
- 1. **Run `harness check-deps`** to analyze all import statements against the constraint model. Capture the full JSON output.
48
-
49
- 2. **Parse the results.** Each violation includes:
50
- - The violating file and line number
51
- - The forbidden import target
52
- - The source layer and target layer
53
- - The specific rule being violated
54
-
55
- ### Phase 3: Analyze Violations
56
-
57
- For each violation, determine:
58
-
59
- 1. **Which layers are involved.** Identify the source file's layer and the imported module's layer. Map them to the constraint model.
60
-
61
- 2. **What rule is violated.** Common violation types:
62
- - **Upward dependency** — a lower layer imports from a higher layer (e.g., repository importing from UI). This is the most serious type. It creates coupling that makes the lower layer untestable in isolation.
63
- - **Skip-layer dependency** — a layer reaches past its immediate neighbor (e.g., UI importing directly from Repository, bypassing Service). This breaks encapsulation and makes the middle layer pointless.
64
- - **Circular dependency** — two modules or layers depend on each other. This creates fragile coupling where changing either module risks breaking the other.
65
- - **Forbidden import** — a specific import that is explicitly banned (e.g., importing a database driver outside the repository layer). This prevents implementation details from leaking.
66
-
67
- 3. **Explain the impact.** For each violation, state:
68
- - WHY the constraint exists (what architectural property it protects)
69
- - WHAT would happen if the violation were allowed to persist
70
- - HOW it affects testability, maintainability, and changeability
71
-
72
- ### Phase 4: Guide Resolution
73
-
74
- For each violation, provide a specific fix:
75
-
76
- - **Upward dependency:** Introduce an interface or abstraction in the lower layer. The higher layer implements it; the lower layer depends only on the abstraction. Alternatively, use dependency injection.
77
- - **Skip-layer dependency:** Route the call through the intermediate layer. Add a method to the Service layer that delegates to the Repository, then have the UI call the Service.
78
- - **Circular dependency:** Break the cycle by extracting shared types into a common module that both can depend on, or restructure so the dependency flows in one direction only.
79
- - **Forbidden import:** Replace the forbidden import with the approved alternative. If no alternative exists, the feature may need to live in a different layer.
80
-
81
- ## Common Violation Patterns
82
-
83
- ### Pattern: "I just need one thing from that layer"
84
-
85
- A UI component imports a repository function directly because "it is just one query." Fix: add the query to the Service layer. The extra indirection is the architecture working correctly.
86
-
87
- ### Pattern: "Shared types across layers"
88
-
89
- Two layers both need the same type definition. Fix: place shared types in the lowest layer that both depend on, or create a dedicated `types` or `shared` module at the bottom of the layer stack.
90
-
91
- ### Pattern: "Test utilities importing production code from wrong layer"
92
-
93
- Test helpers import across layer boundaries for convenience. Fix: each layer's tests should only import from that layer and below. Test utilities should follow the same constraints as production code.
94
-
95
- ### Pattern: "Circular dependency through re-exports"
96
-
97
- Module A re-exports from Module B, and Module B imports from Module A. The circular dependency is hidden by the re-export. Fix: identify the true dependency direction and remove the reverse path.
98
-
99
- ## Harness Integration
100
-
101
- - **`harness check-deps`** — Primary tool. Analyzes all imports against the layer model defined in `harness.config.json`. Returns structured violation data including file, line, source layer, target layer, and rule violated.
102
- - **`harness check-deps --json`** — Machine-readable output for automated pipelines. Use this when parsing results programmatically.
103
- - **`harness validate`** — Includes dependency checking as part of full project validation. Use when you want a complete health check, not just architecture.
104
-
105
- ## Success Criteria
106
-
107
- - `harness check-deps` reports zero violations
108
- - All imports flow downward through the layer stack (or follow explicitly configured exceptions)
109
- - No circular dependencies exist between modules or layers
110
- - No forbidden imports are present anywhere in the codebase
111
- - Every new module is assigned to the correct layer in the config
112
- - The layer model in `harness.config.json` accurately reflects the intended architecture
113
-
114
- ## Examples
115
-
116
- ### Example: Service layer importing from UI layer
117
-
118
- **Violation from `harness check-deps`:**
119
-
120
- ```
121
- VIOLATION: Upward dependency
122
- File: src/services/user-service.ts:12
123
- Import: import { UserForm } from '../components/UserForm'
124
- Source layer: service (level 2)
125
- Target layer: ui (level 3)
126
- Rule: service layer must not depend on ui layer
127
- ```
128
-
129
- **Impact:** The UserService now depends on a React component. It cannot be used in a CLI tool, a background job, or tested without a DOM. The service layer should be framework-agnostic.
130
-
131
- **Resolution:**
132
-
133
- ```typescript
134
- // BEFORE (violating)
135
- import { UserForm } from '../components/UserForm';
136
- const data = UserForm.defaultValues; // using UI defaults in service
137
-
138
- // AFTER (fixed)
139
- // Define the defaults where they belong — in the service layer
140
- const DEFAULT_USER_DATA: UserInput = { name: '', email: '' };
141
- ```
142
-
143
- ### Example: Circular dependency between modules
144
-
145
- **Violation from `harness check-deps`:**
146
-
147
- ```
148
- VIOLATION: Circular dependency detected
149
- Cycle: src/services/order-service.ts -> src/services/inventory-service.ts -> src/services/order-service.ts
150
- order-service imports checkStock from inventory-service
151
- inventory-service imports getOrderQuantity from order-service
152
- ```
153
-
154
- **Resolution:** Extract the shared concern into a new module:
155
-
156
- ```typescript
157
- // src/services/stock-calculator.ts (new, shared module)
158
- export function calculateRequiredStock(quantity: number, reserved: number): number {
159
- return quantity - reserved;
160
- }
161
- ```
162
-
163
- Both services import from `stock-calculator` instead of from each other. The cycle is broken.
164
-
165
- ## Gates
166
-
167
- These are hard stops. Architecture violations are not warnings — they are errors.
168
-
169
- - **No code with layer violations may be approved or merged.** If `harness check-deps` reports violations, the code must be fixed before it proceeds.
170
- - **No new modules without layer assignment.** Every new directory or package must be mapped to a layer in `harness.config.json` before code is written in it.
171
- - **No "temporary" violations.** There is no TODO for architecture. Either the code respects the constraints or it does not ship.
172
- - **No suppressing violations without team approval.** If a violation needs to be allowed, the constraint in `harness.config.json` must be explicitly updated with a comment explaining why.
173
-
174
- ## Escalation
175
-
176
- - **When a violation seems impossible to fix within the current architecture:** The architecture may need to evolve. Escalate to the human with a clear explanation of the constraint, the use case, and why they conflict. Propose options: update the constraint, restructure the code, or add a new layer.
177
- - **When `harness check-deps` reports false positives:** Verify the layer assignments in `harness.config.json` are correct. If a file is assigned to the wrong layer, fix the config. If the tool is genuinely wrong, report the issue.
178
- - **When fixing one violation creates another:** This usually indicates a deeper structural issue. Step back and look at the dependency graph as a whole rather than fixing violations one at a time.
179
- - **When the team wants to change the layer model:** This is a significant architectural decision. All existing code must be migrated to the new model. Plan this as a dedicated refactoring effort, not a side task.
180
-
181
-
182
- --- skill.yaml (agents/skills/claude-code/enforce-architecture/skill.yaml) ---
183
- name: enforce-architecture
184
- version: "1.0.0"
185
- description: Validate architectural layer boundaries and detect circular dependencies
186
- cognitive_mode: meticulous-verifier
187
- triggers:
188
- - manual
189
- - on_pr
190
- - on_commit
191
- platforms:
192
- - claude-code
193
- - gemini-cli
194
- tools:
195
- - Bash
196
- - Read
197
- - Glob
198
- cli:
199
- command: harness skill run enforce-architecture
200
- args:
201
- - name: path
202
- description: Project root path
203
- required: false
204
- mcp:
205
- tool: run_skill
206
- input:
207
- skill: enforce-architecture
208
- path: string
209
- type: rigid
210
- state:
211
- persistent: false
212
- files: []
213
- depends_on: []
214
-
215
- </execution_context>
216
-
217
- <process>
218
- 1. Try: invoke mcp__harness__run_skill with skill: "enforce-architecture"
219
- 2. If MCP unavailable: follow the SKILL.md workflow provided above directly
220
- 3. Pass through any arguments provided by the user
221
- </process>
222
- """