feat: Pluggable orchestrators — composable workflow definitions#502
feat: Pluggable orchestrators — composable workflow definitions#502jcasimir wants to merge 8 commits intoEveryInc:mainfrom
Conversation
Reviewer .md files no longer ship with the plugin. Instead, they live in external Git repos and are synced on demand via /ce:refresh. This lets users customize their review team — add custom reviewers, exclude ones they don't need, or mix reviewers from multiple repos — without forking the plugin. What changed: - Removed 28 built-in reviewer .md files from agents/review/ - Added .gitignore so synced reviewers aren't committed to the plugin - Added _template-reviewer.md as a starting point for custom reviewers - Added reviewer-registry.yaml with source configuration (which repos to sync from, with except lists and conflict resolution) - Refactored persona-catalog.md to explain the system rather than enumerate reviewers - Updated tests to check registry structure and skip gracefully when reviewer files aren't present (pre-refresh) Each reviewer's selection metadata (category, select_when) lives in its own frontmatter, so adding a reviewer is a single file in a single repo — no registry entry needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
A new skill and bash script that fetches reviewer .md files from configured Git repos into the plugin's agents/review/ directory. Features: - User config at ~/.config/compound-engineering/reviewer-sources.yaml (auto-created on first run with sensible defaults) - Interactive menu: sync, edit config, or type natural language changes - Multiple sources with priority ordering (first listed wins) - Per-source except lists to skip specific reviewers - gh CLI with git clone fallback - Detailed per-source summary written to a file for verbatim display - Compatible with macOS bash 3 (no associative arrays) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Root README: add /ce:refresh as a post-install step - Plugin README: replace hardcoded reviewer list with docs for the pluggable system (setup, source configuration, custom reviewers, categories, conflict resolution) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The ce-reviewers repo now stores reviewer files under reviewers/ instead of at the root. Update the default source path to match. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The commented-out example in the sync script's first-run template showed path: . which was inconsistent with the actual default source using path: reviewers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… refactor Orchestrators are pluggable workflow definitions that compose existing skills and reviewers with different intent. They use the same .md format as reviewers (YAML frontmatter + prose body) and sync via /ce:refresh. - Add /ce:run skill to load and execute named orchestrators - Add orchestrator-registry.yaml as default source config - Generalize sync-reviewers.sh to handle reviewers, orchestrators, and other content types via a config-name parameter - Add generate-shims.sh to auto-create agent shims from definitions with agent-shim: true in frontmatter, making them addressable by name in natural language - Update /ce:refresh to sync orchestrators and generate agent shims - Refactor /lfg to delegate to /ce:run lfg - Update default reviewer registry path to reviewers/ subdirectory Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cf7189d to
2648187
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf7189d7ac
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| 8. Output `<promise>DONE</promise>` when video is in PR | ||
|
|
||
| Start with step 2 now (or step 1 if ralph-loop is available). Remember: plan FIRST, then work. Never skip the plan. | ||
| Run `/ce:run lfg $ARGUMENTS` |
There was a problem hiding this comment.
Ship a default lfg orchestrator or keep local fallback
This change turns /lfg into a pure delegation to /ce:run lfg, but this commit does not add any bundled orchestrator files under plugins/compound-engineering/orchestrators, so a fresh install cannot execute the LFG workflow until users run /ce:refresh manually and network sync succeeds. That is a regression from the previous self-contained /lfg behavior and breaks a primary workflow path out of the box.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Yes, the approach is that users are fetching the default orchestrators and reviewers at install time when they do their first /ce:refresh.
|
|
||
| # Fetch files | ||
| src_tmp=$(mktemp -d) | ||
| fetched_files=$(fetch_files "$repo" "$branch" "$path" "$src_tmp" 2>&1) || { |
There was a problem hiding this comment.
Keep fetch stderr out of the filename parsing path
The script captures fetch_files with 2>&1 and then iterates the result as filenames, so any warning text emitted on stderr (for example a partial download warning) is tokenized and treated as file names, which causes bogus copy/log entries and incorrect refresh summaries. Capture only stdout for file names (newline-safe) and leave stderr separate so diagnostics do not corrupt sync state.
Useful? React with 👍 / 👎.
|
This also may need to wait a bit for us to think about it. We have plans to overhaul how lfg works, to be more full autopilot. |
The 2>&1 on the fetch_files call caused any stderr warnings to be tokenized as filenames, leading to bogus copy/log entries. Capture only stdout for filenames and let stderr flow to the terminal. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
/lfg now delegates to /ce:run lfg, so the test checks for the delegation call instead of inline review mode flags. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
To be honest I don't love LFG, but it was an easy way to demonstrate the pattern of behavior. If you check out my other orchestrators in https://github.com/JumpstartLab/ce-reviewers-jsl/tree/main/orchestrators , I think it's more compelling. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: da1cc57e0c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| Find the plugin's install location in the Claude plugin cache: | ||
|
|
||
| ```bash | ||
| PLUGIN_DIR=$(find "$HOME/.claude" "$HOME/.claude-"* -path "*/compound-engineering/*/agents/review" -type d 2>/dev/null | head -1 | sed 's|/agents/review$||') |
There was a problem hiding this comment.
Resolve plugin directory without Claude-cache assumptions
This path discovery hardcodes Claude cache locations and then falls back to plugins/compound-engineering, so /ce:refresh (and the same pattern in /ce:run) cannot locate the plugin in converted Codex/Gemini installs where neither path exists. That makes the new refresh/run workflows fail outside a repo checkout. It also conflicts with the cross-platform and script-path guidance in plugins/compound-engineering/AGENTS.md, which requires portable skill-local pathing instead of platform-specific cache probing.
Useful? React with 👍 / 👎.
| cat > "$REVIEW_DIR/_shim-${SHORT_NAME}.md" << SHIM | ||
| --- | ||
| name: $SHORT_NAME | ||
| description: "$DESC Use when the user mentions $SHORT_NAME by name or asks for their opinion." |
There was a problem hiding this comment.
Escape shim descriptions before writing YAML frontmatter
$DESC is interpolated directly into a double-quoted YAML string, so descriptions containing unescaped " produce invalid frontmatter (for example when source files use single-quoted YAML with embedded double quotes). When that happens, generated shims cannot be parsed/loaded as agents, so natural-language shim dispatch silently breaks for those personas.
Useful? React with 👍 / 👎.
| [ -n "$NAME" ] || continue | ||
|
|
||
| # Short name: first part before hyphen (avi from avi-rails-architect) | ||
| SHORT_NAME=$(echo "$NAME" | cut -d'-' -f1) |
There was a problem hiding this comment.
Avoid short-name collisions when generating reviewer shims
Deriving shim names from only the first hyphen-delimited token causes collisions whenever multiple shim-enabled reviewers share a prefix (e.g., kieran-rails and kieran-python both become _shim-kieran.md). The later file overwrites the earlier one, making one reviewer unreachable and routing name-based requests to the wrong persona.
Useful? React with 👍 / 👎.
Building on the idea of pluggable reviewers, I wanted to create a concept of orchestrators. Sometimes you want to run a workflow through a quick spike, sometimes you want a strong process, sometimes you want to deep-dive.
The base plugin has the
/lfgconcept which is an example of an orchestrator. I wanted to be able to model out some different personalities and processes.My orchestrators can be found here: https://github.com/JumpstartLab/ce-reviewers-jsl
I also updated my suggested repo of base reviewers with a base LFG orchestrator here: https://github.com/JumpstartLab/ce-reviewers
In addition, I like to be able to refer to Orchestrators and Reviewers using natural language. Like "Ask Avi for his opinions on this Rails routes file" without using slash commands. I implemented some optionality in the orchestrator and reviewer profiles where they can self-elect to be turned into agents that are triggered by that kind of natural-language sentence. The
refreshcommand uses a bash script to generate "shim" agent profiles for the profiles that request it. So, after a refresh, it just works!Summary
/ce:run <name>skill to load and execute a named orchestrator/lfgto a thin wrapper for/ce:run lfg/ce:refreshto sync orchestrators alongside reviewers and auto-generate agent shimsagent-shim: truein frontmatter and creates_shim-*.mdfiles so orchestrators and named reviewers are addressable by name in natural languageOrchestrator format
Same
.mdformat as reviewers — structured YAML frontmatter (phases, review-preferences, synthesis lens, model config) with personality prose in the body. Key fields:phases— ordered list of skills to invoke with optional gates and skip conditionsreview-preferences— constraints on reviewer composition (required/preferred categories)synthesis.lens— how to weigh and filter review findingsorchestrator-model/agent-model— separate model control for the orchestrator vs its subagentsagent-shim: true— opt-in to natural language addressabilityDepends on
🤖 Generated with Claude Code