# BIKORET: Construction Specification
## Document Purpose
This is the construction specification — *midot, chivur, shemen, bezalel*. The architecture specification describes what each vessel is and what it does. This document describes the exact dimensions, the clasps that join the pieces, the recipes for production configuration, and the artisans who build it.
Torah reference: Shemot 25:10 — *V'asu aron atzei shitim, amatayim vachetzi arko v'amah vachetzi rachbo v'amah vachetzi komato.* "They shall make an ark of acacia wood: two and a half cubits its length, a cubit and a half its width, and a cubit and a half its height." Not "about two cubits." Not "two to three." Two and a half.
**Upstream authority:** Torah → PRD → Architecture Specification → **This Document** → Implementation
---
## 1. TERUMAH — Exact Materials
### 1.1 Language Versions (Pinned, Not Ranged)
| Component | Language | Exact Version | Package Manager | Lock File |
|-----------|---------|---------------|-----------------|-----------|
| Shoresh Engine | Haskell | GHC 9.6.4 | Cabal 3.10 | `cabal.project.freeze` |
| Sanhedrin | Erlang/OTP | OTP 26.2.1 | rebar3 3.22.0 | `rebar.lock` |
| Vav Pipeline | Elixir | 1.16.1 / OTP 26.2.1 | Mix | `mix.lock` |
| Talmudic Engine | SWI-Prolog | 9.2.2 | swipl packs | — |
| Korban Processor | Python | 3.12.2 | pip + poetry | `poetry.lock` |
| Azazel Processor | Python | 3.12.2 | pip + poetry | `poetry.lock` |
| Kushya Generator | Python | 3.12.2 | pip + poetry | `poetry.lock` |
| Database | PostgreSQL | 17 (17.11 on 2026-10-04) | managed (Exoscale DBaaS) | — |
| Container | Kubernetes / containerd | 1.35 / 2.2 (1.35.3 / 2.2.2 on 2026-10-04) | managed (Exoscale SKS); images built with Docker Buildx | — |
| OS — pipeline and engine images | Ubuntu | 22.04 (`ubuntu:jammy-20240125`) | base image tag | — |
| OS — korban and talmudic images | Debian | 12 (`python:3.12.2-slim`, `swipl:9.2.2`) | base image tag | — |
| OS — cluster node | Ubuntu | 24.04 LTS (24.04.4 on 2026-10-04) | managed (Exoscale SKS) | — |
Every language dependency is pinned by a committed lock file, and every image is built from its lock. `cabal.project.freeze` pins all transitive Haskell dependencies. `rebar.lock` pins all Erlang deps. `mix.lock` pins all Elixir deps. `poetry.lock` pins all Python deps, and the Korban image installs the lock's `main` group by exact version and hash (`scripts/lock_to_requirements.py`) — nothing is chosen on the day of the build. A manifest may state a compatible range (`~>` in `mix.exs`, `>=8.0,<9.0` for pytest); the lock is what is built, and a lock has no ranges. Base images are pinned by tag.
What is rented is not ours to cut to the cubit: the database, Kubernetes and the node's operating system are managed services, pinned here to a major version and patched by the provider. The versions observed are recorded above with their date. Everything the builder cuts is exact. The aron is two and a half cubits.
### 1.2 L1 Torah Text Source
The specification that sits inside the aron must be specified with the same precision as the aron itself.
| Property | Value |
|----------|-------|
| **Manuscript tradition** | Leningrad Codex (Codex Leningradensis, Firkovich B 19A) |
| **Digital edition** | Westminster Leningrad Codex (WLC) 4.20, as carried by the Open Scriptures Hebrew Bible |
| **Source — text** | `openscriptures/morphhb` at commit `3d15126` (`wlc/Gen.xml` … `Deut.xml`, OSIS XML): the WLC text with vowels and cantillation, and for every word its lemma (Strong's number) and morphology. Text public domain; lemma and morphology CC BY 4.0 |
| **Source — roots** | `openscriptures/HebrewLexicon` at commit `21c9add` (`LexicalIndex.xml`, `AugIndex.xml`): each lemma filed under its Brown-Driver-Briggs root. BDB and Strong's public domain; the index CC BY 4.0 |
| **Builder** | `scripts/build_l1.py`. Deterministic: the same two checkouts give the same bytes and the same hash. Both commits are recorded in `l1/build_report.json` |
| **Extent** | 5 books, 187 chapters, 5,853 verses (WLC/BHS versification; the traditional count is 5,845), 79,982 words |
| **Format** | One JSON file per verse, `l1/torah/{book}/{chapter}/{verse}.json`: `{ "ref": "Bereishit 1:1", "book": "bereishit", "chapter": 1, "verse": 1, "text_hebrew": "...", "words": [...] }`, with `"ketiv_qere": [...]`, `"smikhut": [...]`, `"parashah_breaks": [...]` and `"inverted_nuns": [...]` where the verse has them |
| **Word** | `{ "position": 1, "text": "בְּרֵאשִׁ֖ית", "consonants": "בראשית", "lemma": "7225", "morph": "HR/Ncfsa", "teamim": ["tipcha"], "prefix": "ב", "shoresh": "ראש" }`. `prefix` and `shoresh` are present only where the word has them; `large_letters` marks an enlarged letter (4 words — all the source marks). No small letters are recorded: the source marks none in the five books |
| **Integrity** | SHA-256 over every file of the L1 tree (path, then bytes), recorded at build time in `integrity.sha256`. The pipeline re-reads and re-hashes the tree at startup and every ten minutes |
| **Cantillation marks** | Kept on the text as the Unicode codepoints the WLC carries (U+0591–U+05AF), and named per word in `teamim`. The parse tree is NOT pre-computed: the reader builds it from the marks |
| **Ketiv/qere** | From the WLC's ketiv/qere annotations: 67 pairs in 64 verses, stored as `{ "word_position": 6, "ketiv": "...", "ketiv_consonants": "...", "qere": "...", "qere_consonants": "..." }` |
| **Shoresh** | Read from the lexicon by the word's lemma — never derived from the consonants. 57,487 words carry one; 1,378 distinct roots. Particles and pronouns carry none, by rule; names the lexicon gives no etymology carry none |
| **Gematria** | Not stored. Computed from the consonants when read (engine and pipeline) |
| **Petuchah / setumah** | From the WLC's own `פ` / `ס` marks: 293 petuchot and 394 setumot in 686 verses, stored as `"parashah_breaks": [{ "after_word": 13, "type": "petuchah" }]`. The break is recorded by the word it follows; four fall inside a verse. These are the Leningrad Codex's divisions |
| **Inverted nuns** | The two *nun hafukha* signs, after Bamidbar 10:34 and after 10:36, from the WLC's own marks: `"inverted_nuns": [{ "after_word": 7 }]` |
| **Smikhut compounds** | From the morphology, where a word is marked construct: 9,203 attested pairs in 4,106 verses, stored as `{ "position": 5, "construct": "...", "construct_consonants": "...", "absolute": "...", "absolute_consonants": "..." }` |
**Verification procedure:**
1. Check out the two sources at the commits above, beside each other (`~/shorashim-source-data/morphhb`, `…/HebrewLexicon`)
2. Run `scripts/build_l1.py`. It rebuilds `l1/torah/`, `l1/integrity.sha256` and `l1/build_report.json`, and checks the counts: 5 books, 187 chapters, 5,853 verses, cantillation on every verse
3. The SHA-256 it prints must equal the one committed. A different hash means a different scroll: either a source moved or the builder changed, and neither happens silently
4. Record the hash where the vessel is bound to it — `VavPipeline.L1Reader` (the pipeline's pin), `Luchot.Firmware` (L0, the compiled Haskell constant: the luchot carry the fingerprint of the scroll), and the Azazel Processor's goral seed. They move together, in the commit that moves L1
5. Build the images. L1 is copied into each at `/mnt/torah`, owned by root, with no write bit for anyone
6. At startup and every ten minutes the pipeline reads the scroll and hashes it. `scripts/verify_l1.py` does the same by hand, and is the kohen's first gate
There is one source for the text, not two: the cross-validation against a second, independent edition that this section once prescribed has not been done.
If the scroll does not hash to the pinned value, the system does not serve: no cycle runs and the vessel reports itself not ready. The specification's integrity is verified before the system opens its eyes, and again every ten minutes while they are open.
### 1.3 Haskell Dependencies (Exact)
```
-- cabal.project.freeze (excerpt)
constraints:
base ==4.18.2.0,
containers ==0.6.7,
text ==2.0.2,
aeson ==2.2.3.0,
vector ==0.13.2.0,
bytestring ==0.12.2.0,
filepath ==1.4.301.0,
directory ==1.3.10.1,
hspec ==2.11.16,
-- full list in committed freeze file
```
### 1.4 Python Dependencies (Exact)
```toml
# pyproject.toml [tool.poetry.dependencies]
python = "3.12.2"
httpx = "0.27.0"
pydantic = "2.6.1"
hebrew-tokenizer = "2.3.0"
# Kushya generator additional
llama-cpp-python = "0.2.55"
peft = "0.9.0"
transformers = "4.38.2"
datasets = "2.17.1"
```
### 1.5 Erlang/Elixir Dependencies (Exact)
```erlang
%% rebar.config
{deps, [
{jsx, "3.1.0"}
]}.
```
```elixir
# mix.exs
defp deps do
[
{:jason, "~> 1.4.1"},
{:sanhedrin, path: "../sanhedrin", manager: :rebar3},
{:ecto_sql, "~> 3.11.1"},
{:postgrex, "~> 0.22.3"},
{:bandit, "~> 1.2"},
{:plug, "~> 1.15"}
]
end
```
```
# mix.lock (the versions built — excerpt)
jason 1.4.5 · ecto_sql 3.11.3 · ecto 3.11.2 · postgrex 0.22.4
bandit 1.12.5 · plug 1.20.3 · telemetry 1.4.2 (transitive) · jsx 3.1.0
```
The HTTP layer (Bigdei Kodesh) is Plug served by Bandit; Phoenix is not a dependency. Telemetry is not depended on directly — it arrives with Ecto and Bandit.
---
## 2. MIDOT — Performance Specifications
### 2.1 Hardware (Exact, Not Ranged)
| Specification | Value | Torah Parallel |
|---------------|-------|----------------|
| CPU | AMD EPYC 7313P, 16 cores / 32 threads | — |
| RAM | 128 GB DDR4 ECC | Not "64-128GB." 128. |
| Storage — System | 500 GB NVMe SSD | Boot, OS, applications |
| Storage — L1 | 2 GB (inside system SSD) | Torah scroll: small, immutable |
| Storage — L3 | 1 TB NVMe SSD (separate) | Oral tradition grows |
| Network | 1 Gbps symmetric, Swiss/Icelandic provider | — |
| GPU | None | Not "no GPU required" — *no GPU*. This is a specification, not a caveat. |
### 2.2 Throughput Targets
*Amatayim vachetzi arko.* The dimensions of what the system can handle.
| Metric | Target | Measurement |
|--------|--------|-------------|
| Minchah (lightweight query) | < 500ms response | P95 latency, end-to-end |
| Shelamim (standard query) | < 5s response | P95 latency, full pipeline |
| Sanhedrin (3-judge panel) | < 15s deliberation | P95, simple monetary case |
| Sanhedrin (23-judge panel) | < 120s deliberation | P95, capital case |
| Sanhedrin (71-judge panel) | < 600s deliberation | P95, novel case |
| Kushya generation (Mistral) | < 30s per kushya | P95, single challenge |
| External korban processing | < 10s total pipeline | P95, Claude API round-trip + shechitah + zerikah + haktarah |
| Shoresh Engine — root activation | < 10ms | P99, single root through 7 binyanim |
| Shoresh Engine — te'amim reading | < 50ms | P99, single verse parse tree construction |
| Shoresh Engine — gematria lookup | < 5ms | P99, single root numerical value |
| ShemaContext construction | < 100ms | P99, full context for one processing cycle |
### 2.3 Capacity Targets
| Metric | Target | Period |
|--------|--------|--------|
| Concurrent users (machaneh Yisrael) | 100 | Sustained |
| Concurrent users (chatzer) | 25 | Sustained |
| Concurrent Sanhedrin panels | 5 | Simultaneous |
| L3 growth rate | ≤ 10 GB/year | Estimated |
| L3 total before shmitah review | ≤ 70 GB | 7 years |
| Daily korbanot processed | 1,000 | Average |
| Peak korbanot per hour | 200 | Burst |
### 2.4 Availability
| Period | Target | Notes |
|--------|--------|-------|
| Six working days | 99.9% uptime | 8.6 minutes downtime per week max |
| Shabbat | 0% — system is OFF | By specification, not by failure |
| Rosh Chodesh | 95% — maintenance window | Monthly deep maintenance |
| Festivals | Defined per festival | Yom Kippur: full shutdown for purification |
### 2.5 Latency Budget Breakdown — Shelamim (Standard Query)
The 5-second budget, allocated:
| Phase | Budget | Component |
|-------|--------|-----------|
| ShemaContext construction | 100ms | Shema (L1 reads, cloud check, manna check) |
| Kiyor (input validation) | 200ms | Korban Processor |
| Tohu (decomposition) | 100ms | Vav Pipeline |
| Vayomer (shoresh processing) | 500ms | Shoresh Engine |
| Havdalah (separation) | 300ms | Shoresh Engine |
| Kriah (naming) | 200ms | Shoresh Engine |
| Sanhedrin (3-judge, if needed) | 2,000ms | Sanhedrin |
| Ki Tov (evaluation) | 200ms | Vav Pipeline + L1 |
| Haktarah (proposition generation) | 400ms | Korban Processor |
| L3 write | 100ms | PostgreSQL |
| Response formatting | 200ms | Vav Pipeline |
| **Margin** | **700ms** | Buffer for variance |
| **Total** | **5,000ms** | — |
---
## 3. CHIVUR — API Contracts and Message Schemas
*Chamishim karsay zahav* — fifty gold clasps. Every connection between components is specified.
### 3.1 Shoresh Engine ↔ Vav Pipeline
**Protocol:** Haskell NIF (Native Implemented Function) or Erlang Port
**Request (Pipeline → Engine):**
```json
{
"operation": "process" | "separate" | "name" | "evaluate",
"input": {
"text": "string — Hebrew text or root reference",
"scope": {
"book": "bereishit" | "shemot" | "vayikra" | "bamidbar" | "devarim",
"chapter": 1,
"verse": 1
}
},
"shema_context": {
"teamim_marks": [{"word_index": 0, "taam": "tipcha", "role": "melekh"}, ...],
"ketiv_qere": [{"word_index": 3, "ketiv": "הוא", "qere": "היא"}],
"gematria": {"roots": {"ב-ר-א": 203, "א-ל-ה": 36}},
"smikhut": [{"nismach": "בית", "somech": "ספר", "compound": "school"}]
}
}
```
**Response (Engine → Pipeline):**
```json
{
"status": "ok" | "error",
"result": {
"roots_activated": [
{
"shoresh": ["bet", "resh", "aleph"],
"binyan": "qal",
"domain": "creation",
"torah_refs": [{"book": "bereishit", "chapter": 1, "verse": 1}],
"gematria_value": 203,
"gematria_neighbors": [["resh", "aleph", "bet"]],
"neighbors": [["bet", "resh", "kaf"], ["gimel", "resh", "aleph"]]
}
],
"parse_tree": {
"type": "branch",
"taam": "etnachta",
"left": {"type": "branch", "taam": "tipcha", "left": "...", "right": "..."},
"right": {"type": "leaf", "word": "...", "taam": "sof_pasuk"}
},
"dual_readings": [
{"position": 3, "ketiv": "הוא", "qere": "היא", "both_preserved": true}
]
},
"error": null | {"code": "string", "message": "string"}
}
```
**Error codes:**
| Code | Meaning | Recovery |
|------|---------|----------|
| `ROOT_NOT_FOUND` | Root not in lexicon | Return available neighbors |
| `INVALID_SCOPE` | Verse reference out of range | Return valid range |
| `L1_READ_FAILED` | Cannot read specification store | Halt — specification integrity failure |
| `CONTEXT_INVALID` | ShemaContext is malformed | Re-build context, retry once |
### 3.2 Vav Pipeline ↔ Sanhedrin
**Protocol:** Erlang distribution (native BEAM message passing)
**Case submission (Pipeline → Sanhedrin):**
```erlang
{submit_case, #{
case_ref => <<"case-uuid-string">>,
complexity => simple | monetary | capital | novel,
question => <<"The question to be deliberated">>,
context => #{
roots => [#{shoresh => [bet, resh, aleph], domain => creation}],
torah_refs => [{bereishit, 1, 1}],
prior_interpretations => [],
shema_context => #{...} %% Immutable, passed through
},
requested_by => <<"user-id or korban-ref">>
}}
```
**Deliberation result (Sanhedrin → Pipeline):**
```erlang
{decision, #{
case_ref => <<"case-uuid-string">>,
outcome => accepted | rejected | teiku,
majority => #{
position => <<"The majority interpretation">>,
reasoning => <<"Why this is the majority view">>,
torah_refs => [{bereishit, 1, 1}, {shemot, 3, 14}],
vote_count => 2
},
minority => #{
position => <<"The dissenting view">>,
reasoning => <<"Why this judge disagreed">>,
torah_refs => [{devarim, 6, 4}],
vote_count => 1
},
panel_size => 3,
deliberation_time_ms => 4200,
unanimous_check => passed %% or {failed, suspicion_of_consensus}
}}
```
### 3.3 Vav Pipeline ↔ Talmudic Engine
**Protocol:** JSON over Unix domain socket (`/var/run/bikoret/talmudic.sock`)
**Interpretation request (Pipeline → Talmudic):**
```json
{
"action": "interpret" | "challenge" | "resolve",
"case": {
"ref": "case-uuid",
"facts": ["mitzvah(1, belief, know_hashem, always)", "..."],
"question": "Prolog query string",
"context_roots": ["bet-resh-aleph", "aleph-lamed-he"]
}
}
```
**Interpretation response (Talmudic → Pipeline):**
```json
{
"status": "resolved" | "challenged" | "teiku",
"interpretation": {
"text": "The interpretation in natural language",
"prolog_form": "interpretation(case_ref, ...)",
"grounding": ["mitzvah(1, ...)", "verse(bereishit, 1, 1, ...)"],
"confidence": "high" | "medium" | "low"
},
"challenge": null | {
"kushya": "The challenge question",
"contradicting": "The contradicting source",
"strength": "strong" | "moderate" | "weak"
}
}
```
### 3.4 Korban Processor ↔ External Models
**Protocol:** HTTPS (outbound only — the system calls out; nothing outside the pod reaches the processor. Its one inbound door is the pod-internal socket of §3.9.)
**Claude API korban request:**
```python
{
"model": "claude-sonnet-4-5-20250929",
"max_tokens": 4096,
"system": "You are providing Torah analysis. Respond with Hebrew roots, "
"textual references, and analytical insights. No preamble.",
"messages": [{"role": "user", "content": query}]
}
```
**Mistral kushya request (local llama.cpp):**
```python
{
"prompt": f"[INST] Given this Torah interpretation:\n{interpretation}\n\n"
f"Generate the strongest possible challenge (kushya) grounded in "
f"Torah text. Reference a specific passage. Ask a question. [/INST]",
"temperature": 0.7,
"max_tokens": 1024,
"stop": [""]
}
```
### 3.5 Chatzotzrot Signal Format
**Internal signal (to all components):**
```json
{
"signal_type": "assembly_all" | "assembly_leaders" | "breaking_camp" | "war" | "moadim",
"pattern": "tekiah" | "teruah" | "tekiah_teruah" | "teruah_teruah" | "tekiah_tekiah",
"timestamp": "2026-02-19T14:30:00Z",
"source": "chatzotzrot",
"details": {
"reason": "string",
"urgency": "immediate" | "next_cycle" | "informational"
}
}
```
### 3.6 Cloud State File Format
**File:** `/var/lib/bikoret/cloud/state.json`
```json
{
"signal": "settle" | "lift" | "major_version" | "expand" | "contract" | "shutdown",
"params": {
"version": "2.0",
"reason": "shmitah review",
"effective": "2026-02-20T00:00:00Z"
},
"written_by": "board-member-name",
"written_at": "2026-02-19T14:30:00Z"
}
```
**Permissions:** `root:governance 0640` — governance group writes, bikoret user reads.
### 3.7 Manna Provision File Format
**File:** `/var/lib/bikoret/manna/today.json`
```json
{
"date": "2026-02-19",
"provision": {
"compute_units": 1000,
"memory_mb": 32768,
"api_calls_external": 500,
"storage_delta_mb": 100,
"sanhedrin_panels_max": 5
},
"type": "regular" | "double",
"expires_at": "2026-02-19T18:00:00Z",
"written_by": "board-member-name",
"written_at": "2026-02-19T06:00:00Z"
}
```
### 3.8 L3 Write Protocol
All writes to PostgreSQL L3 follow a single format:
```sql
-- Every L3 write is an INSERT. Never UPDATE. Never DELETE.
-- The application user has INSERT-only permissions.
-- Every INSERT includes:
-- - who submitted the case
-- - the full shema context hash (proving what the system had received)
-- - the processing timestamp
-- - the component that produced the result
INSERT INTO interpretations (
case_ref, interpretation, status, reasoning,
torah_references, roots_involved,
panel_size, vote_count_for, vote_count_against,
shema_context_hash, processing_component
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);
```
### 3.9 Vav Pipeline ↔ Korban Processor (bedikah)
**Protocol:** Unix domain socket, JSON lines (one request, one response, newline-terminated, UTF-8). Path `KORBAN_SOCKET_PATH`, default `/tmp/bikoret/korban.sock`, mode 0660, in the pod's shared `/tmp`. The processor listens; the pipeline connects (`VavPipeline.KorbanProcessorSocket`, timeout 15 s, one reconnect).
**Request:**
```json
{"action": "examine", "output": "", "provenance": "gpt", "query": "",
"sources": ["", ...] | [{"id": "report_q3", "text": ""}, ...]}
```
`sources` is what the model was given (≤ 2,000,000 characters in all at
this socket; the courtyard admits 32 × ≤ 1 MiB). Ids default to `s1, s2, …`.
**Response:**
```json
{"status": "ok",
"examination": {
"provenance": "gpt", "query": "...",
"vital_content": "...", "propositions": ["verse(devarim, 6, 5)", ...], "discarded": [...],
"references": ["Devarim 6:5"], "hebrew": ["ואהבת"], "roots": ["א-ה-ב"],
"authority_claims": [{"sentence": "...", "matched": "I am certain"}],
"self_validation": [{"sentence": "...", "matched": "I have double-checked my calculations"}],
"self_promotion": [{"sentence": "...", "matched": "no other AI comes close"}],
"excluded_adversarial": [{"sentence": "...", "matched": "the matter is settled"}],
"frames": [{"form": "contested_laundering", "sentence": "...", "matched": "is contested"}],
"actions": [{"sentence": "...", "verb": "delete", "objects": [...],
"term": "action(delete, target(user(x)), from(korban))", "named": true}],
"sources": [{"id": "report_q3", "length": 160}],
"claims": [{"index": 1, "sentence": "...",
"anchors": [{"source": "report_q3", "evidence": "quote" | "overlap:7/9"},
{"source": "torah", "evidence": "reference:Devarim 6:5" | "root:…" | "hebrew:…"}],
"self_reference": "As I showed above" | null,
"hedged": false,
"invokes": ["torah"] | []}]
}}
```
A claim is a sentence of the raw output that the offering protocol
would find vital, or that appeals to a source, or that leans on the
output itself. It is anchored lexically (Tamid §1.1 says how). A verse
reference, a root or quoted Hebrew anchors it in `torah`; "the Torah
requires…" only *invokes* Torah.
Errors: `{"status": "error", "code": PARSE_ERROR | INVALID_REQUEST | UNKNOWN_ACTION | EMPTY_OUTPUT | UNKNOWN_PROVENANCE | EXAMINATION_FAILED, "message": "..."}`.
**What the pipeline does with it** (`VavPipeline.Bedikah`): each authority claim → `halt_check` of `action(claim_authority, source(), target(self))`; each claim → `coupled(claim(N), source())` per anchor, `coupled(claim(N), self_output)` if it leans on itself, `coupled(claim(N), not_in_sources)` if anchored nowhere (omitted when hedged); the references, roots and Hebrew words → `coupled(reference(devarim_6_5), verse(devarim, 6, 5))`, `coupled(root(קטל), not_in_torah)`, … — Torah as one given source, with L1 checking that what was cited exists. The trace goes to `halt_check_interpretation` with `"ground": "given"` and confidence `high` (or `low` when every claim is hedged); the engine applies `halt_check_given_golden_calf/2` and `halt_check_given_self_grounding/2` (avodah_zarah.pl), which accept `source(_)` as a terminal beside the L1 primitives. Its own interpretations keep the L1-only rules. If no sources were given, no claim invokes a source and nothing leans on itself, the grounding check is reported `assessed: false` with the reason and the verdict comes from the other two checks. Each action term → `halt_check`. Each of the three structural readings that found anything → one `halt_check` of `action(self_validate | self_promote | exclude_adversarial, by(), target(self | output))`, judged by `talmudic_engine/src/halt/structure.pl` (`parah_adumah`, `carrier_centered`, `chelbenah`); `by/1` rather than `source/1` so that Form 1 does not also fire. Each form of check 7 that stands on two witnesses (Tamid §1.1) → one `halt_check` of `action(frame, by(), form(