Skip to content

Latest commit

 

History

History
139 lines (99 loc) · 3.74 KB

File metadata and controls

139 lines (99 loc) · 3.74 KB

Contributing to scpn-control

Development setup

git clone https://github.com/anulum/scpn-control.git
cd scpn-control
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
pre-commit install

Rust toolchain (stable) is required for the PyO3 crates:

cd scpn-control-rs
cargo test
cargo clippy -- -D warnings

To build the Python extension module from Rust:

pip install maturin
cd scpn-control-rs/crates/control-python
maturin develop --release

Preflight (blocks push)

One-time setup:

git config core.hooksPath .githooks

This wires tools/preflight.py as a pre-push hook. It mirrors CI locally (10 gates, ~3 min). To run manually:

python tools/preflight.py            # full (lint + test + Rust)
python tools/preflight.py --no-tests # lint-only (~10 sec)
python tools/preflight.py --coverage # full + 99% coverage gate
python tools/preflight.py --no-rust  # skip cargo gates

Bypass once (when you know what you're doing):

git push --no-verify

Running tests

Pre-commit hooks (ruff, mypy, yaml, whitespace):

pre-commit run --all-files    # check everything
pre-commit run ruff            # single hook

Python (3,300+ tests, 100% coverage):

pytest                       # full suite
pytest tests/ -k "not slow"  # skip long-running regression tests
pytest --cov=scpn_control    # with coverage (gate: 99%)

Rust (5 crates: control-core, control-math, control-types, control-control, control-python):

cd scpn-control-rs
cargo test --workspace

Type checking (scoped to configured files only):

mypy

Code style

This project enforces an anti-slop policy. Follow the private local rule stack when available. Public summary:

Comments exist only to cite papers/equations, state non-obvious assumptions, or mark TODO(gh-ISSUE): items. Delete anything that restates what the code does.

Names must describe what code does, not what it aspires to be. A 2-layer MLP is DynamicsMLP, not NeuralODEDynamics. Gradient descent on an action sequence is trajectory_optimizer, not NMPC.

Magic numbers require a source citation or a named constant with units:

COULOMB_LOG = 15.0  # dimensionless, Wesson Ch.14

No trivial wrappers. If a function body can be inlined at the call site, inline it.

No cargo-cult typing. Type hints are mandatory on public API signatures. Internal helpers do not need annotations nobody checks.

Commit messages: imperative mood, under 72 characters, no filler. Fix Riccati sign error in H-inf observer -- not a paragraph about what was comprehensively addressed.

Submitting changes

  1. Fork the repository and create a feature branch off main.
  2. Keep commits atomic. One logical change per commit.
  3. Open a pull request against main.
  4. CI must pass (20 jobs: lint, type-check, pre-commit, pytest matrix, cargo test/clippy/deny/audit/bench, maturin interop, JAX parity, SNN (pure LIF+NEF), coverage gate, RMSE gate, notebook smoke).
  5. At least one maintainer review is required before merge.

If your change touches Rust code, ensure cargo clippy -- -D warnings is clean. If your change touches Python public API, add or update tests.

Reporting issues

File issues at https://github.com/anulum/scpn-control/issues.

Include:

  • Python version, OS, Rust toolchain version (if relevant)
  • Minimal reproduction steps
  • Full traceback or error output

For security vulnerabilities, email protoscience@anulum.li directly. Do not open a public issue.

License

scpn-control is licensed under AGPL-3.0-or-later (commercial licensing available).

By submitting a pull request, you agree that your contribution is licensed under AGPL-3.0-or-later.