Contributing / Process Notes
This is a solo learning workspace, so this file is primarily a process contract with future-me (and any curious visitor). The authoritative rules live in CLAUDE.md/AGENTS.md; the notebook quality contract is the Notebook Standards section below.
Setup
See README.md, "Quick Start & Installation" — requirements.txt pins the
notebook runtime, pip install -e ".[dev]" adds the library plus test/lint/type tooling.
Quality gates (all must pass before pushing)
mlfp check
Runs lint, format, notebook format, types, library tests with the coverage floor, and project tests — in that order, continuing past failures and naming every gate that failed. CI runs this exact script, so green locally means green in CI.
Notebook content changes additionally require a fresh-kernel pass:
mlfp nb-exec --only <path> --write # canonical outputs
mlfp nb-exec # full read-only sweep
Committed notebook outputs may ONLY come from execute_all_notebooks.py --write
— never from an interactive kernel (Notebook Standards §7/§11 below).
Code conventions
General Python style — from __future__ import annotations, type hints on signatures,
Google-style docstrings on public API — is AGENTS.md §8. Where content
belongs (theory vs notebook vs src/) is Notebook Standards §2 below.
Specific to this library:
- NumPy
NDArraytyping on array parameters and returns. ValueErrorfor bad arguments,RuntimeErrorfor not-fitted state.- New public names go into the alphabetized
__all__insrc/ml_first_principles/__init__.py(a test enforces it resolves). - Additive, non-breaking API changes preferred; breaking changes need a CHANGELOG entry and a version bump discussion.
Release procedure (maintainer)
- Move CHANGELOG
[Unreleased]into a new[x.y.z]section (Keep a Changelog). - Bump
versioninpyproject.tomlAND__version__insrc/ml_first_principles/__init__.py(a test fails if they diverge). python -m build→ sdist + wheel indist/.git tag vx.y.z && git push origin master --tags.gh release create vx.y.z dist/* --title vx.y.z --notes-file <notes>.- No PyPI (see the decisions log below); TestPyPI once as a learning exercise is allowed.
Ecosystem Roadmap
From a 22-topic first-principles curriculum to a complete learning ecosystem: verified curriculum, reusable library, applied projects, published docs.
Per-topic maturity lives in INDEX.md; what each release shipped lives in CHANGELOG.md.
| Phase | Pillar | Goal | Status |
|---|---|---|---|
| 1 | Infrastructure | Verification foundation | ✅ Done |
| 2 | Curriculum | Curriculum hardening | 🟡 Content done, CI streak pending |
| 3 | Publishing | Docs site | ✅ Done |
| 4 | Projects | Applied capstone projects | ✅ Done |
| 5 | Library | v0.2.0 + release | ✅ Done |
Per-phase task checklists are finished work; they stay in git history rather than here, and their outcome is recorded in CHANGELOG.md.
Open
- Phase 2 exit criterion — CI streak. All 22 topics are Verified in INDEX.md and
topics/synthesis/covers all 5 curriculum phases. What remains is the weekly notebook execution job (.github/workflows/ci.yml,notebooks) staying green 3 consecutive weeks.
Decisions Log
- Infra before content (2026-08): the Verified gate was undefined while the standards demanded cleared outputs and the tree deliberately kept them; the expensive full re-execution sweep should happen exactly once, after the policy is settled.
- Outputs stay committed (2026-08): GitHub browsing is self-contained and the docs site can render notebooks without executing them at build time. The invariant is not no outputs but no hand-run stale outputs —
execute_all_notebooks.py --writeis the only legitimate producer. - Inline matplotlib backend for
--write(2026-08): the headless sweep originally forcedMPLBACKEND=Agg, which is non-interactive — everyplt.show()committed aFigureCanvasAggwarning and no image, leaving the tree with zero figures.module://matplotlib_inline.backend_inlineis equally headless and deterministic but captures figures. - MkDocs Material over Jupyter Book/Quarto (2026-08): both alternatives require converting the ```math fences that were just adopted for GitHub rendering; Material renders them with config only.
- Flat library namespace retained (2026-08): 17 modules with a curated
__all__is within flat-namespace comfort; revisit past ~25 modules. - No PyPI (2026-08): solo learning repo — GitHub Releases carry the artifacts; one TestPyPI upload allowed as a learning exercise, not institutionalized.
- Single source per fact (2026-08): the topic list, the agent guidelines, and the dependency set each had 2–4 hand-synced copies. Each now has one owner — INDEX.md, AGENTS.md, and pyproject.toml respectively — and the others link to it.
- Process docs merged (2026-08): ROADMAP.md folded into this file. Both were process contracts with future-me, and a roadmap whose phases are all done is not a second document. Kept at repo root rather than
.github/becausedocs/is a symlink farm rooted at the repo root — a.github/location would break relative links in either the GitHub view or the docs site.
Notebook Standards
The quality contract for active curriculum content (referenced elsewhere as
"Notebook Standards §N"). Repository-level instructions in AGENTS.md and
CLAUDE.md take precedence if a conflict remains.
1. First Principles Contract
Every completed topic must answer these questions in order:
| Stage | Required question | Primary location |
|---|---|---|
| WHY | What original problem requires this method? | theory.md |
| WHAT | What are the assumptions, variables, model, and objective? | theory.md |
| HOW | How is the solution derived or computed? | Theory plus notebook checks |
| BUILD | Can the core method be implemented from scratch? | first_principles.ipynb, then src/ |
| VERIFY | Does theory match simulation and a trusted reference? | first_principles.ipynb, tests/ |
| CONNECTIONS | What are its prerequisites, alternatives, and applications? | Both files and topics/synthesis/ |
A title, file skeleton, imported estimator, or single successful plot does not satisfy a stage.
2. File-Type Contract
Markdown
Use .md for:
- motivation, definitions, assumptions, notation, and proofs;
- navigation, learning paths, maps, reports, and references;
- comparisons that do not require computation.
theory.md must define dimensions and domains before derivations, name the rule used at
each important step, distinguish assumptions from conclusions, and finish major
derivations with Result:.
Jupyter notebooks
Use .ipynb for:
- numerical verification of mathematical claims;
- from-scratch implementation walkthroughs;
- seeded simulations, plots, experiments, and failure cases;
- comparison with a trusted library implementation.
Do not use a notebook for title-only scaffolding or long theory that contains no computation. A focused notebook may be added when a topic cannot remain readable in one main notebook.
Python modules
Use .py for implementations reused by at least two notebooks, tests, or projects.
Notebooks must still explain the core algorithm before importing the reusable version.
3. Required Topic Artifacts
The default topic layout is:
XX_topic/
├── README.md
├── theory.md
├── first_principles.ipynb
└── exercises.ipynb
The topic README records:
- maturity and validation status separately;
- prerequisites with valid relative links;
- scope and explicit exclusions;
- files in recommended order;
- related synthesis documents and, where useful, the sister applied-mathematics-foundation repository.
4. Main Notebook Structure
A complete first_principles.ipynb uses the following learner-facing order:
- title, goal, prerequisites, and link to
theory.md; ## 1. Problem Setup — WHY;## 2. Mathematical Core — WHATwith only the equations needed by code;## 3. Solution Method — HOW;## 4. Implementation — BUILD;## 5. Library Comparison;## 6. Experiments and Failures — VERIFY;## 7. Connections;- concrete takeaway and next step.
Derivations belong in theory.md; the notebook verifies them numerically instead of
duplicating them.
5. First Principles Reasoning Flow
The reusable reasoning process applied to every algorithm. Each topic notebook follows this flow — from raw problem to verified implementation.
flowchart TD
START(["Original Problem"]) --> ASSUMPTIONS
ASSUMPTIONS["1. Identify Assumptions
What do we assume about the data?
What simplifications do we make?"]
ASSUMPTIONS --> MATH
MATH["2. Mathematical Formulation
Define hypothesis: ŷ = f(x; θ)
Define input/output spaces"]
MATH --> OBJECTIVE
OBJECTIVE["3. Objective Function
Define loss: L(θ)
Add regularization if needed"]
OBJECTIVE --> OPTIMIZE
OPTIMIZE{"4. Optimization Method
Closed-form? Gradient descent?
EM? Convex or non-convex?"}
OPTIMIZE -->|"closed form"| CLOSED["Normal Equation"]
OPTIMIZE -->|"iterative"| ITERATIVE["Gradient Descent"]
OPTIMIZE -->|"EM"| EM["E-step → M-step"]
CLOSED --> IMPLEMENT
ITERATIVE --> IMPLEMENT
EM --> IMPLEMENT
IMPLEMENT["5. Implementation
NumPy from scratch
Vectorized, numerically stable"]
IMPLEMENT --> VERIFY
VERIFY["6. Verification
Match sklearn/PyTorch?
Convergence plots"]
VERIFY --> FAILURES
FAILURES["7. Failure Cases
When does the model break?
Assumption violations"]
FAILURES --> CONNECTIONS
CONNECTIONS["8. Connections
Related algorithms?
Change loss → new model?"]
How this maps to the topic file pattern:
| Step | Location |
|---|---|
| 1–3. Assumptions, formulation, objective | theory.md |
| 4. Optimization method | theory.md + first_principles.ipynb |
| 5–6. Implementation, verification | first_principles.ipynb |
| 7. Failure cases | first_principles.ipynb |
| 8. Connections | Both files and topics/synthesis/ |
6. Reproducibility
The first code cell of every computational notebook must contain:
import random
import matplotlib.pyplot as plt
import numpy as np
%load_ext autoreload
%autoreload 2
SEED = 42
random.seed(SEED)
rng = np.random.default_rng(SEED)
Add framework seeds only when that framework is imported. PyTorch notebooks must seed CPU and CUDA and use inference mode for inference.
Further requirements:
- use local random generators rather than mutating NumPy global state;
- use relative repository paths and document every dataset;
- use stable operations such as
lstsq,solve,eigh,logsumexp, and log-probabilities; - compare floating-point results with an explicit tolerance;
- use the same split and metric for scratch and library implementations;
- show at least one failure case or violated assumption;
- label axes, legends, units, and reported metrics.
7. Notebook Format
Machine-enforced by mlfp nb-fmt --check (a CI gate):
no BOM, LF line endings, notebook format 4 with nbformat_minor >= 5, a unique
ID on every cell, canonical python3 kernelspec, and nbformat.validate.
Machine-enforced by mlfp nb-exec: no static Python
errors, since every cell runs top-to-bottom on a fresh kernel.
Not machine-checkable — hold these yourself:
- outputs in source control come exclusively from
mlfp nb-exec --write(fresh kernel, seeded, inline backend), never from a hand-run interactive kernel; - no host-specific paths or volatile editor metadata;
- local Markdown and image references resolve.
Run the dry run before any notebook commit:
mlfp nb-fmt
Use --write only for a controlled normalization change, and --clear-outputs
only when outputs must be deliberately stripped (they are kept by default).
8. Exercise Standard
An exercise artifact contains at least:
- one hand derivation or calculation;
- one implementation task with a deterministic check;
- one conceptual or failure-analysis question;
- expected numerical results or a separate solution path.
If exercises contain no code or interactive computation, use Markdown instead of an empty notebook.
9. Maturity and Validation
Maturity and execution are independent.
| Maturity | Definition |
|---|---|
| Planned | Scope exists but required learning content does not |
| Draft | Substantial topic-specific work exists but gates are incomplete |
| Complete | All First Principles stages and exercises are present |
| Verified | Complete plus all validation gates pass |
| Validation | Definition |
|---|---|
| Not run | No result exists for current source and environment |
| Passed | Current notebook ran from a fresh kernel |
| Failed | Current notebook was attempted and failed |
10. Verified Gate
A topic may be marked Verified only when:
- assumptions, notation, derivations, and numerical conventions were reviewed;
- theory and notebook do not duplicate each other;
- the from-scratch implementation is exercised by tests;
- edge and failure cases are demonstrated;
- the notebook passes schema, static, link, and fresh-kernel checks;
- scratch and reference results agree within stated tolerances;
- committed outputs are fresh, i.e. produced by the latest
execute_all_notebooks.py --writerun of the current source; - all synthesis, topic, and prerequisite-graph links resolve.
11. Safe Execution Protocol
Notebook validation executes an in-memory copy and leaves source files untouched.
The only sanctioned way to write generated outputs into source notebooks is
mlfp nb-exec --write; interactive kernels and other
tools must never overwrite them. Redirect Jupyter and Matplotlib runtime files
to a temporary directory in restricted environments.