Перейти до змісту

Що вже працює — довідник

Технічний довідник можливостей: команди, джерела, заміри. Для помічника й для того, хто хоче знати подробиці. Людині простими словами — «Як працювати».

Два зрізи їдуть разом із пакетом, тож nysh find "моє село" працює одразу після встановлення — ні сканів, ні відеокарти, ні обходу чужих сайтів:

  • каталог ДАХмО — 9020 справ 47 фондів, роки 1648-2025;
  • поаркушевий покажчик плівок — 62 412 записів, 1594 населені пункти: яке село на яких КАДРАХ якої плівки. Це найкоротша відповідь на «де метрики мого села», і вона не вимагає завантажити жодного байта сканів.

🔴 Зрізи старіють, тож кожна відповідь несе їхню дату й межі покриття (покажчик плівок сьогодні накриває лише Молдову — в інших регіонах дзеркала поаркушевого покажчика немає в принципі). Зібране на місці має пріоритет над вкладеним.

Каталоги й завантаження

Переглядачі архівів (ARCHIUM — обласні та центральні), дзеркало плівок FamilySearch, Wikimedia Commons і онлайн-архів «Бабин Яр» (21 архів України, зокрема книги РАЦС 1921-1946, яких більше ніде не виставляють), зведений покажчик Duck Inspector, каталог книг за селом ridni.org і список альбомів фотоархіву Олександра Волока на Flickr (зйомка РДІА, ДАДО, ДАКО, ГА РФ і друкованих довідників) — за спільним контрактом джерела: search / browse / manifest / fetch; що саме вміє кожне, показує nysh sources. Найцінніше в дзеркалі — поаркушевий покажчик плівки: він відповідає «де метрики мого села» без жодного завантаження. Найцінніше в Commons — повний файл: дзеркала обрізають великі справи в рази (25 МБ проти 771 МБ), і виглядає обрізане як нормальна копія.

nysh find "Ракулешты"                  # де взагалі є щось про село
nysh browse fsfilm moldova             # що лежить у регіоні
nysh get fsfilm "<плівка>" --out . --frames 6-10
nysh crawl archium                     # зібрати каталог справ для пошуку
nysh crawl babynyar                    # те саме для «Бабиного Яру» (~900 запитів)

«Бабин Яр» стоїть за Cloudflare, який відсікає клієнта по відбитку TLS, тож джерело ходить через curl_cffi (pip install "nyshporka[cfshield]"), а без нього — системним curl.

Друковане: Чтиво

Архівна копія е-бібліотеки chtyvo.org.ua на shron.org (~79 тис. відновлених творів): краєзнавство, збірники документів, словники говірок. Пошук іде не лише по назві, а й по тексту книг — але сервер кладе в індекс тільки перші 100 тис. знаків кожного PDF (~70 сторінок) і не індексує DjVu, тож нуль по довгій книзі нічого не доводить. Уривка сервер не дає: знахідка каже «слово є в цій книзі», а сторінку показує текстовий шар, що лягає поруч із завантаженим PDF (<файл>.pdf.text/p0012.txt) і накриває книгу цілком. Файл звіряється з розміром і MD5, які назвав сервер. Твори, чиї файли не відновлено, у копії відсутні — нуль звідси означає «серед відновленого немає».

nysh find '"метричні книги"' --source chtyvo   # * і лапки — синтаксис сервера
nysh get chtyvo "chtyvo:<Автор>/<Твір>" --out data/raw/chtyvo/<твір>
nysh text grep "<регекс>" --dir data/raw/chtyvo/<твір>

Друковане: Internet Archive

Газети діаспори, єпархіальні відомості, пам'ятні книжки — з пошуком по тексту сканів. Кожен збіг приходить із номером листа й вирізкою навколо слова, тож око бачить рядок до завантаження. Межу пошуку задає сам запит (in:<колекція або запис>, year:1900-1920). Індекс шукає лише точне слово: зірка, форми слова й OR тут відмова, а не нуль, а OCR-калік точним словом не ловиться — його знайде нечіткий пошук по тексту, взятому nysh get. Текст звіряється з розміром і MD5 і лягає по листах; --frames бере JPEG листів.

