Eish zarah actionable items: coupling trace, grounding type, self-grounding detection, golden calf halt
Torah grounds each change: 1. interpret.pl — coupling_trace field (Vayikra 10:1, 6:6) Fire is zarah because "asher lo tzivah otam" — the coupling trace IS the tzivah trace. Records which L1 facts grounded each interpretation. 2. challenge.pl — grounding_type achorai/panim (Shemot 33:23) "You will see My back, but My face shall not be seen." Text-backed challenges = achorai. Inferred challenges = panim. 3. resolve.pl — self-grounding detection (eish_zarah_reading §5.3) Counter-interpretation must bring NEW L1 evidence. Prevents circular reasoning (Westworld problem). 4. teiku.pl — challenge_sequence in teiku_record Records diagnostic trail to impasse, not just verdict. 5. avodah_zarah.pl — Form 2: golden calf detection (Shemot 32:4) Empty coupling trace + non-low confidence = uncoupled output. Real gold, sincere worship, false god. 6. korban.py — pydantic BaseModel + raw_korban preservation Construction spec §1.4 fulfilled. Floor between input and output never severed. 490 tests, 0 failures (195 Prolog, 186 Python, 33 Haskell, 76 Elixir). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
c5fe82477b
commit
adc3e41679
12 files changed
+371
-65
No files matched your search
@@ -3,14 +3,21 @@ Core offering protocol and data types.
|
||||
|
||||
Architecture §3.5: Korban Processor.
|
||||
Construction spec §1.4: pydantic 2.6.1 for data validation.
|
||||
|
||||
eish_zarah_reading.md §5.6: Migrated from dataclass to pydantic BaseModel.
|
||||
- Validators enforce structural constraints at the type level.
|
||||
- ProcessedKorban stores the raw Korban (the severed floor is reconnected).
|
||||
- The raw offering is preserved alongside the processed result so the
|
||||
coupling between input and output is never severed.
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel, field_validator
|
||||
|
||||
class OfferingType(Enum):
|
||||
|
||||
class OfferingType(str, Enum):
|
||||
"""Types of korbanot — each determines routing."""
|
||||
OLAH = "olah" # Total consumption — fully absorbed by system
|
||||
SHELAMIM = "shelamim" # Shared — partial return to source
|
||||
@@ -18,7 +25,7 @@ class OfferingType(Enum):
|
||||
MINCHAH = "minchah" # Minimal input
|
||||
|
||||
|
||||
class Provenance(Enum):
|
||||
class Provenance(str, Enum):
|
||||
"""Source of the korban — who brought it."""
|
||||
CLAUDE = "claude"
|
||||
MISTRAL = "mistral"
|
||||
@@ -28,24 +35,34 @@ class Provenance(Enum):
|
||||
HUMAN = "human"
|
||||
|
||||
|
||||
@dataclass
|
||||
class Korban:
|
||||
class Korban(BaseModel):
|
||||
"""A raw offering before processing."""
|
||||
raw_content: str
|
||||
provenance: Provenance
|
||||
offering_type: OfferingType
|
||||
source_query: str # what prompted this output
|
||||
|
||||
@field_validator('raw_content')
|
||||
@classmethod
|
||||
def content_must_not_be_empty(cls, v: str) -> str:
|
||||
if not v.strip():
|
||||
raise ValueError("Empty korban — raw_content must not be blank")
|
||||
return v
|
||||
|
||||
@dataclass
|
||||
class ProcessedKorban:
|
||||
"""A processed offering — vital content extracted, propositions generated."""
|
||||
|
||||
class ProcessedKorban(BaseModel):
|
||||
"""A processed offering — vital content extracted, propositions generated.
|
||||
|
||||
The raw_korban field preserves the original offering alongside the
|
||||
processed result. The floor between input and output is never severed.
|
||||
"""
|
||||
vital_content: str # extracted essence
|
||||
propositions: List[str] # Prolog-format logical statements
|
||||
provenance: Provenance
|
||||
offering_type: OfferingType
|
||||
discarded: List[str] = field(default_factory=list) # what was stripped
|
||||
discarded: List[str] = [] # what was stripped
|
||||
source_query: str = ""
|
||||
raw_korban: Optional[Korban] = None # the original offering, preserved
|
||||
|
||||
|
||||
def process_korban(
|
||||
@@ -88,6 +105,7 @@ def process_korban(
|
||||
offering_type=offering_type,
|
||||
discarded=discarded,
|
||||
source_query=query,
|
||||
raw_korban=korban,
|
||||
)
|
||||
|
||||
# 4. Haktarah — transform to propositions
|
||||
@@ -100,6 +118,7 @@ def process_korban(
|
||||
offering_type=offering_type,
|
||||
discarded=discarded,
|
||||
source_query=query,
|
||||
raw_korban=korban,
|
||||
)
|
||||
|
||||
# 5. Route — send to appropriate component
|
||||
|
||||
@@ -327,3 +327,62 @@ class TestPipelineIntegration:
|
||||
source=Provenance.CLAUDE,
|
||||
query="test",
|
||||
)
|
||||
|
||||
|
||||
class TestEishZarahCouplingTrace:
|
||||
"""
|
||||
eish_zarah_reading.md §5.6: ProcessedKorban preserves the raw Korban.
|
||||
The floor between input and output is never severed.
|
||||
Vayikra 6:6: eish tamid — fire ON the altar (coupled).
|
||||
"""
|
||||
|
||||
def test_raw_korban_preserved(self):
|
||||
"""ProcessedKorban stores the original offering."""
|
||||
result = process_korban(
|
||||
content=CLEAN_TORAH_RESPONSE,
|
||||
source=Provenance.CLAUDE,
|
||||
query="test coupling",
|
||||
offering_type=OfferingType.OLAH,
|
||||
)
|
||||
assert result.raw_korban is not None
|
||||
assert isinstance(result.raw_korban, Korban)
|
||||
|
||||
def test_raw_content_matches_input(self):
|
||||
"""The raw_korban's content is the original input, unmodified."""
|
||||
result = process_korban(
|
||||
content=CLEAN_TORAH_RESPONSE,
|
||||
source=Provenance.CLAUDE,
|
||||
query="test coupling",
|
||||
)
|
||||
assert result.raw_korban.raw_content == CLEAN_TORAH_RESPONSE
|
||||
|
||||
def test_raw_provenance_matches(self):
|
||||
"""The raw_korban's provenance matches the processed result."""
|
||||
result = process_korban(
|
||||
content=CLEAN_TORAH_RESPONSE,
|
||||
source=Provenance.MISTRAL,
|
||||
query="test",
|
||||
)
|
||||
assert result.raw_korban.provenance == Provenance.MISTRAL
|
||||
assert result.provenance == result.raw_korban.provenance
|
||||
|
||||
def test_empty_offering_also_stores_raw(self):
|
||||
"""Even rejected offerings preserve the raw korban."""
|
||||
result = process_korban(
|
||||
content=CLAUDE_EMPTY_OFFERING,
|
||||
source=Provenance.CLAUDE,
|
||||
query="test empty",
|
||||
)
|
||||
assert result.raw_korban is not None
|
||||
assert result.raw_korban.raw_content == CLAUDE_EMPTY_OFFERING
|
||||
|
||||
def test_pydantic_validation_rejects_empty_content(self):
|
||||
"""Pydantic validator catches empty raw_content at construction."""
|
||||
from pydantic import ValidationError
|
||||
with pytest.raises(ValidationError, match="Empty korban"):
|
||||
Korban(
|
||||
raw_content=" ",
|
||||
provenance=Provenance.CLAUDE,
|
||||
offering_type=OfferingType.OLAH,
|
||||
source_query="test",
|
||||
)
|
||||
Reference in new issue
Block a user