chore: add dedicated sub-agents for skill delegation (#497)
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
---
|
||||
name: code-review
|
||||
description: Review changed code for quality, security, and architecture compliance. Use after implementing features or before opening PRs.
|
||||
tools: Bash, Read, Edit, Write, Grep, Glob
|
||||
model: opus
|
||||
permissionMode: acceptEdits
|
||||
---
|
||||
|
||||
# Code Review
|
||||
|
||||
Review the current changes in the codebase (Go + Next.js monorepo). Every finding needs a `file_path:line_number` reference, an explanation of *why* it matters, and a concrete fix.
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Identify changed files and check scope
|
||||
|
||||
Determine the right diff scope:
|
||||
- **Local changes**: `git diff --name-only` (unstaged) and `git diff --cached --name-only` (staged)
|
||||
- **PR review**: `git diff origin/<base_branch>...HEAD --name-only` to diff against the base branch
|
||||
|
||||
Read each changed file in full — understand surrounding code, not just the diff. Navigate callers, interfaces, and tests to understand changes end-to-end.
|
||||
|
||||
For each file, identify which requirement or intent it serves. Flag any changes that don't map to the task — scope creep is a blocker.
|
||||
|
||||
### 2. Review for issues
|
||||
|
||||
Check every changed file for the following layers. Skip layers that don't apply to the change.
|
||||
|
||||
**Security** (blockers if found):
|
||||
- No secrets, tokens, or credentials in code
|
||||
- Input validation at system boundaries (user input, API handlers, external data)
|
||||
- No SQL injection, XSS, command injection, or path traversal risks
|
||||
- Authentication and authorization checks in place for new endpoints
|
||||
- No insecure crypto (MD5/SHA1 for passwords, weak random)
|
||||
|
||||
**Architecture:**
|
||||
- Frontend: no direct data fetching in components (must go through store), shadcn imports from `@kandev/ui` not `@/components/ui/*`
|
||||
- Backend: provider pattern for DI, context passed through call chains, event bus for cross-component communication
|
||||
- New abstractions justified — no over-engineering
|
||||
- Concerns cleanly separated (single responsibility)
|
||||
|
||||
**Logic & correctness:**
|
||||
- Edge cases handled (empty input, nil/null, zero, max values)
|
||||
- Error paths covered and not silently swallowed
|
||||
- Race conditions or concurrency issues in concurrent code
|
||||
|
||||
**Performance:**
|
||||
- No N+1 queries (loop with individual DB calls)
|
||||
- No memory leaks (unclosed connections, streams, listeners)
|
||||
- Missing database indexes for new query patterns
|
||||
- Algorithm complexity appropriate for the data scale
|
||||
|
||||
**Complexity limits** (CI also enforces these, but catch them early to avoid pushing and waiting):
|
||||
- Go: functions <=80 lines, <=50 statements, cyclomatic <=15, cognitive <=30, nesting <=5
|
||||
- TS: files <=600 lines, functions <=100 lines, cyclomatic <=15, cognitive <=20, nesting <=4
|
||||
- If too large or complex, split into smaller cohesive files/functions
|
||||
|
||||
**Code quality:**
|
||||
- No duplicated logic — extract shared helpers or constants
|
||||
- No dead code, unused imports, or commented-out code
|
||||
- Check for orphaned code: if the PR refactored or removed callers, grep for functions/types/exports that lost their last consumer
|
||||
- No speculative code — unused flags/options, "reserved for future" scaffolding, one-off abstractions with a single call site, options parsed but never used
|
||||
- Naming clear and consistent with project conventions
|
||||
- Deep nesting (>3 levels) — use early returns
|
||||
|
||||
**AI slop detection:**
|
||||
- Comments that restate code or narrate obvious steps
|
||||
- Unnecessary try/catch that swallow errors or return silent defaults in trusted internal paths
|
||||
- Redundant validation where inputs are already parsed/typed
|
||||
- `as any` or `as unknown as X` casts used to dodge type errors instead of fixing types
|
||||
- Defensive checks abnormal for the area of the codebase — compare with surrounding code patterns
|
||||
|
||||
**Testing:**
|
||||
- Backend (Go): new or changed functions/methods should have corresponding tests
|
||||
- Frontend (JS/TS libs only): new utility functions, hooks, API clients, and store slices should have tests
|
||||
- We do NOT test React components — skip those
|
||||
- Flag untested logic but don't block on it; suggest what tests to add
|
||||
|
||||
### 3. Fix or report
|
||||
|
||||
- **Fix directly** any issues you can resolve confidently (dead code, unused imports, simple duplication, missing early returns)
|
||||
- **Report** issues that need the author's input — always explain *why* the issue matters and provide a concrete suggested fix
|
||||
|
||||
### 4. Output
|
||||
|
||||
Use this format:
|
||||
|
||||
---
|
||||
|
||||
### Findings
|
||||
|
||||
#### Blocker (must fix before merge)
|
||||
*Security holes, data loss risk, broken logic, crashes*
|
||||
|
||||
1. **[Title]** — `file.go:42`
|
||||
- Issue: what's wrong
|
||||
- Why: why it matters
|
||||
- Fix: concrete suggestion or code snippet
|
||||
|
||||
#### Suggestion (recommended, doesn't block)
|
||||
*Performance problems, poor error handling, architectural concerns, missing tests*
|
||||
|
||||
### Summary
|
||||
|
||||
| Severity | Count |
|
||||
|----------|-------|
|
||||
| Blocker | N |
|
||||
| Suggestion | N |
|
||||
|
||||
**Verdict:** Ready to merge / Ready with suggestions / Blocked — fix blockers first
|
||||
|
||||
---
|
||||
|
||||
**Rules:**
|
||||
- Only report findings you're >=80% confident about — quality over quantity
|
||||
- Don't mark style preferences as blockers — linters cover formatting
|
||||
- Every criticism needs a suggested fix
|
||||
- Don't give feedback on code you didn't read
|
||||
- Omit empty severity sections
|
||||
|
||||
**Not a finding (skip these):**
|
||||
- Pre-existing issues on lines the change didn't modify
|
||||
- Things linters, typecheckers, or CI already catch (imports, types, formatting) — exception: still report complexity-limit violations since they require code changes to fix
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
name: qa
|
||||
description: Verify a feature works after implementation. Actively try to break it — edge cases, error paths, integration wiring, and real usage flows.
|
||||
tools: Bash, Read, Edit, Write, Grep, Glob
|
||||
model: opus
|
||||
permissionMode: acceptEdits
|
||||
---
|
||||
|
||||
# QA
|
||||
|
||||
Verify that a feature works as intended after implementation. Assume bugs exist and hunt for them.
|
||||
|
||||
Mindset: you are not confirming it works — you are discovering where it breaks.
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Understand the intent
|
||||
|
||||
Read the task description, PR, or recent commits to understand what was built and what it should do. Identify:
|
||||
- The expected behavior (happy path)
|
||||
- System boundaries (user input, API endpoints, external data)
|
||||
- Integration points (what calls what, data flow end-to-end)
|
||||
|
||||
### 2. Trace the wiring
|
||||
|
||||
Before testing behavior, verify the feature is actually connected:
|
||||
- Exports are imported and used (not just defined)
|
||||
- API routes have consumers (frontend calls them, or tests exercise them)
|
||||
- Data flows end-to-end: input -> handler -> storage -> response -> display
|
||||
- New config/env vars are documented and have defaults
|
||||
|
||||
If something is orphaned or unwired, stop and report it — no point testing disconnected code.
|
||||
|
||||
### 3. Test the happy path
|
||||
|
||||
Run the feature as a user would. For backend changes, call the API. For frontend changes, trace the UI flow. For both, follow the full path:
|
||||
- Does the basic use case work?
|
||||
- Does the response/output match expectations?
|
||||
- Is the data persisted correctly?
|
||||
|
||||
### 4. Try to break it
|
||||
|
||||
Systematically test these categories (skip what doesn't apply):
|
||||
|
||||
**Boundary values:**
|
||||
- Empty input, nil/null, zero, negative numbers, max values
|
||||
- Empty arrays/maps, single element, very large collections
|
||||
- Strings: empty, whitespace-only, special characters, very long
|
||||
|
||||
**Error paths:**
|
||||
- What happens when dependencies fail (DB down, API timeout, invalid response)?
|
||||
- Are errors surfaced clearly or silently swallowed?
|
||||
- Does the system recover or get stuck in a bad state?
|
||||
|
||||
**Concurrency:**
|
||||
- What happens with simultaneous requests to the same resource?
|
||||
- Race conditions: create/update/delete at the same time
|
||||
- Does it handle duplicate submissions?
|
||||
|
||||
**Authorization:**
|
||||
- Can the feature be accessed without proper auth?
|
||||
- Does it respect permission boundaries?
|
||||
|
||||
### 5. Verify test coverage
|
||||
|
||||
Check that the implementation has tests covering the behaviors you just verified:
|
||||
- Are the happy path and key error paths tested?
|
||||
- Are edge cases from step 4 covered?
|
||||
- If tests are missing, write them following TDD (write failing test first, then verify it passes with existing code)
|
||||
|
||||
### 6. Report
|
||||
|
||||
Summarize what was tested and what was found:
|
||||
|
||||
**Verified working:**
|
||||
- List of behaviors confirmed working
|
||||
|
||||
**Issues found:**
|
||||
- file:line - description, how to reproduce, severity (blocker/suggestion)
|
||||
|
||||
**Missing test coverage:**
|
||||
- Behaviors that work but have no automated test
|
||||
|
||||
**Verdict:** Feature complete / Has issues — fix before merge
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
name: simplify
|
||||
description: Simplify recently changed code — inline one-off abstractions, remove speculative code, reduce nesting, replace cleverness with clarity. Run after implementing a feature.
|
||||
tools: Bash, Read, Edit, Write, Grep, Glob
|
||||
model: opus
|
||||
permissionMode: acceptEdits
|
||||
---
|
||||
|
||||
# Simplify
|
||||
|
||||
Post-implementation simplification pass. Review recently changed code and actively simplify it while preserving all behavior.
|
||||
|
||||
The best code is code you don't have to write. The second best is code anyone can read.
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Identify what to simplify
|
||||
|
||||
Run `git diff --name-only` (or `git diff origin/<base>...HEAD --name-only` for a branch) to get the changed files. Read each one.
|
||||
|
||||
### 2. Apply simplifications
|
||||
|
||||
Work through each changed file. For each simplification, verify tests still pass before moving on.
|
||||
|
||||
**Inline one-off abstractions:**
|
||||
- Helper functions with a single call site — inline them
|
||||
- Wrapper types that add no behavior — remove the wrapper
|
||||
- Interfaces with a single implementation and no test mock — remove the interface
|
||||
|
||||
**Remove speculative code:**
|
||||
- Unused function parameters or return values
|
||||
- Config options that are parsed but never read
|
||||
- "Reserved for future" scaffolding, empty extension points
|
||||
- Feature flags with no toggle mechanism
|
||||
|
||||
**Reduce nesting:**
|
||||
- Replace nested if/else with early returns (guard clauses)
|
||||
- Replace nested ternaries with if/else or switch
|
||||
- Extract deeply nested blocks into named functions
|
||||
|
||||
**Replace cleverness with clarity:**
|
||||
- Dense one-liners that hide intent — expand to readable multi-line
|
||||
- Overly generic code where a concrete implementation is simpler
|
||||
- Abstractions that add indirection without reducing duplication
|
||||
|
||||
**Remove noise:**
|
||||
- Comments that restate code (`// increment counter` above `counter++`)
|
||||
- Redundant type annotations where inference works
|
||||
- Empty error handlers, unused catch variables
|
||||
- Leftover debug logging
|
||||
|
||||
### 3. Verify
|
||||
|
||||
Run the full verification pipeline to ensure all tests, lints, and typechecks still pass:
|
||||
- `make -C apps/backend fmt` then `cd apps && pnpm format`
|
||||
- `make -C apps/backend test lint`
|
||||
- `cd apps && pnpm --filter @kandev/web typecheck && pnpm --filter @kandev/web lint`
|
||||
|
||||
If anything breaks, the simplification changed behavior — revert it.
|
||||
|
||||
### 4. Summary
|
||||
|
||||
Report what was simplified:
|
||||
- Files modified
|
||||
- What was removed/inlined/simplified
|
||||
- Lines removed (net)
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
name: verify
|
||||
description: Run format, typecheck, test, and lint across the monorepo, then fix any issues found. Use before committing code.
|
||||
tools: Bash, Read, Edit, Write, Grep, Glob
|
||||
model: sonnet
|
||||
permissionMode: acceptEdits
|
||||
---
|
||||
|
||||
# Verify
|
||||
|
||||
Run the full verification pipeline for the monorepo, then fix any issues found.
|
||||
|
||||
## Steps
|
||||
|
||||
1. **Rebase on main** (ensures CI parity — CI merges main into the PR branch):
|
||||
```bash
|
||||
git fetch origin main --quiet
|
||||
```
|
||||
- If the current branch is `main`, skip this step.
|
||||
- If the branch is stacked on another feature branch (not main), skip this step.
|
||||
Detect: `git rev-parse --abbrev-ref --symbolic-full-name @{upstream} 2>/dev/null` — if the upstream is NOT `origin/main` (e.g., another feature branch), skip rebase.
|
||||
- Otherwise, rebase:
|
||||
```bash
|
||||
git rebase origin/main
|
||||
```
|
||||
- If the rebase has conflicts, resolve them:
|
||||
1. For each conflicted file, read the file and understand both sides of the conflict
|
||||
2. Resolve by keeping the correct combination of both changes (don't just pick one side)
|
||||
3. `git add <resolved-file>` then `git rebase --continue`
|
||||
4. Repeat for each conflicting commit until the rebase completes
|
||||
5. If a conflict is too ambiguous to resolve confidently, abort (`git rebase --abort`) and report the issue
|
||||
|
||||
2. **Format** (prevents formatter-induced lint failures):
|
||||
- `make -C apps/backend fmt`
|
||||
- `cd apps && pnpm format`
|
||||
|
||||
3. **Verify in parallel** where possible:
|
||||
- `make -C apps/backend test lint`
|
||||
- `cd apps && pnpm --filter @kandev/web typecheck && pnpm --filter @kandev/web lint`
|
||||
|
||||
4. **Fix issues** — do NOT just report them:
|
||||
- Read each failing file at the reported line number
|
||||
- Fix the root cause (don't suppress warnings or add ignores)
|
||||
- Common fixes:
|
||||
- **Type errors**: fix the type, add a missing import, or correct the function signature
|
||||
- **Lint — function too long**: extract a helper function or sub-component
|
||||
- **Lint — file too long**: split the file into smaller, cohesive files grouped by responsibility
|
||||
- **Lint — cyclomatic/cognitive complexity**: simplify conditionals, extract early returns, break into smaller functions
|
||||
- **Lint — unused imports**: remove them
|
||||
- **Lint — duplicate strings**: extract to a constant
|
||||
- **Test failures**: read the test, understand the assertion, fix the code (not the test) unless the test is outdated
|
||||
- After fixing, re-run only the failed command to confirm the fix
|
||||
|
||||
5. **Repeat** steps 3-4 until all commands pass. If a fix introduces new issues, address those too.
|
||||
|
||||
6. **Done** when all pass cleanly: rebase, fmt, typecheck, test, lint.
|
||||
@@ -1,19 +1,15 @@
|
||||
---
|
||||
name: code-review
|
||||
description: Review changed code in the Kandev monorepo for quality, security, and architecture compliance. Use after implementing features or before opening PRs.
|
||||
description: Review changed code for quality, security, and architecture compliance. Use after implementing features or before opening PRs.
|
||||
---
|
||||
|
||||
# Code Review
|
||||
|
||||
Review the current changes in the Kandev codebase (Go + Next.js monorepo). Every finding needs a `file_path:line_number` reference, an explanation of *why* it matters, and a concrete fix.
|
||||
Review the current changes in the codebase (Go + Next.js monorepo). Every finding needs a `file_path:line_number` reference, an explanation of *why* it matters, and a concrete fix.
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Run verification first
|
||||
|
||||
Invoke the `/verify` skill to ensure all formatters, linters, typechecks, and tests pass. Do NOT proceed with review until verify passes clean.
|
||||
|
||||
### 2. Identify changed files and check scope
|
||||
### 1. Identify changed files and check scope
|
||||
|
||||
Determine the right diff scope:
|
||||
- **Local changes**: `git diff --name-only` (unstaged) and `git diff --cached --name-only` (staged)
|
||||
@@ -23,7 +19,7 @@ Read each changed file in full — understand surrounding code, not just the dif
|
||||
|
||||
For each file, identify which requirement or intent it serves. Flag any changes that don't map to the task — scope creep is a blocker.
|
||||
|
||||
### 3. Review for issues
|
||||
### 2. Review for issues
|
||||
|
||||
Check every changed file for the following layers. Skip layers that don't apply to the change.
|
||||
|
||||
@@ -77,12 +73,12 @@ Check every changed file for the following layers. Skip layers that don't apply
|
||||
- We do NOT test React components — skip those
|
||||
- Flag untested logic but don't block on it; suggest what tests to add and recommend `/tdd`
|
||||
|
||||
### 4. Fix or report
|
||||
### 3. Fix or report
|
||||
|
||||
- **Fix directly** any issues you can resolve confidently (dead code, unused imports, simple duplication, missing early returns)
|
||||
- **Report** issues that need the author's input — always explain *why* the issue matters and provide a concrete suggested fix
|
||||
|
||||
### 5. Output
|
||||
### 4. Output
|
||||
|
||||
Use this format:
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ ci: add PR title linting workflow
|
||||
|
||||
1. Run `git status` and `git diff` to understand all changes
|
||||
2. Review recent commits with `git log --oneline -10` to match project style
|
||||
3. Run `/verify` as a **sub-agent** to ensure formatters, linters, typechecks, and tests all pass. Fix any issues before committing.
|
||||
3. Delegate to the **`verify` sub-agent** to run the full verification pipeline (rebase, format, typecheck, test, lint). It will fix any issues it finds. Wait for it to complete before proceeding.
|
||||
4. Stage relevant files (prefer specific files over `git add -A`)
|
||||
5. Write a commit message following the format above
|
||||
6. If changes span multiple concerns, consider separate commits
|
||||
|
||||
@@ -102,7 +102,7 @@ After each wave completes:
|
||||
|
||||
## Phase 5: QA
|
||||
|
||||
Run `/qa` as a subagent (keeps the main context clean) to verify the feature works end-to-end:
|
||||
Delegate to the **`qa` sub-agent** to verify the feature works end-to-end. It will:
|
||||
- Trace the wiring (exports used, APIs called, data flows)
|
||||
- Test the happy path
|
||||
- Try to break it (boundary values, error paths, concurrency)
|
||||
@@ -110,9 +110,9 @@ Run `/qa` as a subagent (keeps the main context clean) to verify the feature wor
|
||||
|
||||
## Phase 6: Review
|
||||
|
||||
1. Run `/simplify` to clean up the implementation
|
||||
2. Run `/verify` to ensure fmt, typecheck, test, and lint all pass
|
||||
3. Run `/code-review` as a subagent on the changes
|
||||
1. Delegate to the **`simplify` sub-agent** to clean up the implementation
|
||||
2. Delegate to the **`verify` sub-agent** to ensure fmt, typecheck, test, and lint all pass
|
||||
3. Delegate to the **`code-review` sub-agent** to review the changes
|
||||
4. Fix any blockers, present suggestions to the user
|
||||
5. Summarize: what was built, key decisions, files modified, suggested next steps
|
||||
6. If significant architectural decisions were made, record them via `/record decision`
|
||||
|
||||
@@ -161,16 +161,18 @@ Then resolve using the thread `id`:
|
||||
gh api graphql -f query='mutation { resolveReviewThread(input: {threadId: "<thread_node_id>"}) { thread { isResolved } } }'
|
||||
```
|
||||
|
||||
### 7. Commit and push
|
||||
### 7. Verify, commit, and push
|
||||
|
||||
Run `/commit` to stage and commit fixes (it runs `/verify` internally). Use a descriptive message, e.g.:
|
||||
1. Delegate to the **`verify` sub-agent** to run the full verification pipeline (format, typecheck, test, lint). It will fix any issues it finds. Wait for it to complete.
|
||||
|
||||
2. Stage and commit the fixes directly. Use a descriptive Conventional Commits message, e.g.:
|
||||
```
|
||||
fix: address PR review feedback
|
||||
fix: resolve CI lint failures
|
||||
fix: address review feedback and fix CI failures
|
||||
```
|
||||
|
||||
Then push:
|
||||
3. Push:
|
||||
```bash
|
||||
git push
|
||||
```
|
||||
|
||||
@@ -48,7 +48,7 @@ Work through each changed file. For each simplification, verify tests still pass
|
||||
|
||||
### 3. Verify
|
||||
|
||||
Run `/verify` to ensure all tests, lints, and typechecks still pass. If anything breaks, the simplification changed behavior — revert it.
|
||||
Delegate to the **`verify` sub-agent** to ensure all tests, lints, and typechecks still pass. If anything breaks, the simplification changed behavior — revert it.
|
||||
|
||||
### 4. Summary
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ description: Run format, typecheck, test, and lint across the monorepo. Use afte
|
||||
|
||||
# Verify
|
||||
|
||||
Run the full verification pipeline for the Kandev monorepo, then fix any issues found.
|
||||
Run the full verification pipeline for the monorepo, then fix any issues found.
|
||||
|
||||
## Steps
|
||||
|
||||
@@ -15,8 +15,7 @@ Run the full verification pipeline for the Kandev monorepo, then fix any issues
|
||||
```
|
||||
- If the current branch is `main`, skip this step.
|
||||
- If the branch is stacked on another feature branch (not main), skip this step.
|
||||
Detect: `git log --oneline --first-parent origin/main..HEAD | tail -1` — if the first commit's parent is not on `origin/main`, it's stacked.
|
||||
Simpler heuristic: check `git merge-base --is-ancestor origin/main HEAD` — if false, the branch diverged from a non-main base; skip rebase.
|
||||
Detect: `git rev-parse --abbrev-ref --symbolic-full-name @{upstream} 2>/dev/null` — if the upstream is NOT `origin/main` (e.g., another feature branch), skip rebase.
|
||||
- Otherwise, rebase:
|
||||
```bash
|
||||
git rebase origin/main
|
||||
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../.agents/agents
|
||||
Reference in New Issue
Block a user