Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
606 commits
Select commit Hold shift + click to select a range
c662562
Merge pull request #58 from palmoni5/fix/acronymizer-otzaria-fork
Y-PLONI Sep 30, 2026
c73c207
Update release manifest [skip ci]
github-actions[bot] Sep 30, 2026
1b99183
סכמת DB 7: טקסט השורות דחוס ב-zstd עם מילון קבוע
palmoni5 Oct 1, 2026
48c5c97
הדחיסה נכנסת לסכמה 6 עצמה, בלי סכמה 7
palmoni5 Oct 1, 2026
2bac7b9
QA: תקרת אורך שורה זהה לאפליקציה, והערות שמסבירות את חוזה סכמה 6
palmoni5 Oct 1, 2026
623dca4
דחיסת השורות: האימות מפענח כל מסגרת, גם אלה שהריצה דילגה עליהן
palmoni5 Oct 1, 2026
14cf58a
דחיסת השורות: CDict ו-DDict אחד לכל ה-workers
palmoni5 Oct 1, 2026
a6d9bdd
מילון הדחיסה: מה ידוע על האימון שלו
palmoni5 Oct 1, 2026
52fb1be
מילון הדחיסה: מזהה 32768 במקום 908519771
palmoni5 Oct 1, 2026
1976330
fix(compression): validate the full signed row key range
Y-PLONI Oct 2, 2026
9a5d30f
Merge pull request #62 from palmoni5/feat/line-content-zstd-dict
Y-PLONI Oct 2, 2026
e80ae47
Update release manifest [skip ci]
github-actions[bot] Oct 2, 2026
140f031
DB מלא מעל מגבלת GitHub מתפרסם בחלקים, וכל הצרכנים מחברים אותו
palmoni5 Oct 1, 2026
47738e4
בדיקות ההכרזה: חוזה שלב הקטלוגים בצורת stream_full_db
palmoni5 Oct 1, 2026
ca51ab2
test(prefetch): preserve copy failures across sandbox hosts
Y-PLONI Oct 2, 2026
3cf0b8e
Merge pull request #63 from palmoni5/feat/split-full-db
Y-PLONI Oct 2, 2026
18670e9
בדיקות דחיסת השורות: וקטור golden לאפליקציה, ודלתא אמיתית בין שני מסד…
palmoni5 Oct 1, 2026
c3dc868
Merge pull request #64 from palmoni5/tests/line-content-zstd-vectors
Y-PLONI Oct 2, 2026
0d61c1a
book_moves: מזהה יציב מה-build state לתיקיית יעד שנוצרת
Y-PLONI Oct 1, 2026
e909f99
אור הישר/סדר נשים חוזר למזהה 1478, וכללי הש״ס מקבלת מזהה חדש
Y-PLONI Oct 1, 2026
e68fcf7
book_moves: תיקיית יעד שיש בה גם ספרי אוצריא שומרת על המזהה שלה
Y-PLONI Oct 1, 2026
8d2bd4b
פרקים בירושה: כותרת דף נתלית בפרק שהעמוד שלה בו, ופרק נפתח בדף הראשון…
Y-PLONI Oct 1, 2026
0739db1
פרקים בירושה: פרק לא נפתח מעל שורת "הדרן" של הפרק הקודם, ובסיס שקישור…
Y-PLONI Oct 2, 2026
4db583a
פרקים בירושה: סדר האחים לפי מזהה הוא סדר השורות
Y-PLONI Oct 2, 2026
b6502fb
תיקון(sefariasqlite): בלי "(א)" כפול לפני סימון שכבר קיים בשורה
Y-PLONI Oct 1, 2026
f1d55a7
תיקון(linker): ה-linker מקבל שורת ספריא בלי סימון ה-"(א)" שבראשה
Y-PLONI Oct 1, 2026
f3c0574
תיקון(sefariasqlite): "(א)" יורד רק כשהשורה נושאת את המספר שלה עצמה
Y-PLONI Oct 1, 2026
85910cb
תיקון(linker): גם ספרי אוצריא עם סימוני "(א)" רבים מגיעים ל-linker בל…
Y-PLONI Oct 1, 2026
3a1f96b
תיקון(sefariasqlite): עוד צורות של סימון, ודיבור מודגש שנראה כמספר לא…
Y-PLONI Oct 2, 2026
bec7e35
תיקון(sefariasqlite): סימון שנכתב בצורה אחרת מבטל את "(X)" רק בחלק שמ…
Y-PLONI Oct 2, 2026
6290c74
שיפור(linker): DumpLines כותב כל ספר שורה אחר שורה, בלי להחזיק אותו ב…
Y-PLONI Oct 2, 2026
0369bdf
fix(havrouta): אזהרה כשעיצוב דולף מפיל את ההתאמה של ספר חברותא
Y-PLONI Oct 1, 2026
8bcd85f
fix(havrouta): ציטוט מודגש עם תג פנימי נקרא, וקישור שהחטיא את ציטוטו …
Y-PLONI Oct 1, 2026
e73f971
fix(havrouta): האזהרה עולה גם כשספר חברותא קורס ל-0 קישורים, ומגיעה ל…
Y-PLONI Oct 1, 2026
1ddec4e
feat(havrouta): חברותא על שקלים מקושר לתלמוד ירושלמי שקלים לפי פרק והלכה
Y-PLONI Oct 1, 2026
44627fc
תיקון(sefariasqlite): כיוון וסוג של קישורי פירוש-על-פירוש עמידים לתזו…
Y-PLONI Oct 2, 2026
fcbd8a2
כינויים: ספר ששמו שונה שומר את הכינויים שנשמרו תחת שמו הקודם
Y-PLONI Oct 2, 2026
17d3c05
כינויים: ספר ששמו שונה נבחן לפי השורות השונות שלו, לא לפי מספר השורות
Y-PLONI Oct 2, 2026
21c3d6c
קורא אוצריא: הסרת BOM מתחילת קבצי ספרים, הערות ו-JSON
Y-PLONI Oct 2, 2026
83dc512
ספריא: תיקון שמות פרקים ג-ד ברי"ף מגילה
Y-PLONI Oct 2, 2026
c3a1b91
seedGenerations: הדורות מ-ForDB/book_info.csv במקום generations.csv
palmoni5 Oct 1, 2026
c9ec56c
שולחן ערוך: נושא הסימן בשורה מודגשת משלו לפני סעיף א
palmoni5 Sep 30, 2026
e754963
fix(sefariasqlite): preflight generation archive migration
Y-PLONI Oct 3, 2026
ffe8790
שולחן ערוך: גם "ובו סעיף אחד" בשורה משלו, וכותרות מפנות לשורת הנושא
palmoni5 Sep 30, 2026
16d796a
test(sefariasqlite): pin valid build state in archive CLI fixtures
Y-PLONI Oct 3, 2026
6e630a2
Merge pull request #66 from Otzaria/weekly-fixes-2026-10-01
Y-PLONI Oct 3, 2026
c3e95e0
שולחן ערוך: פיצול נושא הסימן לפי ה-<br> של ספריא
Y-PLONI Oct 4, 2026
15f22c4
ספריא: דיבור המתחיל ופרשנות מסווגים לפי סוג הספר
palmoni5 Oct 4, 2026
8b1ee83
Merge pull request #65 from Otzaria/feat/book-info-generations
Y-PLONI Oct 3, 2026
936e337
feat(vectors): a GPU worker for the sidecar's external embedding inte…
Y-PLONI Oct 2, 2026
496a118
נושא הסימן בשורה משלו גם בעוד שבעה ספרים מספריא
Y-PLONI Oct 4, 2026
278541b
Merge pull request #69 from palmoni5/fix/sefaria-provenance-link-types
Y-PLONI Oct 4, 2026
8472f3b
feat(vectors): present a whole-library run as a v2 shard
Y-PLONI Oct 2, 2026
ab95cdf
Merge pull request #61 from palmoni5/feat/shulchan-aruch-siman-topic-…
Y-PLONI Oct 4, 2026
8508c32
feat(vectors): pins, and an idempotent bootstrap of the build machine
Y-PLONI Oct 2, 2026
6a435ed
feat(vectors): build_library_vectors.sh, the release build by hand or…
Y-PLONI Oct 2, 2026
ef6594d
ci(vectors): build-library-vectors.yml after the index build, with it…
Y-PLONI Oct 2, 2026
0abf0b8
feat(vectors): plan with export_semantic_plan at b946633; the v30 dry…
Y-PLONI Oct 2, 2026
c745590
fix(vectors): publish vectors-<tag> through a draft at the library ta…
Y-PLONI Oct 2, 2026
fc32c55
feat(vectors): vectors-<tag> is a prerelease unless LIBRARY_VECTORS_P…
Y-PLONI Oct 2, 2026
b446cf9
fix(vectors): the first build on a clean runner plans every text and …
Y-PLONI Oct 2, 2026
9a216cb
fix(vectors): fetch the model from the mirror at its pinned commit, n…
Y-PLONI Oct 2, 2026
094ea15
fix(vectors): a small update embeds on the CPU with embed-shard, not …
Y-PLONI Oct 2, 2026
c6d6a94
build(vectors): pin the plugin at 1c27820 and the sidecar it pins, bf…
Y-PLONI Oct 3, 2026
77649bb
build(vectors): bootstrap builds validate_semantic_vectors and hands …
Y-PLONI Oct 3, 2026
9863744
feat(vectors): nothing is published unless validate_semantic_vectors …
Y-PLONI Oct 3, 2026
e0a0653
ci(vectors): run the library-vectors suites on pull requests
Y-PLONI Oct 3, 2026
6e429b5
build(vectors): pin the plugin at 78ff9f5 and its sidecar at 76900fd
Y-PLONI Oct 3, 2026
6585a8d
build(vectors): pin the plugin at 45831a3 and its sidecar at 5d71ae5
Y-PLONI Oct 4, 2026
68eb41f
fix(vectors): build vectors only from an index whose provenance is th…
Y-PLONI Oct 4, 2026
96bb628
fix(vectors): a --state or --work path with spaces or odd characters …
Y-PLONI Oct 4, 2026
60115a6
fix(vectors): hash the release-files manifest from stdin, so a backsl…
Y-PLONI Oct 4, 2026
dfbe2ee
test(vectors): cover the driver's anonymous path, through a stub curl
Y-PLONI Oct 4, 2026
b4f31d3
fix(vectors): verify the warehouse, and rebuild a bad index, before t…
Y-PLONI Oct 4, 2026
e1c88ea
test(vectors): the stub curl answers as GitHub and curl do, so fetch'…
Y-PLONI Oct 4, 2026
b5814cb
build(vectors): pin the plugin at 62b2ed1 and its sidecar at 2663873
Y-PLONI Oct 4, 2026
53b0947
fix(vectors): protect persistent state from scratch cleanup
Y-PLONI Oct 4, 2026
d180842
build(vectors): pin reviewed sidecar and plugin fixes
Y-PLONI Oct 4, 2026
009a67e
Merge pull request #67 from Otzaria/library-vectors
Y-PLONI Oct 4, 2026
2ca2fe0
עוגני מפרשים לפי תווית בלבד: לפי המספר המודפס של ההערה
palmoni5 Oct 3, 2026
3543fd8
Merge pull request #68 from palmoni5/fix/inline-anchor-printed-label
Y-PLONI Oct 4, 2026
20d6cdd
כינויים: כשל בקריאת ה-Acronymizer מפיל את הבנייה, ובדיקת QA 9 על book…
palmoni5 Sep 30, 2026
b017e33
Merge pull request #59 from palmoni5/fix/acronyms-fail-loud
Y-PLONI Oct 4, 2026
0549f2f
כינויים: ההערה על carryAcronymsAcrossRenames מתאימה לכך שכשל בקריאת ה…
palmoni5 Oct 4, 2026
e60dfa9
Update release manifest [skip ci]
github-actions[bot] Oct 4, 2026
cfc52aa
טיפול בהכנה לריצת הוקטורים
Y-PLONI Oct 5, 2026
9f406b0
Update release manifest [skip ci]
github-actions[bot] Oct 5, 2026
d715be2
build(vectors): pin search engine v3.1.0 and its sidecar
Y-PLONI Oct 5, 2026
7bc8960
Update release manifest [skip ci]
github-actions[bot] Oct 5, 2026
095f67c
fix(vectors): plan and validate a schema 5 index with its release DB
Y-PLONI Oct 5, 2026
d34f7d4
Update release manifest [skip ci]
github-actions[bot] Oct 5, 2026
29b9eab
Fix 10 stale entries in books blacklist to match current Sefaria titles
Y-PLONI Oct 7, 2026
e46bb61
feat(blacklist): weekly check that every blacklist line still matches…
Y-PLONI Oct 8, 2026
64562fb
Books blacklist: follow Sefaria title changes
github-actions[bot] Oct 8, 2026
2ca637f
build: upgrade to Gradle 9.8.0
Y-PLONI Oct 8, 2026
bc00975
ci: require Gradle 9.8.0 on the durable runners
Y-PLONI Oct 8, 2026
f57d431
fix(dao): drop kotlinx-coroutines-test from commonMain
Y-PLONI Oct 8, 2026
053b278
fix(sefariasqlite): translate English section names leaking into Hebr…
Y-PLONI Oct 8, 2026
5a1ba0d
fix(sefariasqlite): stop orienting links between reference works and …
Y-PLONI Oct 8, 2026
5bdbd9b
fix(sefariasqlite): resolve authors with an empty Hebrew name
Y-PLONI Oct 8, 2026
3582a2d
fix(sefariasqlite): name the Maharsha in his Talmud commentaries' titles
Y-PLONI Oct 8, 2026
c6e2444
ci(release): pick the durable Gradle toolchain per checked-out tree
Y-PLONI Oct 8, 2026
36164f0
fix(sefariasqlite): fail when ForDB names a renamed book by its forme…
Y-PLONI Oct 8, 2026
4eadbc9
Merge pull request #74 from Otzaria/fix/sefaria-section-names-upstream96
Y-PLONI Oct 8, 2026
6475730
fix(qa): check book acronyms against the Acronymizer file the build used
Y-PLONI Oct 10, 2026
0d4b447
Update release manifest [skip ci]
github-actions[bot] Oct 10, 2026
1d2a6b7
fix(sefariasqlite): catch category descriptions of emptied library fo…
Y-PLONI Oct 9, 2026
1e5a56e
Merge pull request #76 from Otzaria/fix/fordb-gate-library-tree
Y-PLONI Oct 10, 2026
9ea54a6
perf(linker): Phase-2 source-line lookups on one persistent connection
Y-PLONI Oct 10, 2026
f3cc546
fix(release): wait out a lagging release listing when resolving the d…
Y-PLONI Oct 11, 2026
b35d85b
perf(release): reap the early buildstate upload at the start of publish
Y-PLONI Oct 11, 2026
59d5cc7
perf(release): compress and start uploading the buildstate right afte…
Y-PLONI Oct 11, 2026
7d0f15e
Merge pull request #78 from Otzaria/perf/build-speedups
Y-PLONI Oct 11, 2026
920cc94
Update release manifest [skip ci]
github-actions[bot] Oct 11, 2026
ecf39f7
fix(sefariasqlite): drop translator footnotes from Noda BiYehudah I, …
kdroidFilter Oct 8, 2026
3016cba
fix(sefariasqlite): link the whole Darkhei Moshe to the Tur through t…
kdroidFilter Oct 8, 2026
9ab88e3
fix(sefariasqlite): leave Choshen Mishpat out of the Darkhei Moshe an…
Y-PLONI Oct 10, 2026
2b61b7d
fix(sefariasqlite): stop labelling Mishnah Berurah segments
kdroidFilter Oct 8, 2026
19250f4
fix(sefariasqlite): keep the Mishnah Berurah's {א} markers as Sefaria…
Y-PLONI Oct 10, 2026
25136c1
refactor(sefariasqlite): let upstream's Mishnah Berurah rule replace …
Y-PLONI Oct 10, 2026
e0c8ddf
fix(sefariasqlite): number and index Midrash Rabbah paragraphs
kdroidFilter Oct 8, 2026
6c5f73f
fix(sefariasqlite): take the Midrash Rabbah books out of the Simanim …
Y-PLONI Oct 10, 2026
53db5f7
fix(sefariasqlite): anchor the Darkhei Moshe through the Tur's own Be…
Y-PLONI Oct 11, 2026
ef3bae6
fix(generator): keep book ids when Otzaria re-keys a book
kdroidFilter Oct 10, 2026
f45e609
fix(generator-common): move an aliased book's id to its new key inste…
Y-PLONI Oct 11, 2026
980ab05
fix(generator-common): keep an id by content only when the match is u…
Y-PLONI Oct 11, 2026
49c6a6b
fix(otzariasqlite): plan the books to alias with our importer's own s…
Y-PLONI Oct 11, 2026
9004971
fix(otzariasqlite): keep and check only the ids of the books the prev…
Y-PLONI Oct 11, 2026
187ddd4
fix(generator-common): follow a renamed book through every later rename
Y-PLONI Oct 11, 2026
0642fb5
fix(otzariasqlite): fail a build whose books the next one could not tell
Y-PLONI Oct 11, 2026
2b5e5c3
fix(generator-common): let a renamed book take a key an older build had
Y-PLONI Oct 11, 2026
4b610aa
Merge pull request #77 from Otzaria/feat/upstream-100-103
Y-PLONI Oct 11, 2026
e3cffc3
עדכוני ספרייה לmd בrelease
Y-PLONI Oct 12, 2026
ca827b4
רשימה שחורה: מעשה רוקח על המשנה (ספריא) - הוחלף בנוסח ויקיטקסט המלא ב…
Y-PLONI Oct 12, 2026
b809c8a
הסרת מהרי ברונא
Y-PLONI Oct 13, 2026
fc6fbff
הסרת תיבת גמא
Y-PLONI Oct 14, 2026
1b0d736
fix(linker): end a LINKER anchor after the bracket its citation opened
dudua99 Oct 12, 2026
f628f4b
fix(linker): complete nested anchors without crossing notes or citations
Y-PLONI Oct 15, 2026
2eec7c4
Merge pull request #87 from dudua99/fix/linker-dangling-paren-2366
Y-PLONI Oct 15, 2026
b7567e8
fix(sefariasqlite): letter Be'er HaGolah notes as the Shulchan Arukh …
Y-PLONI Oct 15, 2026
c4eceb4
Merge pull request #88 from Otzaria/fix/beer-hagolah-base-text-letter…
Y-PLONI Oct 15, 2026
faf3518
feat(buildstate): keep ids across Sefaria renames and Sefaria/Otzaria…
Y-PLONI Oct 15, 2026
9dcd327
fix(otzariasqlite): tell the Sefaria books gone by id, not by DB title
Y-PLONI Oct 15, 2026
4652360
fix(buildstate): never let a cross-source alias give one id to two books
Y-PLONI Oct 15, 2026
b442db2
fix(buildstate): never let a key gone since make a Sefaria takeover a…
Y-PLONI Oct 16, 2026
571e4b5
Merge pull request #90 from Otzaria/feat/sefaria-book-aliases
Y-PLONI Oct 16, 2026
302f114
ספריא: הסרת שם המסכת עצמה אחרי לקמן/לעיל בפירושי הבבלי
palmoni5 Oct 11, 2026
ea9329b
ספריא: ספרות עזר בבבלי אחרי המפרשים ולפני מראי מקומות
palmoni5 Oct 11, 2026
be3f08a
ספריא: כותרת "הלכות" בטור בשורה משלה מעל סעיף א
palmoni5 Oct 12, 2026
233389d
ספריא: טור ושו"ע כקישור מקביל על כל הסימן
palmoni5 Oct 13, 2026
1e8894e
ספריא: מספור סעיפי שולחן ערוך הרב בהלכות רבית ובחושן משפט
palmoni5 Oct 13, 2026
2f7a454
ספריא: מספרים עד 1199 בתי"ו כפולה (תתר) ולא "א "
palmoni5 Oct 13, 2026
596bd4d
Merge pull request #79 from palmoni5/fix/sefaria-same-tractate-refs
Y-PLONI Oct 16, 2026
2de1c09
וקטורים: בניית משפחת החלונות לצד המשפחה הקיימת, כל אחת ב-release משלה
palmoni5 Oct 12, 2026
fcc5485
וקטורים: מקום פנוי לכל משפחה, הערות ה-release של המשפחה הקיימת ללא שי…
palmoni5 Oct 12, 2026
da4d63a
וקטורים: הצמדת המנוע לענף החלונות שנדחף
palmoni5 Oct 12, 2026
4afd57d
fix(vectors): preserve occurrence ledgers and expose bounded text cov…
Y-PLONI Oct 16, 2026
0bcb6b3
fix(vectors): distinguish standalone character coverage from borrowed…
Y-PLONI Oct 16, 2026
dcf85eb
build(vectors): pin occurrence-aware engine and sidecar fixes
Y-PLONI Oct 16, 2026
80c26b2
build(vectors): pin sparse book fingerprint compatibility fix
Y-PLONI Oct 16, 2026
3e0e847
build(vectors): pin strict-clippy-compatible reader updates
Y-PLONI Oct 16, 2026
ec05566
Merge pull request #81 from Otzaria/feat/long-line-windows
Y-PLONI Oct 17, 2026
e586e4c
וקטורים: בנייה מחדש של אינדקס ל-release שכבר פורסמו לו וקטורים אינה נ…
palmoni5 Oct 17, 2026
be5d969
fix(vectors): report secondary draft releases
Y-PLONI Oct 17, 2026
5e6a371
Merge pull request #91 from palmoni5/ci/vectors-skip-existing-release
Y-PLONI Oct 17, 2026
6e63885
Update release manifest [skip ci]
github-actions[bot] Oct 17, 2026
376036e
ספריא: שם המסכת בהפניות לאותה מסכת — בשלוש הצורות שספריא הוסיפה
Y-PLONI Oct 18, 2026
c49a9ad
ספריא: שם המסכת בהפניות — כתיב מספר תקני, ירושלמי מעבר לתגית, סריקה ל…
Y-PLONI Oct 18, 2026
760523a
ספריא: שם המסכת בהפניות — בלי גלישת מחסנית ברצף רווחים או תגיות אחרי …
Y-PLONI Oct 18, 2026
6864863
ספריא: שם המסכת בהפניות — רווח כמו במימוש ה-Python, ירושלמי בכל אותיו…
Y-PLONI Oct 18, 2026
fc4b0b8
ספריא: שם המסכת בהפניות — "התוספ'" הן התוספות, לא התוספתא
Y-PLONI Oct 18, 2026
a8c6b63
Merge pull request #92 from Otzaria/fix/sefaria-same-tractate-three-f…
Y-PLONI Oct 18, 2026
43dd9f4
fix(linker): link LINKER targets that name a whole daf or section (ot…
Y-PLONI Oct 18, 2026
6171eaa
fix(release): overlay SefariaRangeRefs.kt in Phase-2 recovery
Y-PLONI Oct 18, 2026
bde403f
Merge pull request #93 from Otzaria/fix/linker-section-targets
Y-PLONI Oct 18, 2026
55bf874
feat(schema): טבלאות book_banner ו-book_protection מחוץ לחוזה סכמה 6
palmoni5 Oct 7, 2026
6bf05ca
feat(patch): ערוץ צד לטבלאות האופציונליות ב-patch ובמניפסט
palmoni5 Oct 7, 2026
c702ddb
feat(generator): seedBookNotices ממלא את book_banner ו-book_protectio…
palmoni5 Oct 7, 2026
e410426
fix(patch): ה-applier דוחה DDL אופציונלי שאינו CREATE TABLE IF NOT EX…
palmoni5 Oct 7, 2026
6247117
ci(release): קלט אופציונלי של מאגר ספרים פרטי בבניית ה-release
palmoni5 Oct 7, 2026
4bf5cf3
fix(generator): שער ForDB מזהיר על שורות הגנה ללא ספר, הבנייה נכשלת ג…
palmoni5 Oct 7, 2026
befc796
fix(patch): בדיקת foreign_key_check לכל טבלה אופציונלית שהוחלפה
palmoni5 Oct 7, 2026
2ac97f7
ci(release): הטוקן של המאגר הפרטי בשלב נפרד, ובדיקות מיזוג לפני כתיבה
palmoni5 Oct 7, 2026
191959d
test(generator): עדכון book_protection.csv לגרסה הנוכחית ב-otzaria-li…
palmoni5 Oct 7, 2026
798350a
feat: שלב buildLineDivineNameIndex וטבלה אופציונלית line_divine_name
palmoni5 Oct 12, 2026
1785f27
feat(divine): יה, צבאות, אלוה ואֵל בסידור לפי רשימות מאומתות
palmoni5 Oct 12, 2026
0684c73
סכמת DB 7: book_banner, book_protection, line_divine_name ו-line_note…
palmoni5 Oct 14, 2026
a52cd6f
line_note: שלב buildLineNoteIndex מוציא את גופי ההערות מטקסט השורה
palmoni5 Oct 14, 2026
29d833b
הערות על חברותא נבחנות למיזוג כמו כל ספר הערות נלווה
palmoni5 Oct 14, 2026
e2da2b7
patch_anchor_schema: התיעוד חוזר לכך שכל טבלה ב-DB היא טבלת patch
palmoni5 Oct 14, 2026
12b58ad
line_note: סינון מוקדם רחב כמו המפענח, קיטום עוגני טווח ורווח קשיח כס…
palmoni5 Oct 14, 2026
491e735
מיזוג הערות: הדקדוק של חברותא רק להערות על ספר חברותא
palmoni5 Oct 14, 2026
5db6105
line_note: sup רגיל שצמוד לגוף ההערה הוא הסמן שלה
palmoni5 Oct 14, 2026
09af51e
סכמה 7: line_note.charPos והטבלה line_note_divine_name בחוזה
palmoni5 Oct 14, 2026
64ea04a
line_note_divine_name: שלב השמות הקדושים סורק גם את גופי ההערות
palmoni5 Oct 14, 2026
434f142
linker: dumpLines ו-Phase-2 קוראים את השורה עם גופי ההערות במקומם
palmoni5 Oct 14, 2026
2fe1efd
line_note: תג footnote שבתוך sup של סמן שייך לסמן ואינו הערה
palmoni5 Oct 14, 2026
d79955e
סכמה 7: book.contentHash — טביעת 64 ביט של טקסט השורות וההערות של כל ספר
palmoni5 Oct 18, 2026
916ec95
fix(notes): keep rehydrated bodies outside marker markup
Y-PLONI Oct 18, 2026
65c8693
fix(notes): align schema 7 rehydration across consumers
Y-PLONI Oct 18, 2026
eb2a64f
fix(notes): anchor empty markers behind opening markup
Y-PLONI Oct 18, 2026
4f3ef58
Merge pull request #73 from palmoni5/feat/book-banner-protection
Y-PLONI Oct 18, 2026
093adfd
וקטורים: מצב auto — דלתא למשפחת החלונות ב-release נפרד, וגיבוי ה-ledger
palmoni5 Oct 17, 2026
ea6b06e
וקטורים: משפחת החלונות ב-rot192-i8i4 עם סף כינוי 0.99, וסיבוב מוצמד א…
palmoni5 Oct 17, 2026
6a8aacd
וקטורים: הצמדת ה-sidecar ל-730ba8e (rot192-i8i4, fit-rotation, סף כינוי)
palmoni5 Oct 18, 2026
f706207
וקטורים: תיקוני QA — דלתא בלי לתקוע את השרשרת, אימות שרשרת עד 8 צעדים…
palmoni5 Oct 18, 2026
802fd48
וקטורים: הצמדת ה-sidecar ל-541f7f6 וה-plugin ל-62b40db
palmoni5 Oct 18, 2026
e2a02a2
fix(vectors): pin merged schema 7 engine and matching sidecar
Y-PLONI Oct 18, 2026
0abbba7
Merge pull request #94 from palmoni5/feat/vectors-deltas
Y-PLONI Oct 18, 2026
f628a2b
ci(release): generatorHeap 8g → 13g
Y-PLONI Oct 19, 2026
726d22f
feat(patch): hash schema-7 rows in primary-key order
Y-PLONI Oct 20, 2026
2b3c5df
fix(patch): no default hash row order; CLIs hash by DB schema
Y-PLONI Oct 20, 2026
24ccba2
fix(notes): keep link_anchor offsets on the full line with note bodies
Y-PLONI Oct 20, 2026
9eca2e6
fix(notes): fail the build on a line whose offsets would not map back
Y-PLONI Oct 20, 2026
3ef6aa0
ci(release): refuse recovery onto a payload that remaps link_anchor
Y-PLONI Oct 20, 2026
e6c035b
feat(notes): compress line_note.body with the line text zstd dictionary
Y-PLONI Oct 20, 2026
b6f2e9b
ci(index): refuse compressed note bodies with an engine that skips them
Y-PLONI Oct 21, 2026
784a350
test(notes): cover a compression run interrupted inside line_note
Y-PLONI Oct 21, 2026
2ee8572
feat(notes): store line_note.hasMarker instead of the marker text
Y-PLONI Oct 21, 2026
a16ee2a
fix(notes): Dart word boundaries in the readers' rule, strict hasMark…
Y-PLONI Oct 21, 2026
9db5643
feat(divine): pack divine-name length, kind and source into one span …
Y-PLONI Oct 20, 2026
5c5a265
fix(divine): refuse a pre-pack divine-name table by name
Y-PLONI Oct 21, 2026
5a6fe06
fix(divine): require divine_name_overrides.csv
Y-PLONI Oct 21, 2026
4470b0e
ci(delta): note that inputs_from=released needs a schema-7 ForDB archive
Y-PLONI Oct 21, 2026
94d3cff
feat(banner): store banner texts once under stable ids
Y-PLONI Oct 20, 2026
3e01cab
test(banner): 7 to 7 deltas that remove, swap and orphan banner rows
Y-PLONI Oct 21, 2026
882f1b1
fix(notices): fail the build when a notices CSV is missing
Y-PLONI Oct 21, 2026
595f797
test(patch): the schema-7 oracle creates every table with its real DDL
Y-PLONI Oct 21, 2026
dab88ac
docs(release): re-wrap the banners and protection paragraph
Y-PLONI Oct 21, 2026
3fb9623
fix(linker): support historical recovery note schemas
Y-PLONI Oct 22, 2026
3a725d6
Merge pull request #98 from Otzaria/schema7/hardening
Y-PLONI Oct 22, 2026
1b372d5
ci(release): tmpfs 20G → 26G, memory gate 30 → 44 GiB
Y-PLONI Oct 22, 2026
ea976b8
feat(banner): books with the same banner text share its id
palmoni5 Oct 22, 2026
bed2ec8
Update release manifest [skip ci]
github-actions[bot] Oct 22, 2026
3c56cc0
alt_toc: אחים על אותה שורה נשמרים כולם (otzaria#3181)
palmoni5 Oct 24, 2026
e8a4992
Merge pull request #101 from palmoni5/fix/alt-toc-shared-line-3181
Y-PLONI Oct 25, 2026
3cd2257
Update release manifest [skip ci]
github-actions[bot] Oct 25, 2026
fcddb36
fix(sefariasqlite): canonical author name on the book's author line
Bshlomecha Oct 22, 2026
ce2cd34
fix(sefariasqlite): preserve books and manual links during author map…
Y-PLONI Oct 25, 2026
8378135
Merge pull request #99 from Bshlomecha/fix/sefaria-author-line-canonical
Y-PLONI Oct 25, 2026
024823f
אינדקס הספרייה: מתפרסם שלם כשהוא נכנס בנכס אחד
palmoni5 Oct 26, 2026
b6ae482
אינדקס הספרייה: Rust בתמונת הבנייה במבנה .rustup/.cargo
palmoni5 Oct 26, 2026
2521b28
Update release manifest [skip ci]
github-actions[bot] Oct 26, 2026
1bc25a5
אינדקס הספרייה: יישור ל-Flutter 3.47.7 ולבניית Linux הנוכחית של אוצריא
palmoni5 Oct 26, 2026
8cf35d9
וקטורי הספרייה: הצמדת התוסף למנוע 6.0.0
palmoni5 Oct 26, 2026
5e5982c
Update release manifest [skip ci]
github-actions[bot] Oct 26, 2026
2c85f1b
Update release manifest [skip ci]
github-actions[bot] Oct 26, 2026
88c2067
וקטורים: רף G6 נפרד למשפחת החלונות (0.97)
palmoni5 Oct 26, 2026
6f5f873
Update release manifest [skip ci]
github-actions[bot] Oct 27, 2026
e93fe01
sefariasqlite: מיזוג קטגוריות רקורסיבי, וסתירת תיאורים נפתרת כש־ForDB…
YOSEFTT Oct 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
13 changes: 13 additions & 0 deletions .github/contracts/linker_relink_timeouts_v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"contractVersion": 1,
"workflow": "relink.yml",
"timeouts": {
"relink": {
"kaggle": 90,
"local": 2880,
"server": 480
},
"resolve": 480,
"publish": 30
}
}
6 changes: 6 additions & 0 deletions .github/host/otzaria-pipeline.tmpfiles.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Install on every shared heavy host as /etc/tmpfiles.d/otzaria-pipeline.conf.
d /run/lock/otzaria 1777 root root -
f /run/lock/otzaria/host-heavy.lock 0666 root root -
# Linker writes linker-ner.scope.json dynamically as 0644. The sticky
# directory preserves its ownership; this repo only removes it via sudo after
# verifying the complete /proc identity while holding host-heavy.lock.
54 changes: 54 additions & 0 deletions .github/scripts/assemble_split_asset.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# Join the parts split_release_asset.sh wrote, verifying every part and the whole.
# A copy of Otzaria/otzaria tool/release/assemble_split_asset.sh; change both together.
set -euo pipefail

manifest=${1:?usage: assemble_split_asset.sh <manifest.json> [output-file]}
[ -f "$manifest" ] || { echo "manifest not found: $manifest" >&2; exit 1; }

manifest_dir=$(cd "$(dirname "$manifest")" && pwd)
archive_name=$(jq -er '.archive' "$manifest")
[ "$archive_name" = "$(basename "$archive_name")" ] || {
echo "unsafe archive name in manifest: $archive_name" >&2
exit 1
}
output=${2:-$manifest_dir/$archive_name}
[ ! -e "$output" ] || { echo "output already exists: $output" >&2; exit 1; }

expected_count=$(jq -er '.parts | length' "$manifest")
[ "$expected_count" -gt 0 ] || { echo "manifest contains no parts" >&2; exit 1; }

hash_file() {
if command -v sha256sum >/dev/null 2>&1; then
sha256sum "$1" | awk '{print $1}'
else
shasum -a 256 "$1" | awk '{print $1}'
fi
}

while IFS=$'\t' read -r part_name expected_sha; do
[ "$part_name" = "$(basename "$part_name")" ] || {
echo "unsafe part name in manifest: $part_name" >&2
exit 1
}
part="$manifest_dir/$part_name"
[ -f "$part" ] || { echo "missing part: $part_name" >&2; exit 1; }
actual_sha=$(hash_file "$part")
[ "$actual_sha" = "$expected_sha" ] || {
echo "checksum mismatch: $part_name" >&2
exit 1
}
done < <(jq -r '.parts[] | [.name, .sha256] | @tsv' "$manifest")

touch "$output"
for part_name in $(jq -r '.parts[].name' "$manifest"); do
cat "$manifest_dir/$part_name" >> "$output"
done

expected_archive_sha=$(jq -er '.sha256' "$manifest")
actual_archive_sha=$(hash_file "$output")
[ "$actual_archive_sha" = "$expected_archive_sha" ] || {
echo "archive checksum mismatch: $output" >&2
exit 1
}
echo "Reassembled and verified: $output"
318 changes: 318 additions & 0 deletions .github/scripts/blacklist/books_blacklist_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@
#!/usr/bin/env python3
"""Check books_blacklist.txt against the titles the importer will actually see.

The importer drops a Sefaria book when normalizeTitleKey(heTitle or enTitle)
equals the key of a blacklist line (SefariaBlacklists.kt). Nothing complains
when a line stops matching: Sefaria renames a book, or a line was typed with
different punctuation ("תלמוד מהו" vs "תלמוד מהו?"), and the book silently
comes back unless the author blacklist happens to catch it too. Ten lines had
drifted like that by October 2026.

Two title sources are compared:

* export: titles.json of the latest Otzaria/SefariaExport release. That is
the dump the next build imports, so a line must match it.
* live: sefaria.org/api/index. A rename shows up here first, and the export
follows days later. In October 2026 "Learning to Read Midrash" was
"לפשוטו של מדרש" live and still "ללמוד לקרוא מדרש" in the export.

books_blacklist_titles.tsv (next to this script) maps every line to the
English title it blocked when it last matched. The English title is the
book's key in Sefaria and survives Hebrew renames, so a renamed book is found
for certain even after both sources moved on.

With --fix, only certain changes are written:

* add the book's current Hebrew title (export or live) under a line that
blocks it by an old one. The old line stays: it is harmless, and it still
holds if Sefaria reverts.
* replace a line that matches nothing but differs from exactly one title only
in punctuation or spacing (these never matched anything).
* drop a later line whose key duplicates an earlier one.

Anything else is reported with close-match suggestions and fails the run.
Exit codes: 0 clean (possibly after fixes), 1 lines need a decision,
2 a title source could not be fetched (nothing is written).
"""

import argparse
import difflib
import json
import os
import re
import sys
import urllib.request
from dataclasses import dataclass, field
from pathlib import Path

ROOT = Path(__file__).resolve().parents[3]
BLACKLIST = ROOT / "generator/sefariasqlite/src/jvmMain/resources/books_blacklist.txt"
LOCK = Path(__file__).resolve().parent / "books_blacklist_titles.tsv"
EXPORT_TITLES_URL = "https://github.com/Otzaria/SefariaExport/releases/latest/download/titles.json"
LIVE_INDEX_URL = "https://www.sefaria.org/api/index/"
# Both sources list ~6,600 books. A response far below that is truncated, and
# checking against it would call half the blacklist stale.
MIN_TITLES = 5000

LOCK_HEADER = (
"# Maintained by books_blacklist_check.py: blacklist line <TAB> the Sefaria English\n"
"# title it blocked when it last matched. Used to follow Hebrew renames.\n"
)


def normalize_key(value):
"""normalizeTitleKey from SefariaImportText.kt, character for character."""
if value is None or not value.strip():
return None
for quote in ('"', "'", "׳", "״"):
value = value.replace(quote, "")
return re.sub(r"\s+", " ", value.lower()).replace("_", " ").strip()


def loose_key(value):
"""Letters and digits only: what a punctuation-only typo cannot change."""
key = normalize_key(value) or ""
return re.sub(r"[\W_]+", "", key)


def unescape(value):
return value.replace('\\"', '"').replace("\\'", "'")


@dataclass
class Entry:
index: int # position in the file's line list
title: str # as the importer reads it (trimmed, unescaped)

@property
def key(self):
return normalize_key(self.title)


def parse_blacklist(text):
entries = []
for i, raw in enumerate(text.split("\n")):
line = raw.removeprefix("").strip()
if line and not line.startswith("#"):
entries.append(Entry(i, unescape(line)))
return entries


@dataclass
class Result:
adds: list = field(default_factory=list) # (entry, new title, source)
replaces: list = field(default_factory=list) # (entry, new title)
duplicates: list = field(default_factory=list) # (entry, earlier entry)
unresolved: list = field(default_factory=list) # (entry, [suggestions])
obsolete: list = field(default_factory=list) # (entry, en title)
skipped_paths: list = field(default_factory=list)
lock: dict = field(default_factory=dict)

@property
def changed(self):
return bool(self.adds or self.replaces or self.duplicates)


def analyze(entries, export_titles, live_titles, lock):
"""export_titles / live_titles: {English title: Hebrew title}."""
by_key = {}
for source in (export_titles, live_titles):
for en, he in source.items():
for title in (en, he):
k = normalize_key(title)
if k:
by_key.setdefault(k, en)
hebrew_titles = sorted({he for s in (export_titles, live_titles) for he in s.values() if he})
by_loose = {}
for he in hebrew_titles:
by_loose.setdefault(loose_key(he), set()).add(he)

result = Result()
seen = {}
covered = {e.key for e in entries if e.key}
for entry in entries:
if "/" in entry.title or "\\" in entry.title:
result.skipped_paths.append(entry)
continue
if entry.key in seen:
result.duplicates.append((entry, seen[entry.key]))
continue
seen[entry.key] = entry

en = by_key.get(entry.key)
if en is None and entry.title in lock and (lock[entry.title] in export_titles or lock[entry.title] in live_titles):
en = lock[entry.title]
if en is not None:
result.lock[entry.title] = en
if normalize_key(en) in covered:
continue # the English line blocks it under any Hebrew name
for source_name, source in (("export", export_titles), ("live", live_titles)):
he = source.get(en)
if he and normalize_key(he) not in covered:
result.adds.append((entry, he, source_name))
covered.add(normalize_key(he))
if entry.key not in by_key:
result.obsolete.append((entry, en))
continue

candidates = by_loose.get(loose_key(entry.title), set())
if len(candidates) == 1:
new = next(iter(candidates))
if normalize_key(new) in covered:
result.duplicates.append((entry, seen.get(normalize_key(new), entry)))
else:
result.replaces.append((entry, new))
covered.add(normalize_key(new))
en = by_key.get(normalize_key(new))
if en:
result.lock[new] = en
continue

result.unresolved.append((entry, suggest(entry.title, hebrew_titles)))
return result


def suggest(title, hebrew_titles, limit=3):
target = loose_key(title)
loose = {}
for he in hebrew_titles:
loose.setdefault(loose_key(he), he)
picks = [loose[k] for k in difflib.get_close_matches(target, list(loose), n=limit, cutoff=0.6)]
if len(target) >= 6:
for k, he in loose.items():
if len(k) >= 6 and (k in target or target in k) and he not in picks:
picks.append(he)
return picks[:limit]


def apply_fixes(text, result):
lines = text.split("\n")
drop = {entry.index for entry, _ in result.duplicates}
replace = {entry.index: new for entry, new in result.replaces}
after = {}
for entry, new, _ in result.adds:
after.setdefault(entry.index, []).append(new)
out = []
for i, line in enumerate(lines):
if i in drop:
continue
out.append(replace.get(i, line))
out.extend(after.get(i, []))
return "\n".join(out)


def render_lock(entries_text, lock):
rows = [f"{e.title}\t{lock[e.title]}" for e in parse_blacklist(entries_text) if e.title in lock]
return LOCK_HEADER + "".join(row + "\n" for row in rows)


def read_lock(path):
lock = {}
if path.exists():
for line in path.read_text(encoding="utf-8").splitlines():
if line and not line.startswith("#") and "\t" in line:
he, en = line.split("\t", 1)
lock[he] = en
return lock


def fetch_json(url):
request = urllib.request.Request(url, headers={"User-Agent": "seforim-library-ci/1.0"})
with urllib.request.urlopen(request, timeout=120) as response:
return json.loads(response.read().decode("utf-8"))


def fetch_live_titles():
titles = {}

def walk(node):
if isinstance(node, list):
for item in node:
walk(item)
elif isinstance(node, dict):
if "contents" in node:
walk(node["contents"])
elif node.get("title"):
titles[node["title"]] = node.get("heTitle") or ""

walk(fetch_json(LIVE_INDEX_URL))
return titles


def render_report(result, export_count, live_count):
out = [f"Checked against {export_count} export titles and {live_count} live Sefaria titles.", ""]
if result.adds or result.replaces or result.duplicates:
out += ["### Fixed", ""]
for entry, new, source in result.adds:
out.append(f"- added `{new}` under `{entry.title}` (the book's current title, {source})")
for entry, new in result.replaces:
out.append(f"- `{entry.title}` → `{new}` (punctuation/spacing only)")
for entry, earlier in result.duplicates:
out.append(f"- removed duplicate `{entry.title}` (same key as `{earlier.title}`)")
out.append("")
if result.unresolved:
out += ["### Needs a decision", "",
"These lines match no book in the export or on Sefaria, so they block nothing.", "",
"| line | suggestions |", "| --- | --- |"]
for entry, picks in result.unresolved:
shown = "<br>".join(f"`{p}`" for p in picks) or "no close title"
out.append(f"| `{entry.title}` (line {entry.index + 1}) | {shown} |")
out.append("")
if result.obsolete:
out += ["### Old names kept", ""]
for entry, en in result.obsolete:
out.append(f"- `{entry.title}` no longer matches; the book ({en}) is blocked by its current title")
out.append("")
if result.skipped_paths:
out.append(f"{len(result.skipped_paths)} path line(s) not checked.")
if not (result.changed or result.unresolved):
out.append("All lines match a book.")
return "\n".join(out).rstrip() + "\n"


def main():
parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0])
parser.add_argument("--fix", action="store_true", help="write the certain fixes and the lock file")
parser.add_argument("--report", type=Path, help="write the Markdown report here")
args = parser.parse_args()

