Python Package Layout
Buffalo Core is intentionally small. Its package layout should prioritize discoverability of the public interface over internal layering for its own sake.
Core Rule
Expose the supported public modules directly from buffalo_core.
Keep the main reusable concepts easy to find, import, and document.
Current Structure
The package is organized around a few focused public modules:
buffalo_core/
__init__.py
diagnostics.py
numeric.py
typing.py
This layout is appropriate because each module corresponds to a clear cross-project concept:
typing.pydefines shared NumPy-oriented type aliases,numeric.pyprovides normalization helpers built on those aliases,diagnostics.pyprovides structured diagnostics and workflow result primitives.
Why Buffalo Core Does Not Use Deep Internal Layering
Buffalo Core is not a large domain package.
Its public API is the package.
Adding an internal/ layer here would make the package harder to browse without providing much architectural benefit.
This differs from larger Buffalo projects such as Buffalo Wings or Buffalo Panel where subpackage boundaries may carry significant domain meaning. In Buffalo Core, the public modules already provide the right level of separation.
Growth Rule
Add a new public module only when it represents a stable shared concept that belongs in multiple Buffalo projects. Do not turn Buffalo Core into a catch-all utility package.
Documentation Conventions
When public dataclasses are rendered through Sphinx autodoc, prefer brief class docstrings plus attribute docstrings on the dataclass fields themselves.
This keeps field documentation attached to the generated attribute entries instead of burying it in one class-level Attributes block.
For @property methods rendered through autodoc, prefer an attribute-style summary and semantic notes without a Returns section unless a repository-specific convention requires otherwise.