Contributing to Ophamin¶
Thanks for taking an interest. This document covers the what and how of
contribution. The framework is open-source under the Apache License
2.0 (see LICENSE + NOTICE). External
contributions are welcome through the standard GitHub PR flow; the
project follows an RFC process for non-trivial design changes (see
docs/rfc/ once the process lands; currently architectural
decisions are captured in the audit + extended-audit documents under
docs/).
Ground rules¶
- No silent fallbacks. A misconfigured adapter raises; a missing tool
reports
status="unavailable"; a pillar that does not apply to a configuration isskippedwith an explicit reason. We never fabricate a plausible-looking result. - Wrap, don't rewrite. New audit pillars should orchestrate existing mature tools, not reimplement them. New analytic pillars should delegate to a battle-tested library and cross-check against it.
- Pre-registration discipline. A new scenario MUST capture its claim, threshold, and analysis plan BEFORE the substrate runs. A REFUTED verdict is the framework working — it surfaces a real architectural debt.
- Loud failure, no fabrication. Every error path explains itself; no empty-dict returns hiding a real bug.
Dev setup¶
git clone https://github.com/IdirBenSlama/Ophamin.git
cd Ophamin
python3.12 -m venv .venv
.venv/bin/python -m pip install -e ".[all,dev]" # full optional surface
.venv/bin/python -m pytest -q # 842+ tests must pass
Optional: enable the pre-push test gate¶
GitHub Pro is required for server-side branch protection on private repos, so until the repo goes public (or upgrades), we ship an opt-in pre-push git hook that runs the full test suite before allowing a push:
The hook lives at .githooks/pre-push and adds ~8 s
to every push. Skip a one-off push with git push --no-verify.
Authoring a new scenario¶
See docs/SCENARIO_AUTHORING.md. The short
version:
- Subclass
ophamin.measuring.scenarios.base.Scenario. - Set
name,corpus_name,target,n_cycles. - Implement
build_claim()— return aClaimwith a falsifiableThreshold. - Implement
score()— readcycle_results, return aScenarioScore. Use the helpers inophamin.measuring.scenarios.helpersfor shape-aware extraction (gwf_cleared, dissonance_count, …), Wilson 95% CI, inconclusive guards, and distribution stats. - Register the class in
ophamin.measuring.scenarios.__init__.py. This step is load-bearing for theophamin scenario <name>CLI path. Scenarios whose files exist but whose classes aren't added to theSCENARIOSdict are reachable from Python but not from the CLI — seedocs/ARCHITECTURE_INTENT_VS_REALITY_2026_05_16.mdfor the current registry gap inventory. - Add unit tests in
tests/test_scenario_*.py(use the_FakeCyberCorpus/_FakeFloresCorpuspatterns). - Add an example runner in
examples/run_<scenario>.py.
New scenarios should land in ~80 LOC (analytic-deep scenarios in
~300–500 LOC; see prime_structure.py, causal_discovery.py).
Authoring a new audit pillar¶
- Subclass
ophamin.auditing.base.AuditPillar. - Set
name(display) andtool_binary(the CLI to look up on PATH). - Implement
run(target_path) -> PillarResult— invoke the tool viasubprocess.run, parse its output, normalise intoFindingdataclasses. - Map the tool's native severity scale onto
FindingSeverity(CRITICAL / HIGH / MEDIUM / LOW / INFO). - Register the class in
ophamin.auditing.pillars.__init__.py(add toDEFAULT_PILLAR_CLASSES). - Add an extra to
pyproject.tomlso users canpip install 'ophamin[audit]'and get the tool. - Add tests in
tests/test_auditing.pyusingunittest.mock.patchagainstsubprocess.run(no live tool invocation in unit tests).
RFC-first rule for design changes¶
Some changes need a written design document before code lands. The
RFC process (docs/rfc/README.md) covers:
- new public APIs (CLI commands, codec functions, Protocol contracts)
- signed-record schema field changes (see
SCHEMAS.md) - new dependencies in
[project.dependencies](vs. an extra) - new experimentation tiers in the scenario taxonomy
- splits / merges of the six wheels
Open a PR adding docs/rfc/NNNN-<slug>.md based on
docs/rfc/0000-template.md. The
maintainer either accepts the RFC (after which an implementation PR
references it by number) or asks for revisions.
Bug fixes, refactors that don't change behavior, new tests, doc improvements, and dependency-version bumps go straight to a PR — no RFC needed.
Pull request checklist¶
Before opening a PR:
- [ ]
pytest -q --ignore=tests/benchruns green locally (1208+ tests). - [ ]
mypy --strict src/ophaminclean (138/138 source files). - [ ]
ruff check src testsreports no new violations. - [ ] If you added a public API, you also added tests for it.
- [ ] If you added a signed-record field, you also updated
SCHEMAS.mdand the corresponding codec round-trip property test. - [ ] If you added an external dependency, it's reflected in
pyproject.tomlextras AND the relevant lockfile is refreshed. - [ ] If you added a scenario, you also added an example runner.
- [ ] If the change is design-shaped (per the RFC-first rule above), the RFC PR landed first.
- [ ] Your commit message explains the why in the body, not just the what in the title.
Reporting issues¶
See SECURITY.md for security issues; use the issue
templates for everything else.
Code of conduct¶
See CODE_OF_CONDUCT.md. Engage in good faith, be
respectful, and bring your honest thinking. Ophamin is a project that values
empirical refutation over comfortable validation — the same disposition
applies to discussion.