diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index a6aea30c..17d4d38e 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -12,7 +12,7 @@ { "name": "compound-engineering", "description": "AI-powered development tools that get smarter with every use. Make each unit of engineering work easier than the last. Includes 29 specialized agents, 22 commands, and 20 skills.", - "version": "2.38.1", + "version": "2.38.2", "author": { "name": "Kieran Klaassen", "url": "https://github.com/kieranklaassen", diff --git a/plugins/compound-engineering/.claude-plugin/plugin.json b/plugins/compound-engineering/.claude-plugin/plugin.json index e659557f..d833afc9 100644 --- a/plugins/compound-engineering/.claude-plugin/plugin.json +++ b/plugins/compound-engineering/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "compound-engineering", - "version": "2.38.1", + "version": "2.38.2", "description": "AI-powered development tools. 29 agents, 22 commands, 20 skills, 1 MCP server for code review, research, design, and workflow automation.", "author": { "name": "Kieran Klaassen", diff --git a/plugins/compound-engineering/CHANGELOG.md b/plugins/compound-engineering/CHANGELOG.md index e7664980..83f7b782 100644 --- a/plugins/compound-engineering/CHANGELOG.md +++ b/plugins/compound-engineering/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to the compound-engineering plugin will be documented in thi The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.38.2] - 2026-03-06 + +### Fixed + +- **`/ce:review` context budget guardrails** — Review agents now build and share a compact review packet instead of receiving the full PR content by default, dedupe always-on agents, and stage follow-up agents for large PRs to reduce context-limit failures during high-effort reviews. ([#166](https://github.com/EveryInc/compound-engineering-plugin/issues/166)) +- **`setup` review depth dedupe** — Comprehensive review configs no longer add `agent-native-reviewer` to `review_agents`, because `/ce:review` already runs it automatically alongside `learnings-researcher`. + +--- + ## [2.38.1] - 2026-03-01 ### Fixed diff --git a/plugins/compound-engineering/commands/ce/review.md b/plugins/compound-engineering/commands/ce/review.md index cf4a0614..00012622 100644 --- a/plugins/compound-engineering/commands/ce/review.md +++ b/plugins/compound-engineering/commands/ce/review.md @@ -65,19 +65,67 @@ Read `compound-engineering.local.md` in the project root. If found, use `review_ If no settings file exists, invoke the `setup` skill to create one. Then read the newly created file and continue. +#### Build Review Packet (REQUIRED BEFORE SPAWNING AGENTS) + + + +Before launching any review agent, create a compact review packet from local repo inspection and `gh pr view --json` output. + +The packet should contain: +- PR title, body summary, and linked issues in 5 bullets or fewer +- Changed files grouped by subsystem, plus churn totals (file count / additions / deletions) +- High-risk files and why they matter +- Test coverage summary: existing tests touched, new tests added, missing test areas +- Open questions or suspicious patterns that need deeper inspection + +Keep the packet lean: +- Target under 200 lines and under ~3k tokens +- Do NOT paste the full diff, full PR body, or full file contents into every Task +- Omit generated files, lockfiles, snapshots, vendored assets, and build artifacts unless they are the source of risk +- For large files, include only the specific functions/classes/line ranges that matter + +Each Task should receive: +- the review packet +- the project-specific review context from `compound-engineering.local.md` +- the exact file paths it should inspect next + +If an agent needs more detail, instruct it to read files from disk directly rather than relying on pasted context. + + + #### Parallel Agents to review the PR: -Run all configured review agents in parallel using Task tool. For each agent in the `review_agents` list: +Build the final base agent set as: + +1. `review_agents` from config +2. Always-on agents: `agent-native-reviewer`, `learnings-researcher` + +Deduplicate this list while preserving order. Never run the same agent twice. + +Run the deduped agent set in parallel using Task tool. For each agent: ``` -Task {agent-name}(PR content + review context from settings body) +Task {agent-name}(review packet + exact file paths to inspect + review context from settings body) ``` -Additionally, always run these regardless of settings: -- Task agent-native-reviewer(PR content) - Verify new features are agent-accessible -- Task learnings-researcher(PR content) - Search docs/solutions/ for past issues related to this PR's modules and patterns +Additionally: +- `agent-native-reviewer` verifies that new features are agent-accessible +- `learnings-researcher` searches `docs/solutions/` for past issues related to this PR's modules and patterns + +#### Large-PR Context Guardrails + +If the PR is large (for example: >25 files changed, >800 changed lines, multiple subsystems, or the model has already warned about compaction/context pressure), do NOT fan out to every configured agent immediately. + +Instead: + +1. Start with a first wave: stack-specific reviewer(s), `agent-native-reviewer`, `learnings-researcher`, and only the most relevant focus agent(s) for the risky files. +2. Wait for first-wave results and identify unresolved hot spots. +3. Launch second-wave agents only for those hot spots, passing a narrower follow-up packet and the specific file paths. +4. Prefer targeted follow-up Tasks over repeating a full-repo review. + +When context pressure is visible, breadth yields to precision. It is better to run fewer well-targeted agents than many shallow agents that compact and lose the actual code under review. @@ -89,9 +137,9 @@ These agents are run ONLY when the PR matches specific criteria. Check the PR fi **MIGRATIONS: If PR contains database migrations, schema.rb, or data backfills:** -- Task schema-drift-detector(PR content) - Detects unrelated schema.rb changes by cross-referencing against included migrations (run FIRST) -- Task data-migration-expert(PR content) - Validates ID mappings match production, checks for swapped values, verifies rollback safety -- Task deployment-verification-agent(PR content) - Creates Go/No-Go deployment checklist with SQL verification queries +- Task schema-drift-detector(review packet + migration file paths) - Detects unrelated schema.rb changes by cross-referencing against included migrations (run FIRST) +- Task data-migration-expert(review packet + migration file paths) - Validates ID mappings match production, checks for swapped values, verifies rollback safety +- Task deployment-verification-agent(review packet + migration file paths) - Creates Go/No-Go deployment checklist with SQL verification queries **When to run:** - PR includes files matching `db/migrate/*.rb` or `db/schema.rb` @@ -203,7 +251,9 @@ Complete system context map with component interactions ### 4. Simplification and Minimalism Review -Run the Task code-simplicity-reviewer() to see if we can simplify the code. +If `code-simplicity-reviewer` is NOT already in the deduped agent set, run it now with the same review packet. + +If it already ran in the main review wave, reuse that result. Do not spawn `code-simplicity-reviewer` twice for the same PR. ### 5. Findings Synthesis and Todo Creation Using file-todos Skill diff --git a/plugins/compound-engineering/skills/setup/SKILL.md b/plugins/compound-engineering/skills/setup/SKILL.md index 73fc0fb7..ab6e2f42 100644 --- a/plugins/compound-engineering/skills/setup/SKILL.md +++ b/plugins/compound-engineering/skills/setup/SKILL.md @@ -114,9 +114,9 @@ options: - label: "Thorough (Recommended)" description: "Stack reviewers + all selected focus agents." - label: "Fast" - description: "Stack reviewers + code simplicity only. Less context, quicker." + description: "Stack reviewers + code simplicity only. Lowest context use for large PRs." - label: "Comprehensive" - description: "All above + git history, data integrity, agent-native checks." + description: "All above + git history and data integrity. Always-on review agents stay deduped." ``` ## Step 4: Build Agent List and Write File @@ -136,7 +136,9 @@ options: **Depth:** - Thorough: stack + selected focus areas - Fast: stack + `code-simplicity-reviewer` only -- Comprehensive: all above + `git-history-analyzer, data-integrity-guardian, agent-native-reviewer` +- Comprehensive: all above + `git-history-analyzer, data-integrity-guardian` + +`agent-native-reviewer` and `learnings-researcher` are always added by `/ce:review`, so do not include them in `review_agents`. **Plan review agents:** stack-specific reviewer + `code-simplicity-reviewer`. @@ -169,6 +171,10 @@ Review depth: {depth} Agents: {count} configured {agent list, one per line} +Always-on during /ce:review: + agent-native-reviewer + learnings-researcher + Tip: Edit the "Review Context" section to add project-specific instructions. Re-run this setup anytime to reconfigure. ``` diff --git a/tests/cli.test.ts b/tests/cli.test.ts index 390d06ce..9fe477e3 100644 --- a/tests/cli.test.ts +++ b/tests/cli.test.ts @@ -310,6 +310,56 @@ describe("CLI", () => { expect(await exists(path.join(codexRoot, "AGENTS.md"))).toBe(true) }) + test("convert preserves compound-engineering review guardrails in codex output", async () => { + const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "cli-ce-codex-home-")) + const codexRoot = path.join(tempRoot, ".codex") + const pluginRoot = path.join(import.meta.dir, "..", "plugins", "compound-engineering") + + const proc = Bun.spawn([ + "bun", + "run", + "src/index.ts", + "convert", + pluginRoot, + "--to", + "codex", + "--codex-home", + codexRoot, + ], { + cwd: path.join(import.meta.dir, ".."), + stdout: "pipe", + stderr: "pipe", + }) + + const exitCode = await proc.exited + const stdout = await new Response(proc.stdout).text() + const stderr = await new Response(proc.stderr).text() + + if (exitCode !== 0) { + throw new Error(`CLI failed (exit ${exitCode}).\nstdout: ${stdout}\nstderr: ${stderr}`) + } + + const reviewPromptPath = path.join(codexRoot, "prompts", "ce-review.md") + const reviewSkillPath = path.join(codexRoot, "skills", "ce-review", "SKILL.md") + const setupSkillPath = path.join(codexRoot, "skills", "setup", "SKILL.md") + + expect(stdout).toContain("Converted compound-engineering") + expect(await exists(reviewPromptPath)).toBe(true) + expect(await exists(reviewSkillPath)).toBe(true) + expect(await exists(setupSkillPath)).toBe(true) + + const reviewPrompt = await fs.readFile(reviewPromptPath, "utf8") + const reviewSkill = await fs.readFile(reviewSkillPath, "utf8") + const setupSkill = await fs.readFile(setupSkillPath, "utf8") + + expect(reviewPrompt).toContain("create a compact review packet") + expect(reviewPrompt).toContain("Deduplicate this list while preserving order. Never run the same agent twice.") + expect(reviewPrompt).toContain("Do not spawn `code-simplicity-reviewer` twice for the same PR.") + expect(reviewSkill).toContain("Task {agent-name}(review packet + exact file paths to inspect + review context from settings body)") + expect(setupSkill).toContain("`agent-native-reviewer` and `learnings-researcher` are always added by `/ce:review`, so do not include them in `review_agents`.") + expect(setupSkill).toContain("Always-on during /ce:review:") + }) + test("install supports --also with codex output", async () => { const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "cli-also-")) const fixtureRoot = path.join(import.meta.dir, "fixtures", "sample-plugin") diff --git a/tests/compound-review-command.test.ts b/tests/compound-review-command.test.ts new file mode 100644 index 00000000..c8d7cc84 --- /dev/null +++ b/tests/compound-review-command.test.ts @@ -0,0 +1,40 @@ +import { describe, expect, test } from "bun:test" +import { promises as fs } from "fs" +import path from "path" + +const repoRoot = path.join(import.meta.dir, "..") +const reviewCommandPath = path.join( + repoRoot, + "plugins", + "compound-engineering", + "commands", + "ce", + "review.md", +) +const setupSkillPath = path.join( + repoRoot, + "plugins", + "compound-engineering", + "skills", + "setup", + "SKILL.md", +) + +describe("compound-engineering review workflow content", () => { + test("ce:review uses a compact review packet and dedupes agents", async () => { + const reviewCommand = await fs.readFile(reviewCommandPath, "utf8") + + expect(reviewCommand).toContain("#### Build Review Packet (REQUIRED BEFORE SPAWNING AGENTS)") + expect(reviewCommand).toContain("Deduplicate this list while preserving order. Never run the same agent twice.") + expect(reviewCommand).toContain("Task {agent-name}(review packet + exact file paths to inspect + review context from settings body)") + expect(reviewCommand).toContain("Do not spawn `code-simplicity-reviewer` twice for the same PR.") + }) + + test("setup skill avoids duplicating always-on review agents", async () => { + const setupSkill = await fs.readFile(setupSkillPath, "utf8") + + expect(setupSkill).toContain("Comprehensive: all above + `git-history-analyzer, data-integrity-guardian`") + expect(setupSkill).toContain("`agent-native-reviewer` and `learnings-researcher` are always added by `/ce:review`, so do not include them in `review_agents`.") + expect(setupSkill).toContain("Always-on during /ce:review:") + }) +})