Files
bikoret/kushya_generator
Scott KarpandClaude Fable 5.1 f4e8e5afc8 specs §1.1/§1.5 + Doorpost: the pins say what is built, and the build obeys them
The pin audit (2026-10-04) found Construction §1 wrong in three ways.

1. §1.5's mix.exs block was not the real mix.exs.
   phoenix ~> 1.7.11 was never a dependency (the API is Plug on
   Bandit); `ecto` is `ecto_sql`; telemetry is transitive (locked
   1.4.2, outside the stated ~> 1.2.1); bandit, plug and the sanhedrin
   path dependency were missing. The block now matches mix.exs and adds
   the versions mix.lock actually builds. Terumah's Elixir table
   matched the wrong block and also said postgrex ~0.17.4; corrected.

2. §1.1's component table described a machine that is not the one
   running. PostgreSQL 16.2 via apt → 17, managed (17.11 today).
   Podman 4.9.3 → Kubernetes/containerd, managed; Podman is used
   nowhere. Ubuntu 24.04.1 → what each image is in fact built on
   (Ubuntu 22.04 for pipeline and engine, Debian 12 for korban and
   talmudic) and the managed node (24.04). rebar3 3.23.0 → 3.22.0, the
   version in the build image. Azazel Processor added as a component.
   The spec is corrected to the deployment, not the reverse.

3. §1.1's rule — "No >=. No +. No ranges." — was not true of the spec's
   own Elixir deps, and "lock files are committed" was not true of two
   components. Both halves fixed:
   - The rule now says what is the case: a manifest may give a range;
     the committed lock is the pin; every image is built from its
     lock; base images are pinned by tag; managed services are pinned
     to a major version and patched by the provider.
   - And the build was made to obey it. The Korban image installed
     three packages named by hand and let pip pick every transitive
     one on the day of the build, plus an unpinned poetry-core. It now
     installs the lock's main group by exact version AND hash
     (scripts/lock_to_requirements.py; --require-hashes --no-deps;
     pip check). The image holds the lock's 12 packages and nothing
     else.
   - azazel_processor/poetry.lock: generated (it had none).
   - kushya_generator/pyproject.toml + poetry.lock: the four §1.4 pins
     (llama-cpp-python 0.2.55, peft 0.9.0, transformers 4.38.2,
     datasets 2.17.1) were pinned nowhere in the repo. They are now
     declared and locked (74 packages). The lock resolves; it has NOT
     been installed or run — Step 21 is unbuilt and needs a GPU.
     Its test config gains the korban and azazel source paths, which
     the external backend needs: 3 tests there had been failing since
     the azazel build, unnoticed because that suite is in no total.

Doorpost @expected_hash 39b66c31… → 1cd07079…, in this commit, with the
witnessed file that moved it (vayakhel).

Read before committing: Elixir 474/0 (seeds 0, 42) · korban 222 passed
1 skipped and azazel 125 passed, each with dependencies installed from
its lock by hash · kushya 17 passed (was 14 of 17) · korban image
starts, imports korban_processor + azazel_processor, pip check clean ·
pipeline image reports specification_identity verified 1cd07079….

Left as written: architecture §2's technology table still names
Phoenix, PostgreSQL 16, Ubuntu 24.04 and rootless Podman for Sanhedrin
isolation, and terumah §B still lists systemd, squashfs, Caddy,
nftables for a self-hosted server. Those describe a design, not a pin.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 19:17:46 +00:00
..

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.