Skip to content
101 changes: 101 additions & 0 deletions BRANCHES_OVERVIEW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
Branch overview for TB-Seed and child branches

This document describes the branch structure created from `TB-Seed`, the role of each child branch, how the pieces interact, how to run focused tests, and an LLM runbook that specifies what an LLM agent should do to run or validate the system.

## Branch topology

- TB-Seed (root)
- The canonical seed baseline. Minimal, self-contained project that defines the `frame`-first contract and DB-backed persistence policy. This branch is intentionally stable and kept as the origin for producing children.

- tb-minimal (child)
- Purpose: a minimal runtime that is fast to run in CI and easy to use for reproducing core behaviors.
- Key artifacts: `scripts/run_minimal.py`, `src/training/game_runner.py`, lightweight `DummyDetector` and `FrameProvider`, `src/database/db_facade.py` (lightweight facade), and a stub API (`src/api/stub_api_manager.py`) that is opt-in via `--use-stub-api-for-ci`.
- Intended usage: quick smoke tests, CI checks that do not rely on the external ARC-AGI-3 API.

- tb-core-stable (child)
- Purpose: stabilize and refactor core orchestration logic. Incrementally extract initialization responsibilities into `src/training/core/orchestrator.py` while keeping behavior backward-compatible.
- Key artifacts: `ContinuousLearningLoop` delegating to `Orchestrator`, migration-safe initializers, and tests verifying delegation.
- Intended usage: base branch for system-level refactors that should be merged into other children.

- tb-performance (child)
- Purpose: contain performance-oriented scaffolding: benchmarking harnesses, profiling tools, and performance-focused CI jobs.
- Key artifacts (planned): `bench/` harness, performance CI jobs, and measurement dashboards.
- Intended usage: experiments to measure runtime & memory impact of refactors.

- tb-research-playground (child)
- Purpose: sandbox for experiments, notebooks, and quick prototypes.
- Key artifacts (planned): `notebooks/`, research utilities, experimental models and adapters.

## High-level interaction

- Core invariants:
- The `frame` object is the canonical input for perception and action-selection. All modules consuming visual data must accept `frame` and validated detection outputs.
- Persistence: non-CI runs must use the DB facade to persist patterns, sequences, and session data. The stub API is explicitly opt-in for CI and testing.
- Orchestrator migration: we moved initialization out of the monolithic `ContinuousLearningLoop` one small initializer at a time into the `Orchestrator` facade. The legacy core will delegate to the Orchestrator when present.

- Branch relationships:
- `tb-core-stable` contains the canonical, tested core refactors. It is merged into children so they inherit the stable core and then implement branch-specific features.
- `tb-minimal` stays small and CI-friendly; it contains the GameRunner and the stub API for fast smoke runs.
- `tb-performance` and `tb-research-playground` branch from `tb-minimal` plus `tb-core-stable` merges so they have the minimal hooks + stable core.

## How to run and test locally

Assumptions: you have Python 3.11+ installed and a working virtualenv. Run these commands from the repository root.

1) Run focused tests (fast):

```pwsh
# from repo root
python -m pytest -q tests
```

2) Run minimal smoke script using stub API (opt-in flag required):

```pwsh
$env:PYTHONPATH = (Resolve-Path .).Path
python scripts/run_minimal.py --use-stub-api-for-ci --max-actions 10
```

3) Run the full continuous training (CAUTION: interacts with external APIs):

```pwsh
python train.py
```

Note: The stub API is for CI/testing only and must be enabled explicitly. For local development against a real API, configure credentials and the upstream API manager.

## LLM runbook — how an LLM agent should run and validate everything

This is a short, prescriptive runbook for an LLM-based automation agent (or a human following steps) to run and validate the codebase. The runbook assumes the agent has a shell on a developer machine where `python` and `gh` are available.

1) Prepare environment
- Create and activate a virtualenv and install the repo requirements (`pip install -r requirements.txt`).
- Ensure `PYTHONPATH` is set to the repo root when running scripts that import `src.*` modules.

2) Run focused tests
- `python -m pytest tests` — confirm all focused tests pass. If there are failures, collect the failing trace and stop.

3) Run the minimal smoke script
- `python scripts/run_minimal.py --use-stub-api-for-ci --max-actions 5`
- Expect deterministic, fast output showing the runner completed (e.g., `Result: {'game_id': 'test_game', 'score': X, 'actions_taken': Y, 'win': False}`)

