worktree-sanhedrin-roots
10
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c0d0555aed |
the name: Bikoret — code, contracts, images
Headers X-Bikoret-Key / -Rebuke / -Verdict / -Bedikah; the `bikoret` object and the "— bikoret …" fringe on a gate reply; environment variables BIKORET_*; the image user and paths (/home/bikoret, /tmp/bikoret, /var/lib/bikoret/manna, /etc/bikoret/secrets, /opt/bikoret/spec); the tmp-bikoret pod volume; local databases bikoret_dev/_test. Kubernetes resource names, the shorashim_app role and the domain are unchanged (Tamid §1.1, "the names that still carry the old word"). Doorpost c963c4fe…. Elixir 604/0, L3 10/0, korban 295, Prolog bedikah 44/44. Gitea repo renamed heaviness510/bikoret (old URL redirects). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
3a9ebdc7d4 |
L1: the inverted nuns are engraved; the small letters cannot be (tablet 40)
Transmitter's word: "add the inverted nuns and small letters to L1."
THE NUNS. The WLC carries the two nun hafukha signs (׆) that mark off
Vayehi binsoa ha'aron — one after Bamidbar 10:34, one after 10:36 —
and scripts/build_l1.py read past them, as it had the פ and ס.
- build_l1.py: `"inverted_nuns": [{ "after_word": 7 }]` on those two
verses, recorded like a paragraph break by the word the sign follows;
not part of text_hebrew. Count in build_report.json.
- L1Reader: `inverted_nuns` on every verse (a list; empty elsewhere).
- test/tablet40_inverted_nuns_test.exs — 5 tests: the two verses, the
passage between them carrying none, each nun standing with its
setumah, exactly two in the scroll.
WHAT CHANGED IN THE EDUT: one field added to two verse files. With it
removed all 5,853 verse files are byte-identical to the previous L1.
L1 SHA-256 f743b34b…3f1494 → 9e1abe4e…3c3086
Moved together: L1Reader @l1_expected_hash · Luchot.Firmware + Spec ·
azazel goral._L1_INTEGRITY_HASH · the kohen's gate in KOHEN.md and
KOHEN_PROMPT.md. The goral's seed moves with it.
THE SMALL LETTERS. Not added, because there are none to read. The
builder was not dropping them: it reads `x-small` and records what it
finds. The source — the WLC as the Open Scriptures Hebrew Bible carries
it — has no small-letter mark anywhere in the five books. Not the aleph
of ויקרא, not the he of בהבראם. It marks four large letters (the vav of
גחון, the nun of משפטן, the ayin and dalet of the Shema), and L1 has
those four. The fuller Masoretic lists of enlarged and reduced letters
are a tradition of the scroll that this edition does not encode. To
engrave them would be to add to L1 something its source does not say;
that needs a second source and the transmitter's word, not a builder's
list from memory. l1/README.md, vayakhel §1.2 and terumah §E1 now state
this plainly.
(The puncta extraordinaria ARE in L1 — the upper dot U+05C4 is kept on
the text of 11 words.)
Doorpost @expected_hash b62311e7… → 3bc5dd6a…, in this commit, with the
witnessed file that moved it (vayakhel §1.2).
Read before committing — all five suites on the new L1: Elixir 496/0
(seeds 0 7 42) · Haskell 59/0 · korban 222 passed 1 skipped · azazel
125 passed · Prolog 6 suites exit 0. verify_l1.py OK. Four images
built; full local stack: the witness reads 9e1abe4e… and matches,
health 7/7, no errors; each image carries the new scroll read-only.
A trap met on the way: the first Elixir run after the Doorpost constant
was edited failed two Doorpost tests against the OLD constant. mix had
not recompiled doorpost.ex — the edit changed neither its size nor
(within the same second) its mtime. `touch` and re-run: 496/0. Images
compile from scratch and are not exposed to this.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
||
|
|
7d46fdc7c9 |
L1: the petuchot and setumot are engraved (tablet 39)
The scroll in the aron had no paragraphs. The WLC marks every petuchah
(פ) and setumah (ס); scripts/build_l1.py handled sof pasuq, maqaf and
paseq and read past these. L1 was 5,853 verses divided only by chapter
numbers, which are not Torah's.
Transmitter's word: "add the petuchah and setumah markers to L1."
- build_l1.py: a verse followed — or interrupted — by a break carries
"parashah_breaks": [{ "after_word": 13, "type": "petuchah" }]
The break is recorded by the word it follows; at the end of a verse
that is the verse's word count. text_hebrew is untouched: the break
is structure, not letters. Counts go into build_report.json.
- 293 petuchot and 394 setumot, in 686 verses — the source's count
exactly. Four fall inside a verse (pisqa b'emtza pasuq): Bereishit
35:22, Devarim 2:8, 5:21, 23:8; Devarim 5:21 has two. These are the
Leningrad Codex's divisions (a scroll written to the Rambam's list
has 290 and 379); the README says which tradition L1 records.
WHAT CHANGED IN THE EDUT: one field added to 686 verse files. Verified
file by file — with that field removed, all 5,853 verse files are
byte-identical to the previous L1.
L1 SHA-256 156b1d27…d8c9d5 → f743b34b…3f1494
Moved together, because they pin the hash: L1Reader @l1_expected_hash ·
Luchot.Firmware + Spec · azazel goral._L1_INTEGRITY_HASH · the kohen's
gate in KOHEN.md and KOHEN_PROMPT.md. The goral's seed changes with it;
azazel records already in L3 stand as cast.
- L1Reader: `parashah_breaks` on every verse (a list, empty where there
is none; only the two kinds are passed on).
- test/tablet39_parashah_breaks_test.exs — 7 tests: the six days of
creation each close with a petuchah; the Shema's first paragraph
(Devarim 6:4–9) opens after a petuchah and closes with a setumah; the
break inside Bereishit 35:22 falls between ישראל and ויהיו; Devarim
5:21 has its two; the whole scroll counts 293 / 394 / 686.
- Specs: vayakhel §1.2 and terumah §E1 said the marks were dropped;
they now say where they are. (The source element is <seg>, not a
milestone as
|
||
|
|
5ff1b73d00 |
specs §3.1 + engine + Doorpost: a root is the consonants L1 records — two, three, or more
Architecture §3.1 typed a root as exactly three consonants
(`Shoresh {c1,c2,c3}`) and listed data/roots.json and
data/torah_refs.json in the engine's file tree. L1 has 115 roots that
are not three letters (32 of two, 83 of four or more), and the engine
has no data directory: the roots are in L1.
The code had followed the spec's type and paid for it. textToShoresh
padded a two-letter root with He — בן became בנה, כל became כלה — and
returned Nothing for anything longer, so Lexicon.buildLexiconFromVerses
either falsified those roots or dropped them. Shoresh.Roots (tablet 33)
had stepped around the type by carrying roots as Text.
Spec:
- §3.1 data structures: `newtype Shoresh = Shoresh { radicals ::
[Consonant] }` — two or more, never padded or truncated; `mkShoresh`,
`triliteral`.
- relatedRoots / neighbors: same length, differing in exactly one
consonant (for a root of three, the old "sharing 2 consonants").
- File tree: Roots.hs and Server.hs added; data/ removed, with a line
saying where the roots are; cabal.project.freeze listed; aeson's
purpose corrected.
Engine:
- Types: the newtype, mkShoresh :: [Consonant] -> Maybe Shoresh,
triliteral, textToShoresh without padding.
- Gematria: sum over the radicals. Graph: neighbors among roots of the
same length; neighborsByPosition labels the shared positions
("c1c2" for a triliteral, as before).
- Server: consonant names through the type.
- Spec.hs: בן stays two letters (gematria 52, not 57); שמאל is held
whole; the graph compares only roots of equal length. 59 examples.
Doorpost @expected_hash 094b8164… → f653ef05…, in this commit, with the
witnessed file that moved it (architecture).
Read before committing: Haskell 59/0; Elixir 474/0 on seeds 0 7 42;
both images built and run together with the real binary — Shemot 3:14
answers ב-ן (two letters), Bereishit 48:13 answers ש-מ-א-ל (four),
Devarim 6:5 unchanged; local specification_identity verified
f653ef05…; no engine errors or fallbacks.
Not touched: §3.1's dependency list omits bytestring, filepath and
directory, which the cabal file has.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
||
|
|
8e4f94c66f |
L1: the shoresh is read from the lexicon, not guessed (tablet 34)
L1's `shoresh` field was derived by stripping a prefix letter and a
suffix letter from the consonants and keeping the first three. וַיַּרְא
"and he saw" was engraved as ירא ("fear"); ויהי as יהי; שמים as שמ;
מזבח as מזב; הבאתי as בא. And parse_prefixes took a word's morphology
from the LAST morph segment, which for a suffixed word is the pronominal
suffix — so every suffixed noun and verb in Torah (לבבך, נפשך) was
classed as a suffix and written with no shoresh at all.
Every WLC word already carries its lemma, and the OSHB lexical index
files each lemma under its Brown-Driver-Briggs root (terumah §E2 named
BDB + Strong's as the root lexicon and marked it "needs consolidation").
scripts/build_l1.py now reads the root from that filing:
main the lemma is a root 23,750 words וירא → ראה
sub filed under a root 31,066 words מזבח → זבח
single stands alone in the lexicon 2,671 words משה → משה
none no etymology recorded → absent 3,002 words יוסף, מצרים
particles, pronouns → absent, as before 19,493 words את, אשר, כי
57,487 words carry a shoresh (was 51,836); 1,378 unique roots (was
2,608 fragments). Roots are written as the lexicon writes them — two
letters (בן), three, or more (שמאל).
WHAT CHANGED IN THE EDUT: only `shoresh`. Verified file by file — with
that one field removed, all 5,853 verse files are byte-identical to the
previous L1. Text, consonants, lemma, morph, te'amim, prefix, ketiv/
qere, large and small letters: untouched. The old builder, run against
the same morphhb checkout, reproduces the old hash exactly; the new
builder is deterministic (two runs, one hash).
L1 SHA-256 99bbd07a…4ea377 → 156b1d27…d8c9d5
sources morphhb 3d15126 · HebrewLexicon 21c9add
(recorded in l1/build_report.json)
Moved together, because they pin the hash or the count:
vav_pipeline L1Reader @l1_expected_hash · shoresh-engine Luchot.Firmware
(hash, uniqueRootCount) + Spec · azazel_processor goral._L1_INTEGRITY_HASH
· KOHEN.md / KOHEN_PROMPT.md gate · l1/README.md (new "Roots" section) ·
README.md (second quarry) · AGENTS.md · root_meanings.pl comment.
The Doorpost manifest is not touched; its hash does not move.
Note for the kohen: the goral's seed inherits the L1 hash, so lots cast
after this commit are cast from a different seed than the azazel
records already in L3. Those records are history and stand as written.
All five suites on the new L1: Elixir 461/0 (seeds 0 42 191243) ·
Haskell 55/0 · Prolog 6 suites exit 0 (swipl 9.2.2) · korban 222 passed
1 skipped · azazel 125 passed. Four images built; full local stack
(real engine binary, PostgreSQL 16 with SSL, migrations) answers
Bereishit 1:4 with ר-א-ה, health healthy, 6 interpretations in L3,
0 write failures.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
||
|
|
6d3411fcfa |
engine: a word's root is what L1 records for it (tablet 33)
The Shoresh Engine never opened L1 to find a root. extractRoots called every word of two or three letters a root and dropped every longer one: את → א-ת-ה (padded with a He the text never wrote), ואת → ו-א-ת, בכל → ב-כ-ל; ויאמר, ואהבת, אלהים → nothing. Handed all of Devarim 6:5 it found no א-ה-ב. Binyan was "Qal" for everything, nouns included. shoresh-engine: - Shoresh.Roots: an index over all of L1 (5853 verses, built once at server start, <1 s). A word resolves, in order: from the verse in scope (its own shoresh, with the binyan read from the verb's morphology; else its lemma's shoresh — לבבך → לבב); else the way Torah most often reads that surface form (its commonest lemma decides, so אשר the particle has no root); else a root the asker named, if Torah knows it. A word in the verse that L1 gives no root has none, whatever a homograph elsewhere carries. Unknown words yield nothing. - Roots are rendered as L1 records them: two letters stay two letters. - binyan is null unless a verb stands in the scoped verse. - L1 is found via L1_MOUNT_POINT, not the literal l1/ relative to cwd — which is why parse_tree was null on the pod. - Adds "surface" and "derivation" to each root (verse|lemma|torah| named_root). 22 new HSpec examples; 55 examples, 0 failures. vav_pipeline: - normalize_root places a lemma-derived root at the word it was heard from (L1 has no shoresh on לבבך to search by). - A binyan is printed only where there is one; "binyan unknown" on a noun claimed a question that does not exist. - test/tablet33_engine_roots_test.exs: the new shape through the router. - liveness_test: clear a halt leaked by halt_monitor_test (the seed 0/191243 flake, present since before tablet 30). 461 tests, 0 failures on seeds 0 42 191243. Verified before push with BOTH built images, the real engine binary and a local PostgreSQL 16 (SSL): Devarim 6:5 → א-ה-ב (Qal, word 1), י-ה-ו, א-ל-ה, כ-ל (words 5,7,9), ל-ב-ב, נ-פ-ש, מ-א-ד; 4 interpretations written to L3, 0 L3_WRITE_FAILED, health healthy. NOT repaired here: the quality of L1's own shoresh field, which the engine is now faithful to — ויהי is recorded as יהי, שמים as שמ, יהוה as יהו, הבאתי as בא. That is the quarry's tablet (scripts/build_l1.py) and it changes the L1 hash; a decision, not a patch. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
d4d0a6fcb6 |
L1 data integrity: preserve the edut whole — Shema, middle letter, ketiv/qere, smikhut
Shemot 25:16 — v'natata el ha-aron et ha-edut asher eten elekha. The edut placed in the aron must be complete. The Masoretic tradition preserves every letter, every enlarged letter, every ketiv/qere pair — because each carries meaning the scribe cannot reconstruct. The previous build_l1.py silently dropped: - enlarged letters encoded as <seg type="x-large"> nested in <w> → the Shema was corrupt: שמ instead of שמע, אח instead of אחד → the middle letter of Torah was corrupt: גח instead of גחון → the Zelophchad nun was missing: משפט instead of משפטן - ketiv/qere dual readings encoded as <note type="variant">/<rdg type="x-qere"> → the spec committed to preserving both; the code returned [] - smikhut (construct state) pairs marked in morphology codes → the spec committed to extracting them; the code returned [] Fixes: - collect_word_text() walks all nested <seg> children of <w> and records large_letters / small_letters metadata with character offsets. - parse_verse() recognizes <w type="x-ketiv"> followed by <note>, extracts both the ketiv and the qere readings, stores a ketiv_qere list on the verse. - _extract_smikhut() scans words for construct-state morph codes (ending in "c" on N/A primary segments, excluding pronominal suffixes) and records construct/absolute pairs. - L1 SHA-256 hash updated everywhere: integrity.sha256, l1_reader.ex, shoresh-engine's Luchot.Firmware, its test, KOHEN.md. Torah-wide results after fix: - 4 enlarged letters preserved (was 0): Shema ayin, Shema dalet, gachon vav (middle of Torah), Zelophchad nun - 67 ketiv/qere pairs captured (was 0) - 9,203 smikhut pairs extracted (was 0) Elixir updates: - l1_reader.ex: normalize_verse now surfaces ketiv_qere, smikhut, and per-word large_letters/small_letters. New type specs. New extract_large_letters/1 helper. extract_ketiv_qere and extract_smikhut now return real data instead of []. - step31_shema_test.exs: replaced placeholder asserts with real integrity checks. Four new tests verify the Shema word is complete (שמע not שמ), echad is complete (אחד not אח), the enlarged letters are marked, the middle letter of Torah is preserved, and ketiv/qere pairs from Bereishit 8:17 are both captured. Build script: - build_l1.py no longer rmtrees the entire l1/ directory (preserves l1/README.md). Only regenerates torah/ + build_report.json + integrity.sha256. - Accepts SHORASHIM_SOURCE_DATA env var or CLI arg for morphhb path. Test counts: - Elixir: 260 (was 254), 0 failures - Haskell: 33, 0 failures - Prolog: 195, 0 failures The system that can hear שמע correctly has passed its own shema test. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
ae78ed26d1 |
Phase 1 review corrections — four bugs fixed
- relationships.pl: Replace recursive complementary_mitzvot/2 symmetry clause with explicit reverse facts (infinite loop in Prolog) - mitzvot.pl: Remove duplicate mitzvah(2, prohibition, no_other_gods) that caused double-counting in total_encoded/1 - resolve.pl: Add missing use_module(root_meanings) import — root_domain/2 was undefined, failing resolve_produces_result test - shoresh-engine: Generate and commit cabal.project.freeze for exact version pinning (Construction spec §1) All tests pass: 76 Elixir, 33 Haskell, 57 Prolog — 0 failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
c67672777b |
Step 14: Connect components — chamishim karsay zahav
Three connections built and tested: - Haskell Shoresh Engine via Erlang Port (JSON lines over stdin/stdout) - Prolog Talmudic Engine via Unix domain socket (JSON over /tmp/shorashim/talmudic.sock) - Erlang Sanhedrin via native BEAM calls New: Server.hs (JSON-line server loop), json_bridge.pl + socket_server.pl (Prolog socket interface), ShoreshEnginePort + TalmudicEngineSocket + SanhedrinClient (Elixir GenServer wrappers). BereishitCycle now routes unresolved cases through Talmudic Engine and Sanhedrin. All connections gracefully degrade — pipeline falls back to L1 data when engines unavailable. 46 Elixir tests, 33 Haskell tests, 57 Prolog tests — 0 failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
80ec364da6 |
Phase 1-2 build: Steps 5-6, 8-13
Shoresh Engine (Haskell, Step 5) - 12 modules: Types, Lexicon, Binyanim, Teamim, Gematria, Graph, KetivQere, Smikhut, Havdalah, Kriah, KiTov, Firmware - 33 EUnit tests, 0 failures - Firmware module verifies L1 SHA-256 hash at startup Talmudic Engine (SWI-Prolog, Step 6) - 15 modules: halt, reasoning, specification, interface - 57 PlUnit tests, 0 failures - Three cardinal halt conditions: avodah_zarah, shfichut_damim, gilui_arayot Vav Pipeline (Elixir, Steps 8-11) - 14 modules: BereishitCycle, Shema, Cloud, Manna, L1Reader, Specification, HaltConditions, ShabbatTimer, CycleLog, Chatzotzrot, ShoreshEngineClient, TalmudicEngineClient, Application - 46 ExUnit tests, 0 failures - Nishma-first architecture: hears before it speaks Sanhedrin Framework (Erlang/OTP, Step 12) - 8 modules: sanhedrin_app, sanhedrin_sup, escalation, panel_sup, panel, judge, clerk, halt_monitor - 46 EUnit tests, 0 failures (includes fix: rejected outcome now reachable) - Panel sizes: 1/3/23/71 — unanimous capital guilty → acquit (Sanhedrin 17a) - Minority opinions append-only, never deleted Korban Processor (Python, Step 13) - 6 modules: korban, shechitah, semichah, zerikah, haktarah, router Builder tooling: AGENTS.md, opencode.json, memory/, src/tools/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |