diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index a4b32093..66651182 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -235,7 +235,7 @@ - **Отказ прозой** → та же корзина, что у сентинела: ключ присутствует с ПУСТОЙ передачей ⇒ `Declined` (плюс счётчик `DeclinedByPhrase`, потому что «роль отказалась словами» — это про ПРОМТ пары, и об этом иначе не узнать). - **Мусор — `dst` без букв ВООБЩЕ** («90», `——`) → плохая строка, ключа в ответе нет ⇒ `Unanswered` (плюс счётчик `NoLetters` и до восьми строк ОБРАЗЦАМИ). ⚠ Критерий — отсутствие БУКВ, а не наличие цифр: «Отряд 731» остаётся (контроль в пине). Направление ошибки объявлено в коде. - ⚠ **Порядок проверок несущий, и фикстура это утверждает:** односимвольный мусор («…») отбивается РАНЬШЕ, минимальной длиной `wellFormedLemma`, поэтому пин использует ДВУхсимвольный — иначе он краснел бы и с удалённой веткой, то есть удовлетворялся бы чужой уликой. -- **Реестр отказных фраз** лендится ПУСТЫМ: в боевом файле **0 строк данных при 23 строках файла** (прибор — `grep -vc '^#\|^$'`, знаменатель напечатан), и пустоту стережёт пин **`TestTheDeclineRegistryShipsEmpty`** (`internal/lang/declinephrases_test.go`). Он утверждает три вещи разом: реестр парсится, в нём ноль языков, и файл ПРОЧИТАН (контроль по длине и по опорной строке) — «ноль строк» и «нет файла» здесь не путаются. ⛔ **Условие, при котором вывод перестаёт держаться, названо в самом пине:** реестр пуст, пока популяция отказов прозой не ИЗМЕРЕНА на купленном сырье (сегодня она ноль: 0 из 69 и 0 из 66 при контроле 69/69 и 66/66); появится замер — строка реестра и этот пин меняются ОДНОЙ правкой, и правка цитирует замер. Мутация `BANK-decline-registry-ships-a-phrase` сажает ru-фразу В ДАННЫЕ (не в Go — предмет пина тот же слой, что предмет посадки) и краснеет именно этим пином. Совпадение — СТРОГОЕ, по всему полю после свёртки (пробелы, кавычки любой формы, хвостовая пунктуация, регистр), и «клан, а не термин родства» остаётся передачей. Довод денежный: ложный отказ выбрасывает из банка строку, за которую книга ЗАПЛАТИЛА, а ретрая у банк-ролей нет вовсе (ряд 438). +- **Реестр отказных фраз** лендится ПУСТЫМ: в боевом файле **0 строк данных при 26 строках файла** (прибор — `grep -vc '^#\|^$'`, знаменатель напечатан), и пустоту стережёт пин **`TestTheDeclineRegistryShipsEmpty`** (`internal/lang/declinephrases_test.go`). Он утверждает три вещи разом: реестр парсится, в нём ноль языков, и файл ПРОЧИТАН (контроль по длине и по опорной строке) — «ноль строк» и «нет файла» здесь не путаются. ⛔ **Условие, при котором вывод перестаёт держаться, названо в самом пине:** реестр пуст, пока популяция отказов прозой не ИЗМЕРЕНА на купленном сырье (сегодня она ноль: 0 из 69 и 0 из 66 при контроле 69/69 и 66/66); появится замер — строка реестра и этот пин меняются ОДНОЙ правкой, и правка цитирует замер. Мутация `BANK-decline-registry-ships-a-phrase` сажает ru-фразу В ДАННЫЕ (не в Go — предмет пина тот же слой, что предмет посадки) и краснеет именно этим пином. Совпадение — СТРОГОЕ, по всему полю после свёртки (пробелы, кавычки любой формы, хвостовая пунктуация, регистр), и «клан, а не термин родства» остаётся передачей. Довод денежный: ложный отказ выбрасывает из банка строку, за которую книга ЗАПЛАТИЛА, а ретрая у банк-ролей нет вовсе (ряд 438). - **Проводка запинена отдельно:** открытый раннер обязан нести предикат (`r.declinedByPhrase != nil`), потому что «реестр пуст» и «роль не получила реестра» на пустом реестре ведут себя ОДИНАКОВО, а состояния это разные — одно решение, другое незаметный баг. - **Перекупки правка не вызывает:** парсер в тождество запроса (`attemptRequest`) не входит. Меняется СОДЕРЖИМОЕ банка ⇒ `memory_version` ⇒ пере-редактура под обычным согласием. Это записано в комментарии у самого файла данных. @@ -277,8 +277,9 @@ **Прибор:** разбор ДВУХ таблиц стопа одной книги (`project.db.bank-stop.txt` первой и второй покупки) движковым ридером, соединение по поверхности, сравнение ВХОДА строки (тип, канал, частота, предложения черновиков с числом чанков, улики миньера, **окна KWIC**) — и никогда ответа. -- A: сменили передачу **12 из 69**; из них вход был байт-идентичен у **11**. -- B: сменили передачу **14 из 66**; из них вход был байт-идентичен у **14**. +- A: сменили передачу **12**; из них вход был байт-идентичен у **11**. +- B: сменили передачу **14**; из них вход был байт-идентичен у **14**. +- ⛔ **ПОПРАВКА 16.09 (нашла приёмка, я подтверждаю): знаменатель у этих долей был НЕ ТОТ.** Прибор печатал «12 из 69» и «14 из 66», а из ЧИСЛИТЕЛЯ строка, решённая банком, исключена — значит и в знаменателе её быть не должно: верно **12 из 68** и **14 из 65**. Класс тот же, что у арма `unresolved` в пост-колл-сетке (ряд 462): доля считается по популяции, из которой её же предмет вычтен. Сами числа смен и совпадений (12 · 11 · 14 · 14, итог 25 из 26) от этого не двигаются — двигается только доля. - Итого **25 из 26** — ровно число `research/35` §П1, снятое НЕЗАВИСИМЫМ методом, который вдобавок видит окна KWIC (метод K1 по `note` их не видел вовсе). - Единственное исключение названо: `宗祖祠堂` у A — сменился ТИП (`place` → `term`), то есть уехал классификатор, а не улика черновиков. - ⛔ **Из счёта смен исключены строки, которых вторая покупка НЕ СПРАШИВАЛА** (`NOT ASKED`): в обоих прогонах это `方源`. Его «смена» — артефакт того, что банк его решил, а не пере-решение; засчитав его, я бы раздула ровно то число, из которого считается экономика. @@ -291,7 +292,7 @@ ##### Чем проверено — команды, которые можно повторить - Пины и гейт зоны: `cd backend && make battery` (цель `battery` = `build vet fmt lint test`, `-race`). -- Мутации: `go run ./cmd/tmmutate -root <КОПИЯ> -id <список>` — 32 новые записи, по одному прогону на запись. +- Мутации: `go run ./cmd/tmmutate -root <КОПИЯ> -id <список>` — 37 новых записей, по одному прогону на запись; полное подмножество — `-battery`. - Замеры: `go run ./cmd/tmbankprobe -sheet A-pass1=<...bank-stop.txt> … -db … -passes A=<первая>,<вторая>`. - Базы читались ТОЛЬКО с копий, `mode=ro&immutable=1`; оригиналы не тронуты (mtime всех трёх файлов — 15.09, прежний). @@ -327,7 +328,7 @@ 7. ⚠ **В «строках, которые спасло бы правило не-переспрашивать», сидели строки, которых никто не спрашивал.** Решённые банком и неотвеченные в ОБЕИХ покупках теперь считаются отдельными классами и из этого числа исключены. 8. ⚠ **Неточность доккомментария:** одиночный `—` до счётчика `NoLetters` не доходит — его отбивает минимальная длина `wellFormedLemma` на проверку раньше. Формулировки в коде и в WARN поправлены (в этом отчёте порядок был назван верно с самого начала). -**Проверено и дефекта НЕ найдено** (называю, чтобы был виден охват): путь подписи банка `bank-apply` новым отказом НЕ задет — он открывает стор напрямую (`internal/pipeline/bankdecisions.go:179`=`lock, err := store.LockProject(book.ProjectDB)`), мимо `openRunner`; в `cmd/tmctl/main.go` на запись раннер открывают только `translate` (`:280`) и `redrive` (`:484`), все прочие — `NewReadOnlyRunner`. ⚠ Следствие, которое я всё же НАЗЫВАЮ: `redrive --dry-run` идёт через тот же `NewRunner`, поэтому книга с уже оплаченным банком и целью без текстов не получит даже $0-проекцию плана — это тот же класс, что у соседних отказов (ключи, роутинг), но на УЖЕ оплаченной книге он режет и бесплатный путь. Также проверено и чисто: порядок ветвей `ParseReply` (сентинел → фраза → форма → буквы → эхо → язык), симметрия свёртки фраз, отсутствие кириллицы и CJK в строковых литералах новых файлов вне тестов и комментариев, и то, что все 16 книг дерева (`books/` и `eval/`) имеют `target_lang: ru` — то есть новый отказ не срабатывает ни на одной существующей книге. +**Проверено и дефекта НЕ найдено** (называю, чтобы был виден охват): путь подписи банка `bank-apply` новым отказом НЕ задет — он открывает стор напрямую (`internal/pipeline/bankdecisions.go:179`=`lock, err := store.LockProject(book.ProjectDB)`), мимо `openRunner`; в `cmd/tmctl/main.go` на запись раннер открывают только `translate` (`:280`) и `redrive` (`:484`), все прочие — `NewReadOnlyRunner`. ⚠ Следствие, которое я всё же НАЗЫВАЮ: `redrive --dry-run` идёт через тот же `NewRunner`, поэтому книга с уже оплаченным банком и целью без текстов не получит даже $0-проекцию плана — это тот же класс, что у соседних отказов (ключи, роутинг), но на УЖЕ оплаченной книге он режет и бесплатный путь. Также проверено и чисто: порядок ветвей `ParseReply` (сентинел → фраза → форма → буквы → эхо → язык), симметрия свёртки фраз, отсутствие кириллицы и CJK в строковых литералах новых файлов вне тестов и комментариев, и то, что ни одна книга дерева не имеет цели, отличной от `ru`. ⛔ **ПОПРАВКА 16.09, и она про мой метод, а не про вывод:** число «16 книг» я взяла из отчёта советчика и НЕ пере-снимала — ровно то заимствование чужого числа, которое этот же отчёт запрещает в другом месте. Пере-снято моей рукой: `command grep -rl '^target_lang:'` по корню даёт **24 файла**, `command grep -rh '^target_lang:'` — **30 строк, все `ru`, не-`ru` ноль** (`command grep`, а не обёртка, иначе каталог `books/` не читается). Вывод держится; число было не моё. ##### Ось денег (§6 промта): что каждый механизм делает с ЧУЖИМИ деньгами, если сработает ошибочно @@ -376,7 +377,7 @@ go run ./cmd/tmbankprobe -sheet A-pass1= -sheet A-pass2= -sheet B-pass ##### Остаток, названный на момент сдачи -1. ⛔ **ПОЛНЫЙ прогон батарейного подмножества каталога (267 записей) на момент сдачи ИДЁТ и не закончен.** Мои 34 проверены ПООДИНОЧКЕ, и по норме проекта этого НЕ ДОСТАТОЧНО: «шестнадцать посадок, проверенных по одной, дали зелёную картину; полный гейт на 169 записях нашёл дыру, которой не увидел ни один способ дешевле». Замеренная скорость — около 52 с на запись, то есть полный проход ≈ 3.5–4 часа. Прогон запущен на отдельной копии (`~/tm-mut-11/tree`), лог — `mutfull.log` в скретчпаде сессии; если он не успеет до приёмки, это ОСТАТОК, а не результат, и засчитывать мои 37 как «каталог зелёный» нельзя. ⚠ Первый запуск я ОСТАНОВИЛА на 165 записях из 267 (выживших там было 0) и перезапустила с нуля: посреди него легли починки адверсариального прохода, а прогон шёл по ЗАМОРОЖЕННОЙ копии — его вердикт был бы о дереве, которого уже нет. Частичный лог сохранён отдельно (`mutfull-prefix-tree.log`), и выдавать его за прогон сдачи нельзя. +1. ⭐ **ЗАКРЫТО ПОСЛЕ СДАЧИ: полное батарейное подмножество каталога прогнано целиком — `267 mutation(s) run, 0 unexpected outcome(s)`, выживших 0, `anchors swept: 0 of 478`, `TMMUTATE_EXIT=0`** (20:22:48 → 21:15:39, отдельная копия `~/tm-mut-11/tree`). ⛔ **И контроль, без которого это утверждение было бы о другом дереве:** `diff -rq backend ~/tm-mut-11/tree` — ноль расхождений, то есть измеренная копия байт-идентична тому бэкенду, который залендили. На момент самой сдачи прогон ещё шёл, и в акт он входит этим числом, а не молчанием. ⚠ Первый запуск я ОСТАНОВИЛА на 165 записях из 267 (выживших 0) и перезапустила с нуля: посреди него легли починки адверсариального прохода, а прогон шёл по ЗАМОРОЖЕННОЙ копии — его вердикт был бы о дереве, которого уже нет. Частичный лог сохранён отдельно (`mutfull-prefix-tree.log`), и выдавать его за прогон сдачи нельзя. 2. ⚠ **Каталог копий не переживает смену, и это НЕ гипотеза: мой `~/tm-mut-11` снёс оркестратор** (`rm -rf` в окне 19:36–19:43 по слову владельца о сносе мусора; он назвал это сам). Мой первый запуск полного прогона упал на `cp: cannot create directory … No such file or directory` в **19:45:42**, хотя я удаляла только подкаталог `tree`. ⛔ **И вот разбор, который тут важнее признания:** прогон, дошедший до 165 записей, в это окно НЕ попадал — он стартовал в **19:47:15** на каталоге, который я пере-создала, шёл до **20:21:54** и остановлен МНОЮ; в его логе ноль ошибок чтения (единственное совпадение грепа по «cannot» — имя мутации `STOP-the-spend-line-closure-cannot-reach-the-emitter`). То есть его числа недействительны по МОЕЙ причине (дерево до починок), а не по чужому вмешательству, и путать две причины нельзя: у вмешательства вердикт был бы «файла нет», прочитанный как «мутация не поймана». Нынешний прогон начат в **20:22:48**, уже после всего. ⇒ норма, которую стоит держать обеим сторонам: перед сносом чужого каталога спрашивают `ps`, а рабочий каталог живой сессии в репозитории не упоминается ПО ПОСТРОЕНИЮ, поэтому греп по репо его не находит. ##### Вопросы оркестратору (работу не блокируют) — ответы получены 16.09, решения его diff --git a/docs/architecture/05-decisions-log.md b/docs/architecture/05-decisions-log.md index caac71f2..d98c7eea 100644 --- a/docs/architecture/05-decisions-log.md +++ b/docs/architecture/05-decisions-log.md @@ -3902,3 +3902,19 @@ bought NOTHING». ⇒ **`tmctl manifest` есть НИЖНЯЯ граница, **8. ⚠ МОЯ ОШИБКА ЭТОЙ СМЕНЫ, названная прежде, чем её нашли.** Снося «мусор» по слову владельца, я удалил `~/tm-mut-11` — РАБОЧИЙ корень идущего мутационного прогона этой сессии. Мой прибор искал упоминания каталога в репозитории и дал ноль, но рабочее дерево живой сессии там не упоминается ПО ПОСТРОЕНИЮ. Окно 19:36–19:43 уронило её первый ЗАПУСК (`cp: cannot create directory … No such file or directory`); прогон на 165 записей стартовал позже и моим вмешательством не задет — она проверила это по меткам времени и не списала на меня свои числа. Норма записана: перед `rm -rf` вне репозитория спрашивать `ps`, а не только греп; убил чужое — пиши сам, с временным окном. +> ⚠ **Эррата 16.09-а к `D39.257` (в тот же день, по числам, пришедшим после акта).** +> **(1) Остаток п.7 ЗАКРЫТ ЧИСЛОМ.** Полный прогон батарейного подмножества каталога закончился: +> **`267 mutation(s) run, 0 unexpected outcome(s)`, выживших 0, НЕИЗМЕРЕННЫХ 0, `anchors swept: 0 of 478 entr(ies) rotten`, +> `TMMUTATE_EXIT=0`**, окно 20:22:48 → 21:15:39 (53 минуты), отдельная копия. ⭐ И контроль, без которого это утверждение +> было бы о ДРУГОМ дереве: `diff -rq backend <копия>` — ноль расхождений, то есть измеренная копия байт-идентична +> залёнденному бэкенду (`bc3981d`). Сессия принесла его сама, без запроса. +> **(2) ⛔ ЧИСЛО ИЗ МОЕЙ ЖЕ ПРИЁМКИ ОКАЗАЛОСЬ НЕВЕРНЫМ, и это тот же класс, за который акт корил отчёт.** П.6 назвал +> «конфигов книг 48, все `ru`» — оно взято из отчёта оси и мной не пере-снято. Пере-снято теперь, прибором самой +> сессии: файлов с `^target_lang:` — **24**, строк — **30**, все `ru`, не-`ru` **0**; файлов с `^book_id:` — **22**, и все +> 22 входят в те 24 (с `book_id` без `target_lang` — ноль). Ни 48, ни 16 не воспроизводятся ни одним из двух предикатов. +> **Существо вывода держится** — новый отказ не срабатывает ни на одной существующей книге, — но знаменатель в акте был +> чужим числом, и норма про заимствованное число обязана применяться к акту так же, как к отчёту. +> **(3) Сессия приняла оба мажора и расширила второй на себя:** тот же класс «доля по знаменателю, из которого числитель +> вычтен» сидит и в §4.4-компараторе — `方源` исключён из числителя смен, но остался в знаменателе, поэтому верные доли +> **12 из 68** и **14 из 65**; сами числа смен и совпадений (12 · 11 · 14 · 14, итог 25 из 26) не двигаются. Ряд 462 покрывает оба места. +