# Contributing to Basic Memory Thank you for considering contributing to Basic Memory! This document outlines the process for contributing to the project and how to get started as a developer. ## Getting Started ### Development Environment 1. **Clone the Repository**: ```bash git clone https://github.com/basicmachines-co/basic-memory.git cd basic-memory ``` 2. **Install Dependencies**: ```bash # Using just (recommended) just install # Or using uv uv install -e ".[dev]" # Or using pip pip install -e ".[dev]" ``` > **Note**: Basic Memory uses [just](https://just.systems) as a modern command runner. Install with `brew install just` or `cargo install just`. 3. **Activate the Virtual Environment** ```bash source .venv/bin/activate ``` **Keep dev state out of your everyday config.** The repo's `.envrc` sets `BASIC_MEMORY_CONFIG_DIR` to `~/.config/basic-memory-dev` for this checkout, so dev settings such as a Postgres backend never land in `~/.config/basic-memory`. With [direnv](https://direnv.net) installed, run `direnv allow` once per checkout or worktree. Without direnv, export the variable yourself before running `bm`: ```bash export BASIC_MEMORY_CONFIG_DIR=~/.config/basic-memory-dev ``` direnv only acts in an interactive shell, so agents and scripts that run `bm` in a checkout should set the variable explicitly. 4. **Run the Tests**: ```bash # Run all tests with unified coverage (unit + integration) just test # Run unit tests only (fast, no coverage) just test-unit # Run integration tests only (fast, no coverage) just test-int # Generate HTML coverage report just coverage # Run a specific test pytest tests/path/to/test_file.py::test_function_name ``` ### Development Workflow 1. **Fork the Repo**: Fork the repository on GitHub and clone your copy. 2. **Create a Branch**: Create a new branch for your feature or fix. ```bash git checkout -b feature/your-feature-name # or git checkout -b fix/issue-you-are-fixing ``` 3. **Make Your Changes**: Implement your changes with appropriate test coverage. 4. **Check Code Quality**: ```bash # Run all checks at once just check # Or run individual checks just lint # Run linting just format # Format code just type-check # Type checking ``` 5. **Test Your Changes**: Ensure all tests pass locally and maintain 100% test coverage. ```bash just test ``` 6. **Submit a PR**: Submit a pull request with a detailed description of your changes. ## LLM-Assisted Development This project is designed for collaborative development between humans and LLMs (Large Language Models): 1. **CLAUDE.md**: The repository includes a `CLAUDE.md` file that serves as a project guide for both humans and LLMs. This file contains: - Key project information and architectural overview - Development commands and workflows - Code style guidelines - Documentation standards 2. **AI-Human Collaborative Workflow**: - We encourage using LLMs like Claude for code generation, reviews, and documentation - When possible, save context in markdown files that can be referenced later - This enables seamless knowledge transfer between different development sessions - Claude can help with implementation details while you focus on architecture and design 3. **Adding to CLAUDE.md**: - If you discover useful project information or common commands, consider adding them to CLAUDE.md - This helps all contributors (human and AI) maintain consistent knowledge of the project ## Pull Request Process 1. **Create a Pull Request**: Open a PR against the `main` branch with a clear title and description. PR titles must follow the semantic format `type(scope): summary`, enforced by CI — for example `fix(core): unresolve inbound relations on entity delete`. Allowed types: `feat`, `fix`, `chore`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`. Allowed scopes: `core`, `cli`, `api`, `mcp`, `sync`, `ui`, `ci`, `deps`, `installer`, `plugins`, `skills`, `integrations`. 2. **Sign the Developer Certificate of Origin (DCO)**: All commits require a `Signed-off-by` line certifying that you have the right to submit your contributions. The DCO status check verifies this automatically when you create a PR. See [Signing Your Commits](#signing-your-commits) below, including how to fix commits you already pushed. 3. **Accept the Contributor License Agreement (CLA)**: All contributors must also accept the [Contributor License Agreement](CLA.md). The `license/cla` status check verifies this separately from the DCO check. There is no separate step outside GitHub: when you open your first PR, the CLA assistant bot comments with a link (also at [cla-assistant.io/basicmachines-co/basic-memory](https://cla-assistant.io/basicmachines-co/basic-memory)). Sign in with your GitHub account, agree, and the check turns green on its own. You sign once per GitHub account; it covers your future PRs too. 4. **PR Description**: Include: - What the PR changes - Why the change is needed - How you tested the changes - Any related issues (use "Fixes #123" to automatically close issues) 5. **Code Review**: Wait for code review and address any feedback. 6. **CI Checks**: Ensure all CI checks pass. Note that the test matrix runs only on pushes to this repository, so a PR from a fork gets the DCO, CLA, and static checks but not the full test suite. Run `just test` locally before asking for review. 7. **Merge**: Once approved, a maintainer will merge your PR. For fork PRs, a maintainer usually cherry-picks your commits onto an in-repo branch so the full matrix can run, opens a replacement PR that references yours, and rebase-merges it. Your commits land on `main` with your authorship and sign-off intact; the original PR is closed with a link to the replacement. ## Developer Certificate of Origin and CLA Basic Memory requires both a DCO commit sign-off and CLA acceptance for pull requests. The DCO sign-off means you certify that: - You have the right to submit your contributions - You're not knowingly submitting code with patent or copyright issues - Your contributions are provided under the project's license (AGPL-3.0) The CLA is a separate contributor agreement that allows Basic Machines LLC to incorporate, distribute, and relicense accepted contributions. The `license/cla` check verifies CLA acceptance, while the DCO check verifies commit sign-off. ### Signing Your Commits Sign your commit: **Using the `-s` or `--signoff` flag**: ```bash git commit -s -m "Your commit message" ``` This adds a `Signed-off-by: Your Name ` line to your commit message, certifying that you adhere to the DCO. The name and email must match the commit's author (`git config user.name` / `user.email`), or the DCO check fails. If you already made commits without a sign-off, add it retroactively and force-push your branch: ```bash # Sign off every commit on your branch (all commits since main) git rebase --signoff origin/main git push --force-with-lease ``` The sign-off certifies that you have the right to submit your contribution under the project's license and verifies your agreement to the DCO. ## Code Style Guidelines - **Python Version**: Python 3.12+ with full type annotations (3.12+ required for type parameter syntax) - **Line Length**: 100 characters maximum - **Formatting**: Use ruff for consistent styling - **Import Order**: Standard lib, third-party, local imports - **Naming**: Use snake_case for functions/variables, PascalCase for classes - **Documentation**: Add docstrings to public functions, classes, and methods - **Type Annotations**: Use type hints for all functions and methods ## Testing Guidelines ### Test Structure Basic Memory uses two test directories with unified coverage reporting: - **`tests/`**: Unit tests that test individual components in isolation - Fast execution with extensive mocking - Test individual functions, classes, and modules - Run with: `just test-unit` (no coverage, fast) - **`test-int/`**: Integration tests that test real-world scenarios - Test full workflows with real database and file operations - Include performance benchmarks - More realistic but slower than unit tests - Run with: `just test-int` (no coverage, fast) ### Running Tests ```bash # Run all tests with unified coverage report just test # Run only unit tests (fast iteration) just test-unit # Run only integration tests just test-int # Generate HTML coverage report just coverage # Run specific test pytest tests/path/to/test_file.py::test_function_name # Run tests excluding benchmarks pytest -m "not benchmark" # Run only benchmark tests pytest -m benchmark test-int/test_sync_performance_benchmark.py ``` ### Performance Benchmarks The `test-int/test_sync_performance_benchmark.py` file contains performance benchmarks that measure sync and indexing speed: - `test_benchmark_sync_100_files` - Small repository performance - `test_benchmark_sync_500_files` - Medium repository performance - `test_benchmark_sync_1000_files` - Large repository performance (marked slow) - `test_benchmark_resync_no_changes` - Re-sync performance baseline Run benchmarks with: ```bash # Run all benchmarks (excluding slow ones) pytest test-int/test_sync_performance_benchmark.py -v -m "benchmark and not slow" # Run all benchmarks including slow ones pytest test-int/test_sync_performance_benchmark.py -v -m benchmark # Run specific benchmark pytest test-int/test_sync_performance_benchmark.py::test_benchmark_sync_100_files -v ``` See `test-int/BENCHMARKS.md` for detailed benchmark documentation. ### Testing Best Practices - **Coverage Target**: We aim for high test coverage for all code - **Test Framework**: Use pytest for unit and integration tests - **Mocking**: Avoid mocking in integration tests; use sparingly in unit tests - **Edge Cases**: Test both normal operation and edge cases - **Database Testing**: Use in-memory SQLite for testing database operations - **Fixtures**: Use async pytest fixtures for setup and teardown - **Markers**: Use `@pytest.mark.benchmark` for benchmarks, `@pytest.mark.slow` for slow tests ## Creating Issues If you're planning to work on something, please create an issue first to discuss the approach. Include: - A clear title and description - Steps to reproduce if reporting a bug - Expected behavior vs. actual behavior - Any relevant logs or screenshots - Your proposed solution, if you have one ## Code of Conduct All contributors must follow the [Code of Conduct](CODE_OF_CONDUCT.md). ## Thank You! Your contributions help make Basic Memory better. We appreciate your time and effort!