nysh find "Креницька in:svoboda_newspaper" --source ia
nysh get ia ia:podillya_vidomosti/PEV.1900 --out data/raw/ia/PEV.1900          # текст по листах
nysh get ia ia:podillya_vidomosti/PEV.1900 --frames 521-521 --out data/raw/ia/PEV.1900

Що взагалі існує у фонді

Окреме питання від «що вже оцифровано», і саме воно вирішує, чи має сенс замовляти документ в архіві. Складають відповідь збирачі реєстру опису:

nysh registry sources                                  # які збирачі є
nysh registry plan  duck --repo ДАВіО --fond 904       # скільки це коштуватиме
nysh registry collect archium --repo ЦДІАК --fond 224 --fond-id 198
nysh registry rate                                     # чи витримали темп
nysh registry merge --repo ЦДІАК --fond 224            # звести в один реєстр

Приймач збирання — не число рядків. Позиційний розбір таблиці опису вже одного разу віддав 2944 справи з однаковим заголовком, і за кількістю це виглядало успіхом. Тому кожен запуск друкує, скільки рядків мають роки, аркуші й заголовок, і чого джерело не бачить: позиції «вільний номер» і «Справа вибула» лягають окремо — пущені в реєстр, вони стають фантомами в черзі, за якою замовляють документи.

🔴 Duck Inspector — безкоштовний волонтерський сервіс, і його ліміт (5 запитів на 10 с) міряється по клієнту, а не по процесу. Тому запити йдуть через чергу, спільну на всю машину: дві сесії з бездоганною паузою кожна дали б подвійний темп. nysh registry rate показує максимум у вікні за журналом фактичних відправок — не за наміром.

Зведення джерел

