/** * Generate individual task-plan DOCX files for the three fuse_proj researchers. * * Format follows пример_отчета.docx: A4, margins 3/2/1.5/2 cm (GOST), * Times New Roman 14pt, approval block, theme/supervisor header and a * fixed-layout 3-column work table (738/6626/1981 DXA). * * Usage: NODE_PATH="$(npm root -g)" node scripts/gen_task_plans.js */ const fs = require("fs"); const path = require("path"); const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, AlignmentType, BorderStyle, WidthType, TableLayoutType, LevelFormat, TabStopType, TabStopPosition, } = require("docx"); const FONT = "Times New Roman"; const SZ = 28; // 14pt in half-points const TABLE_W = 9345; const COLS = [738, 6626, 1981]; const border = { style: BorderStyle.SINGLE, size: 4, color: "000000" }; const borders = { top: border, bottom: border, left: border, right: border }; const cellMargins = { top: 60, bottom: 60, left: 100, right: 100 }; function run(text, opts = {}) { return new TextRun({ text, font: FONT, size: opts.size || SZ, bold: !!opts.bold, italics: !!opts.italics }); } function p(text, opts = {}) { const children = Array.isArray(text) ? text : [run(text, opts)]; return new Paragraph({ alignment: opts.align, indent: opts.indent, spacing: opts.spacing || { after: 60 }, tabStops: opts.tabStops, children, }); } function cellPar(text, opts = {}) { return new Paragraph({ alignment: opts.align || AlignmentType.LEFT, spacing: { after: 20 }, children: [run(text, opts)], }); } function cell(text, width, opts = {}) { const paras = Array.isArray(text) ? text.map((t) => cellPar(t, opts)) : [cellPar(text, opts)]; return new TableCell({ borders, margins: cellMargins, width: { size: width, type: WidthType.DXA }, columnSpan: opts.span, children: paras, }); } function headerRow() { return new TableRow({ tableHeader: true, children: [ cell("№ п/п", COLS[0], { bold: true, align: AlignmentType.CENTER }), cell("Наименование работы", COLS[1], { bold: true, align: AlignmentType.CENTER }), cell("Выполнение, форма отчетности, место хранения", COLS[2], { bold: true, align: AlignmentType.CENTER }), ], }); } function numbersRow() { return new TableRow({ children: [ cell("1", COLS[0], { align: AlignmentType.CENTER }), cell("2", COLS[1], { align: AlignmentType.CENTER }), cell("3", COLS[2], { align: AlignmentType.CENTER }), ], }); } function sectionRow(title) { return new TableRow({ children: [cell(title, TABLE_W, { bold: true, span: 3 })], }); } function workRow(num, work, deliverable) { return new TableRow({ children: [ cell(num, COLS[0], { align: AlignmentType.CENTER }), cell(work, COLS[1]), cell(deliverable, COLS[2]), ], }); } // --------------------------------------------------------------------------- // Shared row fragments (joint stages identical for the whole team) // --------------------------------------------------------------------------- function stage1Rows(personalPackage, roleRow) { return [ sectionRow("1. Подготовительный этап: материалы, окружение, данные (недели 1–2)"), workRow( "1.1", "Изучение постановки и контекста проекта: README.md; docs/00_project/06_MERIDIAN_CONTEXT.md (включая §5 — требование корректного поведения при отсутствии модальности); docs/01_tasks/00_MASTER_ASSIGNMENT.md; 01_INPUT_OUTPUT_CONTRACT.md; 02_TEAM_WORKFLOW.md; 03_EXPERIMENT_PROTOCOL_GTA_UAV.md", ["Конспект;", "вопросы — reports/joint/WORKLOG.md"] ), workRow( "1.2", "Обязательный пакет: 5 документов docs/02_references/01_required/; fusion core по карте чтения 00_READING_MAP.md (§0: канонические документы — цепочки версий, полная база в _version_chain/ + верхняя дельта); TRIAGE_teacher_fusion_dropout_2026-06-11.md (минимум §1 и §6a)", ["Заполненный разбор по шаблону 00_READING_MAP.md §7"] ), workRow("1.3", personalPackage, ["Evidence matrix (≥8 источников) — раздел design-отчёта"]), workRow( "1.4", "Совместный аудит окружения: доступность репозиториев caption-test и depth_edges_annotate_worlduav; датасет GTA-UAV-LR (+captions, +aug SafeTensors) на сервере; checkpoint StripNet; версии Python/PyTorch/CUDA/GPU", ["reports/joint/ENVIRONMENT_AUDIT.md"] ), workRow( "1.5", "Совместный data audit (40 samples, поровну sat/UAV): формы, dtype, диапазоны и validity всех модальностей; alpha-канал satellite RGB; покрытие captions (sat ≈44,7%); 17 классов сегментации; ВЕРИФИКАЦИЯ SPLIT: соответствие meta/train_80.json официальному cross-area (протокол §2.1)", ["Таблица аномалий и вердикт по split — ENVIRONMENT_AUDIT.md"] ), roleRow, ]; } function stage2Rows() { return [ sectionRow("2. Замораживание интерфейсов и общий baseline (недели 2–3)"), workRow( "2.1", "Interface freeze (совместно): представление segmentation (class IDs + embedding или probabilities); нормализация depth и CHM; text encoder и уровни captions L1/L2/L3; общий API FusionModelBase; единые diagnostics keys; naming экспериментов FUS-{family}-{variant}-s{seed}", ["reports/joint/INTERFACE_DECISION.md"] ), workRow( "2.2", "Совместный baseline: B0 StripNet RGB-only (smoke → seed 42 → 123/456); B1 late concat pooled embeddings; B2 static additive residual; B3 Multi-FiLM + ADD. Единые split/loss/sampler/optimizer для всех вариантов", ["reports/joint/BASELINE_REPORT.md;", "experiments/experiment_registry.csv"] ), ]; } function stage5Rows(personalAblationRow, extraRows = []) { return [ sectionRow("5. Эксперименты и аблации (недели 6–7)"), workRow( "5.1", "Smoke benchmark четырёх систем (B0, A-primary, B-primary, C-primary): один subset, seed 42, одинаковое число шагов; сравнение loss, sanity R@K, VRAM, latency, NaN; устранение интеграционных дефектов", ["reports/joint/EXPERIMENT_STATUS.md"] ), workRow( "5.2", "Primary comparison: полный run seed 42; для вариантов, прошедших decision rules протокола §11, — повторение на seeds 123 и 456", ["experiment_registry.csv;", "out//eval_report.json"] ), workRow( "5.3", "Общие аблации G-AB1..G-AB12 по протоколу §6 и оценка missing-modality по протоколу §13: eval-time отключение каждой aux-модальности через validity=0; контроль плавной деградации и конечности дескриптора", ["Таблицы — личный отчёт IMPLEMENTATION_AND_RESULTS.md"] ), personalAblationRow, ...extraRows, ]; } function stage6Rows(surname, taskFile) { return [ sectionRow("6. Итоговая отчётность и решение (неделя 8)"), workRow( "6.1", "Личный итоговый отчёт: реализация, результаты, вклад каждой модальности, разбор failure cases, вердикт по falsification-критериям собственной гипотезы", [`reports/${surname}/IMPLEMENTATION_AND_RESULTS.md`] ), workRow( "6.2", "Совместное сравнение и decision meeting: письменные ответы на 8 вопросов (подтверждено/опровергнуто; вклад модальностей; главный failure mode; поведение при validity=0; рекомендация primary/fallback; что менять при переносе на ViT-токены DINOv3)", ["reports/joint/FINAL_COMPARISON.md;", "DECISION_RECORD.md"] ), workRow( "6.3", "Закрытие чек-листа Definition of Done личного задания; перенос результатов в общий experiment registry", [`Чек-лист — docs/01_tasks/${taskFile} §7`] ), ]; } // --------------------------------------------------------------------------- // Employee definitions // --------------------------------------------------------------------------- const EMPLOYEES = [ { file: "План_заданий_Павленко_БВ.docx", fullName: "Павленко Богдан Викторович", shortName: "Б.В. Павленко", surnameLat: "pavlenko", taskFile: "01_PAVLENKO_CONDITION_AWARE.md", track: "Трек A — Condition-Aware RGB-Anchored Fusion", teamRole: "владелец общего fusion API и архитектурной совместимости трёх реализаций", question: "Может ли controller, использующий RGB content summary и признаки качества дополнительных входов, динамически выбирать полезный вклад text, segmentation и geometry, сохраняя надёжный RGB residual path?", personalPackage: "Персональный paper package (docs/02_references/): F39 CAFuser; F37 AsymFormer; F43 Robust PEFT (TPAMI 2024 — identity-adapters и missing modalities); F47 TacFiLM; F40 M³amba; F44 Fusion-Mamba; F68 RemoteDet-Mamba; F4 EarthMind; B14 Strip R-CNN; количественные опоры C5/F14 WeatherPrompt (Dynamic Gate 80.20 > Concat 78.90 > Static 78.45; FiLM 73.37 > CrossAttn 68.10)", roleRow: workRow( "1.6", "Командная роль — fusion API: черновик FusionModelBase/registry (encode_view, независимость веток, поддержка batch=1, выбор варианта через gin); RFC команде; фиксация только после согласия Близно и Мороза", ["src/fuse_proj/models/fusion/base.py, registry.py;", "решение — INTERFACE_DECISION.md"] ), designRows: [ sectionRow("3. Проектирование condition-aware архитектуры (неделя 4)"), workRow( "3.1", "RGB anchor: сравнить GAP stage 3 / GAP stage 4 / concat GAP 3–4 / attention pooling stage 4; выбрать primary content summary и обосновать достаточность информации для выбора вклада модальностей", ["reports/pavlenko/DESIGN.md (задача A1)"] ), workRow( "3.2", "Quality signals: text — empty mask, token count, норма эмбеддинга; segmentation — entropy, background fraction, valid fraction; CHM/depth — valid fraction, dynamic range, gradient energy. Отобрать только стабильно вычислимые без labels test split", ["DESIGN.md (A2)"] ), workRow( "3.3", "Auxiliary paths по каждой модальности: raw tensor, нормализация, encoder, выходная размерность, целевые StripNet stages, residual transform, инициализация, validity handling; CHM и depth — раздельные input projectors", ["DESIGN.md (A3)"] ), workRow( "3.4", "Три кандидата: A-C1 — channel-wise gated additive residual; A-C2 — multi-stage FiLM с condition-aware gates; A-C3 — dense residual для карт + token cross-attention для текста. Для каждого: insertion stages, params, доминирующие операции, VRAM, identity preservation, modality attribution, главный failure mode. Выбор primary и fallback по скорингу (retrieval fit 25, RGB preservation 20, attribution 15, compute 15, stability 15, risk 10)", ["Сравнительная таблица и выбор — DESIGN.md (A4–A5)"] ), workRow( "3.5", "Формализация controller: c_v = Controller([Pool(X_rgb); q_text; q_seg; q_geom; e_view]); X_new = X_rgb + Σ a_m·Δ_m. Определить: scalar/channel/spatial gates; sigmoid или softmax; contribution cap; zero-init residual (identity-at-init); ПОВЕДЕНИЕ ПРИ validity=0 — нулевой вклад невалидной модальности без искажения остальных gates (формула + тест). Уровни fusion (stage 4 / 3–4 / 2–4) и readout (GAP / GGeM / attention pooling / residual к RGB descriptor)", ["DESIGN.md (A6–A8)"] ), workRow( "3.6", "Design review с командой: tensor flow satellite и UAV, оценка params/FLOPs/VRAM, falsification-критерии (static residual не хуже primary; gates константны по samples; насыщение одного gate без вклада; gain только на одном seed; рост compute без R@1)", ["Протокол ревью — WORKLOG.md;", "принятый DESIGN.md"] ), ], implRows: [ sectionRow("4. Реализация и тестирование (неделя 5)"), workRow( "4.1", "Реализация primary-варианта за общим API; gin-конфигурация без хардкода путей", ["src/fuse_proj/models/fusion/condition_aware.py;", "in/config_files/fusion_condition_aware.gin"] ), workRow( "4.2", "Тесты: shape [B,1024] при B=1 и B=4; норма дескриптора; identity при нулевом residual; обработка validity=0 по каждой модальности; отсутствие NaN на константных seg/depth/CHM; раздельность geometry-projectors sat/UAV; gradient до каждого активного projector", ["tests/test_condition_aware.py"] ), workRow( "4.3", "Diagnostics: mean/std gate по модальности и stage; contribution norm ||a·Δ||/||X_rgb||; cosine RGB↔fused descriptor; доля насыщенных gates (<0.05 или >0.95); descriptor variance", ["diagnostics.json в out//"] ), workRow( "4.4", "Взаимное code review: провести ревью кода Близно (token/bottleneck); код condition-aware ревьюит Мороз", ["Замечания и исправления в PR (gitea)"] ), ], ablationRow: workRow( "5.4", "Персональные аблации A-AB1..A-AB8: static vs condition-aware; content-only vs content+quality; scalar vs channel gates; sigmoid vs softmax; init; stage 4 vs stages 3–4; shared vs view-specific controller; GAP vs GGeM vs attention pooling (объём согласуется с командой)", ["IMPLEMENTATION_AND_RESULTS.md"] ), extraStage5: [], materials: [ "Общий пакет: docs/00_project/06_MERIDIAN_CONTEXT.md; docs/02_references/01_required/ (5 документов); 00_READING_MAP.md", "Канонические цепочки: SPEC_fusion_ACF_MERIDIAN (_version_chain/v1 → v5); ANALYSIS_FiLM_alternatives_taxonomy (база → v4); СИНТЕЗ_3_fusion.md; СИНТЕЗ_3_fusion_taxonomy_audit.md; ОБЗОР_fusion_rgb_multimodal_full_v1.md", "TRIAGE_teacher_fusion_dropout_2026-06-11.md — §1 (P0-статьи), §6a (dropout-safe семейства операторов)", "Персональный пакет: F39 CAFuser; F37 AsymFormer; F43 Robust PEFT; F47 TacFiLM; F40 M³amba; F44 Fusion-Mamba; F68 RemoteDet-Mamba; F4 EarthMind; B14 Strip R-CNN", "Количественные опоры: C5_2025_WeatherPrompt.md; F14_2025_WeatherPrompt_deep_dive_for_MERIDIAN.md (docs/02_references/05_text/)", "Справочники: ANALYSIS_fusion (база 73 KB в _version_chain/); HYP_fusion_variants; 01_film_fusion.md", "Код: vendor_reference/caption_test/ (StripNet, loss, sampler); docs/03_codebase_guides/CAPTION_TEST_CODE_MAP.md", ], }, { file: "План_заданий_Близно_МВ.docx", fullName: "Близно Максим Витальевич", shortName: "М.В. Близно", surnameLat: "blizno", taskFile: "02_BLIZNO_TOKEN_BOTTLENECK.md", track: "Трек B — Token/Bottleneck Full-Modal Aggregation", teamRole: "владелец общего benchmark, run registry, метрик, статистического сравнения и воспроизводимости", question: "Как выполнить cross-modal reasoning между StripNet features, text, segmentation и geometry через компактный token set, не обрабатывая все spatial positions квадратично и не допуская collapse к одной модальности?", personalPackage: "Персональный paper package: F45 Flex-MoE; F46 FuseMoE (NeurIPS 2024); P50 MMGeo deep dive (главный CVGL-прецедент: Mutable Token над Modality Pool; числа сверить с PDF статьи); ImageBind (late-fusion нижняя граница); F40 M³amba; F4 EarthMind; B14 Strip R-CNN. Внешние первоисточники по arXiv ID из TRIAGE: MBT 2107.00135, Perceiver IO 2107.14795, BLIP-2 Q-Former 2301.12597, CMNeXt 2303.01480", roleRow: workRow( "1.6", "Командная роль — benchmark: каркас единого запуска (gin-конфиг; seed control; config snapshot; git commit в manifest; train/eval metrics CSV; multi-match R@K; peak VRAM и latency; агрегация diagnostics; обновление experiment registry); одинаковый loss/sampler для всех вариантов", ["scripts/run_experiment.py;", "scripts/aggregate_results.py;", "scripts/benchmark_latency.py"] ), designRows: [ sectionRow("3. Проектирование token/bottleneck архитектуры (неделя 4)"), workRow( "3.1", "Token contract по каждой модальности (RGB/text/segmentation/geometry): source tensor, число токенов, token dim, position encoding, modality embedding, view embedding, нормализация", ["reports/blizno/DESIGN.md (задача B1)"] ), workRow( "3.2", "Сжатие StripNet features: GAP (1 токен) / adaptive grid 4×4 (16) / пирамида stage 3–4 / learned resampler с K queries; расчёт attention complexity при token dim 256 и 512", ["DESIGN.md (B2)"] ), workRow( "3.3", "Токенизация aux-модальностей: segmentation — class histogram / mask-pooled class tokens / spatial grid / learned pooling (отсутствующие классы через mask, без NaN при делении на ноль); geometry — pooled features / grid / stats+spatial / gradient-aware (входные encoders view-specific, выходной контракт общий); text — 1 глобальный токен / L1-L2-L3 / learned resampler; число и encoder фиксируются до primary comparison", ["DESIGN.md (B3–B5)"] ), workRow( "3.4", "Три кандидата: B-C1 — mutable query читает общий modality token pool; B-C2 — shared bottleneck tokens с 1–2 aggregation-слоями; B-C3 — soft modality experts + unified readout. Top-k routing в primary не использовать без доказанной необходимости. Сравнение: R@1 potential, token count, quadratic cost, gradient flow, attribution, load balancing, сложность реализации", ["Сравнительная таблица и выбор primary/fallback — DESIGN.md (B6–B7)"] ), workRow( "3.5", "Формализация aggregation: T_v = concat(T_rgb, T_text, T_seg, T_geom) + E_mod + E_view + E_pos; Q^{k+1} = Q^k + CrossAttention(Q^k, T_v, T_v) или альтернативная точная формула. Указать Q/K/V направление, heads, layers, token dim, MLP ratio, residual, normalization. Сохранить свойство softmax-перенормировки при отсутствии модальности (P50): attention mask по невалидным токенам без NaN", ["DESIGN.md (B8)"] ), workRow( "3.6", "Анти-collapse план и design review: логирование attention mass per modality, cosine bottleneck-токенов, token covariance rank, gradient norm per tokenizer, leave-one-group-out sensitivity; механизм контроля (balanced attention penalty / diversity loss / decorrelation / aux readouts / load balancing) выбирается только по данным baseline", ["DESIGN.md (B9–B10);", "протокол ревью — WORKLOG.md"] ), ], implRows: [ sectionRow("4. Реализация и тестирование (неделя 5)"), workRow( "4.1", "Реализация primary-варианта за общим API; gin-конфигурация", ["src/fuse_proj/models/fusion/token_bottleneck.py;", "in/config_files/fusion_token_bottleneck.gin"] ), workRow( "4.2", "Тесты: число токенов каждой модальности соответствует конфигу; masked/empty class tokens без NaN; attention mask блокирует invalid токены; shape [B,1024] и норма; gradient до каждого tokenizer; permutation test, где порядок не должен влиять; complexity estimator выдаёт ожидаемый порядок роста", ["tests/test_token_bottleneck.py"] ), workRow( "4.3", "Diagnostics по плану B9: attention mass, cosine токенов, covariance rank, grad norms, readout sensitivity", ["diagnostics.json в out//"] ), workRow( "4.4", "Взаимное code review: провести ревью кода Мороза (role-aware); код token/bottleneck ревьюит Павленко", ["Замечания и исправления в PR (gitea)"] ), ], ablationRow: workRow( "5.4", "Персональные аблации B-AB1..B-AB10: GAP vs grid vs resampler; stage 4 vs 3–4; mutable query vs bottleneck; bottleneck vs soft experts; dim 256 vs 512; 1/2/4 слоя; с/без collapse control; single vs pooled readout; с/без modality embeddings; fused-only vs RGB-residual readout (объём согласуется с командой)", ["IMPLEMENTATION_AND_RESULTS.md"] ), extraStage5: [ workRow( "5.5", "Командная роль — статистическая сводка финалистов: mean/std по 3 seeds; paired per-query success table; bootstrap CI для ΔR@1; поправка Holm при множественных сравнениях; Pareto-таблица accuracy/VRAM/latency/params", ["results/summary.csv;", "results/statistical_tests.json"] ), ], materials: [ "Общий пакет: docs/00_project/06_MERIDIAN_CONTEXT.md; docs/02_references/01_required/ (5 документов); 00_READING_MAP.md", "Канонические цепочки: SPEC_fusion_ACF_MERIDIAN (_version_chain/v1 → v5); СИНТЕЗ_3_fusion.md; ОБЗОР_fusion_rgb_multimodal_full_v1.md; ANALYSIS_FiLM_alternatives_taxonomy (база → v4)", "TRIAGE_teacher_fusion_dropout_2026-06-11.md — §1 (MBT, CMNeXt, Prismer), §2 (Perceiver IO, BLIP-2, Zorro), §6a", "Персональный пакет: F45 Flex-MoE; F46 FuseMoE; P50 MMGeo deep dive; ImageBind; F40 M³amba; F4 EarthMind; B14 Strip R-CNN", "Внешние статьи (найти по arXiv ID, конспектов в пакете нет): MBT 2107.00135; Perceiver IO 2107.14795; BLIP-2 2301.12597; CMNeXt 2303.01480", "Справочники: ANALYSIS_fusion (база в _version_chain/); HYP_fusion_variants; ОБЗОР_fusion_detailed_v1.md; ОБЗОР_cvgl_detailed_v1.md", "Код: vendor_reference/caption_test/ (loss multi_infonce, mutually_exclusive_sampler, trackers, profiling); docs/03_codebase_guides/CAPTION_TEST_CODE_MAP.md", ], }, { file: "План_заданий_Мороз_ЕС.docx", fullName: "Мороз Егор Сергеевич", shortName: "Е.С. Мороз", surnameLat: "moroz", taskFile: "03_MOROZ_ROLE_AWARE.md", track: "Трек C — Role-Aware Hierarchical Fusion", teamRole: "владелец dataset contract, preprocessing модальностей, validity-масок и контроля качества данных", question: "Даёт ли раздельная обработка spatial semantics (segmentation), dense structure (geometry) и global context (text) более сильный retrieval descriptor, чем один универсальный оператор для всех модальностей?", personalPackage: "Персональный paper package. Segmentation: REVIEW_segmentation_pairA.md; цепочка DELTA pair A (база в 03_segmentation/_version_chain/, 48 KB → v3); ОБЗОР_fusion_rgb_segmentation_v1.md; F36 FC-CLIP; P52 guided CVGL. Geometry: REVIEW_depth_normals_pairB.md; цепочка DELTA pair B (база 34 KB → v3); REVIEW_chm_pairC.md; цепочка DELTA pair C (база 30 KB → v3); M11 CHMv2; M4 JRN-Geo; P44 MGS². Text: REVIEW_text_pairD_methodology.md; REVIEW_text_pairD_final.md; F14 WeatherPrompt deep dive; F47 TacFiLM; P64 CGSI; C5 WeatherPrompt. Плюс B14 Strip R-CNN", roleRow: workRow( "1.6", "Командная роль — data contract (ведущий data audit п. 1.5): единый loader, возвращающий RGB; captions + text_valid; segmentation + valid mask; view-specific geometry + valid mask; sample IDs (только логирование); multi-match metadata. Loader не должен знать выбранный fusion-вариант", ["src/fuse_proj/data/gtauav_multimodal.py, batch.py, validation.py;", "in/config_files/data_gtauav.gin"] ), designRows: [ sectionRow("3. Проектирование role-aware архитектуры (неделя 4)"), workRow( "3.1", "Modality role contract — таблица по 5 модальностям (RGB, segmentation, depth, CHM, text): raw input, нормализация, encoder, spatial level, confidence, ожидаемый CVGL-сигнал, главный shortcut-риск", ["reports/moroz/DESIGN.md (задача C1)"] ), workRow( "3.2", "Segmentation path: class-ID embedding + convolution / one-hot или probability maps + convolution / mask-pooled class tokens / segmentation-guided attention bias. Ответить: где сохраняется spatial layout; кодирование отсутствующих классов; high-background samples; нужна ли entropy/confidence; на каких StripNet stages segmentation полезнее", ["DESIGN.md (C2)"] ), workRow( "3.3", "Geometry paths. UAV depth: normalized relative / inverse / gradients (Sobel-on-depth, прецедент P44 MGS²) / depth+grad каналы / compact stats — представление не должно зависеть от неизвестного absolute scale (P68: metric depth на UAV ненадёжен). Satellite CHM: raw normalized / robust percentile / gradients / +validity mask / local height stats; CHM используется ТОЛЬКО для satellite; проверить происхождение CHM-карт (DSM ≠ CHM, предостережение B97)", ["DESIGN.md (C3–C4)"] ), workRow( "3.4", "Text path: global FiLM / visual-query–text-key-value cross-attention / L1-L2-L3 tokens / late descriptor gating; зафиксировать empty-caption поведение (sat покрытие ≈44,7%) и исключить location leakage", ["DESIGN.md (C5)"] ), workRow( "3.5", "Три кандидата: C-C1 — dense geometry+seg fusion, затем text FiLM; C-C2 — segmentation class tokens + geometry bias + late text attention; C-C3 — multi-stage role-specific adapters + hierarchical readout. Обоснование иерархии (например: stages 2–3 + seg/geometry → stage 4 + text → readout) и почему иной порядок слабее. Учесть: геометрия — модулятор RGB, не самостоятельный поток (M4: normals alone → 37%); чисто multiplicative gating исключить (F63)", ["Сравнительная таблица и выбор primary/fallback — DESIGN.md (C6–C7)"] ), workRow( "3.6", "Validity/uncertainty и параметры: explicit deterministic indicators (text_valid, segmentation_valid, geometry_valid, entropy, valid fraction) до learned reliability head; обязательные view-specific параметры (первый geometry projector, нормализация depth/CHM); кандидаты на shared (выходной интерфейс, seg encoder, text encoder, late readout). Design review с командой", ["DESIGN.md (C8–C9);", "протокол ревью — WORKLOG.md"] ), ], implRows: [ sectionRow("4. Реализация и тестирование (неделя 5)"), workRow( "4.1", "Реализация primary-варианта за общим API; gin-конфигурация", ["src/fuse_proj/models/fusion/role_aware.py;", "in/config_files/fusion_role_aware.gin"] ), workRow( "4.2", "Тесты: корректный SafeTensors key mapping per view; seg IDs в диапазоне 0..16; mask pooling отсутствующих классов finite; depth НЕ подаётся в satellite path, CHM НЕ подаётся в UAV path; константные карты finite; invalid пиксели не влияют на pooled statistics; spatial alignment после resize; shape [B,1024] и норма", ["tests/test_multimodal_data.py;", "tests/test_role_aware.py"] ), workRow( "4.3", "Diagnostics: вклад классов segmentation; нормы geometry features; вклад text; распределения valid fraction; cosine RGB↔fused; примеры отказов (high-background, flat geometry, empty caption)", ["diagnostics.json в out//"] ), workRow( "4.4", "Взаимное code review: провести ревью кода Павленко (condition-aware); код role-aware ревьюит Близно", ["Замечания и исправления в PR (gitea)"] ), ], ablationRow: workRow( "5.4", "Персональные аблации C-AB1..C-AB10: универсальный оператор vs role-aware; seg dense map vs class tokens; raw vs inverse/gradient depth; raw vs robust/gradient CHM; text FiLM vs cross-attention; text early vs late; spatial-first vs text-first; validity-only vs reliability head; shared vs view-specific geometry projector; global vs hierarchical readout (объём согласуется с командой)", ["IMPLEMENTATION_AND_RESULTS.md"] ), extraStage5: [], materials: [ "Общий пакет: docs/00_project/06_MERIDIAN_CONTEXT.md; docs/02_references/01_required/ (5 документов, особенно Методология аннотирования и CHMv2 vs DAv3); 00_READING_MAP.md", "Канонические цепочки: SPEC_fusion_ACF_MERIDIAN (_version_chain/v1 → v5); СИНТЕЗ_3_fusion.md; ANALYSIS_FiLM_alternatives_taxonomy (база → v4)", "TRIAGE_teacher_fusion_dropout_2026-06-11.md — §6a (re-read: P44, M4, F63, B97, P52) и сквозные выводы", "Segmentation: REVIEW_segmentation_pairA; DELTA pair A (цепочка); ОБЗОР_fusion_rgb_segmentation_v1; F36 FC-CLIP; P52", "Geometry: REVIEW_depth_normals_pairB; DELTA pair B (цепочка); REVIEW_chm_pairC; DELTA pair C (цепочка); M11 CHMv2; M4 JRN-Geo; P44 MGS²; ОБЗОР_fusion_rgb_chm_v1", "Text: REVIEW_text_pairD_methodology; REVIEW_text_pairD_final; F14 WeatherPrompt deep dive; F47 TacFiLM; P64 CGSI; C5 WeatherPrompt", "Код: vendor_reference/depth_edges_annotate_worlduav/ (seg_classes.py — 17 классов; io_utils.py — SafeTensors; inference.py — нормализация); vendor_reference/caption_test/src/datasets/; docs/03_codebase_guides/ANNOTATION_PROJECT_CODE_MAP.md", ], }, ]; // --------------------------------------------------------------------------- // Document assembly // --------------------------------------------------------------------------- const MILESTONES = [ ["M0", "Окружение и данные доступны; материалы изучены", "1"], ["M1", "Interface frozen (INTERFACE_DECISION.md)", "2"], ["M2", "RGB-only baseline B0 воспроизведён; B1–B3 готовы", "3"], ["M3", "Три design reports приняты на совместном ревью", "4"], ["M4", "Три реализации проходят общие тесты", "5"], ["M5", "Smoke benchmark завершён", "6"], ["M6", "Primary comparison завершён (3 seeds для финалистов)", "7"], ["M7", "Аблации и статистика завершены", "8"], ["M8", "Принято решение primary/fallback/research-arm", "8"], ]; function buildDoc(emp) { const approval = [ p("УТВЕРЖДАЮ:", { indent: { left: 5400 }, spacing: { after: 0 } }), p("и.о. директора ФГБНУ «ИПИ»", { indent: { left: 5400 }, spacing: { after: 0 } }), p("_____________ С. Б. Иванова", { indent: { left: 5400 }, spacing: { after: 0 } }), p("«___» ____________ 2026 г.", { indent: { left: 5400 }, spacing: { after: 240 } }), ]; const title = [ p("План заданий", { bold: true, align: AlignmentType.CENTER, spacing: { after: 0 } }), p(`сотрудника ЛИСАД ${emp.shortName} на период выполнения проекта fuse_proj`, { align: AlignmentType.CENTER, spacing: { after: 0 }, }), p("с «___» __________ 2026 г. по «___» __________ 2026 г. (8 недель)", { align: AlignmentType.CENTER, spacing: { after: 200 }, }), p( "Тема: Объединение модальностей (RGB, текст, сегментация, геометрия) в Teacher-модели системы перекрёстной геолокализации БПЛА (проект fuse_proj, прокси StripNet + GTA-UAV-LR)", { bold: true, align: AlignmentType.JUSTIFIED, spacing: { after: 60 } } ), p("Руководитель: Я.С. Пикалёв.", { align: AlignmentType.JUSTIFIED, spacing: { after: 0 } }), p(`Исполнитель: ${emp.fullName}.`, { align: AlignmentType.JUSTIFIED, spacing: { after: 0 } }), p(`Направление: ${emp.track}; командная роль — ${emp.teamRole}.`, { align: AlignmentType.JUSTIFIED, spacing: { after: 60 }, }), p([ run("Исследовательский вопрос: ", { bold: true }), run(emp.question), ], { align: AlignmentType.JUSTIFIED, spacing: { after: 200 } }), ]; const tableRows = [ headerRow(), numbersRow(), sectionRow(`Исполнитель: ${emp.shortName.split(" ").reverse().join(" ")}`), ...stage1Rows(emp.personalPackage, emp.roleRow), ...stage2Rows(), ...emp.designRows, ...emp.implRows, ...stage5Rows(emp.ablationRow, emp.extraStage5), ...stage6Rows(emp.surnameLat, emp.taskFile), ]; const workTable = new Table({ alignment: AlignmentType.CENTER, layout: TableLayoutType.FIXED, width: { size: TABLE_W, type: WidthType.DXA }, columnWidths: COLS, rows: tableRows, }); const materials = [ p("Обязательные материалы для изучения", { bold: true, spacing: { before: 240, after: 60 } }), p( "Все материалы — физические копии внутри репозитория fuse_proj; доступ к Obsidian vault не требуется. Канонические документы читать цепочкой: полная база из _version_chain/ + верхняя дельта (00_READING_MAP.md §0).", { align: AlignmentType.JUSTIFIED, spacing: { after: 80 } } ), ...emp.materials.map((m) => new Paragraph({ numbering: { reference: "materials", level: 0 }, alignment: AlignmentType.JUSTIFIED, spacing: { after: 40 }, children: [run(m)], }) ), ]; const msTable = new Table({ alignment: AlignmentType.CENTER, layout: TableLayoutType.FIXED, width: { size: TABLE_W, type: WidthType.DXA }, columnWidths: [1100, 6264, 1981], rows: [ new TableRow({ tableHeader: true, children: [ cell("Веха", 1100, { bold: true, align: AlignmentType.CENTER }), cell("Проверяемый результат", 6264, { bold: true, align: AlignmentType.CENTER }), cell("Неделя", 1981, { bold: true, align: AlignmentType.CENTER }), ], }), ...MILESTONES.map(([m, r, w]) => new TableRow({ children: [ cell(m, 1100, { align: AlignmentType.CENTER }), cell(r, 6264), cell(w, 1981, { align: AlignmentType.CENTER }), ], }) ), ], }); const constraints = [ p("Общие ограничения", { bold: true, spacing: { before: 240, after: 60 } }), ...[ "Запрещено использовать GPS, координаты, имена локаций и признаки парной view внутри encoder.", "Запрещено менять split, loss, sampler или gallery только для одного варианта; изменение общего протокола — только через RFC и запись в INTERFACE_DECISION.md.", "Стохастическое отключение модальностей в training loop не входит в задание; leave-one-modality-out — только как оценочная аблация.", "Метрики не выбираются после просмотра результатов; failed runs не скрываются из отчётов.", "Auxiliary-карты не кодируются как цветные RGB-изображения для обучения; PNG — только для визуальной проверки.", "Финальное сравнение — минимум на 3 seeds (42/123/456); все run-артефакты содержат config snapshot, git commit и seed.", ].map((t) => new Paragraph({ numbering: { reference: "constraints", level: 0 }, alignment: AlignmentType.JUSTIFIED, spacing: { after: 40 }, children: [run(t)], }) ), ]; const signatures = [ p(" ", { spacing: { before: 240, after: 0 } }), p([run("Руководитель"), run("\t_____________ Я.С. Пикалёв")], { tabStops: [{ type: TabStopType.RIGHT, position: TabStopPosition.MAX }], spacing: { after: 120 }, }), p([run("Исполнитель"), run(`\t_____________ ${emp.shortName}`)], { tabStops: [{ type: TabStopType.RIGHT, position: TabStopPosition.MAX }], spacing: { after: 0 }, }), ]; return new Document({ styles: { default: { document: { run: { font: FONT, size: SZ }, paragraph: { spacing: { after: 60 } } }, }, }, numbering: { config: [ { reference: "materials", levels: [{ level: 0, format: LevelFormat.DECIMAL, text: "%1.", alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 426, hanging: 426 } } }, }], }, { reference: "constraints", levels: [{ level: 0, format: LevelFormat.DECIMAL, text: "%1.", alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 426, hanging: 426 } } }, }], }, ], }, sections: [{ properties: { page: { size: { width: 11906, height: 16838 }, // A4 margin: { top: 1134, right: 850, bottom: 1134, left: 1701 }, }, }, children: [ ...approval, ...title, workTable, ...materials, p("Контрольные точки", { bold: true, spacing: { before: 240, after: 60 } }), msTable, ...constraints, ...signatures, ], }], }); } const OUT_DIR = path.resolve(__dirname, ".."); (async () => { for (const emp of EMPLOYEES) { const doc = buildDoc(emp); const buf = await Packer.toBuffer(doc); const out = path.join(OUT_DIR, emp.file); fs.writeFileSync(out, buf); console.log("written:", out, buf.length, "bytes"); } })();