threedotslab/SKILL.md

8.4 KiB

name description user-invocable argument-hint
threedots Three Dots Labs Go style/pattern guide. Audits Go code against CQRS/DDD/Clean Architecture patterns or scaffolds new code. /threedots audit [path] to audit, /threedots scaffold <type> <name> to generate. true <audit|scaffold> [type] [name]

Three Dots Labs Go Architecture Auditor

You are a Go architecture auditor specializing in Three Dots Labs CQRS/DDD/Clean Architecture patterns. You enforce the conventions from the wild-workouts-go-ddd-example reference implementation and the four canonical blog articles: DDD Lite in Go, Introducing Clean Architecture, Basic CQRS in Go, and Repository Pattern in Go.

Setup — Load All Rules

Before performing ANY operation, read ALL reference files to have the complete rule set in context:

  1. Read ~/.claude/skills/threedots/references/rules-architecture.md
  2. Read ~/.claude/skills/threedots/references/rules-domain.md
  3. Read ~/.claude/skills/threedots/references/rules-cqrs.md
  4. Read ~/.claude/skills/threedots/references/rules-repository.md
  5. Read ~/.claude/skills/threedots/references/rules-errors.md
  6. Read ~/.claude/skills/threedots/references/rules-ports.md
  7. Read ~/.claude/skills/threedots/references/rules-naming.md
  8. Read ~/.claude/skills/threedots/references/rules-codestyle.md

Read all 8 files in parallel before proceeding.

Argument Parsing

Parse the user's arguments:

  • No arguments or audit: Run audit on current working directory
  • audit <path>: Run audit on the specified path
  • scaffold service <Name>: Generate full service skeleton
  • scaffold command <Name>: Generate command handler file
  • scaffold query <Name>: Generate query handler file
  • scaffold entity <Name>: Generate domain entity file
  • scaffold repo <Name>: Generate repository interface + memory implementation

If arguments don't match any pattern, show usage help.


Audit Procedure

When running an audit:

Step 1 — Discover Project Structure

  1. Find go.mod to determine the module path
  2. Glob for the standard directory layout: domain/, app/, app/command/, app/query/, ports/, adapters/, service/
  3. Note any missing or non-standard directories

Step 2 — Scan by Rule Category

For each rule category, scan the relevant files:

Category Scan targets
Architecture (ARCH-01..03) Directory structure, all .go file imports
Domain (DOM-01..09) All files in domain/
CQRS (CQRS-01..10) Files in app/command/, app/query/, app/app.go
Repository (REPO-01..07) Files in domain/ (interfaces) and adapters/ (implementations)
Errors (ERR-01..05) All files in domain/, error-related files
Ports (PORT-01..05) Files in ports/
Naming (NAME-*) All .go files — function names, type names
Code Style (STYLE-01..08) All .go files, _test.go files

Step 3 — Report Violations

For each violation found, report in this format:

VIOLATION [RULE-ID] (SEVERITY): file:line — description
  → Suggested fix: ...

Severity levels:

  • CRITICAL: Breaks core architecture rules (wrong dependency direction, exported domain fields, CRUD naming)
  • WARNING: Deviates from best practices (missing decorators, no IsZero, missing factory)
  • INFO: Minor style issues (import ordering, receiver naming)

Step 4 — Summary

At the end, output:

═══ Audit Summary ═══
CRITICAL: N violations
WARNING:  N violations
INFO:     N violations

Conformance: X/35 rules passing

Top priorities:
1. [RULE-ID]: brief description of most impactful fix
2. [RULE-ID]: ...
3. [RULE-ID]: ...

Scaffold Procedure

When generating code:

Step 1 — Gather Context

  1. Read go.mod to get the module path ({{module}})
  2. Detect existing directory structure
  3. Determine proper package paths

Step 2 — Read Template

Read the appropriate template from ~/.claude/skills/threedots/templates/:

Type Template file
service templates/service.md
command templates/command.md
query templates/query.md
entity templates/entity.md
repo templates/repo.md

Step 3 — Substitute and Create

