Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion go-linter-driven-development/agents/go-code-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ tools:
- Read
- Grep
- Skill(go-linter-driven-development:pre-commit-review) # Auto-loaded for design analysis guidance
- mcp__ide__getDiagnostics
---

You are a Go Code Design Reviewer specializing in detecting design patterns and architectural issues that linters cannot catch. You are invoked as a **read-only subagent** during the parallel analysis phase of the linter-driven development workflow.
Expand All @@ -27,7 +28,7 @@ Your job: Analyze the code and return a **structured report** that the orchestra

<step number="1" name="Load Pre-Commit Review Skill">

Automatically use the @pre-commit-review skill to guide your analysis. This skill contains:
**Use the Skill tool** to invoke `Skill(go-linter-driven-development:pre-commit-review)` to load design analysis guidance. This skill contains:
- Detection checklist for 8 design issue categories
- Juiciness scoring algorithm for primitive obsession
- Examples of good vs bad patterns
Expand Down
16 changes: 16 additions & 0 deletions go-linter-driven-development/agents/quality-analyzer.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ description: |
tools:
- Bash
- Task
- mcp__ide__getDiagnostics
---

You are a Quality Analyzer Agent that orchestrates parallel quality analysis for Go projects. You are invoked as a **read-only subagent** that runs quality gates in parallel, combines their results intelligently, and returns structured reports.
Expand Down Expand Up @@ -126,6 +127,21 @@ normalized_issue:
message: "Cognitive complexity 18 (>15)"
raw_output: "..."
```

**Linter Categorization Reference:**

| Linter | Category | Severity | Routes To |
|--------|----------|----------|-----------|
| `nestif` | complexity | high | @refactoring (storify → early returns) |
| `cyclop`, `gocognit` | complexity | high | @refactoring (storify → extract type) |
| `funlen` | complexity | medium | @refactoring (storify → extract function) |
| `argument-limit` (revive) | design | high | @code-designing (options struct) |
| `function-result-limit` (revive) | design | high | @code-designing (result type) |
| `confusing-results` (revive) | design | medium | @code-designing (named result type) |
| `early-return` (revive) | style | low | @refactoring (early return pattern) |
| `file-length-limit` (revive) | design | high | @code-designing (file splitting) |
| `wrapcheck` | bug | medium | Direct fix (error wrapping) |
| `varnamelen` | style | low | Direct fix (rename variable) |
</phase>

<phase name="D" title="Find Overlapping Issues">
Expand Down
1 change: 1 addition & 0 deletions go-linter-driven-development/commands/go-ldd-analyze.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ allowed-tools:
- Grep
- Bash
- Task
- mcp__ide__getDiagnostics
---

Run comprehensive quality analysis with intelligent combining of test results, linter findings, and code review feedback.
Expand Down
3 changes: 2 additions & 1 deletion go-linter-driven-development/commands/go-ldd-autopilot.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ description: Start complete linter-driven autopilot workflow (Phase 1-5)
argument-hint: ""
allowed-tools:
- Skill(go-linter-driven-development:linter-driven-development)
- mcp__ide__getDiagnostics
---

Invoke the @linter-driven-development skill to run the complete autopilot workflow from design through commit-ready.
**Use the Skill tool** to invoke `Skill(go-linter-driven-development:linter-driven-development)` to run the complete autopilot workflow from design through commit-ready.

⏱️ **Estimated Duration**: 5-15 minutes (depends on feature complexity and issues found)

Expand Down
11 changes: 9 additions & 2 deletions go-linter-driven-development/commands/go-ldd-quickfix.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ description: Run quality gates loop until all green (tests+linter+review → fix
argument-hint: "[file_pattern]"
allowed-tools:
- Skill(go-linter-driven-development:linter-driven-development)
- mcp__ide__getDiagnostics
---

Execute the quality gates loop for already-implemented code that needs cleanup.

⏱️ **Estimated Duration**: 2-5 minutes (depends on number of issues found)

Run these phases from @linter-driven-development skill:
**Use the Skill tool** to invoke `Skill(go-linter-driven-development:linter-driven-development)` and run these phases:

**Phase 2**: Parallel Analysis
- Discover project test/lint commands
Expand All @@ -29,8 +30,14 @@ Run these phases from @linter-driven-development skill:
- Re-verify with parallel analysis (incremental review mode)
- Repeat until all green

**Phase 5**: Orchestrator Review (after linter clean)
- Check types with >15 methods (god object threshold)
- If found: Apply @refactoring for storification first
- Then apply @code-designing for composition (service extraction)
- Re-verify with linter

**Loop until**:
✅ Tests pass | ✅ Linter clean | ✅ Review clean
✅ Tests pass | ✅ Linter clean | ✅ Review clean | ✅ No god objects (≤15 methods per type)

Use this when code is already written but needs to pass quality gates.
Skip the implementation phase (Phase 1) and go straight to fixing issues.
1 change: 1 addition & 0 deletions go-linter-driven-development/commands/go-ldd-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ allowed-tools:
- Grep
- Bash
- Task
- mcp__ide__getDiagnostics
---

Run final verification checks **without** the auto-fix loop.
Expand Down
1 change: 1 addition & 0 deletions go-linter-driven-development/commands/go-ldd-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ argument-hint: ""
allowed-tools:
- Read
- Bash(git *)
- mcp__ide__getDiagnostics
---

!`git status --porcelain`
Expand Down
106 changes: 106 additions & 0 deletions go-linter-driven-development/skills/code-designing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ description: |
Focuses on vertical slice architecture and type safety.
allowed-tools:
- Skill(go-linter-driven-development:testing)
- mcp__ide__getDiagnostics
---

<objective>
Expand All @@ -15,6 +16,16 @@ Use when planning new features or identifying need for new types during refactor
**Reference**: See `reference.md` for complete design principles and examples.
</objective>

<skill_invocation>
**CRITICAL**: When this skill says "Use @skill-name" or routes to "@skill-name", you MUST use the **Skill tool** explicitly.

| Notation | Skill Tool Call |
|----------|-----------------|
| @testing | `Skill(go-linter-driven-development:testing)` |

**DO NOT** just reference the skill - actually invoke it using the Skill tool.
</skill_invocation>

<quick_start>
1. **Analyze Architecture**: Check for vertical vs horizontal slicing
2. **Understand Domain**: Identify problem domain, concepts, invariants
Expand All @@ -31,6 +42,10 @@ Ready to implement? Use @testing skill for test structure.
- Refactoring reveals need for new types (complexity extraction)
- Linter failures suggest types should be introduced
- When you need to think through domain modeling
- **`argument-limit`** linter failure (>4 parameters) → Design options struct
- **`function-result-limit`** linter failure (>3 returns) → Design result type
- **`confusing-results`** linter failure → Design named result type
- **`file-length-limit`** linter failure (>450 lines) → Analyze and split juicy types to own files
</when_to_use>

<purpose>
Expand Down Expand Up @@ -176,6 +191,97 @@ Check design against (see reference.md):
- [ ] Clear separation of concerns
</review_against_principles>

<linter_triggered_patterns>
**When invoked by linter failures, apply these patterns:**

<pattern name="options_struct" trigger="argument-limit (>4 params)">
```go
// BEFORE - Too many parameters
func CreateUser(name string, email string, age int, role string, dept string) (*User, error)

