Contributing to OntoCast¶
This page covers what you need to change OntoCast and get the change merged: setting up, running the tests, writing documentation, and the checklist a pull request has to pass.
Licensing your contribution¶
OntoCast is released under the Apache License 2.0. Before we can merge your first pull request, you need to accept the Growgraph Contributor License Agreement (CLA). You do it once, and it covers all your future contributions to Growgraph projects. You keep the copyright in your work, and everything you contribute stays available under an open source license.
When you open a pull request, a bot checks whether you have accepted the CLA. If you have not, it comments with a link. Read the agreement and reply on the pull request with:
The cla check then turns green. You can also sign the agreement on paper:
see its section 11.
Contributing as part of your job? Contributions written at work are welcome. Many employers own what their employees write, though, so before you contribute, either get your employer's permission or ask them to sign our Corporate CLA (write to team@growgraph.dev). If you are not sure whether your employer has a claim, ask them first.
Do not submit code you did not write without telling us its source and license.
Every commit must be authored with an e-mail address linked to your GitHub account; otherwise the check cannot match the commit to your acceptance.
Set up¶
- Fork the repository on GitHub and clone your fork.
-
Install every extra, including the development and documentation tools:
-
Install the pre-commit hooks:
Run every Python command through uv run, so it uses the project's locked
environment.
Run the tests¶
This is the run every change has to pass: offline, without model weights or
provider credentials. Two markers carve out the rest. slow tests load an ML
model or take more than a few seconds; integration tests need a live service
and skip themselves when it is unreachable. Select them with -m, exporting
only the service URLs they need:
Do not load your .env into a test run
The suite checks the declared defaults, and your live configuration
silently changes what it tests: a local RENDER_MODE=facts leaves the whole
ontology half untested while the suite stays green. pytest-dotenv is
disabled in addopts (-pno:dotenv), and test/conftest.py stops the run
if a pipeline mode setting is present in the environment. Set what a single
test needs with monkeypatch.
Test layout¶
Tests are grouped by the part of the source they cover:
| Package | Covers |
|---|---|
test/facts/ |
tool/facts_validation/: term policy, per-unit findings, the gate, acceptance, the repair loop |
test/ontology/ |
The ontology half: catalog identity, per-unit context, delta validation, reconciliation, loop telemetry |
test/chunking/ |
Conversion to content units: segmentation, section labels, schema detection |
test/aggregation/ |
tool/agg/: entity disambiguation, merge guards, provenance |
test/manual/ |
Opt-in; collected only with ONTOCAST_RUN_MANUAL_TESTS=1 |
Everything else stays at the top level of test/. Put a new test beside the
tests for the same subsystem. When you merge two test modules, check for
top-level names both define, private fixture factories especially: a
duplicate silently shadows the other, and half the tests stop testing what
they were written for while the suite still passes.
Fixtures live under test/¶
The source distribution ships test/ but not docs/, demo/ or any data
directory, so a test that reads a file outside test/ cannot run from it. Put
fixtures under test/data/. test/test_repo_isolation.py enforces this; if a
test must read a file at the repository root, add it to ALLOWED_ESCAPES in
that module with the reason.
Retrieval quality¶
test/test_retrieval_recall.py checks whether a relevant catalog term reaches
the ontology context a unit is shown, reporting how many expected terms survive
vector search and how many survive graph expansion. It makes no LLM call and
can run on an embedded LanceDB. Point ONTOCAST_RECALL_CORPUS at a corpus
directory (cases.jsonl plus ontologies/*.ttl); without it the tests skip.
The corpora live in ontocast-validation.
ONTOCAST_RECALL_CORPUS=<corpus dir> LANCEDB_ENABLED=true \
uv run pytest test/test_retrieval_recall.py -m "integration and slow" -s
Set ONTOCAST_RECALL_JSON to write the results to a file; the module
docstring lists the other controls.
Measurement lives elsewhere¶
Documentation, the changelog, docstrings, comments and test names in this repository describe mechanisms, contracts and defaults. They do not carry measured results:
- Describe what a setting controls, which direction it moves things, and what saturates. Do not quote the number a sweep produced.
- Name the telemetry a reader uses to measure their own deployment:
budget,retrieval_metrics, the run manifest. - Do not name a corpus, a benchmark or an evaluation run, and do not name a test, fixture or flag after one; name it after what it guards.
- Justify a default by its mechanism ("saturates quickly", "gates everything below it"), not by the run that chose it.
Benchmark and evaluation results are tracked in ontocast-validation; link
there when a number is needed. The rule covers claims, not vocabulary: fixture
data such as an example namespace or a sample document is exempt.
Documentation¶
The documentation is built with ProperDocs. To work on it, install the documentation tools and serve the site locally:
Name every extra you need in one uv sync command: uv sync removes the
extras you leave out. Before you open a pull request, check that the strict
build passes:
- Add a new page to the
navinproperdocs.yml. - The Python API reference and the
configuration reference are generated at
build time (
docs/_build/gen_pages.py,docs/_build/gen_config.py). Do not write pages for them: add docstrings to a module, and adescriptionto a settingsField. - A
Fielddescription states what the setting does, in the present tense.test/test_settings_reference.pyfails on history wording such as "previously", "no longer" or "deprecated". - The workflow diagrams in
docs/assets/are generated: regenerate them withuv run plot-graph, which needs theplotextra. - Keep
README.mdshort and put detail indocs/.
Code style¶
- Python 3.12 or later, with type hints everywhere.
pydantic.BaseModelfor structured data.- Google-style docstrings on public APIs.
- Follow the naming and patterns of the module you edit.
Pull request checklist¶
- The tests pass:
HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 uv run pytest -m "not slow". - The docs build with
uv run properdocs build --strictwhen you changed docs, settings or public API. CHANGELOG.mdhas an entry for every user-visible change.- The description states the problem and the solution.
- Every contributor has accepted the CLA: the
clacheck is green.
Reporting issues¶
Include your Python and OntoCast versions, the steps to reproduce, what you expected and what happened, and the relevant logs.