Invariants and Architecture Contracts

This page lists rules that must not be broken. They protect scientific correctness, implementation consistency, and predictable public behavior. Most of these rules are checked automatically by tests/test_architecture_contracts.py.

Important

Run the architecture contract tests before submitting changes:

pytest tests/test_architecture_contracts.py -m unit

Scientific correctness

Invariant

Rationale

Prevent data leakage

Feature selection, scaling, and resampling must be inside one sklearn Pipeline and fitted only on training folds.

Train/predict symmetry

Predict must reuse the clustering centers, scaler parameters, selected features, and other state learned by fit.

Controlled randomness

Every stochastic step must accept and propagate a random seed so the same configuration can be reproduced.

Configuration rules

  • Root configuration models use extra='forbid' where strict validation is required. New fields must be declared in the schema.

  • habit/core/schemas/ is the source of truth for schema definitions. Compatibility modules may re-export schemas but must not define duplicates.

  • A component with configurable params must define and register a Pydantic parameter model.

Registry contracts

All registries must:

  • inherit from the appropriate _BaseRegistry subclass;

  • expose register, get, available, register_params_model, and get_params_model;

  • keep an independent _registry dictionary;

  • return a list from available().

Class factories additionally provide create(). Callable registries provide their callable-entry accessors.

Orchestrator contracts

Every top-level orchestrator must expose the terminal methods declared in ORCHESTRATOR_CONTRACT. Batch processors and workflows normally expose run(); habitat analysis exposes fit() and predict().

Engineering conventions

  • Use habit/utils/progress_utils.py for all progress bars.

  • Put reusable cross-subsystem utilities in habit/utils/.

  • Text generated inside plots must be English.

  • Import heavy optional dependencies lazily inside command or factory methods.

  • Keep business logic in core/*/run.py and command layers thin.

  • Annotate function inputs and outputs explicitly, and write code comments in English.

See also