Files
bikoret/kushya_generator/README.md
Scott KarpandClaude Opus 4.6 e223ab15b3 Phase 4 complete: Steps 21, 22, 24 — Korban external integration, L2 Urim v'Tumim, Kushya generator
Vayikra 9:24 — vatetzei esh milifnei Hashem vatokhal al hamizbeach.
Phase 4 of the architecture is now complete. The remaining three steps
that were marked "blocked on external infrastructure" are built —
discipline-respecting, eish-zarah-aware, and tested.

## Step 22 — Korban Processor external model integration
   (korban_processor/src/korban_processor/external_offering.py)

   The single legitimate entry point for external model consultation.
   Wraps Claude API calls through the offering protocol so external
   output is treated as korban (raw material), never authoritative:

   - semichah  — provenance is tagged (avodah zarah Form 1 prevention)
   - shechitah — assistant voice, hedging, formatting stripped
   - zerikah   — vital content extracted
   - haktarah  — converted to Prolog propositions
   - route     — sent to internal component per offering type

   The raw Korban is preserved on the ProcessedKorban (gilui arayot
   Form 3 prevention — input/output coupling never severed).
   No internal component should call call_claude() directly.

   11 tests, mocked external calls. Live API test opt-in via
   SHORASHIM_LIVE_API=1.

## Step 24 — L2 Urim v'Tumim interface
   (vav_pipeline/lib/vav_pipeline/urim_v_tumim.ex)

   PRD §4.7: housed in the kohen gadol's breastplate; consulted only
   on high-stakes decisions where normal deliberation is insufficient.
   Bamidbar 27:21 — al-piv yetz'u v'al-piv yavo'u.

   Three escalation steps, three honest outcomes:
     1. resolved_by_specification — re-read produced an answer
     2. resolved_by_external — external testimony recorded (NOT binding)
     3. deferred_to_human — the system stops, asks for human judgment

   Pre-condition gating refuses cases that didn't reach Sanhedrin teiku
   first (no preempting deliberation) or that aren't flagged high-stakes
   (ordinary teiku stays teiku). Records every consultation with steps
   taken — there is no quiet escalation.

   Per PRD: "The Urim v'Tumim never fabricates certainty where none
   exists." When external also fails, the system stops. It does not
   proceed on a guess.

   Added to VavPipeline supervision tree. 14 tests.

## Step 21 — Kushya generator scaffolding
   (kushya_generator/)

   Directory layout per Architecture §3.6 with three layers:

   - data/training_pairs/seed_pairs.jsonl — 10 hand-curated bootstrap
     pairs covering 9 kushya types (scope_narrowing, internal_tension,
     harmonization, exception_test, edge_case, scope_application,
     rabbinic_constraint, method_question, subject_identification)
   - data/prepare_training.py — validates the four kushya requirements
     (specific Torah passage, identified weakness, question form,
     non-trivial), produces train.jsonl + eval.jsonl with stratified
     80/20 split by type
   - fine_tune/config.yaml + train.py — QLoRA configuration and
     training script. Operator's task — needs GPU. Script is
     complete and self-contained.
   - inference/kushya_api.py — three-backend interface
     (fine_tuned → external → fallback). When fine-tuned model isn't
     deployed, falls back to external via Korban Processor (Step 22).
     The fallback is honest: returns no kushya rather than inventing
     one. The Talmudic Engine's rule-based challenge.pl remains the
     primary kushya source.

   17 tests covering dataset validation, backend selection, and
   reference extraction.

## .gitignore fix

   The earlier "data/" line was too broad — it caught
   kushya_generator/data/. Scoped to /data/ (root-level only).

## Test counts

   - Elixir:           274 (was 260; +14 for UrimVTumim)
   - Korban Python:    196 + 1 skipped (was 195; +1 module = 11 tests)
   - Kushya Python:     17 (new)
   - Haskell:           33 (unchanged)
   - Prolog:           195 (unchanged)
   - Total:            715 + 19 L3 excluded

## Phase 4 status

   All 12 steps now have implementations:
   - Steps 23, 25, 26, 27, 28, 29, 30, 31, 32: complete
   - Steps 21, 22, 24: complete with discipline preserved

   Step 21's fine-tuning run remains the operator's GPU task; the
   pipeline is built such that a deployed adapter slots into the
   inference backend without touching the Talmudic Engine or anything
   above.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 17:12:03 -04:00

3.5 KiB

Kushya Generator — Component F (Architecture §3.6)

Fine-tuned Mistral Medium 3.1 whose sole function is to generate adversarial challenges (kushyot) to proposed Torah interpretations.

Eilu v'eilu divrei Elohim chayim, v'halakhah k'beit Hillel. Both these and those are the words of the living God; the law follows Beit Hillel — but the dispute is preserved (Eruvin 13b).

Status

This directory holds the scaffolding for a fine-tuned kushya generator. The actual training run requires a GPU + curated dataset and is the operator's task. Until then, kushya generation in production falls back to:

  1. Rule-based kushyot from the Talmudic Engine (see talmudic_engine/src/reasoning/challenge.pl)
  2. External-model consultation via Korban Processor (Step 22) wrapped in the offering protocol so external output is never treated as authoritative

The fine-tuned generator replaces step 2 with a model that has consumed only the kushya-generation function — eliminating the eish zarah risk that general-purpose model output presents.

Layout

kushya_generator/
├── README.md                       This file
├── data/
│   ├── prepare_training.py         Extracts (interpretation, kushya) pairs
│   └── training_pairs/
│       ├── seed_pairs.jsonl        Hand-curated seed pairs to bootstrap
│       └── README.md               Provenance and curation notes
├── fine_tune/
│   ├── config.yaml                 QLoRA configuration
│   └── train.py                    Fine-tuning script (transformers + peft)
├── inference/
│   ├── kushya_api.py               In-process API the Talmudic Engine calls
│   └── serve.py                    HTTP server (when self-hosted)
└── test/
    └── test_dataset.py             Validates training data structure

How a Kushya is Built

A kushya must:

  1. Reference a specific Torah passage that creates tension with the proposed interpretation
  2. Identify the logical or textual weakness in the interpretation
  3. Be expressible as a question, not a statement
  4. Not be resolvable by trivial clarification

These four requirements are encoded in data/prepare_training.py's validator — every training pair must pass them or be rejected.

Data Sources

The training data should come from the existing rabbinic tradition:

  • Talmud Bavli — kushyot from disputes recorded in the Gemara
  • Talmud Yerushalmi — parallel disputes
  • Rishonim — Rashi, Tosafot, Rambam's challenges to other rishonim
  • Acharonim — later commentary kushyot

The seed_pairs.jsonl in this repo is a small hand-curated set sufficient to validate the training pipeline. A production training run requires several thousand pairs.

Fine-Tuning

# Activate environment with PyTorch + transformers + peft + bitsandbytes
python fine_tune/train.py --config fine_tune/config.yaml

Output: a LoRA adapter that wraps the base Mistral Medium 3.1 model. Quantize to GGUF Q5_K_M and serve via inference/serve.py over llama.cpp.

Until Then

The Talmudic Engine generates rule-based kushyot. The pipeline can also consult external models via the Korban Processor's consult_external_model function, with output passing through the offering protocol.

The system has been built to NOT depend on this fine-tuned model. When the fine-tuned model exists, it strengthens kushya generation; until then, the system functions on rule-based + external testimony.