Phase 1: Add 5 SKILL.md files to .agents/skills/ - backlog-sync: plans/ markdown ↔ DB contract - convoy-lifecycle: status machine, gates, MCP tools, checkpoints - model-routing: role→model via OmniRoute profiles + registry - code-review-two-axis: Standards vs Spec parallel sub-agent review - tdd-red-green: TDD loop with seams Phase 2: OmniRoute operational docs - docs/omniroute-role-mapping.md: profile→role matrix, convoy examples - docs/omniroute-setup.md: step-by-step operator guide Phase 3: Worker OpenHands integration - apps/worker/src/session/load-skills.ts: loads .agents/skills/ - apps/worker/src/session/openhands-session.ts: agent-server REST adapter - apps/worker/src/executor/index.ts: createOpenHandsExecutor() factory - apps/worker/src/env.ts: WORKER_SESSION_TYPE, AGENT_SERVER_URL, SESSION_API_KEY - apps/worker/src/handle-job.ts: routes to OpenHands when configured - apps/worker/src/session/minimal-session.ts: injects skills into system prompt - packages/shared/src/worker/index.ts: re-export WorkerExecutorOptions
243 lines
No EOL
9.4 KiB
Markdown
243 lines
No EOL
9.4 KiB
Markdown
---
|
|
name: code-review-two-axis
|
|
description: Review code changes along two axes: Standards (does code follow repo conventions?) and Spec (does it match the originating issue/requirement?). Uses parallel sub-agents to keep concerns separate, then aggregates findings. Use when role-reviewer runs, a human requests PR review, or you're asked to review "changes since X".
|
|
---
|
|
|
|
# Code Review: Two-Axis Method
|
|
|
|
A rigorous but practical code review method that separates **Standards** from **Spec**, runs them as parallel sub-agents, and aggregates findings. Adapted from the approach in [mattpocock/skills](https://github.com/mattpocock/skills/blob/main/skills/engineering/code-review/SKILL.md) for Echodo's convoy pipeline.
|
|
|
|
## When to Activate
|
|
|
|
Use this skill when:
|
|
- **Role-reviewer** is triggered during convoy `pr_review` gate
|
|
- A human requests a PR review in Mission Control
|
|
- Someone asks "review the changes since commit X" or "review branch Y"
|
|
- You're asked to evaluate if code meets the acceptance criteria from the originating brief
|
|
|
|
## Core Method
|
|
|
|
### Two Axes
|
|
|
|
**1. Standards (Does the code follow repo conventions?)**
|
|
- Follows `AGENTS.md` and codebase style
|
|
- Uses existing patterns (file locations, naming, imports)
|
|
- Passes linter/formatter checks
|
|
- No obvious code smells (from Fowler's refactoring book)
|
|
|
|
**2. Spec (Does the code match what was asked for?)**
|
|
- Implements acceptance criteria from the originating brief
|
|
- Matches the description in `.convoys/<slug>/brief-*.md`
|
|
- Addresses the issue/story/task it claims to solve
|
|
- No missing functionality or edge cases
|
|
|
|
### Why Two Separate?
|
|
|
|
- **Separation of concerns:** A change might be well-written (Standards) but not solve the problem (Spec), or vice versa
|
|
- **Clearer feedback:** "This is good code but doesn't match the spec" vs "This matches the spec but violates our style"
|
|
- **Parallel sub-agents:** Run both in parallel to avoid context pollution between concerns
|
|
|
|
## The Process
|
|
|
|
### Step 1: Pin the Fixed Point
|
|
|
|
Whatever the user specifies as the comparison base:
|
|
- Commit SHA: `abc1234`
|
|
- Branch: `feature-x`
|
|
- Tag: `v1.2.0`
|
|
- Relative: `HEAD~5`, `main`
|
|
|
|
**Capture:**
|
|
- Diff command: `git diff <fixed-point>...HEAD` (three-dot for merge-base comparison)
|
|
- Commit log: `git log <fixed-point>..HEAD --oneline`
|
|
|
|
**Validate:**
|
|
- `git rev-parse <fixed-point>` must resolve
|
|
- Diff must be non-empty
|
|
|
|
### Step 2: Identify the Spec Source
|
|
|
|
Find what the change is supposed to implement, in this order:
|
|
|
|
1. **Issue references in commits:** `#123`, `Closes #45`, etc.
|
|
2. **Brief path:** User passed `.convoys/<slug>/brief-N-*.md`
|
|
3. **Matching spec file:** Look in `docs/`, `specs/`, `.scratch/` for files matching branch name
|
|
4. **Ask the user:** If none found, ask where the spec is
|
|
|
|
### Step 3: Identify the Standards Sources
|
|
|
|
- `AGENTS.md` at repo root
|
|
- `.cursor/rules/*.mdc` files (if not migrated to `.agents/skills/`)
|
|
- `docs/` for architecture decisions
|
|
- Existing code patterns in the same module
|
|
- **Fowler code smells baseline** (below)
|
|
|
|
### Step 4: Run Both Sub-Agents in Parallel
|
|
|
|
Run **Standards agent** and **Spec agent** as separate conversations with their own context. Each receives:
|
|
- The diff
|
|
- Its specific criteria
|
|
- Output format instructions
|
|
|
|
**Standards sub-agent receives:**
|
|
- Diff
|
|
- Standards sources (AGENTS.md, rules, patterns)
|
|
- Code smell baseline
|
|
- Instruction: "Review ONLY for standards violations"
|
|
|
|
**Spec sub-agent receives:**
|
|
- Diff
|
|
- Brief/spec source
|
|
- Acceptance criteria from originating task
|
|
- Instruction: "Review ONLY for spec conformance"
|
|
|
|
### Step 5: Aggregate Findings
|
|
|
|
After both sub-agents complete, merge their reports:
|
|
|
|
```markdown
|
|
# Code Review: <convoy/branch>
|
|
|
|
## Summary
|
|
<Combined 2-3 sentence summary>
|
|
|
|
## Standards Findings
|
|
<Issues from Standards axis, grouped by severity>
|
|
|
|
## Spec Findings
|
|
<Issues from Spec axis, grouped by severity>
|
|
|
|
## Recommendations
|
|
<Combined recommendations, prioritized>
|
|
|
|
## Verdict
|
|
[ ] Approve - meets standards and spec
|
|
[ ] Approve with comments - minor issues, not blocking
|
|
[ ] Request changes - significant issues must be addressed
|
|
[ ] Block - blocker-level issues (security, correctness)
|
|
```
|
|
|
|
## Code Smell Baseline (Standards)
|
|
|
|
Even if repo docs say nothing, apply this baseline. **Repo rules always override.**
|
|
|
|
### The 11 Smells
|
|
|
|
| Smell | What It Is | How to Fix |
|
|
|-------|------------|------------|
|
|
| **Mysterious Name** | Function/variable/type name doesn't reveal purpose | Rename to something descriptive |
|
|
| **Duplicated Code** | Same logic in multiple files/hunks | Extract to shared function |
|
|
| **Feature Envy** | Method reaches into another object's data more than its own | Move method to the data it envys |
|
|
| **Data Clumps** | Same fields/params travel together | Bundle into a type |
|
|
| **Primitive Obsession** | Primitives standing in for domain concepts | Create small types |
|
|
| **Repeated Switches** | Same switch/if-cascade repeats | Use polymorphism or map |
|
|
| **Shotgun Surgery** | One logical change forces edits in many files | Gather related changes together |
|
|
| **Divergent Change** | One file edited for unrelated reasons | Split by concern |
|
|
| **Speculative Generality** | Abstraction/params added for imagined future needs | Delete until real need appears |
|
|
| **Message Chains** | Long `a.b().c().d()` navigation | Hide behind method on first object |
|
|
| **Middle Man** | Class/function that mostly just delegates | Call target directly |
|
|
| **Refused Bequest** | Subclass ignores most of what it inherits | Use composition, not inheritance |
|
|
|
|
## Severity Levels
|
|
|
|
| Level | Meaning | Action |
|
|
|-------|---------|--------|
|
|
| **Blocker** | Security vulnerability, correctness bug, data loss risk | Must fix before merge |
|
|
| **Major** | Significant issue affecting functionality or maintainability | Should fix before merge |
|
|
| **Minor** | Nits, style issues, minor improvements | Fix before merge or follow-up |
|
|
| **Nit** | Style preference, whitespace, naming convention | Optional, can defer |
|
|
|
|
## Categories
|
|
|
|
| Category | What It Covers |
|
|
|----------|----------------|
|
|
| **Correctness** | Logic errors, bugs, edge cases not handled |
|
|
| **Security** | Vulnerabilities, input validation, auth issues |
|
|
| **Performance** | Inefficiency, unnecessary work, memory issues |
|
|
| **Readability** | Clarity, naming, documentation |
|
|
| **Style** | Formatting, lint violations (let linter handle these) |
|
|
| **Test-Coverage** | Missing tests for new functionality |
|
|
|
|
## Example Review Output
|
|
|
|
### Input
|
|
|
|
- **Convoy:** `feature-add-auth-endpoint`
|
|
- **Fixed point:** `main`
|
|
- **Brief:** `.convoys/feature-add-auth-endpoint/brief-1-implement.md`
|
|
- **Acceptance criteria from brief:**
|
|
- [ ] Route at `apps/web/app/api/auth/register/route.ts`
|
|
- [ ] zod schema validates email/password
|
|
- [ ] Database insert creates user row
|
|
- [ ] Returns 201 on success, 400 on validation error
|
|
|
|
### Output
|
|
|
|
```markdown
|
|
# Code Review: feature-add-auth-endpoint
|
|
|
|
## Summary
|
|
Implements POST /api/auth/register endpoint with zod validation and database insert. Route file correctly placed. Meets most acceptance criteria. One validation edge case and missing test coverage identified.
|
|
|
|
## Standards Findings
|
|
|
|
### Minor
|
|
- **[style]** `apps/web/app/api/auth/register/route.ts:15` — Consider extracting validation schema to `lib/validations/auth.ts` for reusability
|
|
- **[readability]** `apps/web/app/api/auth/register/route.ts:8` — `createUser` function name could be more descriptive: `createUserFromCredentials`
|
|
|
|
### Nit
|
|
- **[style]** Missing blank line between imports
|
|
|
|
## Spec Findings
|
|
|
|
### Major
|
|
- **[correctness]** `apps/web/app/api/auth/register/route.ts:28` — Returns 500 on database error instead of appropriate 4xx. Should return 409 if email already exists.
|
|
|
|
### Minor
|
|
- **[test-coverage]** No test file created for this route. Brief AC didn't explicitly require tests but Echodo standard is to add tests.
|
|
|
|
## Recommendations
|
|
|
|
1. **High priority:** Handle duplicate email (409) and database errors (500 → 500, but logged)
|
|
2. **Medium:** Consider extracting validation schema
|
|
3. **Low:** Add minimal test coverage
|
|
|
|
## Verdict
|
|
|
|
[ ] Approve
|
|
[X] Approve with comments - one major issue should be addressed
|
|
[ ] Request changes
|
|
[ ] Block
|
|
|
|
## Metadata
|
|
- **Reviewed by:** role-reviewer (qwen-coder-mlx)
|
|
- **Model:** qwen-coder-mlx
|
|
- **Files reviewed:** 1
|
|
- **Lines changed:** ~45
|
|
```
|
|
|
|
## Running as Role-Reviewer
|
|
|
|
When triggered as `role-reviewer` in a convoy:
|
|
|
|
1. **Find the brief:** Look at convoy's current brief in `.convoys/<slug>/brief-*.md`
|
|
2. **Extract AC:** Get acceptance criteria from brief body
|
|
3. **Pin base:** Use `main` as default fixed point, or ask if different
|
|
4. **Run parallel agents:** Standards + Spec in parallel
|
|
5. **Aggregate:** Merge into final review per format above
|
|
6. **Log:** Call `log_convoy_event` with event type `role_complete`, actor `role-reviewer`
|
|
7. **Transition:** If blocker/major issues, transition convoy back to `in_progress`. If minor/nits, transition to `pr_review`.
|
|
|
|
## Interaction with Other Skills
|
|
|
|
- **backlog-sync:** When review involves changes to markdown import logic
|
|
- **convoy-lifecycle:** When logging role_complete and transitioning status
|
|
- **model-routing:** When determining which model runs the review
|
|
- **tdd-red-green:** When suggesting tests that should exist
|
|
|
|
## References
|
|
|
|
- **Original skill:** https://github.com/mattpocock/skills/blob/main/skills/engineering/code-review/SKILL.md
|
|
- **Fowler Refactoring:** Chapter 3 - "Bad Smells in Code"
|
|
- **AGENTS.md:** Root of repo for Echodo-specific standards
|
|
- **Echodo patterns:** Use existing code in `apps/web/`, `packages/` as standards reference |