Skip to content

The repo has no ships / never-ships boundary: plant, prices, ledger and the loop sit beside the controller in core/ #1

Description

@dim-sous

What is wrong

The top level answers what kind of code (core/, strategies/, comparison/, presentation/) instead of what role it plays. Nothing in the tree says which code a real battery controller would run and which exists only to develop and evaluate it.

core/ holds both: planners/, mpc/, estimators/ (product) beside physics/plant.py, simulator/synthetic_day.py, markets/price_loader.py, accounting/ledger.py, visualization/ (harness). comparison/ and presentation/ are harness code that got their own top-level folders because they came later. archive/ (v1–v4, 13,688 lines — 54% of all Python in the repo) sits inside the import root, so every grep, IDE index and future list command has to know to skip it.

Consequences today, verifiable:

  • core/accounting/ledger.py:29 imports core.simulator.traces and core/planners/milp_bidding.py:1035 imports core.simulator.synthetic_day — leaves reaching into the trunk. Nothing forbids it because no boundary is stated.
  • No [project.scripts] in pyproject.toml, no __main__.py: there is no entry point, so the three runner scripts in comparison/ are the interface (see the experiment-registry issue).
  • The package description advertises "EKF/MHE"; core/estimators/ holds ekf.py only.

The target shape

The one every research-simulation repo surveyed converges on (pyOpenSci, Scientific Python dev guide, Wilson et al. Good Enough Practices, and what RCWS #60 walked into): one top-level fold by role, subsystems underneath.

src/bess/            ships — the controller stack a real BESS computer would run
  estimation/  planning/  control/  strategies/  config/  ports.py
devkit/              never ships — exists to develop / evaluate src
  simulation/  (plant, pack, activation, synthetic day, prices, the loop, records)
  accounting/  (ledger + Greek settlement — scoring)
  experiments/ (the registry; today comparison/*.py)
  visualization/
tests/   docs/   out/ (generated, reconstitutable)
archive/  → out of the import root
pyproject.toml → [project.scripts]

ports.py is the hardware seam written down: measurements and prices in, setpoints out — the same move as RCWS engagement/ports.py.

Decisions taken (2026-08-15)

  • Ledger → devkit, at least for now. It is the referee, not a player: it reads truth traces and scores a run. The settlement math (greek_settlement.py) is a market rule and may later be extracted as a shared pure function both sides can call — split out, not moved wholesale.
  • archive/ → moved out of the import root, at least for now (kept in the repo, excluded from pyproject). Tagging and deleting from main is the later option if it still costs attention.

Done when

  • One-way rule held by a test: devkit/ imports src/, never the reverse (RCWS test_src_never_imports_devkit).
  • src/ inventory frozen by a test, so nothing drifts in.
  • archive/ not on the import path; pyproject excludes it.
  • Entry points declared.
  • Proof: existing traces bit-identical before and after — the move changes no number.

This is phase 0 of the platform epic; every seam issue assumes it.

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

    engineseams, run schema, data model

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions