This is a public repository (engrava) — Graph memory database for AI agents.
Assume every commit message, PR title, PR body, branch name, code comment, and docstring is world-visible. Public-safe by default.
| Aspect | Value |
|---|---|
| License | MIT |
| Primary language | python 3.11+ |
| Default branch for PRs | dev |
| Release flow | Conventional Commits → semantic-release |
| Contribution model | issues + PRs on GitHub |
- Public API stability: no breaking changes within X.Y.x patch range.
- Default storage backend: SQLite (others via extensions).
- Quality gate: ruff ALL + mypy strict + 90% test coverage.
This is production code maintained to a high quality bar. A feature is not "done" until every point below holds:
- Linting —
ruff checkclean,ruff format --checkclean, no rule disables without a justifying comment. - Typing —
mypy --strictclean. No bareAny. No# type: ignorewithout a justifying inline comment. - Coverage — 90% minimum, enforced by
--cov-fail-under=90. TDD preferred; tests are first-class code. - Docstrings — Google-style on every public symbol (params, returns, raises, examples).
- Domain modelling — concrete types per concept, no catch-all dicts, no god objects.
- Errors — typed exceptions; never bare
except; never swallow errors silently. - No shortcuts — no
TODO/FIXME/HACKin production code; open an issue instead. No dead code. No magic strings. - Secrets — never hard-code API keys; use env vars or config objects; never log secrets.
pip install -e ".[dev]"
ruff check src/ tests/
ruff format --check src/ tests/
mypy --strict src/
pytest --cov --cov-fail-under=90- Mirror the source layout in
tests/(e.g.,tests/domain/,tests/infrastructure/). asyncio_mode = "auto"if async work is involved —async def test_*directly, no decorators.- Prefer protocol-based fakes over mocks; never test against live external APIs in CI.
- Shared fixtures in
tests/conftest.py. - Run a clean test suite locally before pushing; CI is a check, not a write loop.
Format: <type>(<scope>): <description>
| Type | When | Version impact |
|---|---|---|
feat |
New user-visible feature | minor bump |
fix |
Bug fix | patch bump |
perf |
Performance improvement | patch bump |
docs |
Documentation only | no release |
refactor |
Refactor without behaviour change | no release |
test |
Tests | no release |
build/ci/chore |
Tooling, maintenance | no release |
Breaking changes: add ! after type/scope AND a BREAKING CHANGE: footer.
Branch + commit hygiene. Use the public release tag (vX.Y.Z) and this repo's GitHub issue/PR numbers (#N) as your only durable identifiers. Generic feature descriptions and Conventional Commit headers are always welcome.
Before committing, ask: could this commit message, branch name, or referenced symbol reveal information about a workflow that should stay private? If unsure, ask a maintainer. When in doubt, default to omitting the reference.
A pre-commit hook (installed locally) provides a quick feedback loop for this check.
This repo follows a feature → release → integration → stable flow.
| Branch | Role |
|---|---|
dev |
Release-trigger and integration trunk. semantic-release runs on push to dev — the version tag vX.Y.Z, the release-commit (CHANGELOG + pyproject.toml bump), the PyPI artifact, and the GitHub Release are all created on dev. |
main |
Stable mirror. The branch users land on when cloning. After each release, main is forward-merged from dev with a regular merge so the tagged commit is reachable from both branches (same SHA). main never originates a release on its own. |
release/v<X.Y.Z> |
Per-version stabilisation. Created from main (the last released state); accumulates one squash-commit per change; merged into dev to fire the release pipeline; then deleted. |
<type>/<kebab-description> |
Feature / fix / chore branches. Plain English; no internal identifiers; ≤ 50 chars. |
Open PRs from your feature branch targeting the active release/v<X.Y.Z> branch (or dev directly if no release branch is currently open). Branch names should describe the change in plain English (feature/priority-signal-hybrid-search, fix/empty-count-on-mindql, docs/quickstart-update).
Direct merge from a release/* branch into main is not used in this repo — main is updated exclusively via forward-merge from dev after a release publishes. This keeps the tagged commit reachable from both branches and prevents main from drifting ahead of the publisher branch.
External contributions are welcome. Please:
- Read
CONTRIBUTING.mdfor the contribution flow. - Open an issue first if the change is non-trivial — it's faster than rework after a PR.
- Branch from
dev, follow Conventional Commits, run the local quality gate before pushing. - Open a PR targeting
dev. CI must be green before review.
Code review uses GitHub PR comments. Discussions for design questions live in GitHub Discussions if enabled.