<!-- overlay:python — pytest layout, commands, and fixtures. -->
## STACK (Python)

Tests live in `tests/` (flat, no subdirs). Naming: `src/<pkg>/<domain>/<module>.py` → `tests/test_<module>.py`; CLI → `tests/test_cli_<command>.py`; integration → `tests/test_integration*.py`.

### Tools + commands
```bash
uv run pytest                                                   # all tests
uv run pytest --cov=src --cov-report=term-missing               # with coverage
uv run pytest --cov=src --cov-fail-under=80                     # enforce the floor
uv run pytest tests/test_graph_loader.py -v                     # single file, verbose
```

### Python patterns
- Fixtures in `conftest.py` using `tmp_path`; real SQLite (in-memory or `tmp_path`) for integration, `monkeypatch`/`MagicMock` only at the IO boundary.
- CLI integration via Click's `CliRunner` (`runner.invoke(main, [...])`, assert `exit_code` + parse output).
- Example AAA + factory:
```python
def test_get_context_returns_bundle_for_valid_ref_id(db: sqlite3.Connection) -> None:
    # Arrange
    insert_node(db, ref_id="PROJ-123", kind="feature")
    insert_edge(db, src="PROJ-123", dst="routing", kind="part_of")
    oracle = ContextOracle(db)
    # Act
    bundle = oracle.get_context("PROJ-123")
    # Assert
    assert bundle.focus.ref_id == "PROJ-123"
    assert any(e.kind == "part_of" for e in bundle.graph.edges)
```
- After code-touching tests: `beadloom reindex && beadloom sync-check && beadloom lint --strict`.