try:
export_titles = fetch_json(EXPORT_TITLES_URL)
live_titles = fetch_live_titles()
except Exception as e: # noqa: BLE001 - any network/decoding failure means: do not judge
print(f"::error::could not fetch a title source: {e}")
return 2
if not isinstance(export_titles, dict) or len(export_titles) < MIN_TITLES or len(live_titles) < MIN_TITLES:
print(f"::error::title source looks truncated (export {len(export_titles)}, live {len(live_titles)})")
return 2

text = BLACKLIST.read_text(encoding="utf-8")
old_lock = read_lock(LOCK)
result = analyze(parse_blacklist(text), export_titles, live_titles, old_lock)
report = render_report(result, len(export_titles), len(live_titles))
print(report)
if args.report:
args.report.write_text(report, encoding="utf-8")

changed = False
if args.fix:
new_text = apply_fixes(text, result) if result.changed else text
lock = dict(old_lock)
lock.update(result.lock)
new_lock = render_lock(new_text, lock)
if new_text != text:
BLACKLIST.write_text(new_text, encoding="utf-8")
changed = True
if not LOCK.exists() or LOCK.read_text(encoding="utf-8") != new_lock:
LOCK.write_text(new_lock, encoding="utf-8")
changed = True

if os.environ.get("GITHUB_OUTPUT"):
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as f:
f.write(f"changed={'true' if changed else 'false'}\n")
f.write(f"unresolved={len(result.unresolved)}\n")
return 1 if result.unresolved else 0


if __name__ == "__main__":
sys.exit(main())
Loading
Loading