nysh registry merge зливає всі registry/*.tsv у реєстр фонду. Джерела майже не перекриваються (ф.230: Вікіджерела 256 справ, ukrfamily 916, спільних 21), тож жодне окремо не дає й чверті — сенс має саме сума.

Заголовок обирає РАНГ джерела: опис, прочитаний оком зі скану, сильніший за опис на сайті архіву, той — за чужі транскрипції, а зведені покажчики найслабші. Слабший заголовок не зникає, а лишається слідом.

🔴 У чергу ока подається не всяка розбіжність. Дві транскрипції однієї таблиці розходяться словами постійно («Свято-Покровська» проти «Покрови Пресвятої Богородиці» — та сама церква), і подавати це означає втопити справжнє: на ф.224 таких позицій було 572, на ф.904 — 1606 із 1606. Розбіжністю тут вважається РІЗНЕ СЕЛО, бо саме воно означає переплутану справу. Вердикт, поставлений людиною, перезбірку переживає.

⚠ Покриття рахується лише там, де відома межа опису. Немає межі — немає й відсотка: «0/0 · немає 0» читається як «усе на місці», хоча означає, що знаменника ніхто не публікував.

Читання рукопису

Спершу разово nysh htr install і nysh models get (див. вище) — без них команда відмовляє. Далі nysh read <тека> або екран «Читання»: план (скільки кадрів, яке письмо, яка модель) показується ДО запуску, бо справа читається годинами. Модель обирається за письмом і за файлом бойових ваг — «найновіша» не обов'язково «найкраща». Другий рушій читає ті самі кропи: він помиляється ІНАКШЕ й витягує те, де перший підставив правдоподібне слово.

Рушіїв три, і в кожного своя ділянка. У виводі вони помічені літерою — саме вона, а не колір, розрізняє їх у чорно-білому терміналі, у логах і при дальтонізмі:

рушій письмо де працює
[П] Писар кирилиця головний голос: канцелярія, метрики, сповідки
[Д] Дяк кирилиця другий голос: тримається пікселів там, де перший додумує
[С] Скриба латинка нотаріат і костельні книги

Ваги ставляться окремо від пакета — nysh models get (Писар v17 · Дяк v4 · Скриба v6, разом ~130 МБ, sha256 звіряється завжди). У колесі їх немає навмисно: пакет із вагами ставився б довго й тому, хто хоче лише подивитись каталог справ. Власні ваги в <простір>/data/spotter/models працюють так само.

Гортач

Вирізка рядка з рамкою — щоб було видно, ЗВІДКИ взявся текст. Машина подає кандидата, вирішує око. Дефолт — рядок, бо сторінка коштує в десятки разів дорожче (виміряно: 15 КБ проти 1.1 МБ).

Своя тека стає справою

Скани, зняті в архіві чи прислані колегою, не мають шифри — а без ключа в них немає ні обліку прочитаного, ні місця в реєстрі, ні можливості послатись на знахідку. Екран «Завести справу» (або nysh case) приймає шифру в тих формах, якими її справді пишуть — ДАХмО 315-1-8433, ф.315 оп.1 спр.8433, Ф. 211 Оп. 3 Д. 140. Опис пишеться в теку: вона переїжджає між дисками й потрапляє до колег, і опис їде з нею. Кнопка ✏ у переліку відкриває записане для правки — щоб змінити одне слово, а не передруковувати все наосліп.

Скани можуть лежати де завгодно

Не обов'язково всередині простору: тека на зовнішньому диску чи в мережі береться під облік там, де лежить, — позначкою у формі, командою nysh roots add <тека> або полем case_roots у nyshporka.toml. Файли не переносяться. Ціла тека з десятками книг оголошується БЕЗ шифри (nysh roots add); шифра потрібна лише окремій справі (nysh case … --adopt), бо контейнер справою не є. Розширення зони завжди явне: застосунок ніколи не бере теку сам, бо шлях у гортач приходить із запиту браузера, і «дозволено все» тут коштувало б надто дорого. Тека всередині простору лишається записаною відносним шляхом — щоб простір можна було перенести на інший диск чи віддати колезі.

Зразкова справа в комплекті

nysh sample (або кнопка на екрані «Перевірити цю машину») кладе в простір три аркуші справи ДАХмО ф.315 оп.1 спр.159 — про висвячення в диякони, 1821-1822 — разом із готовим машинним декодом двома голосами. Це відповідь на перше питання після встановлення: клацнувши рядок у гортачі, видно, ЗВІДКИ взявся текст, а пошук по декоду знаходить у ньому прізвище. Весь ланцюг після читання можна пройти до того, як вкладати власні три тисячі сканів; прочитати самі аркуші заново можна після nysh htr install і nysh models get.

Довідники окремим комплектом

Газетир зведеного каталогу ЦДІАК (4566 поселень, 348 408 справ) і реєстри опису чотирьох фондів ставляться окремо від програми — дані оновлюються не тоді, коли код:

nysh catalog install --from <завантажений zip>   # releases
nysh geog find "Липовеньке"      # де взагалі є документи цього села
nysh church find "Липовеньке"    # чи була тут церква ~1772, чия — і де її книги
nysh church near "Шумилів" --km 12   # сусідні парафії того ж часу
nysh geog near "Шумилів" --km 15     # сусідні села газетира з числом справ

Газетир відповідає на питання, з якого починається пошук: які взагалі метрики цього поселення вціліли і що з них уже у вас. Шукає обома мовами й латинкою — Miastkowka знаходить те саме, що й кирилицею; раніше такий запит давав нуль, а це найгірший вид нуля, бо його читають як «такого села немає». І показує три конфесії окремо: метрики православної громади, костелу й рабинату лежать у різних фондах, тож шукати лише в православному розділі означає не бачити решти.

Церкви ~1772 — окремий пак за базою Б. Шади (Кольбук 1998, Radwan «Socjografia» 1782): чи була в селі парафія до поділів, якого деканату, з якою присвятою і чиїм патронатом. Кожна знайдена церква зшита з поселенням газетира, тож поруч видно, де тепер її книги; коло сусідніх парафій показує, куди міг перейти священник і де хрестили, поки своєї церкви не було.

Сховище прочитаного

Облік того, що вже переглянуто оком — щоб наступна сесія не гортала ті самі аркуші вдруге. Пошук по прочитаному: у машинному декоді, у виписаних прізвищах, в учасниках розібраних записів.

Реєстр справ

Що є на диску, що прочитано машиною, що прошукано, що бачило око — з попередженням, коли зріз відстав від джерел.

Розбір актів у поля

Читання рукопису дає ТЕКСТ; щоб у таблиці можна було відфільтрувати «народження 1865 у цьому селі», акт має бути розкладений по полях — дата події, дата обряду, номер у книзі, учасники з ролями, стан, вік, місце.

🔴 Сам розбір робить ВАШ агент і вашим коштом, а не пакет. Аркуш читає модель: за нашим виміром це близько 84 тисяч токенів на скан, тобто книга на дві сотні аркушів — мільйони токенів за прохід, а проходів мусить бути два. Вбудований виклик чужого API витрачав би ваші гроші з коду, який ви поставили подивитись каталог. Тому пакет дає те, чого агент сам собі не зробить:

nysh records prep   "ДАВіО 904-24-24" --scans 0022-0024   # тайли + ЦІНА наперед
#   → агент читає надрукований контракт і тайли, віддає JSON
nysh records ingest "ДАВіО 904-24-24" --file out.json     # валідація + запис
nysh records merge  "ДАВіО 904-24-24" --a гілка1/ --b гілка2/ --apply
nysh records audit  "ДАВіО 904-24-24"                     # чексуми книги

Заради чого розбір і робиться — питання, яких проза не бере:

nysh records grep "Ковальський" --role father    # батько, а не восприємник
nysh records grep "Городківка" --axis place       # хто звідси в чужих книгах
nysh pages   show "ДАВіО 904-24-24" 0022.jpg      # занесене, як воно лежить
  • Тайли обов'язкові. Розворот метричної книги — це ~4000×3000, модель стискає його до ~1568px і бачить у 0.39×: скоропис розсипається. Провал такої вичитки виглядає не помилкою, а впевнено неправильним текстом.
  • Повноту доводять чексуми, а не самозвіт. Метрика нумерує народження й смерті двома окремими лічильниками і сама себе рахує наприкінці місяця. Діра в нумерації — пропущений акт із точністю до номера. Секція без дір і зі збіжним підсумком доведено повна; «агент сказав, що все прочитав» — ні.
  • Один прохід не є джерелом істини. Модель подає помилкове прочитання так само впевнено, як правильне, тож merge зводить дві незалежні вичитки: збіг іде в сховище, розбіжність — у чергу на людський розсуд.
  • Тип книги — налаштуванням, а не кодом. Костел, сповідні розписи й ревізька казка мають іншу геометрію аркуша, інші лічильники й іншу мову. Готові профілі їдуть у пакеті; свої кладуться в <простір>/config/records_profiles.yaml і накладаються зверху, тож оновлення пакета їх не змиває.

Агентові MCP для цього не потрібен: nysh op records.prep --describe віддає повну схему, nysh op records.prep --args '{…}' виконує. Перелік MCP-tool'ів навмисно вужчий — у нього є стеля, за якою модель перестає читати описи.

Виписка таблицею

Розібрані акти йдуть у Ексель — щоб фільтрувати роками, селом, станом і прізвищем, а не гортати.

nysh export case "ДАВіО 904-24-24" --what acts               # подивитись
nysh export case "ДАВіО 904-24-24" --what all -o книга.xlsx  # забрати файлом

Вигляди різні, бо різні питання: acts — рядок на акт, ролі розкладені в колонки (дитина, батько, мати, хрещені); records — рядок на учасника, і саме там фільтруються прізвище, стан і вік; плюс pages і tally. CSV/TSV пишуться без жодного додаткового пакета, XLSX потребує nyshporka[xlsx].

🔴 Кожен рядок несе аркуш. Виписка без посилання на скан — переказ: перевірити її можна лише перечитавши всю справу, тобто ніяк. І підсумки книги («родилось мужеска 5, женска 4») лежать окремим аркушем, а не серед актів: це чексум повноти вичитки, а не подія. Свого «разом» таблиця не рахує — у тій самій книзі трапляються власні total і total_both_sexes, тож обчислена сума показала б число, якого в книзі немає.

Три обличчя, одне ядро

Браузерна консоль, командний рядок і MCP-сервер для Claude Code / Codex — тонкі обгортки навколо одного реєстру операцій. Коли правда одна, вони не можуть розійтись у відповідях; це перевіряється тестом, а не домовленістю. Працювати з агентом не обов'язково — без нього застосунок повний.

Агентові при цьому не потрібен MCP: nysh op <ім'я> дістає будь-яку операцію реєстру, а nysh op <ім'я> --describe віддає схему аргументів і повний докстрінг, нічого не виконуючи. Перелік tool'ів — зручність для тих середовищ, де він є, і він за побудовою вужчий: у нього є стеля, за якою модель перестає читати описи й починає вгадувати.

Якщо агент береться до роботи, він читає AGENTS.md і docs/agents/: що вміє, чого не вміє, як читати нуль, де межа, за якою вирішує людина, і як агенти вже помилялися на цьому матеріалі.

Межі: нуль мусить щось означати

Це головне правило проєкту, і воно вбудоване в код, а не в інструкцію.

Порожній результат пошуку — найдорожча відповідь у генеалогії: «немає» закриває напрям назавжди. Тому джерело, яке не може шукати (каталог не зібраний, дерево регіону не завантажене), не додає нуль до суми — воно відмовляється відповідати й каже, чого бракує:

⚠ archium: каталог справ ще не зібрано, тож шукати нема де — і нуль тут нічого
  не означав би: вбудований пошук сайту індексує лише назви фондів і описів.
⚠ жодне джерело не змогло шукати — цей нуль НІЧОГО не означає

Кожна відповідь несе coverage: де саме шукали. Кожне попередження їде полем конверта, а не лише в лозі, — інакше саме той читач, який не помітить нічого поза даними (агент), лишався б без попередження.

Межі: чого ще немає

Чесно, без замовчувань:

  • Скани ви приносите самі. Качалки з FamilySearch у пакеті немає й не буде: вона вимагає живої сесії в браузері, а масове завантаження суперечить правилам сервісу. Дзеркало плівок (fsfilm) — це не FamilySearch, і його поаркушевий покажчик накриває лише Молдову.
  • Розбір актів у поля робить ваш агент і вашим коштом. Пакет дає нарізку, контракт, валідацію, чексуми й звід — але не читає. Порядок цін названий у розділі про nysh records, і records prep друкує його перед роботою. Вбудувати сюди виклик чужого API означало б витрачати ваші гроші з коду, який ви поставили подивитись каталог.
  • Класифікатора типу сторінки немає. Що це за аркуш — метрика, обкладинка, вказівник — ставить людина або агент; за пікселями пакет цього не визначає.
  • Цифра з декоду не є фактом. Вік, суми, номери звіряються із зображенням: за прозою стоїть мовна модель, за багатозначним числом — ні.
  • Вицвілий аркуш може не врятувати ніщо. Обмежує не роздільність, а контраст: там, де чорнило й папір розділяє ~37 рівнів яскравості з 255, не допомагає ні зум, ні друга вичитка. Таку секцію або перезнімають, або приймають неповною — і пишуть це у звіті.

  • Ваги накривають той матеріал, на якому вчились: кирилиця й латинка скоропису XVIII–XIX ст. українських, молдовських і польських архівів. Поза ним якість не міряна — і мовчазно поганий текст виглядає так само впевнено, як добрий, тож на чужому матеріалі першу справу варто звірити оком.

  • Гортач бачить 86% прогонів. Переміряно на 614 прогонах: готовий скан у 519, рендер зі справи-PDF ще у 7. Решта 88 — здебільшого збірки, у яких теки однієї справи немає в принципі, і прогони, чия тека лишилась на чужій машині; другі лікуються nysh cases bind. Для тих, що видно, аркуш тепер показується правильно й на рендері теж — раніше кроп рядка там з'їжджав.
  • Покажчик плівок накриває лише Молдову. Не наша межа: в інших регіонах дзеркала folder_meta це голий підпис теки, поаркушевого переліку там немає.
  • Описи є не для всіх фондів. Готові зрізи чотирьох фондів приходять довідниками (вище); решту збирає nysh registry build, і лише там, де опис викладено на одному із сайтів, які знають збирачі (nysh registry sources).
  • Кандидатів нема кому подавати. Черга nysh review працює, але кандидатів у неї додають завантажувачі чужих сайтів, яких у цій версії немає (питання їхніх умов використання в роздаваному продукті). На щойно створеному просторі черга порожня — це стан, а не поламка.