# Contributing to Engram

Engram is a local-first MCP memory server for autonomous AI agents.
Contributions are welcome -- bug fixes, new features, documentation improvements, and test coverage.

---

## Getting Started

1. Clone the repository:

   ```bash
   git clone https://github.com/GotThinkSolutions/engram.git
   cd engram
   ```

2. Install in editable mode with dev dependencies (Python 3.10+):

   ```bash
   pip install -e ".[dev]"
   ```

3. Verify the install:

   ```bash
   engram-serve --help
   engram-index --help
   ```

---

## Running Tests

The test suite uses **pytest** with **pytest-asyncio** (async tests run automatically).

```bash
pytest tests/ -v
```

### Test files at a glance

| File | Covers |
|---|---|
| `test_server.py` | MCP server endpoints (search, store, list) |
| `test_librarian.py` | Indexer / librarian scanning and metadata extraction |
| `test_index.py` | In-memory index lookups and ranking |
| `test_guardrail.py` | Tag verification / hallucination rejection |
| `test_consolidator.py` | Session file consolidation and dedup |
| `test_interview_vpn.py` | edge interview wizard VPN stage |

---

## Code Style

The project uses **Ruff** for linting and **mypy** for type checking.
Configuration lives in `pyproject.toml`.

```bash
# Lint
ruff check src/ tests/

# Type check
mypy src/engram/
```

Ruff rules enabled: `E` (pycodestyle errors), `F` (pyflakes), `I` (isort), `W` (pycodestyle warnings).
Target version: Python 3.10.

Fix auto-fixable issues with:

```bash
ruff check --fix src/ tests/
```

---

## Project Structure

```
src/engram/
  server.py          # MCP server — stdio transport, tool handlers
  librarian.py       # Indexer: scans vault, builds metadata catalog
  index.py           # In-memory search index (ripgrep-backed)
  models.py          # Pydantic request/response models
  config.py          # Runtime configuration and paths
  guardrail.py       # Tag verification against ground-truth evidence
  consolidator.py    # Session file consolidation / dedup
  segregation.py     # Data segregation logic
  utils.py           # Shared helpers
  db_models.py       # Database model definitions
  gateway_websocket.py  # WebSocket gateway for remote agents
  worker_api.py      # Worker API definitions
  run_worker_api.py  # Worker API entry point
```

---

## Making Changes

1. **Branch from `main`.**

   ```bash
   git checkout -b feat/my-feature main
   ```

2. **Write tests for new features.** Place them in `tests/` following the `test_<module>.py` convention.

3. **Run the full suite before submitting:**

   ```bash
   pytest tests/ -v
   ruff check src/ tests/
   mypy src/engram/
   ```

4. **Keep commits focused.** One logical change per commit with a clear message.

---

## Pull Request Process

- Open PRs against `main`.
- Title: short summary of the change (under 70 characters).
- Body should include:
  - **What** changed and **why**.
  - How to test or verify the change.
  - Any breaking changes or migration steps.
- All tests must pass before merge.
- Keep PRs small when possible -- easier to review, faster to merge.

---

## Reporting Bugs

Open an issue with:

- Python version and OS.
- Steps to reproduce.
- Expected vs. actual behavior.
- Relevant log output or tracebacks.
- The contents of your vault directory layout if the bug is data-related.

---

## Development Tips

### Run the MCP server locally

```bash
engram-serve
```

The server communicates over stdio using the MCP protocol.
Point your MCP client (Claude Desktop, etc.) at the `engram-serve` command.

### Run the indexer

```bash
engram-index
```

This scans your vault directory and rebuilds the metadata catalog.

### Add a new MCP endpoint

1. Define request/response models in `src/engram/models.py` using Pydantic.
2. Register the tool handler in `src/engram/server.py` (follow the pattern of existing `@server.tool()` handlers).
3. Add tests in `tests/test_server.py`.
4. Run the suite to confirm nothing breaks.

---

## License

By contributing you agree that your contributions will be licensed under the MIT License.