4) Inspect branches & PRs
- Use `git` and `gh` to list branches and open PRs.
- For each child branch (tb-minimal, tb-performance, tb-research-playground) verify it contains `BRANCH_FEATURE.md` and that CI passes.

5) Validate Orchestrator behavior (basic check)
- Run the lightweight delegation test `tests/test_orchestrator_delegation.py` to ensure orchestrator initializers set flags appropriately.

6) If everything passes, mark PRs ready for review and request reviewers.

## Notes and best practices

- Keep `TB-Seed` immutable unless a critical baseline change is required. Use it as an origin for new child branches.
- Make small, easily-reviewable PRs on child branches. Merge `tb-core-stable` into children to deliver core improvements.
- Use `tb-minimal` for CI-friendly smoke runs and `tb-performance` for heavier benchmarks and profiling-based PRs.

---

File created on branch `tb-core-stable`.

If you want this file added to the child branches as well, tell me and I will merge it into them (I can do that next).
1 change: 1 addition & 0 deletions BRANCH_FEATURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TB-RESEARCH-PLAYGROUND: Focus = experimental features, notebooks, playground.
5 changes: 5 additions & 0 deletions FEATURES_SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,8 @@ This document is an inventory of the major features and modules present in the T


*This inventory is intentionally high-level. The next step (SIMPLIFICATIONS.md) will analyze pros/cons and propose simplifications.*

Additions in TB-Seed work:
- `src/vision/schema.py` — small validator for detection outputs (`bbox`,`label`,`confidence/score`).
- `scripts/run_minimal.py` and `src/training/game_runner.py` updated to use the minimal runner & opt-in stub API for CI.

22 changes: 22 additions & 0 deletions README_MINIMAL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Running TB-Seed minimal mode

This README explains the minimal mode runner used for quick experiments and CI smoke tests.

Usage (developer):

- Run with real API manager (if configured):

```powershell
python scripts\run_minimal.py --game-id mygame --max-actions 50
```

- Run in CI/test mode using the stub ARC3 API (explicit opt-in flag required):

```powershell
python scripts\run_minimal.py --use-stub-api-for-ci --game-id test_game --max-actions 2
```

Notes:
- Per the seed contract, production/research runs must use a real ARC3 API and DB-backed persistence.
- The stub API is allowed only for CI/test runs and must be explicitly opted-in with `--use-stub-api-for-ci` or the environment variable `USE_STUB_API_FOR_CI=1`.
- Tests live in `/tests`. The CI workflow runs those tests and a minimal smoke invocation.
1 change: 1 addition & 0 deletions scripts/run_minimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import argparse

from src.training.game_runner import GameRunner
from src.vision.schema import validate_detections

# Try to import APIManager from existing codebase
try:
Expand Down
32 changes: 32 additions & 0 deletions src/database/db_facade.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@
context TEXT
)
""",
"""
CREATE TABLE IF NOT EXISTS migrations (
migration_id TEXT PRIMARY KEY,
applied_at TEXT
)
""",
]

class DBFacade:
Expand All @@ -88,6 +94,32 @@ def _ensure_db(self):
finally:
conn.close()

# Migration helpers
def has_migration(self, migration_id: str) -> bool:
conn = self._get_conn()
try:
cur = conn.cursor()
cur.execute("SELECT 1 FROM migrations WHERE migration_id = ?", (migration_id,))
return cur.fetchone() is not None
finally:
conn.close()

def apply_migration(self, migration_id: str, sql: str) -> None:
"""Apply a migration SQL (simple helper). This is intentionally minimal.