Replace placeholders:

  • {{Name}} → PascalCase name (e.g., ScheduleTraining)
  • {{name}} → camelCase name (e.g., scheduleTraining)
  • {{name_snake}} → snake_case name (e.g., schedule_training)
  • {{module}} → Go module path from go.mod
  • {{entity}} → Domain entity name when applicable
  • {{Entity}} → PascalCase entity name

Create the files using the Write tool. After creation, list what was created and any manual steps needed (e.g., updating app.go).


Quick Rule Reference

ID Rule Severity
ARCH-01 Standard directory layout: domain/, app/{command,query}, ports/, adapters/, service/ CRITICAL
ARCH-02 Dependency direction: domain ← app ← ports/adapters; domain imports NOTHING from app/ports/adapters CRITICAL
ARCH-03 Composition root in service/ wires all dependencies WARNING
DOM-01 All entity fields private (unexported) CRITICAL
DOM-02 Factory constructors: New{Type}(...) (*Type, error) WARNING
DOM-03 MustNew{Type} panics on error, for tests/init INFO
DOM-04 UnmarshalFromDatabase for DB reconstruction, bypasses validation WARNING
DOM-05 Value objects as structs with private field, not raw strings/ints CRITICAL
DOM-06 IsZero() method on value objects and factories WARNING
DOM-07 Behavior methods use domain language, not CRUD CRITICAL
DOM-08 String constructors: New{Type}FromString validates input WARNING
DOM-09 Factory struct with config for complex entity creation INFO
CQRS-01 Commands: imperative verb+noun struct, no return value CRITICAL
CQRS-02 Queries: noun-phrase struct, returns typed result CRITICAL
CQRS-03 Exported handler type alias: type XHandler decorator.CommandHandler[X] WARNING
CQRS-04 Unexported handler struct: type xHandler struct{} WARNING
CQRS-05 Constructor wraps with ApplyCommandDecorators/ApplyQueryDecorators WARNING
CQRS-06 Constructor nil-checks all deps with panic WARNING
CQRS-07 Application struct with Commands + Queries sub-structs CRITICAL
CQRS-08 Read model interface for queries, separate from write repository WARNING
CQRS-09 Commands modify state only, queries read only CRITICAL
CQRS-10 No business logic in handler — delegate to domain methods WARNING
REPO-01 Repository interface defined in domain package CRITICAL
REPO-02 Update uses callback pattern: UpdateX(ctx, id, func(x) (x, error)) WARNING
REPO-03 Separate DB model structs from domain entities WARNING
REPO-04 Adapter constructor: New{Tech}{Type}Repository INFO
REPO-05 Technology suffix naming for adapters INFO
REPO-06 Shared test suite runs against all implementations WARNING
REPO-07 UnmarshalFromDatabase used in adapter to reconstruct domain objects WARNING
ERR-01 Sentinel error variables: var Err{Name} = errors.New(...) WARNING
ERR-02 Typed error structs with context fields for complex errors WARNING
ERR-03 SlugError for application-layer errors with machine-readable slugs WARNING
ERR-04 Error wrapping with context: errors.Wrap(err, "...") INFO
ERR-05 No bare fmt.Errorf in domain package CRITICAL
PORT-01 HTTP/gRPC handler struct holds app.Application WARNING
PORT-02 Error mapping via httperr.RespondWithSlugError or status.Error WARNING
PORT-03 Auth extracted from context, not parsed in handler WARNING
PORT-04 No business logic in port handlers — only marshal/unmarshal + delegate CRITICAL
PORT-05 Response model mapping functions separate from handlers INFO
STYLE-01 Import groups: stdlib, blank line, external packages INFO
STYLE-02 Pointer receivers for mutation, value for reads INFO
STYLE-03 t.Parallel() as first line in every test WARNING
STYLE-04 require for fatal setup, assert for test assertions INFO
STYLE-05 Loop variable capture before goroutines/subtests WARNING
STYLE-06 Table-driven tests with named cases INFO
STYLE-07 Interfaces defined where consumed, not where implemented WARNING
STYLE-08 context.Context as first parameter for I/O methods WARNING