- Published on
How I Built an AI Team That Enforces Its Own Quality Gates
Introduction
I got tired of context-switching. I was building multiple projects -- an AI agent for game analysis, a multi-provider LLM router, a frame extraction library -- and every time I moved between repos, I lost track of what was in progress, what depended on what, and whether changes in one project would break another.
So I built EcoOrchestra. (The repo is currently private but may be made public in the future.) It is an orchestrator that auto-discovers projects in my workspace, generates dependency graphs, and provides a set of slash commands that enforce a development pipeline. The idea is simple: instead of me keeping track of everything in my head, the tooling enforces the workflow.
The Pipeline
The core of EcoOrchestra is a persona-based pipeline. Each step is handled by a different "persona" -- an AI agent with a specific role. The pipeline uses a two-tier model strategy: Opus for the reasoning-heavy steps (vision, plan, build) and Sonnet for the fresh-perspective steps (review, QA):
/vision -> /plan -> /build -> /review -> /qa -> /ship
(opus) (opus) (opus) (sonnet) (sonnet)
Each persona has a specific job:
- Vision challenges the idea before any code is written. Is this the right feature? Does it belong in this repo? What is the blast radius if the approach is wrong?
- Plan decomposes features into atomic tasks with explicit file paths, verification steps, and acceptance criteria.
- Build implements from the task spec. It does not freelance -- it builds what was planned.
- Review is read-only code review with a different model than the developer. The fresh perspective catches what familiarity misses.
- QA takes Playwright screenshots and runs E2E tests. It is the only step that can close GitHub Issues -- the quality gate.
- Ship pushes, creates PRs, and handles last-mile release.
The key design decision was a two-tier model system. Vision, plan, and build all use Opus for strong reasoning -- they need to think deeply about architecture and implementation. Review and QA use Sonnet -- a deliberately different model so it does not share the developer's blind spots. This is the same reason you would not have the person who wrote the code also review it.
Pipeline Enforcement
I did not want the pipeline to be optional. If it is optional, I will skip steps when I am in a hurry -- which is exactly when the steps matter most.
EcoOrchestra enforces the pipeline at three layers:
- Edit/Write hooks block code edits unless the developer persona is active. You cannot modify product code without going through
/build. - Bash hooks block shell commands that would modify code files (like
sed -iorecho >) without the developer persona. This prevents bypassing the Edit/Write enforcement via the terminal. - Session lifecycle hooks clean up persona state on session start and stop, preventing stale state from a crashed session from bypassing enforcement.
If I try to edit a file without running /build first, the hook blocks it. If the reviewer finds critical issues, it automatically sends the work back to /build for fixes. If QA finds problems, same thing -- automatic fix loop back to the developer.
Where Does This Feature Belong?
One of the problems I kept running into was putting code in the wrong repo. A utility function that starts in one project becomes useful in another. A feature that seems app-specific turns out to be generic. By the time you realize the placement is wrong, the code is entangled with project-specific logic and extracting it is painful.
EcoOrchestra addresses this at multiple points in the pipeline:
The Vision step asks placement questions explicitly. Before any planning starts, /vision evaluates: does this feature belong in the project the user is thinking of? Is it generic enough to be a shared module? What is the blast radius if the abstraction is wrong? I have had /vision redirect features from one repo to another before a single line of code was written -- catching placement mistakes when they are free to fix, not expensive.
The modules registry tracks shared code. modules/REGISTRY.md lists every extracted shared library and candidates for extraction. Before writing new functionality, the developer checks: does a shared module already provide this? If something similar exists, use it or extend it. If you are writing something generic, flag it as an extraction candidate -- do not embed it in a project-specific folder.
The Review step checks for boundary violations. The reviewer looks for code that is generic but lives inside a project-specific folder, duplicated logic across projects, and shared types defined in only one project. When the reviewer spots a shared pattern, it adds the candidate to the modules registry.
Auto-discovery classifies projects by role. EcoOrchestra scans the workspace, reads pyproject.toml and package.json manifests, and classifies each project:
- lib -- shared libraries consumed by other projects
- app -- applications that depend on libraries
- hub -- projects that both depend on and are depended on
- standalone -- projects with no dependencies in either direction
This classification drives the dependency graph and makes cross-project relationships visible. When a feature touches a dependency, the pipeline creates a handoff task instead of modifying the dependency directly -- respecting repo boundaries.
The core principle is: generic code gets planned as a separate module from the start, not extracted after it is entangled. The earlier you make the placement decision, the cheaper it is to get right.
How EcoOrchestra Differs from gstax and Superpowers
Two projects heavily influenced how I think about AI-assisted development, and it is worth explaining where EcoOrchestra overlaps and diverges.
vs gstax
gstax shaped my thinking about structured orchestration -- the idea that AI agents benefit from explicit workflow stages rather than free-form prompting. The separation of concerns between planning, building, and reviewing in EcoOrchestra's pipeline is a direct descendant of patterns from gstax.
Where EcoOrchestra diverges: multi-repo awareness. gstax operates within a single project context. EcoOrchestra was built specifically for ecosystems -- multiple repos with dependencies between them. The auto-discovery, dependency graphs, modules registry, and cross-repo handoffs are all about managing complexity that only exists when you have multiple projects that need to stay in sync.
vs Superpowers
Superpowers influenced the methodology side -- atomic task decomposition, systematic debugging (reproduce, hypothesize, trace, verify), and test-first development. When I evaluated Superpowers against EcoOrchestra, I realized the two are complementary: Superpowers provides methodology, EcoOrchestra provides orchestration.
I imported the methodology ideas -- atomic task specs with explicit file paths and verification steps, systematic debugging for fix loops -- without adopting the framework architecture. EcoOrchestra's persona commands already serve the same role as Superpowers' skills system, so adding a skills abstraction layer would have been unnecessary indirection.
Where EcoOrchestra diverges: enforcement over guidance. Superpowers provides best practices that the developer can follow or ignore. EcoOrchestra enforces the workflow with hooks that block non-compliant actions. You cannot edit product code without the developer persona active. You cannot skip the review step. This is a deliberate trade-off -- less flexibility, but the pipeline runs consistently whether I am disciplined or rushing.
The common thread
All three tools are solving the same problem: how do you get consistent, high-quality output from AI-assisted development? gstax says structure the workflow. Superpowers says improve the methodology. EcoOrchestra says enforce both, across repos, with different models checking each other's work. They are complementary approaches, and I borrowed from both.
Conclusion
EcoOrchestra is the foundation everything else runs on. Every feature in every project goes through this pipeline. The enforcement is not optional -- and that is the point. The few times I have tried to skip steps "just for a quick fix," the pipeline caught issues I would have shipped.