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>
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:
- Rule-based kushyot from the Talmudic Engine (see
talmudic_engine/src/reasoning/challenge.pl) - 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:
- Reference a specific Torah passage that creates tension with the proposed interpretation
- Identify the logical or textual weakness in the interpretation
- Be expressible as a question, not a statement
- 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.