Goal
chess-evolve (the reference factory-as-library demo) should define only two things:
task = PositionTask()
workflow = build_position_eval_workflow()
result = SwarmEngine.from_task(task, workflow, budget=100).run()
No adapter, no monkey-patches, no workspace hacks. Today we need a ChessSwarmEvaluator adapter (~30 lines) because of gaps in remote-factory. This issue tracks the path to eliminating it.
Current adapter and why each piece exists
class ChessSwarmEvaluator(SwarmEvaluator):
def evaluate(self, workflow, ...):
_prime_workspace(workspace) # ← Gap A
_runner.invoke_agent = _make_move_invoke(inner) # ← Gap B + C
loop = InnerLoop(project_dir=workspace, workflow=workflow)
record = loop.step()
_runner.invoke_agent = _orig # ← Gap B cleanup
return EvalResult(score=record.score_end)
Gap A: Workspace priming (_prime_workspace)
Creates .factory/chess/ dir and placeholder board_state.md, memory.md before the executor runs — otherwise the executor blocks on reads that don't exist yet.
Fix (chess-evolve side): Move priming into PositionTask.setup() — the Task contract already owns workspace preparation. No factory change needed. Can fix now.
Gap B: Agent backend swap (invoke_agent monkey-patch)
Swaps factory.agents.runner.invoke_agent (spawns claude CLI) for chess-evolve's _sdk_invoke_agent (Haiku API). Restored in finally.
Fix (remote-factory): WorkflowExecutor should accept an optional agent_fn parameter. Tracked in #1488 (Gap #1).
Gap C: Output persistence (_make_move_invoke wrapper)
Writes agent output to .factory/chess/move.md on disk after every call. Needed because WorkflowExecutor keeps output in memory only, but PositionTask.verify() reads from disk.
Fix (remote-factory): Executor should write agent output to paths declared in node.writes automatically. Akash's Factory Artifact Format design (Port-level write validation) is the upstream fix. Tracked in #1488 (Gap #2).
Sequencing
- Now (chess-evolve): Fix Gap A —
Task.setup() handles priming
- Upstream: Fix Gap B —
WorkflowExecutor(agent_fn=...) eliminates monkey-patch
- Upstream: Fix Gap C — executor writes to
node.writes automatically (artifact format)
- Upstream: Add
SwarmEngine.from_task(task, workflow, budget) convenience API
- Final: Delete
ChessSwarmEvaluator. evolution.py becomes 5 lines.
End state
from chess_evolve.tasks import PositionTask
from chess_evolve.pipeline import build_position_eval_workflow
from factory.outer_loop import SwarmEngine
def main():
task = PositionTask()
workflow = build_position_eval_workflow()
result = SwarmEngine.from_task(task, workflow, budget=100).run()
print(f"Best score: {result.best_score}")
Related
🤖 Generated with Claude Code
Goal
chess-evolve (the reference factory-as-library demo) should define only two things:
No adapter, no monkey-patches, no workspace hacks. Today we need a
ChessSwarmEvaluatoradapter (~30 lines) because of gaps in remote-factory. This issue tracks the path to eliminating it.Current adapter and why each piece exists
Gap A: Workspace priming (
_prime_workspace)Creates
.factory/chess/dir and placeholderboard_state.md,memory.mdbefore the executor runs — otherwise the executor blocks on reads that don't exist yet.Fix (chess-evolve side): Move priming into
PositionTask.setup()— the Task contract already owns workspace preparation. No factory change needed. Can fix now.Gap B: Agent backend swap (
invoke_agentmonkey-patch)Swaps
factory.agents.runner.invoke_agent(spawnsclaudeCLI) for chess-evolve's_sdk_invoke_agent(Haiku API). Restored infinally.Fix (remote-factory):
WorkflowExecutorshould accept an optionalagent_fnparameter. Tracked in #1488 (Gap #1).Gap C: Output persistence (
_make_move_invokewrapper)Writes agent output to
.factory/chess/move.mdon disk after every call. Needed becauseWorkflowExecutorkeeps output in memory only, butPositionTask.verify()reads from disk.Fix (remote-factory): Executor should write agent output to paths declared in
node.writesautomatically. Akash's Factory Artifact Format design (Port-level write validation) is the upstream fix. Tracked in #1488 (Gap #2).Sequencing
Task.setup()handles primingWorkflowExecutor(agent_fn=...)eliminates monkey-patchnode.writesautomatically (artifact format)SwarmEngine.from_task(task, workflow, budget)convenience APIChessSwarmEvaluator.evolution.pybecomes 5 lines.End state
Related
_step_with_data_node)🤖 Generated with Claude Code