Skip to content

Refactor: extract helpers from learning_loop() god-function #39

Description

@bordeauxred

Why

`clawloop/core/loop.py:156` defines `learning_loop()`, a single function ~420 lines long that handles:

  • task sampling
  • batch episode execution
  • archive writes
  • evolver context construction
  • per-layer transactions
  • rollback on failure
  • generation flush
  • structured logging

Reading the loop end-to-end requires holding all seven concerns in your head at once. New contributors trying to add a feature touch this function and can't tell what's load-bearing vs incidental.

What

  • Extract `EpisodeCollectorRunner` — handles task sampling + batch execution (lines ~256-380). Lives in `clawloop/core/runner.py`.
  • Extract `LayerTransaction` — handles snapshot → forward_backward → optim_step → rollback-on-failure protocol (lines ~410-510). Lives in `clawloop/core/transaction.py`.
  • Extract `ArchiveRecorder` — handles RunRecord/IterationRecord/EpisodeRecord writes (lines ~520-573). Lives in `clawloop/core/archive_recorder.py`.
  • `learning_loop()` becomes a thin orchestrator: ≤80 lines, reads top-to-bottom as the algorithm.

Acceptance

  • `learning_loop()` is ≤100 lines
  • All existing tests pass with no behavioral change
  • New unit tests for each extracted helper (small, focused)

Effort

~3 hours. Touches a hot path so testing matters; existing 1023-test suite gives good coverage.

Source

Codex code audit, 2026-04-18 (S1 finding).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    refactorInternal restructuring, no behavior change

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions