chore: add .mindmodel/ project constraints and conventions
Generated mindmodel covering stack, architecture, domain glossary, coding conventions, DuckDB/requests/embeddings/error-handling patterns, anti-patterns, and explicit constraints for naming, imports, DB access, error handling, and testing.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# DB connection handling constraints
|
||||
|
||||
rules:
|
||||
- name: use_context_managers_for_connections
|
||||
rule: "Prefer using 'with duckdb.connect(path, read_only=...) as conn' for scoped DB interactions where possible."
|
||||
rationale: "Ensures proper resource cleanup and avoids connection leaks."
|
||||
|
||||
- name: read_only_for_compute
|
||||
rule: "Use read_only=True for compute steps that only read data (SVD, similarity compute)."
|
||||
rationale: "Allows safe parallel workers and reduces write contention."
|
||||
|
||||
- name: short_lived_writes
|
||||
rule: "When performing database writes, open short-lived connections, commit quickly and close."
|
||||
rationale: "Avoids long-lived transactions and reduces lock windows."
|
||||
|
||||
examples:
|
||||
- path: pipeline/svd_pipeline.py
|
||||
snippet: |
|
||||
conn = duckdb.connect(db_path, read_only=True)
|
||||
try:
|
||||
rows = conn.execute(...).fetchall()
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
anti_patterns_and_remediations:
|
||||
- bad: "Creating a global connection at import that performs migrations."
|
||||
remediation: "Move migrations to an explicit init function that runs at deployment/upgrade time."
|
||||
- bad: "Not closing connections on exceptions."
|
||||
remediation: "Wrap connects in `with` or finally: conn.close() blocks."
|
||||
@@ -0,0 +1,36 @@
|
||||
# Error handling style rules (YAML constraint example)
|
||||
|
||||
rules:
|
||||
- name: explicit_exceptions
|
||||
rule: "Raise explicit exceptions (ValueError, ProviderError) for known error conditions rather than returning magic values."
|
||||
examples:
|
||||
- good: |
|
||||
if not isinstance(text, str):
|
||||
raise ProviderError('text must be a string')
|
||||
- bad: |
|
||||
if not isinstance(text, str):
|
||||
return []
|
||||
|
||||
- name: avoid_broad_except
|
||||
rule: "Avoid 'except Exception:' that swallows errors. If broad except is used for best-effort, log the exception with logger.exception and re-raise or convert."
|
||||
examples:
|
||||
- bad: |
|
||||
try:
|
||||
do_work()
|
||||
except Exception:
|
||||
return []
|
||||
- remediation: |
|
||||
try:
|
||||
do_work()
|
||||
except SpecificError as exc:
|
||||
logger.warning('Handled error: %s', exc)
|
||||
raise
|
||||
|
||||
- name: logging_over_print
|
||||
rule: "Prefer logger.* over print() for messages and errors."
|
||||
examples:
|
||||
- bad: "print('Error fetching motions from API: %s' % e)"
|
||||
- good: "logger.exception('Error fetching motions from API')"
|
||||
|
||||
enforcement_examples:
|
||||
- "Add a static code check to flag 'print(' in modules (except in simple scripts) and 'except Exception:' usages without logger.exception."
|
||||
@@ -0,0 +1,24 @@
|
||||
# Import grouping and ordering constraints
|
||||
|
||||
rules:
|
||||
- name: grouping
|
||||
rule: "Group imports in three sections separated by a single blank line: stdlib, third-party, local."
|
||||
examples:
|
||||
- good: |
|
||||
import json
|
||||
import logging
|
||||
|
||||
import requests
|
||||
import duckdb
|
||||
|
||||
from .pipeline import text_pipeline
|
||||
- bad: |
|
||||
import duckdb
|
||||
import json
|
||||
from pipeline import text_pipeline
|
||||
|
||||
- name: from_imports
|
||||
rule: "Prefer 'from x import y' only when it improves clarity or avoids circular import; otherwise import module and reference attributes."
|
||||
|
||||
enforcement_examples:
|
||||
- "Run isort or ruff- import sorting in pre-commit or CI to enforce ordering."
|
||||
@@ -0,0 +1,30 @@
|
||||
# Naming constraint rules (example constraint file)
|
||||
|
||||
rules:
|
||||
- name: module_file_names
|
||||
rule: "Use snake_case for Python module filenames (e.g., text_pipeline.py, ai_provider.py)."
|
||||
examples:
|
||||
- good: "text_pipeline.py"
|
||||
- bad: "TextPipeline.py"
|
||||
|
||||
- name: function_names
|
||||
rule: "Use snake_case for functions and methods."
|
||||
examples:
|
||||
- good: "def compute_similarities(...):"
|
||||
- bad: "def ComputeSimilarities(...):"
|
||||
|
||||
- name: class_names
|
||||
rule: "Use PascalCase for classes."
|
||||
examples:
|
||||
- good: "class MotionDatabase:"
|
||||
- bad: "class motion_database:"
|
||||
|
||||
- name: constants
|
||||
rule: "Constants use UPPER_SNAKE_CASE."
|
||||
examples:
|
||||
- good: "VOTE_MAP = { ... }"
|
||||
- bad: "vote_map = { ... }"
|
||||
|
||||
enforcement_examples:
|
||||
- "Add a linter rule in CI: ruff or flake8 naming plugin to detect violations."
|
||||
- "Run `python -m pip install ruff` and `ruff check` as part of CI."
|
||||
@@ -0,0 +1,26 @@
|
||||
# Testing conventions constraint (YAML)
|
||||
|
||||
rules:
|
||||
- name: test_naming
|
||||
rule: "Use pytest and name tests test_*.py and test_* functions."
|
||||
examples:
|
||||
- good: "tests/test_text_pipeline.py"
|
||||
- bad: "tests/text_pipeline_test.py"
|
||||
|
||||
- name: fixtures_and_conftest
|
||||
rule: "Place shared fixtures in tests/conftest.py or tests/fixtures/ for reuse."
|
||||
examples:
|
||||
- good: "use fixtures declared in tests/conftest.py"
|
||||
|
||||
- name: assert_raises
|
||||
rule: "Explicitly assert expected exceptions with pytest.raises for invalid input."
|
||||
examples:
|
||||
- good: |
|
||||
import pytest
|
||||
|
||||
def test_invalid_input():
|
||||
with pytest.raises(ValueError):
|
||||
function_under_test('bad')
|
||||
|
||||
enforcement_examples:
|
||||
- "Run pytest in CI; fail if tests don't run or if there are regressions."
|
||||
Reference in New Issue
Block a user