refactor: remove dead code and drop bob/codex/opencode runner support - #1309
refactor: remove dead code and drop bob/codex/opencode runner support#1309RobotSail wants to merge 3 commits into
Conversation
Remove genuinely dead code (evolver.md agent prompt, orphaned skills/study/ plugin skill) and drop the unused bob/codex/opencode multi-backend runner infrastructure. These runners were structurally reachable via dynamic dispatch but had zero production invocations in the project's history. Track A — Dead code (zero references): - Delete factory/agents/prompts/evolver.md (38 lines, unreachable) - Delete skills/study/SKILL.md (orphaned plugin, superseded by workflow-study) Track B — Runner removal (user-approved product decision): - Delete 3 runner implementations: bob.py, codex.py, opencode.py (888 lines) - Delete usage.py (179 lines, only used by bob+opencode) - Clean runners/__init__.py to Claude-only dispatch - Delete 2 dedicated test files (1,258 lines) - Remove 10 dead test classes across 4 shared test files - Remove codex plugin functions from plugin.py, admin.py, sync_agents.py - Rewrite docs/runner-v2-spec.md to Claude-only contract - Update CLAUDE.md, SPEC.md to reflect Claude-only runner surface - Clean scattered runner refs across test files and conftest.py Total: 28 files changed, ~4,400 lines removed. Closes akashgit#1301 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1309 +/- ##
==========================================
- Coverage 84.86% 84.72% -0.14%
==========================================
Files 231 227 -4
Lines 25759 25151 -608
Branches 4115 4032 -83
==========================================
- Hits 21860 21310 -550
+ Misses 2922 2882 -40
+ Partials 977 959 -18 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@ceo-review |
There was a problem hiding this comment.
✅ Factory Review: KEEP
Verdict: KEEP
Reason: QA: CLEAN — 597 tests pass, composite 0.9643, 0 critical/important issues. 4 minor stale docstring refs in untouched files.
QA Analysis
Adversarial QA Report — PR #1309
PR: refactor: remove dead code and drop bob/codex/opencode runner support
Changes: 29 files, +87/-4293 lines
Detected project type: CLI (Python, uv-managed)
Date: 2026-08-18
Smoke Test
Command: uv run factory --help
Result: PASS — CLI loads, all subcommands listed, no import errors.
Command: uv run factory --version
Output: remote-factory 0.0.1.dev1+gc2d3a94ad
Result: PASS
Acceptance Criteria
AC1: Removed runner modules (bob, codex, opencode, usage) are no longer importable
Status: VERIFIED
Evidence:
$ uv run python -c "
import importlib
for mod in ['factory.runners.bob', 'factory.runners.codex', 'factory.runners.opencode', 'factory.runners.usage']:
try:
importlib.import_module(mod)
print(f'FAIL: {mod} still importable')
except ImportError:
print(f'OK: {mod} correctly removed')
"
OK: factory.runners.bob correctly removed
OK: factory.runners.codex correctly removed
OK: factory.runners.opencode correctly removed
OK: factory.runners.usage correctly removed
AC2: Runner registry only contains 'claude'
Status: VERIFIED
Evidence:
$ uv run python -c "
from factory.runners import get_available_runners, get_runner_choices
runners = get_available_runners()
assert list(runners.keys()) == ['claude']
print('Registry:', list(runners.keys()))
choices = get_runner_choices()
assert choices == ['claude']
print('Choices:', choices)
"
Registry: ['claude']
Choices: ['claude']
AC3: get_runner('claude') resolves correctly
Status: VERIFIED
Evidence:
$ uv run python -c "from factory.runners import get_runner; r = get_runner('claude'); print(type(r).__name__)"
ClaudeRunner
AC4: get_runner() with removed runner name gives proper error
Status: VERIFIED
Evidence:
$ FACTORY_RUNNER=codex uv run python -c "from factory.runners import get_runner; get_runner()"
ValueError: Unknown runner 'codex'. Available: claude
AC5: factory runners list only shows claude
Status: VERIFIED
Evidence:
$ uv run factory runners list
Name Display Binary Available Auth
---------------------------------------------------------------
claude Claude Code claude yes ok
Note: The bare factory command (installed system-wide at /home/runner/.local/bin/factory) still shows bob/codex/opencode because it runs from an older installation. The PR code (uv run factory) correctly shows only claude.
AC6: ClaudeRunner instantiation and metadata work
Status: VERIFIED
Evidence:
$ uv run python -c "from factory.runners.claude import ClaudeRunner; r = ClaudeRunner(); print(f'name={r.name}')"
ClaudeRunner OK, name: claude
AC7: _sandbox_mode function restored in plugin.py (fix commit 38a8370)
Status: VERIFIED
Evidence:
$ grep -n "_sandbox_mode" factory/agents/plugin.py
98:def _sandbox_mode(role: str) -> str:
AC8: Agent content generation works for all roles
Status: VERIFIED
Evidence:
$ uv run python -c "
from factory.agents.plugin import generate_agent_content, load_agent_config
config = load_agent_config()
print('Agent roles:', list(config.keys()))
for role in config:
content = generate_agent_content(role)
print(f' {role}: {len(content)} chars OK')
"
Agent roles: ['researcher', 'strategist', 'builder', 'archivist', 'ceo', 'failure_analyst', 'refiner', 'profiler', 'refactory']
researcher: 12408 chars OK
strategist: ... OK
builder: 6562 chars OK
...all 9 roles generate OK
AC9: factory install command works end-to-end
Status: VERIFIED
Evidence:
$ # (ran with HOME set to temp dir)
$ uv run python -c "from factory.cli.admin import cmd_install; ..."
Installed factory-researcher -> .../factory-researcher.md
Installed factory-strategist -> .../factory-strategist.md
Installed factory-builder -> .../factory-builder.md
Installed factory-archivist -> .../factory-archivist.md
Installed factory-ceo -> .../factory-ceo.md
Installed factory-failure_analyst -> .../factory-failure_analyst.md
Installed factory-refiner -> .../factory-refiner.md
Installed factory-profiler -> .../factory-profiler.md
Installed factory-refactory -> .../factory-refactory.md
Exit code: 0
AC10: Removed test and doc files are gone
Status: VERIFIED
Evidence:
$ ls tests/test_codex_runner.py tests/test_opencode_runner.py docs/codex-mcp.md skills/study/SKILL.md factory/agents/prompts/evolver.md 2>&1
ls: cannot access 'tests/test_codex_runner.py': No such file or directory
ls: cannot access 'tests/test_opencode_runner.py': No such file or directory
ls: cannot access 'docs/codex-mcp.md': No such file or directory
ls: cannot access 'skills/study/SKILL.md': No such file or directory
ls: cannot access 'factory/agents/prompts/evolver.md': No such file or directory
AC11: All PR-relevant test suites pass
Status: VERIFIED
Evidence:
$ uv run pytest tests/test_runners.py tests/test_user_config.py tests/test_agents.py tests/test_ceo_completion.py tests/test_tmux_cli.py tests/test_plugin_agents.py -v
======================== 309 passed, 3 skipped in ~9s ========================
Breakdown:
- test_runners.py: 74 passed
- test_user_config.py: 60 passed, 3 skipped
- test_agents.py + test_ceo_completion.py + test_tmux_cli.py: 152 passed
- test_plugin_agents.py: 23 passed
- test_runner_e2e.py: 17 passed, 1 skipped (ran separately, 130s)
AC12: Ruff linter passes on changed files
Status: VERIFIED
Evidence:
$ uv run ruff check factory/runners/ factory/agents/plugin.py factory/ceo_completion.py factory/cli/admin.py factory/user_config.py
All checks passed!
Edge Case Tests
EC1: Remaining "bob" references in docstrings (cosmetic, non-breaking)
Status: NOT_VERIFIED (cosmetic issue — not a functional regression)
Evidence:
$ grep -n "bob" factory/ceo_completion.py factory/runners/protocol.py factory/runners/_stream.py
factory/runners/protocol.py:50: """Protocol for CLI backend implementations (claude, bob, etc.)."""
factory/ceo_completion.py:487: runner_name: Runner to use (claude or bob).
factory/runners/_stream.py:91: prefix: Optional prefix to prepend to each line (e.g., b"[bob:researcher] ").
factory/runners/_stream.py:157: prefix: Optional prefix for each line (e.g., "[bob:researcher]").
These are in docstrings/comments only. No functional impact. Low-priority cleanup opportunity.
EC2: test_runner_e2e.py has dead skip logic for removed runners
Status: NOT_VERIFIED (cosmetic issue — dead code, non-breaking)
Evidence:
$ grep -A1 "bob.*codex.*opencode" tests/test_runner_e2e.py
if name in ("bob", "codex", "opencode"):
return False
Guard clause for runners that no longer exist in parameterized tests. Harmless dead code.
EC3: test_user_config.py uses "bob" as a test fixture value
Status: VERIFIED (not a problem)
Evidence:
$ grep -c "bob" tests/test_user_config.py
16
These use "bob" as a generic test value for FACTORY_RUNNER config resolution tests (e.g., testing that config.toml values flow through). The tests exercise config plumbing, not runner instantiation. "bob" here is just an arbitrary string — it correctly shows that config resolution works regardless of whether the runner exists. All 60 tests pass.
Summary
| Category | Passed | Failed | Skipped |
|---|---|---|---|
| Acceptance criteria | 12 | 0 | 0 |
| Edge cases (functional) | 1 | 0 | 0 |
| Edge cases (cosmetic) | 0 | 2 | 0 |
Cosmetic issues found (non-blocking):
- Four stale "bob" references remain in docstrings across
protocol.py,ceo_completion.py, and_stream.py - Dead skip guard in
test_runner_e2e.pyfor removed runner names
Adversarial Verdict: PASS
The refactoring successfully removed bob/codex/opencode runner support without breaking any functionality. The claude runner works correctly as the sole remaining runner. All 309+ tests pass. Error handling for invalid runner names works properly. Agent generation and installation work end-to-end. The two cosmetic issues (stale docstring references) are non-blocking.
Posted by Factory CEO
Closes #1301
Summary
evolver.mdagent prompt (zero references), orphanedskills/study/SKILL.mdplugin skill (superseded byskills/workflow-study/)docs/runner-v2-spec.mdto Claude-only contract (not deleted — documents Runner Protocol used by ClaudeRunner)CLAUDE.mdandSPEC.mdto reflect Claude-only runner surface28 files changed, ~4,400 lines removed
What is NOT touched (PR #1302 false positives)
founder,study,refinemodes — all documented, registered, non-deprecatedrefactory.py,cycle_analyzer.py— actively used (16+ references, 5 active importers)frontend-designmodes — separate product decision pendingparallel-improve— soft-deprecated but still functionalbuild_workflow,improve_workflowfunctions — structural bases for design/research modesTest plan
pytest -x -qpasses (no broken imports from removed modules)ruff check .cleanmypy factory/cleanfactory --helpshows no bob/codex/opencode referencesfactory agent researcher --task "test" --project /tmp/teststill works (Claude runner unaffected)🤖 Generated with Claude Code