You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit cac4b62
Browse filesBrowse the repository at this point in the historyBrowse files
docs: refresh §9 refactor state — R0.1 merged, R0.2 is next
Tracks completion of PR #81 (CLI --help snapshot baseline). The
checked-in source of truth (ROADMAP.md §9) now reflects:
- Phase R0 row → 🟡 R0.1 ✅ / R0.2 + R0.3 pending.
- Completed block — R0.1 file list, LoC, commit chain (95126e1 →
542b61a → 859657f), CHANGELOG entry.
- Tests run — was "None"; now lists the four envs verified pre-merge
plus final CI run 26228761027.
- Dependency graph — was "None"; now records 3,829 → 3,851 nodes and
11,427 → 11,454 edges (delta from indexing the new test file, no
production-code edges).
- Two new risks discovered during R0.1:
1. Env-var-based pinning (NO_COLOR / TERM / COLUMNS) of Rich/Typer
help output is not portable. GitHub Actions sets FORCE_COLOR=1
which Rich honours over NO_COLOR=1. Future Rich-output snapshot
tests must pin typer.rich_utils.{MAX_WIDTH,FORCE_TERMINAL} in a
`python -c` wrapper before importing the CLI.
2. §9.0 originally listed 9 CLI commands; the real surface is 11
(`prof` and the `project` subapp's own --help were missed).
Corrected here; the R0.1 baseline locks all 11.
- Suggested next slice rewritten from R0.1 → R0.2 (optional-dep
subprocess test); scope, rationale, risk recorded.
- Phase R0 section — PR0.1 marked ✅ merged with the merge SHA;
completion criteria show 1/3 PRs done.
Companion edits to CLAUDE.md and plans/adr/README.md (gitignored —
agent-local) are also persisted on disk for the next session.
No production code change. No tests added or modified.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Modified: `CHANGELOG.md` (+11 lines under `[Unreleased] · Added`).
355
+
-**Not modified:** any file under `src/genelab/`. R0.1 is test scaffolding only.
352
356
353
-
**Tests run.** None — the refactor has not begun, so there is no refactor diff to validate. The pre-refactor M1 feature work that landed earlier on `dev` (eval / export / backends — see commits `99389d3..1c80b41`) was tested in its own PRs; those results stand and are not affected by this planning round.
357
+
**Tests run.**
354
358
355
-
**Changes to the dependency graph.** None. Re-running `mcp__codebase-memory-mcp__index_repository` produces the same 3,829-node / 11,427-edge graph that was indexed at the start of the planning round. The hotspots and duplications flagged in the assessment are still present.
359
+
- Pre-R0.1: none. The pre-refactor M1 feature work that landed earlier on `dev` (eval / export / backends — see commits `99389d3..1c80b41`) was tested in its own PRs; those results stand.
360
+
- R0.1: 11 `--help` snapshot tests green locally (×3 byte-deterministic runs), green under `TERM=dumb COLUMNS=80` (CI-equivalent), green under `FORCE_COLOR=1 CI=true` (reproduces the run-2 ANSI failure mode), green under `env -u COLUMNS -u TERM -u FORCE_COLOR -u NO_COLOR` (stripped env). Final CI run `26228761027`: **test PASS / lint PASS / typecheck PASS**.
361
+
362
+
**Changes to the dependency graph.**`mcp__codebase-memory-mcp__index_status` reports **3,851 nodes / 11,454 edges** post-merge (was 3,842 / 11,441 immediately before R0.1). Delta +9 nodes / +13 edges comes from indexing `tests/test_cli_help_snapshots.py` — pure test surface, no production-code edges. The hotspots and duplications flagged in the assessment are still present.
356
363
357
364
**Risks identified (aggregate view).** Detailed per-ADR; the highest-attention items:
358
365
359
366
-**R1 (ADR-0001)** — quiescent `rl.runner ↔ rl.backends` cycle held together by lazy `importlib`. Any contributor "cleaning up" backend imports would break the package; R1 fixes this permanently.
360
367
-**R2.5 (ADR-0002)** — `BaseTermManager._post_init` ordering must preserve current buffer-allocation timing in `RewardManager` / `TerminationManager`. Mitigation: pre-R2.5 assertion test gates the refactor.
361
-
-**R4 (ADR-0004)** — CLI decomposition has large test surface (`test_cli.py` is 1,414 LoC). Mitigation: R0 `--help` snapshots gate every PR.
368
+
-**R4 (ADR-0004)** — CLI decomposition has large test surface (`test_cli.py` is 1,414 LoC). Mitigation: R0.1`--help` snapshots are now in place and gate every PR.
362
369
-**R5.2 (ADR-0006)** — parameterizing motion-tracking rewards risks numerical drift. Mitigation: bit-equivalence test ships in the same PR.
363
370
-**R7 (ADR-0009)** — flipping importlinter from lint-only to blocking may surface latent layering violations not caught in R0. Mitigation: R0 is lint-only for the entire R1–R6 window; baseline must be clean before R7 flips.
364
371
372
+
**Risks discovered during R0.1 (new, not in the original list).**
373
+
374
+
-**Rich/Typer help output is not deterministic under env-var pinning.**`TERM=dumb` / `COLUMNS=N` / `NO_COLOR=1` are honoured differently across Rich versions and CI runners. GitHub Actions sets `FORCE_COLOR=1` which Rich honours *over*`NO_COLOR=1`. The portable mechanism is pinning Typer's module-level constants in a `python -c` wrapper before import: `typer.rich_utils.MAX_WIDTH = 100`, `typer.rich_utils.FORCE_TERMINAL = False`. Any future test that diff-checks Rich-rendered output must follow this pattern. Captured in `tests/test_cli_help_snapshots.py`'s module docstring.
375
+
-**Doc drift: ROADMAP §9.0 originally enumerated 9 CLI commands; the real surface has 11** (`prof` and the `project` subapp's own `--help` were missed). The R0.1 snapshot baseline covers all 11; this document has been updated. New CLI commands or subapps must be added to both `tests/test_cli_help_snapshots.py:HELP_COMMANDS`*and* the §9.0 list.
376
+
365
377
**Next steps.**
366
378
367
379
1. Maintainer review of ADRs 0001–0010. Approve / request-changes per ADR.
368
380
2. Move accepted ADRs to `Status: Accepted` (one-line edit per file).
369
-
3. Land **PR R0.1** — the suggested next slice (see below). R0.1 is the smallest possible starting move, unblocks R3 and R4, and changes no production code.
370
-
4. After R0 lands, fan out: R1 / R5 / R6 can run in parallel; R3 → R4 serial.
381
+
3. Land **PR R0.2** — optional-dep subprocess test (see below). Independent of R0.3; can run in parallel with R0.3 if reviewer bandwidth allows.
382
+
4. Land **PR R0.3** — importlinter lint-only config + CI step.
383
+
5. After R0 fully completes, fan out: R1 / R5 / R6 can run in parallel; R3 → R4 serial.
371
384
372
-
**Suggested next slice: PR R0.1 — CLI `--help` snapshot baseline.**
385
+
**Suggested next slice: PR R0.2 — Optional-dep subprocess test.**
373
386
374
-
-**Scope.** Add `tests/snapshots/help-*.txt` (one per CLI command — root, `cache`, `list`, `info`, `play`, `eval`, `export`, `train`, `project_new`) + `tests/test_cli_help_snapshots.py`that captures `python -m genelab <cmd> --help` and asserts byte-equality against the snapshots.
375
-
-**Why first.**ADR-0004 (CLI decomposition) and ADR-0005 (domain-owned parsing) both depend on having a frozen `--help` baseline. Without R0.1, regressions in those phases are invisible.
387
+
-**Scope.** Add `tests/test_optional_deps.py` (one new test file). For each of `genelab.rl` and `genelab.rl.backends.{rsl_rl,skrl,sb3}`, spawn a subprocess with `rsl_rl` / `skrl` / `stable_baselines3` / `tensordict` poisoned in `sys.modules` (set to a `ModuleType` that raises `ImportError` on attribute access) and assert the import succeeds. Validates invariant #1 from [`CLAUDE.md`](CLAUDE.md) — that `import genelab.rl` does not transitively pull any optional RL library at module-load time.
388
+
-**Why next.**R0.2 catches the optional-dep boundary regression that R7's importlinter contract will codify. Catching it now (runtime test) complements R0.3 (static lint) and gives the team months of lead time to fix any baseline violations before R7 flips importlinter to blocking.
376
389
-**Production change.** None.
377
-
-**Risk.** Low. The snapshots capture what Typer prints today; if a later PR changes the output, the diff is the signal.
378
-
-**Reviewer effort.** Small — one new test file, nine snapshot files.
390
+
-**Risk.** Low. If the test fails on `dev` today, it has surfaced a real invariant-#1 violation that R1 / R2 must fix.
391
+
-**Reviewer effort.** Small — one new test file, ~40–80 LoC.
379
392
380
393
### 9.1 Cross-phase rules
381
394
@@ -421,30 +434,39 @@ before R4 (smaller CLI seam). R7 is the closer.
421
434
importlinter in lint-only mode) before touching production code.
422
435
Nothing in `src/genelab/` changes.
423
436
2.**Scope.**
424
-
- CLI `--help` snapshot tests for every command (`tests/snapshots/help-*.txt`,
425
-
`tests/test_cli_help_snapshots.py`).
426
-
- Optional-dep subprocess test (`tests/test_optional_deps.py`) — boots
427
-
`import genelab.rl` and each `genelab.rl.backends.<lib>` with
428
-
`rsl_rl` / `skrl` / `stable_baselines3` / `tensordict` poisoned in
0 commit comments