diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2015633..1c3e572 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,12 +15,11 @@
git clone https://github.com/YOUR-USERNAME/Engram.git
cd Engram
-# 2. Install
-./install.sh # macOS / Linux
-# or: pip install -e ".[dev]"
+# 2. Install development dependencies
+make install
# 3. Run the MCP server locally
-python -m engram.cli serve --http
+make serve
# 4. Open the local dashboard
# http://127.0.0.1:7474/dashboard
@@ -28,11 +27,15 @@ python -m engram.cli serve --http
# 5. Ask your agent (Claude Code, Cursor, etc.) to set up Engram
# Your agent will call engram_init and you'll see it working.
-# 6. Make a change → open a PR
+# 6. Make a change and open a PR
git checkout -b your-feature-or-fix
```
-That's it. If any step fails, open an issue — a broken setup path is itself a valid first contribution.
+That's it. If any step fails, open an issue - a broken setup path is itself a valid first contribution.
+
+Run `make help` to see every supported development command.
+
+If your machine has multiple Python installations, pass `PYTHON=/path/to/python` to keep install and test targets on the same interpreter.
---
@@ -101,6 +104,26 @@ Keep changes focused. One concern per PR. If you find yourself touching unrelate
**4. Test your work**
+Before opening a PR, run the same local checks used by CI:
+
+```bash
+make check
+```
+
+For faster iteration, use the narrower targets:
+
+```bash
+make test
+make lint
+make format-check
+```
+
+To run one test file through the Makefile, pass `TEST_ARGS`:
+
+```bash
+make test TEST_ARGS="tests/test_cli_config.py -q"
+```
+
Don't submit a PR you haven't run yourself. If tests don't exist yet for what you're changing, add them or note it clearly in the PR description.
**5. Open a PR**
@@ -134,7 +157,7 @@ If you're unsure whether something is in scope, ask first. The cost of a quick d
## Code Style
-Consistency matters more than any particular style. Match what's already there. If you're introducing something new, be deliberate about it and note it in the PR.
+Consistency matters more than any particular style. Match what's already there. Use `make format` for automatic formatting and `make lint` before sending a PR. If you're introducing something new, be deliberate about it and note it in the PR.
diff --git a/CONTRIBUTIONS.md b/CONTRIBUTIONS.md
index 424db05..ff90bac 100644
--- a/CONTRIBUTIONS.md
+++ b/CONTRIBUTIONS.md
@@ -4,6 +4,18 @@ All changes are fully tested — the suite grows from the project's original tes
---
+## Round 9 - Makefile developer workflow
+
+**Summary:** Added a root `Makefile` as the canonical entry point for common contributor commands and updated contribution guidance to use it.
+
+**Files changed:** `Makefile`, `CONTRIBUTING.md`, `CONTRIBUTIONS.md`, `README.md`, `docs/DEVELOPER_SETUP.md`
+
+**Commands added:** `make help`, `make install`, `make test`, `make test-all`, `make lint`, `make format`, `make format-check`, `make check`, `make build`, `make clean`, `make serve`, `make docker-build`, `make docker-up`, `make docker-up-sqlite`, `make docker-up-postgres`, `make docker-down`, `make docker-logs`
+
+**New tests added:** 0 (developer workflow/documentation change)
+
+---
+
## Round 8 — Seven major features
**Summary:** Implemented 7 production-ready features across the full stack (schema, storage, engine, REST, MCP, tests). Schema bumped from v7 to v8 with 5 new tables.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..f80f9f2
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,93 @@
+.DEFAULT_GOAL := help
+
+PYTHON ?= python
+PIP ?= $(PYTHON) -m pip
+PYTEST ?= $(PYTHON) -m pytest
+RUFF ?= $(PYTHON) -m ruff
+DOCKER_COMPOSE ?= docker compose
+TEST_ARGS ?= tests/ -x --tb=short
+TEST_ALL_ARGS ?= tests/
+
+export PYTHONPATH := src
+
+.PHONY: help install install-dev test test-all lint format format-check check build clean serve docker-build docker-up docker-up-sqlite docker-up-postgres docker-down docker-logs
+
+help:
+ @echo "Engram development commands"
+ @echo ""
+ @echo "Setup:"
+ @echo " make install Install Engram with development dependencies"
+ @echo " make install-dev Alias for make install"
+ @echo " Override Python with PYTHON=/path/to/python"
+ @echo ""
+ @echo "Quality:"
+ @echo " make test Run the CI-style pytest suite"
+ @echo " Override with TEST_ARGS='tests/test_file.py -q'"
+ @echo " make test-all Run the full pytest suite without fail-fast"
+ @echo " make lint Run ruff lint checks"
+ @echo " make format Format Python files with ruff"
+ @echo " make format-check Check formatting without modifying files"
+ @echo " make check Run lint, format-check, and tests"
+ @echo ""
+ @echo "Runtime:"
+ @echo " make serve Run the local HTTP MCP server"
+ @echo " make build Build Python package artifacts"
+ @echo " make clean Remove local build and Python cache artifacts"
+ @echo ""
+ @echo "Docker:"
+ @echo " make docker-build Build Docker images"
+ @echo " make docker-up Start the SQLite Docker profile"
+ @echo " make docker-up-sqlite Start the SQLite Docker profile"
+ @echo " make docker-up-postgres Start the PostgreSQL Docker profile"
+ @echo " make docker-down Stop Docker Compose services"
+ @echo " make docker-logs Follow Docker Compose logs"
+
+install:
+ $(PIP) install --upgrade pip
+ $(PIP) install -e ".[dev]"
+
+install-dev: install
+
+test:
+ $(PYTEST) $(TEST_ARGS)
+
+test-all:
+ $(PYTEST) $(TEST_ALL_ARGS)
+
+lint:
+ $(RUFF) check .
+
+format:
+ $(RUFF) format .
+
+format-check:
+ $(RUFF) format --check .
+
+check: lint format-check test
+
+build:
+ $(PIP) install --upgrade build
+ $(PYTHON) -m build
+
+clean:
+ $(PYTHON) -c "import pathlib, shutil; targets=[pathlib.Path('.pytest_cache'), pathlib.Path('.ruff_cache'), pathlib.Path('build'), pathlib.Path('dist')]; targets += list(pathlib.Path('.').rglob('__pycache__')); targets += list(pathlib.Path('.').glob('*.egg-info')); [shutil.rmtree(path, ignore_errors=True) for path in targets]"
+
+serve:
+ $(PYTHON) -m engram.cli serve --http
+
+docker-build:
+ $(DOCKER_COMPOSE) --profile sqlite --profile postgres build
+
+docker-up: docker-up-sqlite
+
+docker-up-sqlite:
+ $(DOCKER_COMPOSE) --profile sqlite up --build
+
+docker-up-postgres:
+ $(DOCKER_COMPOSE) --profile postgres up --build
+
+docker-down:
+ $(DOCKER_COMPOSE) down
+
+docker-logs:
+ $(DOCKER_COMPOSE) logs -f
diff --git a/README.md b/README.md
index ce5dcb1..e9c6ac9 100644
--- a/README.md
+++ b/README.md
@@ -185,7 +185,7 @@ Full literature review: [`docs/LITERATURE.md`](./docs/LITERATURE.md)
## Contributing
-PRs welcome. See [`CONTRIBUTING.md`](./CONTRIBUTING.md) and [`HIRING.md`](./HIRING.md) for paid contract work ($125–185/hour).
+PRs welcome. Run `make help` for common development commands, then see [`CONTRIBUTING.md`](./CONTRIBUTING.md) and [`HIRING.md`](./HIRING.md) for paid contract work ($125–185/hour).
---
diff --git a/docs/DEVELOPER_SETUP.md b/docs/DEVELOPER_SETUP.md
index b05f900..f6ae3f8 100644
--- a/docs/DEVELOPER_SETUP.md
+++ b/docs/DEVELOPER_SETUP.md
@@ -1,291 +1,246 @@
-# Developer Setup Guide
+# Developer Setup Guide
-Welcome to Engram development! This guide walks you through setting up your local environment to contribute code to the project.
+Welcome to Engram development. This guide walks through setting up a local environment for contributing code to the project.
## Prerequisites
Before you start, make sure you have:
-- **Python 3.11 or higher**
- \\\ash
- python --version
- \\\
+- Python 3.11 or higher
+- Git
+- Make
+- A code editor such as VS Code or PyCharm
+- Docker, optional for container-based development
+- PostgreSQL, optional for testing the `ENGRAM_DB_URL` workflow
-- **Git** (for version control)
- \\\ash
- git --version
- \\\
+Verify the core tools:
-- **A code editor** (VS Code, PyCharm, or similar)
+```bash
+python --version
+git --version
+make help
+```
-- **PostgreSQL** (optional, for team-mode testing)
- - Local development works with SQLite by default
- - Only needed if you're testing the \ENGRAM_DB_URL\ workflow
+Local development uses SQLite by default, so PostgreSQL is only needed when you are explicitly testing the team-mode database path.
+## Fork and Clone
-## Part 1: Fork and Clone the Repository
+1. Fork the repository on GitHub.
+2. Clone your fork:
-### 1.1 Fork on GitHub
-
-1. Go to https://github.com/imadahmad9507-ops/Engram
-2. Click the **Fork** button (top-right corner)
-3. Select your GitHub username as the owner
-4. Click **Create fork**
-
-### 1.2 Clone Your Fork
-
-\\\ash
+```bash
git clone https://github.com/YOUR-USERNAME/Engram.git
cd Engram
-\\\
-
-Replace \YOUR-USERNAME\ with your actual GitHub username.
+```
-### 1.3 Add Upstream Reference
+3. Add the upstream remote:
-This lets you stay in sync with the main repository:
+```bash
+git remote add upstream https://github.com/Agentscreator/engram-memory.git
+git remote -v
+```
-\\\ash
-git remote add upstream https://github.com/imadahmad9507-ops/Engram.git
-git remote -v # Verify both origin and upstream are configured
-\\\
+Replace `YOUR-USERNAME` with your GitHub username.
+## Set Up Python
-## Part 2: Set Up Your Development Environment
+Create and activate a virtual environment.
-### 2.1 Create a Python Virtual Environment
+On Windows PowerShell:
-A virtual environment isolates project dependencies from your system Python.
-
-**On Windows (PowerShell):**
-\\\powershell
+```powershell
python -m venv venv
.\venv\Scripts\Activate.ps1
-\\\
+```
+
+On macOS or Linux:
-**On macOS / Linux:**
-\\\ash
+```bash
python3.11 -m venv venv
source venv/bin/activate
-\\\
-
-You should see \(venv)\ appear at the start of your terminal prompt.
+```
-### 2.2 Upgrade pip
+Then install Engram and development dependencies:
-\\\ash
-pip install --upgrade pip
-\\\
+```bash
+make install
+```
-### 2.3 Install Dependencies (with dev tools)
+This installs Engram in editable mode, project dependencies, and development tools such as pytest and ruff.
-\\\ash
-pip install -e ".[dev]"
-\\\
+If your machine has multiple Python installations, pin the interpreter explicitly:
-This installs:
-- Engram itself in editable mode (changes to code take effect immediately)
-- All required dependencies
-- Development tools for testing and linting
+```bash
+make install PYTHON=/path/to/python
+make test PYTHON=/path/to/python
+```
+## Verify the Setup
-## Part 3: Verify the Setup
+Check that Engram imports correctly:
-### 3.1 Check Python Path
+```bash
+python -c "import engram; print('Engram imported successfully')"
+```
-\\\ash
-where python # Windows
-which python # macOS/Linux
-\\\
+Run the local HTTP MCP server:
-### 3.2 Check Imports
+```bash
+make serve
+```
-\\\ash
-python -c "import engram; print('✓ Engram imported successfully')"
-\\\
+Open the local dashboard at:
-### 3.3 Run the MCP Server Locally
+```text
+http://127.0.0.1:7474/dashboard
+```
-\\\ash
-python -m engram
-\\\
+Press `Ctrl+C` to stop the server.
-Press \Ctrl+C\ to stop it.
+## Common Commands
+Use the root `Makefile` as the canonical command entry point:
-## Part 4: Run Tests
+```bash
+make help
+```
-### 4.1 Run All Tests
+Common targets:
-\\\ash
-pytest tests/
-\\\
+```bash
+make install # Install development dependencies
+make test # Run CI-style tests
+make lint # Run ruff lint checks
+make format # Format Python files with ruff
+make format-check # Check formatting without writing changes
+make check # Run lint, format-check, and tests
+make build # Build Python package artifacts
+make clean # Remove local build/cache artifacts
+make serve # Run the local HTTP MCP server
+```
-### 4.2 Run Tests with Coverage Report
+Docker targets:
-\\\ash
-pytest tests/ --cov=src/engram
-\\\
+```bash
+make docker-build
+make docker-up
+make docker-up-sqlite
+make docker-up-postgres
+make docker-down
+make docker-logs
+```
-### 4.3 Run a Specific Test File
+`make docker-up` starts the SQLite profile by default. Use `make docker-up-postgres` when you need the PostgreSQL profile.
-\\\ash
-pytest tests/test_commit.py -v
-\\\
+## Development Workflow
+Create a feature branch before making changes:
-## Part 5: Create a Feature Branch
-
-Before making changes, create a branch:
-
-\\\ash
-# Update main from upstream
+```bash
git checkout main
git pull upstream main
-
-# Create your feature branch
git checkout -b feature/your-feature-name
-\\\
-
-**Good branch names:**
-- \ix/conflict-detection-threshold\
-- \docs/add-troubleshooting-guide\
-- \eature/improve-entity-extraction\
-
-
-## Part 6: Make Changes and Test
+```
-### 6.1 Edit Code
+Good branch names:
-Make your changes in:
-- Core logic: \/src/engram/\
-- Tests: \/tests/\
-- Documentation: \/docs/\ or \README.md\
+- `fix/conflict-detection-threshold`
+- `docs/add-troubleshooting-guide`
+- `feature/improve-entity-extraction`
-### 6.2 Run Tests After Each Change
+Make your changes in the relevant area:
-\\\ash
-pytest tests/ --tb=short
-\\\
+- Core logic: `src/engram/`
+- Tests: `tests/`
+- Documentation: `docs/`, `README.md`, or contributor docs
-### 6.3 Check Code Style (Optional)
+Before opening a PR, run:
-\\\ash
-# Format code
-black src/engram tests/
+```bash
+make check
+```
-# Check linting
-flake8 src/engram tests/
-\\\
+For focused testing:
+```bash
+make test
+make test TEST_ARGS="tests/test_file.py::test_name -vv -s"
+```
-## Part 7: Commit Your Work
+## Commit and Push
-### 7.1 Stage and Commit
+Review your changes:
-\\\ash
-# See what changed
+```bash
git status
+git diff
+```
-# Stage your changes
-git add src/engram/ tests/
+Stage and commit:
-# Commit with a clear message
-git commit -m "docs: add developer setup guide with troubleshooting section"
-\\\
+```bash
+git add
+git commit -m "docs: update developer setup workflow"
+```
-**Commit message format:**
-- Start with \ix:\, \eat:\, \docs:\, \ est:\, or \chore:\
-- First line: short summary (50 chars max)
-- Add blank line + details if needed
+Use conventional commit prefixes such as `fix:`, `feat:`, `docs:`, `test:`, or `chore:`.
-### 7.2 Push to Your Fork
+Push your branch:
-\\\ash
+```bash
git push origin feature/your-feature-name
-\\\
+```
+## Submit a Pull Request
-## Part 8: Submit a Pull Request
-
-### 8.1 Open a PR on GitHub
-
-1. Go to https://github.com/YOUR-USERNAME/Engram
-2. Click **Compare & pull request**
-3. Fill in the PR description explaining what you changed and why
-4. Click **Create Pull Request**
-
-### 8.2 Respond to Reviews
-
-If maintainers suggest changes:
-1. Make the changes on your branch
-2. Commit: \git commit -am "Update based on review feedback"\
-3. Push: \git push origin feature/your-feature-name\
-4. The PR updates automatically
+1. Open your fork on GitHub.
+2. Click **Compare & pull request**.
+3. Explain what changed, why it changed, and how you tested it.
+4. Create the pull request.
+If maintainers request changes, update your branch and push again. The PR updates automatically.
## Troubleshooting
-### "pip install -e fails"
-
-**Solution:**
-Make sure you're in the \Engram\ directory and your venv is activated:
-\\\ash
-cd Engram
-.\venv\Scripts\Activate.ps1 # Windows PowerShell
-source venv/bin/activate # macOS/Linux
-pip install -e ".[dev]"
-\\\
-
-### "ModuleNotFoundError: No module named 'engram'"
+### `make install` fails
-**Solution:**
-Reinstall in editable mode:
-\\\ash
-pip install -e ".[dev]" --force-reinstall
-\\\
+Make sure you are in the repository root and your virtual environment is active:
-### "Tests fail with 'No such table: facts'"
+```bash
+cd Engram
+make install
+```
-**Solution:**
-Initialize the database:
-\\\ash
-python -m engram --init-db
-pytest tests/
-\\\
+### `ModuleNotFoundError: No module named 'engram'`
-### "Permission denied: install.sh"
+Reinstall the editable package:
-**Solution:**
-\\\ash
-chmod +x install.sh
-./install.sh
-\\\
+```bash
+make install
+```
+### Tests fail with missing database tables
-## Common Workflows
+Initialize the local database, then rerun tests:
-### Sync Your Fork with Latest Changes
+```bash
+python -m engram --init-db
+make test
+```
-\\\ash
-git fetch upstream
-git rebase upstream/main
-git push origin main
-\\\
+### Docker services do not start
-### Run a Specific Test with Debug Output
+Check Docker is running and inspect the logs:
-\\\ash
-pytest tests/test_file.py::test_name -vv -s
-\\\
+```bash
+docker --version
+make docker-logs
+```
+For PostgreSQL profile testing, set required overrides in a local `.env` file and never commit secrets.
## Next Steps
-1. **Read the Architecture:** See [docs/IMPLEMENTATION.md](./IMPLEMENTATION.md)
-2. **Check Contribution Guidelines:** See [CONTRIBUTING.md](../CONTRIBUTING.md)
-3. **Ask Questions:** Open a GitHub Discussion if needed
-
----
-
-**Welcome to Engram development! We're glad you're here.** 🎉
+1. Read [docs/IMPLEMENTATION.md](./IMPLEMENTATION.md).
+2. Review [CONTRIBUTING.md](../CONTRIBUTING.md).
+3. Open a GitHub Discussion if you need design alignment before implementing.