Skip to content

keel/commands/ is 23,188 lines — larger than the engine it drives #525

Description

@eaitbrahim

Raised in docs/presentations/se.md §3 and §9.2. Filed as a question to answer deliberately, not a refactor to start.

The observation

keel/commands/     23,188 lines
keel/strategy/      4,033
keel/sim/           3,375
keel/execution/     3,102
keel/data/          2,930
keel/research/      1,658
keel/analysis/      1,308
keel/compliance/      854
                   ------
engine total       17,260

The CLI layer is larger than every compute module combined, by about a third.

The case that this is fine

It is not all UI. commands/ holds the reporting, rendering and operator-facing explanation — and this project deliberately puts a great deal of care there: the console explains its refusals, the admission report names which criterion failed and why, keel versions explains PARTIAL INSTALL rather than just exiting non-zero. That explanatory surface is a feature, and keeping it out of the compute path is the right instinct.

The compute modules are correspondingly small and readable, which is the benefit being bought.

The case that it is a symptom

Three things worth checking before concluding it is healthy:

  1. Is compute leaking into the CLI? commands/rules.py::_run_backtest is named in Opt the promotion gate into per-product slippage — prerequisite-gated on a thin-asset candidate or a load-bearing restatement #335 as the promotion gate's pricing path — a decision-making code path living in the command layer, not a renderer. How much more is like it?
  2. Is the same thing rendered several times? There are at least four front-ends — CLI, TUI console, web viewer, MCP. If each renders the same report independently, the size is duplication rather than care.
  3. Is it tested like the engine? The engine's invariants are pinned hard. A 23k-line layer holding any decision logic needs the same treatment.

Suggested first step — measure before moving anything

Not a refactor. A survey:

  • Split commands/ by role: pure renderers, compute-that-should-move, front-end-specific glue, shared report assembly.
  • Name any decision-making code path found there (_run_backtest is one — are there others?).
  • Quantify duplication across the CLI / TUI / web / MCP front-ends.
  • Then decide, with numbers, whether anything should move — and record the decision either way, including "nothing moves, and here is why".

An answer of "this is the right shape" is a perfectly good outcome and should be written down so the question stops being re-asked.

Notes

  • keel/commands/admission.py's own docstring already describes itself as the "OFFLINE report layer", which suggests the separation is at least partly intentional and documented.
  • Related: C7 — Rules are not pluggable, though brokers are #447 (rules are not pluggable though brokers are) is the other structural question about where behaviour lives.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions