Thank you for contributing. This document describes everything you need to know to open a pull request that will pass CI on the first try.
Before opening a PR, run:
make lint # ruff + mypy + import-linter — must pass with zero errors
make test # unit + integration, CPU — must pass at ≥ 95% coverage
make test-chaos # adversarial bandit tests — must pass
make bench-quick # toy benchmark smoke-test — must passFollow Conventional Commits 1.0.0 strictly.
<type>(<scope>): <subject>
feat · fix · perf · refactor · test · docs · ci · chore · bench
kernel · bandit · engine · sampling · export · bench · paper · ci
- Imperative mood: "add" not "adds" or "added".
- No period at the end.
- ≤ 72 characters total (type + scope + subject).
- Reference the invariant broken or fixed when fixing a correctness bug.
feat(kernel): add Triton verification kernel with dynamic gamma support
perf(kernel): tile over vocab_size dimension for H100 SRAM efficiency
fix(sampling): correct residual distribution for zero-probability tokens
test(bandit): add adversarial acceptance-rate swap convergence test
bench(engine): add Llama-3-70B throughput vs Medusa comparison
docs(kernels): add SRAM usage analysis for verify_kernel
| Branch | Purpose | Rules |
|---|---|---|
main |
Stable, paper-reproducible | Never force-push. All CI must pass. |
dev |
Integration target | All PRs merge here first. |
feat/<name> |
Feature development | Branch from dev, PR back to dev. |
fix/<name> |
Bug fixes | Branch from main for hotfixes, dev otherwise. |
bench/<name> |
Benchmark experiments | Branch from dev. Results committed as CSV. |
paper/<section> |
Paper writing | Branch from main. Docs only. |
Every PR must include:
- What changed and why — a clear description in the PR body.
- Invariant or performance contract reference — cite the relevant §2 or §6 item.
- Test evidence — a pointer to the new or existing test that now passes.
CHANGELOG.mdentry under[Unreleased].- No coverage regression — CI enforces ≥ 95% line coverage.
- New Python functions and classes following all rules in
AGENTS.md. - New Triton kernels following the kernel standards in
AGENTS.md §3.2. - New tests following the test standards in
AGENTS.md §5. - Refactoring that does not change the public API.
- Docstring updates.
CHANGELOG.mdentries.- Linter-flagged fixes.
- Any change to
flashspec/kernels/that has a corresponding test intests/unit/test_verify_kernel.py(correctness-critical). - Modifying the acceptance criterion in
flashspec/sampling/rejection.py. - Changing
pyproject.tomldependencies. - Changing the benchmark result schema in
benchmarks/. - Adding a new public function to the
flashspectop-level namespace. - Any change to the paper after results have been committed.
All style rules are enforced by make lint (ruff + mypy + import-linter).
Key rules (full list in AGENTS.md §3):
- NumPy-style docstrings on every public function and class.
logger.debug(...)instead ofprint(...)in library code.- Never use
tpsas a variable name; usetokens_per_second. - Never use
.cuda()directly; passdeviceas a parameter. - All random seeds set via
flashspec.utils.device.set_seed(seed). - Every
assertin tests must have a failure message.
- All new code must have tests in
tests/unit/,tests/integration/, ortests/chaos/. - Test names follow
test_<what>_<when>_<expected>. - GPU tests must be decorated with
@pytest.mark.gpu. - No
time.sleep()in tests. No network calls. No real model weights.
- Create a class implementing the
DraftModelprotocol (flashspec/engine/drafter.py). - Register it with
@flashspec.engine.drafter.register("your-name"). - Or register it via a Python entry point in your own package:
[project.entry-points."flashspec.drafters"] your-name = "your_package:YourDrafterClass"
- Subclass
DraftSelector(flashspec/bandit/base.py). - Implement
select(),update(),_state_dict(),_from_state_dict(). - Add it to
flashspec/bandit/__init__.pyand theBanditConfig.strategyliteral. - Add unit tests in
tests/unit/test_bandit.py.
- Add a YAML config in
benchmarks/configs/. - Do not modify existing configs after their first committed result.
- Run
make benchand commit the JSON output inbenchmarks/results/. - Add a row to the paper's results table and update
benchmarks/README.md.
Tags follow semver: v{MAJOR}.{MINOR}.{PATCH}.
Every tag must have a corresponding GitHub Release with the relevant
CHANGELOG section. The arXiv paper cites the GitHub tag matching the
submitted version.
Open a GitHub Discussion or email mattral@example.com.