// AFTER - Options struct
type CreateUserOptions struct {
Name string
Email string
Age int
Role string
Dept string
}

func CreateUser(opts CreateUserOptions) (*User, error)
```
**Design Tip**: Add validation in a constructor: `NewCreateUserOptions(...) (CreateUserOptions, error)`
</pattern>

<pattern name="result_type" trigger="function-result-limit (>3 returns)">
```go
// BEFORE - Too many return values
func ParseConfig(path string) (config Config, warnings []string, version int, error)

// AFTER - Result type
type ParseConfigResult struct {
Config Config
Warnings []string
Version int
}

func ParseConfig(path string) (ParseConfigResult, error)
```
</pattern>

<pattern name="named_result_type" trigger="confusing-results">
```go
// BEFORE - Confusing (string, string, error)
func ParseAddress(raw string) (string, string, error) // Which is host? Which is port?

// AFTER - Named result type
type ParsedAddress struct {
Host string
Port string
}

func ParseAddress(raw string) (ParsedAddress, error)
```
</pattern>

<pattern name="file_splitting" trigger="file-length-limit (revive) - file > 450 lines">
**Step 1: Analyze file structure**

| File Pattern | Action |
|--------------|--------|
| Multiple juicy types | Move each juicy type to its own file |
| Single god type | Extract method clusters via composition OR extract juicy logic from methods |
| Long functions, few types | Route to @refactoring first (storify → extract functions) |

**Step 2: Apply juiciness test**

"Juicy" types (deserve their own file):
- Types with ≥2 methods
- Types with complex validation
- Types with transformations/parsing
- Enums WITH methods (behavior makes them juicy)

"Anemic" types (can stay grouped in types.go or similar):
- Simple enums (const block only)
- DTOs with no methods
- Type aliases

**Step 3: For god types** (>15 methods)

| Option | When to Use | Pattern |
|--------|-------------|---------|
| **Storify first** | Methods are hard to read | Apply storification → reveals hidden structure |
| **Extract via composition** | Method clusters exist | Identify cluster → extract to new type → compose |
| **Extract juicy logic** | Primitive obsession inside methods | Find logic on primitives → extract to self-validating type |

**Routing**: God types require two-phase refactoring:
1. **@refactoring** (first): Storify methods to reveal structure
2. **@code-designing** (then): Design service composition

See @refactoring skill → `god_object_decomposition` pattern for detailed mechanics.
</pattern>
</linter_triggered_patterns>

</workflow>

<output_format>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ allowed-tools:
- Skill(go-linter-driven-development:refactoring)
- Skill(go-linter-driven-development:documentation)
- Task
- mcp__ide__getDiagnostics
---

<objective>
Expand All @@ -28,6 +29,25 @@ Use for any commit: features, bug fixes, refactors.
- Working directory contains Go project (go.mod or .go files)
</essential_principles>

<skill_invocation>
**CRITICAL**: When this skill says "Invoke @skill-name" or routes to "@skill-name", you MUST use the **Skill tool** explicitly.

| Notation | Skill Tool Call |
|----------|-----------------|
| @code-designing | `Skill(go-linter-driven-development:code-designing)` |
| @testing | `Skill(go-linter-driven-development:testing)` |
| @refactoring | `Skill(go-linter-driven-development:refactoring)` |
| @documentation | `Skill(go-linter-driven-development:documentation)` |

**DO NOT** just reference the skill in your response - actually invoke it using the Skill tool.
**DO NOT** read the skill file directly - use the Skill tool to load and execute it.

Example: When Phase 1 says "Invoke @testing skill to WRITE tests", you must call:
```
Skill(go-linter-driven-development:testing)
```
</skill_invocation>

<quick_start>
**Immediate Action**: Run Pre-Flight Check, then execute phases sequentially until commit-ready.

Expand Down Expand Up @@ -81,15 +101,28 @@ Scan conversation history (last 50 messages) for step-by-step plan and which ste
- Invoke @code-designing skill
- Output: Type design plan with self-validating domain types

**Write Tests First**:
- Invoke @testing skill for guidance
**Write Tests First** (MANDATORY):
- Invoke @testing skill to WRITE tests (not just guidance)
- Create test files for all new types/functions
- Write table-driven tests or testify suites
- Target: 100% coverage on new leaf types

**Implement Code**:
- Follow coding principles from coding_rules.md
- Keep functions <50 LOC, max 2 nesting levels
- Use self-validating types, prevent primitive obsession

**Test Verification** (before proceeding):
1. For each new type file created:
- Verify corresponding `*_test.go` exists
- Run: `go test -cover ./path/to/package`
- Verify: coverage > 0% (tests actually exercise code)
2. For leaf types: warn if coverage < 80%

**GATE**: DO NOT proceed to Phase 2 until:
- [ ] Test files exist for all new types
- [ ] `go test -cover` shows > 0% coverage for new packages
- [ ] No "no test files" or "[no tests to run]" messages
</phase>

<phase name="2" title="Quality Analysis">
Expand Down Expand Up @@ -120,9 +153,45 @@ Max 10 iterations. If stuck, ask user for guidance.
</phase>

<phase name="3" title="Iterative Fix Loop">

<linter_skill_routing>
**Linter Error → Skill Routing Table**

Route linter failures to the correct skill based on error type:

| Linter Error | Route To | Pattern Priority |
|--------------|----------|------------------|
| `nestif` (deep nesting) | @refactoring | 1. Storify, 2. Early returns, 3. Extract function |
| `argument-limit` (>4 params) | @code-designing | Create options struct type |
| `function-result-limit` (>3 returns) | @code-designing | Create result type |
| `confusing-results` | @code-designing | Create named result type |
| `cyclop`/`gocognit` (complexity) | @refactoring | 1. Storifying, 2. Extract type |
| `funlen` (function too long) | @refactoring | 1. Storify, 2. Extract function |
| `wrapcheck` (unwrapped error) | Direct fix | `fmt.Errorf("context: %w", err)` |
| `varnamelen` (short var name) | Direct fix | Rename variable to be descriptive |
| `early-return` (revive) | @refactoring | Apply early return pattern |
| `file-length-limit` (revive) | Analyze first → route | See file-level concerns below |

**File-Level Concerns** (`file-length-limit` triggers at >450 lines):
When files exceed the limit, analyze structure first:

| File Pattern | Route To | Pattern |
|--------------|----------|---------|
| Multiple juicy types in one file | @code-designing | **Juicy type per file** - move each to own file |
| Single god type (>15 methods) | @refactoring → @code-designing | 1. Storify (refactoring), 2. Decompose (code-designing) |
| Long functions, few types | @refactoring | **Storify → Extract functions** |

**"Juicy" types** (deserve their own file):
- Types with ≥2 methods
- Types with complex validation
- Types with transformations/parsing
- Enums WITH methods (behavior makes them juicy)
</linter_skill_routing>

**For each prioritized fix** (from agent's report):

1. **Apply Fix**:
- Use routing table above to select correct skill
- Invoke @refactoring skill with file, function, issues, and root cause
- @refactoring applies patterns: early returns, extract function, storifying, extract type, switch extraction, extract constant

Expand All @@ -140,6 +209,25 @@ Max 10 iterations. If stuck, ask user for guidance.
- Max 10 iterations per fix loop
- If stuck after 3 attempts → show status, ask user

5. **Orchestrator Check** (after CLEAN_STATE):
- Count methods per type in modified files
- If any type has >15 methods:
- Flag as potential god object
- Apply @refactoring for storification (make it read like a story)
- Apply @code-designing for composition (extract services)
- Re-run quality-analyzer to verify

6. **Test Extracted Types** (mandatory after type extraction):
- Track all new types created during refactoring
- For each leaf type (no external dependencies):
- Invoke @testing skill
- Write table-driven tests for constructor validation
- Write tests for all public methods
- Target: 100% coverage on leaf types
- For orchestrating types:
- Write integration-style tests covering seams
- Re-run `task test` to verify all pass

**Loop until agent returns CLEAN_STATE**.
</phase>

Expand Down Expand Up @@ -198,6 +286,8 @@ Workflow is complete when ALL of the following are true:
- [ ] Tests pass
- [ ] Linter passes (0 errors)
- [ ] Code review clean (0 findings)
- [ ] All extracted leaf types have tests (100% coverage)
- [ ] No god objects (all types have ≤15 methods)
- [ ] Phase 4 complete (documentation added/updated)
- [ ] Commit summary presented to user with options
- [ ] User has chosen commit action (or deferred)
Expand Down
Loading