Contributing Encodings¶
This guide walks you through the complete workflow for contributing halachic encodings to Mistaber. From claiming a seif to getting your PR merged, this document covers prerequisites, workflow, quality expectations, and attribution.
Who Can Contribute¶
Prerequisites¶
Successful contributors need competency in both halachic and technical domains:
Halachic Prerequisites¶
| Requirement | Minimum Level | Verification |
|---|---|---|
| Hebrew reading | Fluent | Can read SA/Rema text |
| Aramaic reading | Basic | Can follow Gemara references |
| SA familiarity | Intermediate | Has studied Yoreh Deah |
| Halachic methodology | Basic | Understands psak process |
Technical Prerequisites¶
| Requirement | Minimum Level | Verification |
|---|---|---|
| Logic programming | Basic | Understands Prolog/ASP syntax |
| Git workflow | Intermediate | Can branch, commit, PR |
| Python testing | Basic | Can write pytest tests |
| Command line | Basic | Can run tests locally |
Recommended Background¶
Ideal contributors have:
- Yeshiva background with Yoreh Deah study
- Programming experience (any language)
- Attention to detail
- Willingness to have work reviewed
First-Time Contributor Path¶
If you're new to Mistaber:
- Study existing encodings - Read
mistaber/ontology/worlds/mechaber.lp - Complete the tutorials - Work through the tutorial series
- Shadow a review - Observe PR review process
- Start small - Pick an uncontroversial seif for first contribution
- Get mentored - Pair with experienced contributor
Workflow Overview¶
graph TD
A[Find Available Seif] --> B[Claim Seif]
B --> C[Study Sources]
C --> D[Encode Rules]
D --> E[Write Tests]
E --> F[Run Locally]
F --> G{Tests Pass?}
G -->|No| D
G -->|Yes| H[Create PR]
H --> I[Technical Review]
I --> J{Approved?}
J -->|No| K[Address Comments]
K --> I
J -->|Yes| L{D'oraita Content?}
L -->|Yes| M[Halachic Review]
L -->|No| N[Final Approval]
M --> O{Approved?}
O -->|No| K
O -->|Yes| N
N --> P[Merge]
Step 1: Claim a Seif¶
Finding Available Work¶
- Check the project board - Look for unclaimed seifim
- Review open issues - Check for requested encodings
- Check roadmap - See prioritized simanim
- Propose new work - Request to encode a specific seif
Claiming Process¶
- Comment on issue or create new issue:
## Seif Claim: YD 87:3 (Fish and Dairy)
**Contributor**: @username
**Estimated completion**: 1 week
**Experience level**: Intermediate
### Scope
- Encode Mechaber's sakana ruling
- Encode Rema's permissive override
- Test both positions
### Prerequisites checked
- [x] Read existing YD 87 encodings
- [x] Have access to SA/Rema text
- [x] Familiar with multi-world encoding
- Wait for assignment - Maintainer assigns you
- Begin work - Only after assignment confirmed
Claim Etiquette¶
| Do | Don't |
|---|---|
| Claim one seif at a time | Claim multiple without completing |
| Provide realistic timeline | Over-commit on deadline |
| Ask questions before claiming | Claim without understanding scope |
| Update if delayed | Go silent on claimed work |
Step 2: Study Sources¶
Source Reading Checklist¶
Before writing any code:
- [ ] Read SA seif in Hebrew
- [ ] Read Rema's gloss (if any)
- [ ] Read Taz and Shach on this seif
- [ ] Check Beit Yosef for SA's reasoning
- [ ] Note any machloket
- [ ] Identify madrega level
- [ ] Check related seifim
Source Notes Template¶
## Source Analysis: YD 87:3
### SA Text
"דגים וחגבים אין בהם איסור אפילו מדרבנן"
"Fish and locusts have no prohibition even rabbinically"
### Rema Gloss
[No explicit gloss - silence implies potential disagreement with
Beit Yosef's sakana position]
### Beit Yosef Analysis
Cites medical authorities for sakana concern with fish+dairy.
This is the basis for Sefardi practice to avoid.
### Taz 87:3
Explains Ashkenazi practice to permit, citing [source]
### Shach 87:5
Supports Ashkenazi permission, explains textual interpretation
### Madrega Analysis
- No issur from Torah (explicit in SA)
- No issur d'rabanan (explicit in SA)
- Sakana (health) concern only (Mechaber's Beit Yosef)
- Classification: sakana (not issur)
### Machloket Identified
Mechaber (via Beit Yosef): Fish+dairy = sakana
Rema (via Taz, Shach): Fish+dairy = permitted
Step 3: Encode Rules¶
Setting Up Development¶
# Clone repository
git clone https://github.com/BrainyBlaze/mistraber.git
cd mistraber
# Create feature branch
git checkout -b encode/yd-87-3-fish-dairy
# Install development dependencies
pip install -e ".[dev]"
File Structure¶
Create or modify files as needed:
mistaber/ontology/
corpus/yd_87/
base.lp # Shared definitions (if needed)
worlds/
mechaber.lp # Mechaber's position
rema.lp # Rema's override
tests/corpus/yd_87/
test_fish_dairy.py # Your tests
Encoding Process¶
Follow the Encoding Methodology:
-
Add helper predicates (if needed):
-
Encode Mechaber's position:
-
Encode Rema's override:
% In worlds/rema.lp rule(r_rema_dag_chalav_mutar). makor(r_rema_dag_chalav_mutar, rema("yd:87:3")). makor(r_rema_dag_chalav_mutar, taz("yd:87:3")). makor(r_rema_dag_chalav_mutar, shach("yd:87:5")). scope(r_rema_dag_chalav_mutar, rema). override(rema, sakana(M), no_sakana) :- is_dag_chalav_mixture(M). asserts(rema, heter(achiila, M)) :- is_dag_chalav_mixture(M). asserts(rema, no_sakana(M)) :- is_dag_chalav_mixture(M). machloket(dag_chalav_sakana, mechaber, rema, M) :- is_dag_chalav_mixture(M).
Step 4: Write Tests¶
Test File Template¶
# tests/corpus/yd_87/test_fish_dairy.py
"""
Tests for YD 87:3 fish + dairy machloket.
Mechaber: Fish with dairy is forbidden due to sakana (health danger)
Rema: Fish with dairy is permitted
This tests the encoding of both positions and inheritance.
"""
import pytest
from mistaber import query
class TestFishDairyMachloket:
"""Tests for fish+dairy machloket between Mechaber and Rema."""
@pytest.fixture
def fish_dairy_mixture(self):
"""Standard fish + dairy mixture for testing."""
return """
mixture(m1).
food(salmon). food_type(salmon, dag).
food(cream). food_type(cream, chalav).
contains(m1, salmon). contains(m1, cream).
"""
# === Positive Tests (5 minimum) ===
def test_mechaber_asserts_sakana(self, fish_dairy_mixture):
"""Mechaber holds fish+dairy is sakana."""
result = query(fish_dairy_mixture, world="mechaber")
assert result.holds("sakana(m1)")
def test_mechaber_issur_achiila_sakana(self, fish_dairy_mixture):
"""Mechaber forbids eating fish+dairy due to sakana."""
result = query(fish_dairy_mixture, world="mechaber")
assert result.holds("issur(achiila, m1, sakana)")
def test_rema_no_sakana(self, fish_dairy_mixture):
"""Rema holds no sakana for fish+dairy."""
result = query(fish_dairy_mixture, world="rema")
assert result.holds("no_sakana(m1)")
def test_rema_heter_achiila(self, fish_dairy_mixture):
"""Rema permits eating fish+dairy."""
result = query(fish_dairy_mixture, world="rema")
assert result.holds("heter(achiila, m1)")
def test_machloket_detected(self, fish_dairy_mixture):
"""Machloket between Mechaber and Rema is detected."""
result = query(fish_dairy_mixture, world="base")
assert result.holds("machloket(dag_chalav_sakana, mechaber, rema, m1)")
# === Negative Tests (3 minimum) ===
def test_beheima_not_affected(self):
"""Beheima+dairy uses issur, not sakana."""
setup = """
mixture(m1).
food(beef). food_type(beef, beheima).
food(milk). food_type(milk, chalav).
contains(m1, beef). contains(m1, milk).
"""
result = query(setup, world="mechaber")
assert not result.holds("sakana(m1)")
assert result.holds("issur(achiila, m1, d_oraita)")
def test_fish_alone_no_sakana(self):
"""Fish alone has no sakana."""
setup = """
food(salmon). food_type(salmon, dag).
"""
result = query(setup, world="mechaber")
assert not result.holds("sakana(salmon)")
def test_dairy_alone_no_sakana(self):
"""Dairy alone has no sakana."""
setup = """
food(cream). food_type(cream, chalav).
"""
result = query(setup, world="mechaber")
assert not result.holds("sakana(cream)")
# === Edge Cases (2 minimum) ===
def test_fish_with_parve_no_sakana(self):
"""Fish + parve has no sakana concern."""
setup = """
mixture(m1).
food(salmon). food_type(salmon, dag).
food(rice). food_type(rice, parve).
contains(m1, salmon). contains(m1, rice).
"""
result = query(setup, world="mechaber")
assert not result.holds("sakana(m1)")
def test_multiple_fish_species(self):
"""Multiple fish with dairy still triggers sakana."""
setup = """
mixture(m1).
food(salmon). food_type(salmon, dag).
food(tuna). food_type(tuna, dag).
food(cream). food_type(cream, chalav).
contains(m1, salmon). contains(m1, tuna). contains(m1, cream).
"""
result = query(setup, world="mechaber")
assert result.holds("sakana(m1)")
# === Multi-World Tests ===
def test_sefardi_yo_inherits_sakana(self, fish_dairy_mixture):
"""Yalkut Yosef inherits Mechaber's sakana ruling."""
result = query(fish_dairy_mixture, world="sefardi_yo")
assert result.holds("sakana(m1)")
def test_ashk_mb_inherits_permission(self, fish_dairy_mixture):
"""Mishnah Berurah inherits Rema's permission."""
result = query(fish_dairy_mixture, world="ashk_mb")
assert result.holds("heter(achiila, m1)")
assert not result.holds("sakana(m1)")
def test_ashk_ah_inherits_permission(self, fish_dairy_mixture):
"""Aruch HaShulchan inherits Rema's permission."""
result = query(fish_dairy_mixture, world="ashk_ah")
assert result.holds("heter(achiila, m1)")
Step 5: Run Locally¶
Running Tests¶
# Run all tests
pytest tests/
# Run specific test file
pytest tests/corpus/yd_87/test_fish_dairy.py
# Run with verbose output
pytest tests/corpus/yd_87/test_fish_dairy.py -v
# Run with coverage
pytest tests/ --cov=mistaber --cov-report=html
Running Type Checker¶
# Check encoding syntax and types
mistaber check mistaber/ontology/worlds/mechaber.lp
# Check all files
mistaber check mistaber/ontology/
Fixing Common Issues¶
| Issue | Solution |
|---|---|
| Import error | Run pip install -e . |
| Test failure | Check encoding logic |
| Type error | Verify predicate signatures |
| Warning about OWA | Remove negation of OWA predicate |
Step 6: Create PR¶
PR Title Format¶
PR Description Template¶
## Summary
Encodes YD 87:3 fish and dairy machloket:
- Mechaber: Fish+dairy forbidden due to sakana
- Rema: Fish+dairy permitted (no sakana concern)
## Changes
- Added `is_dag_chalav_mixture/1` helper in `corpus/yd_87/base.lp`
- Added Mechaber's sakana ruling in `worlds/mechaber.lp`
- Added Rema's override in `worlds/rema.lp`
- Added machloket detection
## Sources Consulted
- SA YD 87:3
- Beit Yosef YD 87
- Rema (by omission)
- Taz 87:3
- Shach 87:5
## Test Coverage
- 5 positive tests
- 3 negative tests
- 2 edge cases
- 4 multi-world tests
## Checklist
- [x] Rule IDs are semantic
- [x] All rules have makor
- [x] Override uses descriptive value
- [x] Tests pass locally
- [x] Type checker passes
Step 7: Address Review¶
Responding to Comments¶
- Read carefully - Understand what's being asked
- Ask if unclear - Request clarification
- Fix issues - Make requested changes
- Explain if disagreeing - Provide reasoning
- Mark resolved - After addressing
Common Review Requests¶
| Request | Action |
|---|---|
| Add more sources | Add makor/2 entries |
| Fix override value | Use descriptive value |
| Add edge case test | Write specific test |
| Explain reasoning | Add comment in code |
| Check Rema gloss | Verify and document |
Quality Expectations¶
Code Quality¶
- Clean, readable code
- Consistent with existing patterns
- Well-commented
- Properly organized
Halachic Quality¶
- Accurate to sources
- Complete machloket handling
- Correct madrega assignment
- Proper world scoping
Test Quality¶
- Comprehensive coverage
- Both positions tested
- Edge cases covered
- Multi-world verified
Attribution and Credit¶
Contributor Attribution¶
Your contribution is recognized:
- Git history - Your name in commit log
- PR record - Linked to your account
- CONTRIBUTORS.md - Added after first merge
- Release notes - Credited for significant additions
Source Attribution¶
You must cite sources accurately:
% Your encoding cites sources, not you
makor(r_example, sa("yd:87:3")). % Source: Shulchan Aruch
makor(r_example, taz("yd:87:3")). % Source: Taz
% NOT: makor(r_example, your_name)
Code of Conduct¶
All contributors must follow the Code of Conduct:
- Be respectful in reviews
- Welcome newcomers
- Focus on technical merit
- Accept feedback gracefully
Getting Help¶
Resources¶
- Encoding Methodology - Core process
- Halachic Concepts - Authority levels
- Testing Requirements - Test details
- Review Standards - What reviewers expect
Asking Questions¶
- GitHub Discussions - General questions
- Issue comments - Specific to claimed work
- PR comments - During review process
Mentorship¶
First-time contributors can request mentorship:
## Mentorship Request
**Contributor**: @username
**Experience**: [Brief background]
**Planned contribution**: YD 87:X
Requesting mentorship for first encoding contribution.
Specific areas I'd like guidance on:
- [ ] Understanding machloket representation
- [ ] Writing effective tests
- [ ] Navigating review process
Related Guidelines¶
- Encoding Methodology - Detailed encoding process
- Testing Requirements - Test specifications
- Review Standards - What to expect in review
- Contributing Guide - General contribution info