Contributing to lessonweaver

August 10, 2026 ยท View on GitHub

Thanks for your interest. lessonweaver is a small, deterministic library with a clear set of principles. Contributions that respect those principles are easy to review and merge.

Read AGENTS.md for the full agent/contributor rules and docs/architecture.md for how the pieces fit together, and docs/protected-invariants.md before changing deterministic core behavior or adding ML/LLM-backed extensions. Significant architecture changes should add or supersede an Architecture Decision Record.

Project principles

  • Deterministic core. No randomness in detection, interview, lint, retrieval, or analysis.
  • No LLM calls in core. Do not add inference calls to src/lessonweaver/. LLM-backed helpers, if any, go behind an optional interface.
  • Human review before activation. A candidate becomes an active skill only after review and governed promotion.
  • Privacy and governance first. Treat traces and skill evidence as sensitive; redact before export.
  • No framework lock-in. Framework integrations live in examples/, never as core dependencies.

Local development

# Setup: editable package + the user-facing MCP integration + local-only tools
python -m pip install --upgrade pip
python -m pip install -e ".[mcp]" --group dev

# Lint, format check, type check, tests, benchmark guard โ€” the same checks CI runs
ruff check src/ tests/
ruff format --check src/ tests/
mypy src/lessonweaver/
pytest
lessonweaver eval-detection benchmark/v1/corpus.json --compare-results benchmark/v1/results.json

The PEP 735 dev dependency group contains contributor/release tooling and is not published as an installable wheel extra. The [mcp] extra is different: it is a real downstream capability and remains part of published package metadata.

CI runs the gating suite on Python 3.10 through 3.14, plus explicit MCP floor / latest-v1 compatibility and a non-gating Python-next canary. Run the commands above locally before opening a PR so there are no surprises. If you change detection behavior, regenerate the benchmark scorecard in the same PR (see detection benchmark).

Where to contribute

AreaWhat it involvesGood entry point
ExamplesNew synthetic traces and skills under examples/Add a trace and document it in examples/README.md
DocsMarkdown under docs/Fix or extend a page; keep it factual
ExportersNew export_<format>_<target> in export.pyOne function + a snapshot test
ImportersMap an external format to the trace schemaKeep it dependency-free (see interoperability)
CLINew subcommands or flags in cli.pyAdd a flag + a tests/test_cli.py case
Governance checksNew SkillLinter / SkillAnalyzer rulesAdd a rule + tests for true/false positives

Good first issues

Self-contained, low-risk starting points (open at the time of writing):

  • Examples: add a trace such as tool_api_fallback.json (#32); usefulness report example (#73).
  • Templates: issue/PR templates (#34, #70).

Browse the issue tracker for the most current list and labels.

Testing expectations

  • Tests live in tests/ and use pytest.
  • Use tmp_path for filesystem tests; never write to a real home directory.
  • No real API or LLM calls in tests.
  • Each new module gets a corresponding tests/test_<module>.py.
  • Prefer small dataclass factory helpers for repeated test data.
  • A new behavior should have a test that fails without the change and passes with it.
  • Assert cross-cutting contract values (e.g. redaction markers) via the shared production helper (redaction_marker), not inline literals, so a contract change updates one place instead of every test that references it.
  • Treat domain models as immutable values at service boundaries: functions that update a model should return a new instance, and callers should use that returned value.

Pull request expectations

  • Start new work from the current main on a fresh branch. Do not reuse a previously merged branch name or assume an old remote branch is still based on current main.
  • Keep PRs focused; describe what changed and why.
  • Run lint, format check, type check, and tests before requesting review.
  • Do not add runtime dependencies casually; optional integrations go in [project.optional-dependencies], while maintainer-only tools belong in [dependency-groups].
  • Do not rename or remove dataclass fields without a migration note.
  • Do not weaken review or promotion gates, and never commit real credentials or personal data.

By contributing, you agree your contributions are licensed under the repository LICENSE.