@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.
- package/dist/bin/harness.js +1 -1
- package/dist/{chunk-IXT3KLVN.js → chunk-APYEWOCR.js} +355 -19
- package/dist/index.js +1 -1
- package/package.json +6 -4
- package/dist/agents/commands/claude-code/harness/add-component.md +0 -34
- package/dist/agents/commands/claude-code/harness/align-documentation.md +0 -33
- package/dist/agents/commands/claude-code/harness/architecture-advisor.md +0 -41
- package/dist/agents/commands/claude-code/harness/brainstorming.md +0 -42
- package/dist/agents/commands/claude-code/harness/check-mechanical-constraints.md +0 -32
- package/dist/agents/commands/claude-code/harness/cleanup-dead-code.md +0 -33
- package/dist/agents/commands/claude-code/harness/code-review.md +0 -33
- package/dist/agents/commands/claude-code/harness/debugging.md +0 -43
- package/dist/agents/commands/claude-code/harness/detect-doc-drift.md +0 -32
- package/dist/agents/commands/claude-code/harness/diagnostics.md +0 -43
- package/dist/agents/commands/claude-code/harness/enforce-architecture.md +0 -32
- package/dist/agents/commands/claude-code/harness/execution.md +0 -43
- package/dist/agents/commands/claude-code/harness/git-workflow.md +0 -32
- package/dist/agents/commands/claude-code/harness/initialize-project.md +0 -33
- package/dist/agents/commands/claude-code/harness/onboarding.md +0 -32
- package/dist/agents/commands/claude-code/harness/parallel-agents.md +0 -35
- package/dist/agents/commands/claude-code/harness/planning.md +0 -41
- package/dist/agents/commands/claude-code/harness/pre-commit-review.md +0 -38
- package/dist/agents/commands/claude-code/harness/refactoring.md +0 -35
- package/dist/agents/commands/claude-code/harness/skill-authoring.md +0 -35
- package/dist/agents/commands/claude-code/harness/state-management.md +0 -35
- package/dist/agents/commands/claude-code/harness/tdd.md +0 -42
- package/dist/agents/commands/claude-code/harness/validate-context-engineering.md +0 -32
- package/dist/agents/commands/claude-code/harness/verification.md +0 -38
- package/dist/agents/commands/gemini-cli/harness/add-component.toml +0 -240
- package/dist/agents/commands/gemini-cli/harness/align-documentation.toml +0 -238
- package/dist/agents/commands/gemini-cli/harness/architecture-advisor.toml +0 -469
- package/dist/agents/commands/gemini-cli/harness/brainstorming.toml +0 -326
- package/dist/agents/commands/gemini-cli/harness/check-mechanical-constraints.toml +0 -249
- package/dist/agents/commands/gemini-cli/harness/cleanup-dead-code.toml +0 -258
- package/dist/agents/commands/gemini-cli/harness/code-review.toml +0 -461
- package/dist/agents/commands/gemini-cli/harness/debugging.toml +0 -436
- package/dist/agents/commands/gemini-cli/harness/detect-doc-drift.toml +0 -215
- package/dist/agents/commands/gemini-cli/harness/diagnostics.toml +0 -401
- package/dist/agents/commands/gemini-cli/harness/enforce-architecture.toml +0 -222
- package/dist/agents/commands/gemini-cli/harness/execution.toml +0 -381
- package/dist/agents/commands/gemini-cli/harness/git-workflow.toml +0 -325
- package/dist/agents/commands/gemini-cli/harness/initialize-project.toml +0 -257
- package/dist/agents/commands/gemini-cli/harness/onboarding.toml +0 -316
- package/dist/agents/commands/gemini-cli/harness/parallel-agents.toml +0 -221
- package/dist/agents/commands/gemini-cli/harness/planning.toml +0 -405
- package/dist/agents/commands/gemini-cli/harness/pre-commit-review.toml +0 -294
- package/dist/agents/commands/gemini-cli/harness/refactoring.toml +0 -209
- package/dist/agents/commands/gemini-cli/harness/skill-authoring.toml +0 -350
- package/dist/agents/commands/gemini-cli/harness/state-management.toml +0 -354
- package/dist/agents/commands/gemini-cli/harness/tdd.toml +0 -247
- package/dist/agents/commands/gemini-cli/harness/validate-context-engineering.toml +0 -186
- 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
|
-
"""
|