The 225KB models.py: When a Single File Becomes the Data Model
LEO's `backend/app/models.py` grew to 225KB — a single-file SQLAlchemy model definition containing the entire data model for the system, indicating that the data layer evolved without decomposition into domain modules.
- Reference
- L020
- Project
- LEO
- Status
- Documented
- Evidence
- medium
- Source
- 020-225kb-models-monolith.md
Context
SQLAlchemy-based projects typically start with a single models.py file. As the project grows, the models should be split into domain-specific modules. When this decomposition doesn't happen, the file grows unbounded.
What Was Found
backend/app/models.py — 224,900 bytes (approximately 225KB)
By comparison:
- Most SQLAlchemy tutorial
models.pyfiles are 1-5KB - A medium-complexity Django project might have 10-30KB in total models
- 225KB in a single file suggests hundreds of table definitions
Given the 43 cognition subsystems alone (each requiring multiple tables for memories, episodes, profiles, events, etc.), the total number of SQLAlchemy model classes is likely large.
Evidence
backend/app/models.py— 224,900 bytes (confirmed in directory scan)backend/app/cognition/— 43 subdirectories each potentially contributing model classesphase_28_x_2_violation_report.md— 281 violations importing fromapp.modelssuggest all model classes are in this single file
Diagnosis
Established: models.py is 225KB. This is unusually large for a single Python module.
Likely: The 43 cognition subsystems, platform subsystems, personality modules, conversation layer, and proactive engines all define their data models in this single file. The file grew as new subsystems were added without reorganization.
Unknown: The exact number of SQLAlchemy model classes in the file. Whether the file used separate Python classes cleanly or had organizational comments/sections.
What I Learned
A single models.py at 225KB is an indication that the data layer grew faster than the organizational discipline applied to it. The architecture was carefully decomposed into 43 cognition subsystems (each with their own manager, repository, tests), but the underlying data models were not decomposed in parallel.
This creates a coupling point: any change to the data layer requires touching this single file, increasing the risk of merge conflicts in team environments and reducing the locality of data model changes relative to the subsystems that own them.
What I Would Do Differently
Hindsight observation: Data models should be co-located with their owning subsystems from the start. The cognition/episodic/ subsystem should have its own models.py with only the EpisodicMemory* tables. This keeps the data model changes local to the subsystem that owns them.
Broader Principle
The principle of co-location applies to data models as much as to code: the model classes for a subsystem should live adjacent to the subsystem's code, not in a central registry. A central models file is a hidden coupling point that grows without natural bounds.
Technical References
backend/app/models.py(225KB)
Failure sequence
On the record- Attempt
- Failure
- Diagnosis
- **Established:** `models.py` is 225KB. This is unusually large for a single Python module. **Likely:** The 43 cognition subsystems, platform subsystems, personality modules, conversation layer, and proactive engines all define their data models in this single file. The file grew as new subsystems were added without reorganization. **Unknown:** The exact number of SQLAlchemy model classes in the file. Whether the file used separate Python classes cleanly or had organizational comments/sections.
- Lesson
- A single `models.py` at 225KB is an indication that the data layer grew faster than the organizational discipline applied to it. The architecture was carefully decomposed into 43 cognition subsystems (each with their own manager, repository, tests), but the underlying data models were not decomposed in parallel. This creates a coupling point: any change to the data layer requires touching this single file, increasing the risk of merge conflicts in team environments and reducing the locality of data model changes relative to the subsystems that own them.
- Next iteration
- **Hindsight observation:** Data models should be co-located with their owning subsystems from the start. The `cognition/episodic/` subsystem should have its own `models.py` with only the `EpisodicMemory*` tables. This keeps the data model changes local to the subsystem that owns them.