From 117e3665db4f27f37be056e64ac1d1fdeec840a3 Mon Sep 17 00:00:00 2001 From: ANTON MAHOMEDOV Date: Fri, 24 Jul 2026 08:49:12 +0300 Subject: [PATCH 1/2] docs: start D1.4a second-book evidence work --- WORK_STATUS.md | 107 +++++++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 43 deletions(-) diff --git a/WORK_STATUS.md b/WORK_STATUS.md index 236926b..24285f6 100644 --- a/WORK_STATUS.md +++ b/WORK_STATUS.md @@ -6,57 +6,78 @@ | Поле | Текущее значение | |---|---| -| Состояние | **READY** — незавершённой активной задачи нет | -| Рабочая ветка | `main` | -| Открытый Pull Request | нет | +| Состояние | **IN_PROGRESS** — начат D1.4a second-book evidence and extraction contract | +| Рабочая ветка | `docs/second-book-evidence-d1.4a` | +| Открытый Pull Request | ещё не открыт | | Стабильный функциональный релиз | `v23.8.0` | -| Документационный/architecture baseline | `23.8.11` — D1.4 two-book architecture завершён | -| Последнее завершённое изменение | PR #31, squash merge `897f89a325c9997f9046455a6df7336e82d2c7d8` | -| Закрытая задача | Issue #30 — D1.4 completed | -| Следующая утверждённая работа | second-book evidence and dataset preparation | - -## Завершённый этап D1.4 - -- создан `docs/TWO_BOOK_ARCHITECTURE.md`; -- создан machine-readable `docs/two-book-architecture.json`; -- добавлен permanent `scripts/validate-two-book-architecture.mjs`; -- GitHub Actions run №129 завершён успешно; -- текущий default остаётся `ru-current-v1`; -- второй сохранённый PDF классифицирован как retained evidence, но не готовый dataset; -- global identity определена как `(dataset_id, record_id)`; -- separate dataset switching выбран первым будущим functional mode; -- combined search определён как federated по отдельным indexes без destructive JSON merge; -- side-by-side comparison требует explicit reviewed relation map; -- определены visible provenance, dataset-aware URLs/history/sharing, atomic activation, cache isolation, fallback и rollback; -- factual uNews patchnote `23.8.11` и новый real PNG сохранены; -- существующие data files, runtime, PWA, package metadata, `versions/` и `_archive/` не изменены; -- Issue #30 закрыт как completed. +| Текущий baseline | `23.8.11`; следующий документационный кандидат будет определён после фактического diff | +| Актуальный `main` при старте | `20325ee0c3d60dbc90b88060dc26b201b6376e6f` | +| Активная задача | Issue #32 — D1.4a second-book evidence and extraction contract | +| Следующий точный шаг | собрать read-only identity, metadata и Git-history evidence для второго PDF, затем создать первый доказательный документ | -## Следующий точный шаг +## Цель + +Подготовить проверяемую доказательную базу и безопасный extraction contract для второй сохранённой книги до создания нового logical dataset и до любой реализации selector, combined search или comparison UI. + +## Планировалось + +- проверить exact path, bytes, SHA-256 и PDF metadata второго сохранённого документа; +- восстановить Git history появления и переименований файла; +- проверить существующие упоминания названия, автора, edition и происхождения; +- разделить сведения на доказанные факты, разумные выводы и неизвестное; +- определить immutable raw-extraction output; +- определить provenance manifest contract; +- определить schema, local-ID и source-reference policy; +- определить validation gates перед регистрацией нового dataset; +- определить retention и rollback; +- не создавать и не изменять данные на этом этапе. + +## Планируемые постоянные файлы -Следующую работу начинать только в новой отдельной ветке после создания Issue и обновления этого файла до `IN_PROGRESS`. +- `WORK_STATUS.md`; +- новый документ evidence/extraction contract под `docs/`; +- при необходимости machine-readable contract под `docs/`; +- при необходимости permanent validator под `scripts/`; +- синхронизация `ROADMAP.md`, `VERSION.md` и связанных документов; +- factual uNews patchnote и новое реальное изображение перед PR. -Цель следующего этапа — подготовить доказательства и безопасный extraction contract для второй книги до создания logical dataset: +## Критерии завершения + +- доказательства и неизвестное разделены честно; +- second-book PDF identity и retained history зафиксированы; +- extraction output и manifest contracts определены; +- protected paths отсутствуют в diff; +- существующие data files не изменены; +- runtime, PWA, package metadata, `versions/` и `_archive/` не изменены; +- validators и GitHub Actions зелёные; +- PR объединён только после полного diff review; +- Issue #32 закрыт completed; +- `main/WORK_STATUS.md` возвращён в READY. + +## Что уже сделано + +- D1.4 завершён PR #31, squash merge `897f89a325c9997f9046455a6df7336e82d2c7d8`; +- Issue #30 закрыт completed; +- создан Issue #32 с точными границами D1.4a; +- создана отдельная ветка `docs/second-book-evidence-d1.4a` от актуального `main`; +- ранний handoff сохранён до начала исследования. + +## Следующий точный шаг -1. зафиксировать точную identity/edition второй сохранённой работы настолько, насколько позволяют файлы и Git history; -2. отделить доказанные сведения, разумные выводы и неизвестное; -3. определить immutable raw-extraction output и provenance manifest; -4. определить schema, local ID policy, source references, hashes и validation gates; -5. не создавать registered dataset до появления фактического extraction output; -6. не менять `ru-current-v1`, runtime, PWA или существующие data files; -7. не реализовывать selector, combined search или comparison UI на этом этапе. +Read-only проверить `_archive/source-files/Unlocking-Your-Dream-Student-Ma.pdf`: exact bytes, SHA-256, PDF metadata, Git history и все maintained references. Затем создать первый доказательный черновик без изменения PDF, данных или runtime. ## Главные запреты -- не менять и не удалять существующие data files; -- не считать наличие PDF готовым dataset; -- не выполнять destructive merge книг; -- не назначать одинаковые numeric IDs между книгами без evidence; -- не менять runtime, PWA, Service Worker, package metadata, `versions/` или `_archive/`; -- не начинать user-facing selector до готовности и регистрации второй базы; -- не запускать AI-assisted translation experiment до отдельного утверждённого этапа; -- не добавлять API keys или секреты. +- не изменять существующие `data/` файлы; +- не изменять или удалять PDF и `_archive/`; +- не создавать registered second-book dataset без фактического extraction output; +- не добавлять selector, combined search или comparison UI; +- не назначать одинаковые numeric IDs между книгами; +- не менять runtime, PWA, Service Worker, package metadata или `versions/`; +- не запускать AI-assisted translation; +- не добавлять API keys; +- не заявлять source URL, edition или permissions без сохранённого evidence. ## Источник истины -Реальные GitHub-факты — `main`, открытые Pull Request, commits, Actions и Issues — имеют приоритет над памятью ИИ, старыми чатами и локальными незапушенными изменениями. +Реальные GitHub-факты — `main`, текущая ветка, commits, Pull Request, Actions и Issues — имеют приоритет над памятью ИИ, старыми чатами и локальными незапушенными изменениями. From 28884bd36e3b83f65d46064e668314d60f6ed137 Mon Sep 17 00:00:00 2001 From: ANTON MAHOMEDOV Date: Fri, 24 Jul 2026 09:08:07 +0300 Subject: [PATCH 2/2] chore: run read-only second-book PDF diagnostics --- .../workflows/analyze-second-book-d1.4a.yml | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 .github/workflows/analyze-second-book-d1.4a.yml diff --git a/.github/workflows/analyze-second-book-d1.4a.yml b/.github/workflows/analyze-second-book-d1.4a.yml new file mode 100644 index 0000000..e37f633 --- /dev/null +++ b/.github/workflows/analyze-second-book-d1.4a.yml @@ -0,0 +1,105 @@ +name: Analyze second book D1.4a + +on: + push: + branches: + - docs/second-book-evidence-d1.4a + paths: + - .github/workflows/analyze-second-book-d1.4a.yml + workflow_dispatch: + +permissions: + contents: read + +jobs: + analyze: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install PDF tools + run: sudo apt-get update && sudo apt-get install -y poppler-utils + + - name: Analyze retained second-book PDF + shell: bash + run: | + set -euo pipefail + PDF="_archive/source-files/Unlocking-Your-Dream-Student-Ma.pdf" + OUT="artifacts/d1.4a" + mkdir -p "$OUT" + + test -f "$PDF" + stat --printf='bytes=%s\n' "$PDF" | tee "$OUT/file-identity.txt" + sha256sum "$PDF" | tee -a "$OUT/file-identity.txt" + file "$PDF" | tee -a "$OUT/file-identity.txt" + pdfinfo "$PDF" | tee "$OUT/pdfinfo.txt" + pdftotext -layout "$PDF" "$OUT/extracted.txt" + + python3 - <<'PY' + from pathlib import Path + import json + import re + import statistics + + text_path = Path('artifacts/d1.4a/extracted.txt') + text = text_path.read_text(encoding='utf-8', errors='replace') + pages = text.split('\f') + if pages and not pages[-1].strip(): + pages.pop() + counts = [len(page.strip()) for page in pages] + word_counts = [len(re.findall(r"\b\w+\b", page, flags=re.UNICODE)) for page in pages] + substantial = sum(count >= 80 for count in counts) + ratio = substantial / len(counts) if counts else 0 + headings = [] + seen = set() + for page_number, page in enumerate(pages, start=1): + for raw in page.splitlines(): + line = re.sub(r'\s+', ' ', raw).strip() + if not 3 <= len(line) <= 90: + continue + if line.isupper() or re.match(r"^[A-Z][A-Za-z'’&:\- ]{3,}$", line): + key = line.casefold() + if key not in seen: + seen.add(key) + headings.append({'page': page_number, 'text': line}) + if len(headings) >= 100: + break + if len(headings) >= 100: + break + + result = { + 'page_count_from_text': len(pages), + 'pages_with_substantial_text': substantial, + 'searchable_page_ratio': round(ratio, 4), + 'total_characters': sum(counts), + 'total_words': sum(word_counts), + 'median_nonempty_page_characters': statistics.median([c for c in counts if c > 0]) if any(counts) else 0, + 'technical_conclusion': ( + 'direct-text-extraction-viable' if ratio >= 0.85 + else 'hybrid-text-and-ocr-likely' if ratio >= 0.35 + else 'ocr-first-likely' + ), + 'first_20_page_character_counts': counts[:20], + 'heading_candidates': headings, + 'samples': [ + {'page': i + 1, 'text': re.sub(r'\s+', ' ', pages[i]).strip()[:1200]} + for i in sorted(set([0, 1, 2, 3, 4, len(pages)//2, max(0, len(pages)-2), max(0, len(pages)-1)])) + if 0 <= i < len(pages) + ], + } + Path('artifacts/d1.4a/extractability.json').write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding='utf-8') + print(json.dumps(result, ensure_ascii=False, indent=2)) + PY + + git log --follow --date=iso-strict --format='%H%x09%aI%x09%s' -- "$PDF" | tee "$OUT/git-history.txt" + git log --all --name-status --date=iso-strict --format='commit %H %aI %s' -- '*Unlocking*' '*Dream-Student*' | tee "$OUT/path-history.txt" + + - name: Upload diagnostics + uses: actions/upload-artifact@v4 + with: + name: udream-d1-4a-second-book-diagnostics + path: artifacts/d1.4a + retention-days: 30