Note: callers should ensure migrations are idempotent.
"""
if self.has_migration(migration_id):
return
conn = self._get_conn()
try:
cur = conn.cursor()
cur.executescript(sql)
cur.execute("INSERT INTO migrations(migration_id, applied_at) VALUES (?, datetime('now'))", (migration_id,))
conn.commit()
finally:
conn.close()

def upsert_session(self, session_id: str, start_time: str, status: str = 'running', metadata: Optional[Dict] = None):
conn = self._get_conn()
try:
Expand Down
39 changes: 39 additions & 0 deletions src/training/core/continuous_learning_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ def _ensure_initialized(self) -> None:
if not hasattr(self, 'api_manager'):
raise RuntimeError("ContinuousLearningLoop not properly initialized")
print("[OK] System initialization verified")

# Backwards compatible wrapper
def ensure_initialized(self) -> None:
return self._ensure_initialized()

async def get_available_games(self) -> List[Dict[str, Any]]:
"""Get list of available games from the real ARC-AGI-3 API."""
Expand Down Expand Up @@ -1193,7 +1197,13 @@ def _find_target_coordinates(self, frame: List[List[int]]) -> Optional[Tuple[int

def _initialize_components(self) -> None:
"""Initialize all modular components."""
# If wrapped by an Orchestrator facade, let it perform initialization
try:
# Orchestrator facade may call into this method; allow idempotent behavior
if hasattr(self, 'orchestrator') and hasattr(self.orchestrator, 'initialize_components'):
return self.orchestrator.initialize_components()

# Otherwise perform the initialization locally
# Memory management (use singleton)
self.memory_manager = create_memory_manager()
self.action_memory = ActionMemoryManager(self.memory_manager)
Expand Down Expand Up @@ -1284,7 +1294,12 @@ def _initialize_components(self) -> None:

def _initialize_losing_streak_systems(self):
"""Initialize losing streak detection systems with database connection."""
# Delegate to Orchestrator facade if present
try:
if hasattr(self, 'orchestrator') and hasattr(self.orchestrator, 'initialize_losing_streak_systems'):
return self.orchestrator.initialize_losing_streak_systems()

# Otherwise continue with local initialization
if self._losing_streak_systems_initialized:
return

Expand All @@ -1310,7 +1325,11 @@ def _initialize_losing_streak_systems(self):

def _initialize_real_time_learning_systems(self):
"""Initialize real-time learning engine systems with database connection."""
# Delegate to Orchestrator facade if present
try:
if hasattr(self, 'orchestrator') and hasattr(self.orchestrator, 'initialize_real_time_learning_systems'):
return self.orchestrator.initialize_real_time_learning_systems()

if self._real_time_learning_initialized:
return

Expand Down Expand Up @@ -1340,6 +1359,10 @@ def _initialize_real_time_learning_systems(self):
def _initialize_attention_communication_systems(self):
"""Initialize enhanced attention + communication systems with database connection."""
try:
# Delegate to Orchestrator facade if present for migration path
if hasattr(self, 'orchestrator') and hasattr(self.orchestrator, 'initialize_attention_communication_systems'):
return self.orchestrator.initialize_attention_communication_systems()

if self._attention_communication_initialized:
return

Expand Down Expand Up @@ -1369,6 +1392,10 @@ def _initialize_attention_communication_systems(self):
def _initialize_fitness_evolution_system(self):
"""Initialize context-dependent fitness evolution system with database connection."""
try:
# Delegate to Orchestrator facade if present
if hasattr(self, 'orchestrator') and hasattr(self.orchestrator, 'initialize_fitness_evolution_system'):
return self.orchestrator.initialize_fitness_evolution_system()

if self._fitness_evolution_initialized:
return

Expand Down Expand Up @@ -1399,6 +1426,10 @@ def _initialize_fitness_evolution_system(self):
def _initialize_neat_architect_system(self):
"""Initialize NEAT-based architect system with database connection."""
try:
# Delegate to Orchestrator facade if present
if hasattr(self, 'orchestrator') and hasattr(self.orchestrator, 'initialize_neat_architect_system'):
return self.orchestrator.initialize_neat_architect_system()

if self._neat_architect_initialized:
return

Expand Down Expand Up @@ -1436,6 +1467,10 @@ def _initialize_neat_architect_system(self):
def _initialize_bayesian_inference_system(self):
"""Initialize Bayesian inference engine with database connection."""
try:
# Delegate to Orchestrator facade if present
if hasattr(self, 'orchestrator') and hasattr(self.orchestrator, 'initialize_bayesian_inference_system'):
return self.orchestrator.initialize_bayesian_inference_system()

if self._bayesian_inference_initialized:
return

Expand Down Expand Up @@ -1475,6 +1510,10 @@ def _initialize_bayesian_inference_system(self):
def _initialize_graph_traversal_system(self):
"""Initialize enhanced graph traversal system with database connection."""
try:
# Delegate to Orchestrator facade if present
if hasattr(self, 'orchestrator') and hasattr(self.orchestrator, 'initialize_graph_traversal_system'):
return self.orchestrator.initialize_graph_traversal_system()

if self._graph_traversal_initialized:
return

Expand Down
Loading