fix(ночь): из четырёх разъездов настоящий один — закрыт; починка пятого ломала чужого сторожа

Находка М-405, правила 242-243.

Смена 26 назвала четыре разъезда (правило 239: обёртка есть, а работа идёт мимо).
Проверил каждый замером — НАСТОЯЩИЙ ОДИН, три ложные тревоги. Ровно та же доля, что
и в разборе 33 долгов: список, собранный беглым взглядом под верным правилом, оказался
наполовину чужим.

 - `readEvents` —  обвинённые делают ДРУГУЮ работу: судья ленту вовсе не читает (только
   проверяет, есть ли файл), а `zhiv-li-progon.mjs` разбирает её своим путём НАРОЧНО —
   `readLines` порванную строку глотает молча, а ему она обязана значить «неизвестно».
   Свёл бы «как велено» — сломал бы нарочную защиту;
 - `vorotaVetkiNochi` —  настоящий, закрыт этим коммитом;
 - `schyotZovushchih` —  общее уже вынесено в `tolkoKod`+`zovyImeni`, обе дороги через него;
 - читалки `schyot-zamerov.mjs` —  живой дороге нужны порванные строки, читалкам нет.

ЧТО ПОЧИНЕНО. `sverkaNastroek` делала «спросить хранилище и разобрать ответ» своими руками —
тем же телом, что лежит внутри ворот `vorotaVetkiNochi`. Дороги уже начали расходиться
МОЛЧА: у ворот умолчание «спрашивать каждый раз», у сверки — «помнить ответ на заход».
Сегодня это не видно ничем, потому что сверка всегда передаёт свой `sprosit` явно, — но
поправь кто-нибудь ворота, и починка до живой дороги не доехала бы.

Доказано вырезанием: разъезд возвращён — краснеет ровно одна, посчитал ДО прогона, сошлось.
Страховка починки отдельной проверкой: ворота и прежняя прямая пара отвечают одинаково
на обоих исходах, включая бросок хранилища, — поведение не изменилось ни на знак.

🔴 ГЛАВНОЕ, ЧТО КУПИЛА СМЕНА, И КУПЛЕНО ЭТО СВОЕЙ ОШИБКОЙ. Замер нашёл рядом пятый разъезд
на вид настоящий: имя ленты `events.jsonl` написано РУКАМИ в трёх местах, хотя обёртка
`eventsPath` заведена ровно затем, чтобы оно жило в одном. Свёл — и полный прогон дал две
красных, ОБЕ У ЧУЖОГО СТОРОЖА, ни одной у моего.

`nadziratel-obyavlyaetsya-a-pribor-chitaet.test.mjs` (сеть 3) требует ПРОТИВОПОЛОЖНОГО:
путь к журналу не берёт себе никто, кроме дома ленты, — потому что взявший однажды начнёт
в журнал ПИСАТЬ мимо единственной пишущей руки `logEvent`, и сети, считающие её зовы,
ослепнут молча. А от них зависит, не запустят ли второй прогон на те же файлы. Разъезд же
имён он закрывает не сведением, а СВЕРКОЙ: читает оба написания и краснеет, если разошлись.

⇒ Беда, которую я шёл закрывать, была уже закрыта — другим способом, которого я не увидел.
Откачено целиком, чужого сторожа не тронул ни знаком, своего убрал и оставил на его месте
записку следующей смене, чтобы она не потеряла тот же час.

242. КРАСНОЕ НА ЧУЖОМ СТОРОЖЕ ПОСЛЕ ТВОЕЙ ПРАВКИ — НЕ ПОМЕХА, А ОТВЕТ: место, которое ты
счёл беззащитным, охраняется, и не так, как ты собирался его чинить.
243. У СПИСКА, СОБРАННОГО ПОД СВЕЖИМ ПРАВИЛОМ, ПРОВЕРЬ КАЖДУЮ СТРОКУ ОТДЕЛЬНО: правило
проверяют мыслью, список — замером, и это две разные работы.

ПОПУТНО: два реза сведены в один дом. `bezPrimechaniy` перенесён к грубому `tolkoKod`
с развилкой «какой брать». Врозь они и стоили смене 26 сторожа, который физически не мог
покраснеть: искала команду, живущую строкой, а взяла рез, который строки режет (правило 234).

🪤 Мелочь, стоившая ложной тревоги: копия утренней бумаги помечена временем МИРОВЫМ
(`toISOString`), а часы на машине московские. Разница три часа — и след моего же прогона
выглядел работой чужой смены, пришедшей после конца предыдущей.

Проверок 2927 в 108 файлах (было 2924 в 107), ноль красных, код 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-08-07 05:08:17 +03:00
parent 5d87423edb
commit 0781b1be8c
8 changed files with 252 additions and 29 deletions
@@ -10768,3 +10768,63 @@ const s = `ушло ${dollary(x)} денег`; → после чистки:
`zadachaKonchena`: «**зовут его двое**». Живого зова нет ни одного. При этом в `supervisor.mjs`
про то же самое сказано честно — «ИМЕННО ЭТА СТРОКА заменяется на зов», в будущем времени.
🔑 **Разница между враньём и честностью тут — одно время глагола.**
---
## М-405. Смена 27: правило было верным, а список под ним — нет
**07.08.2026.** Развилка окупилась **седьмой раз подряд**: новой ночи не было, все шесть
приборов годны. Взялся за пункт 3 промта — «четыре разъезда», найденных сменой 26.
> 🔴 **ГЛАВНОЕ ЧИСЛО СМЕНЫ. Из четырёх разъездов настоящим оказался ОДИН.**
> Три из четырёх — ложные тревоги, ровно как 14 из 33 в смене 26.
| кого смена 26 назвала разъездом | что показал замер |
|---|---|
| `readEvents` | ❌ обвинённые дороги делают **другую работу**: судья ленту вовсе не читает, а `zhiv-li-progon.mjs` разбирает её своим путём **нарочно** (`readLines` порванную строку глотает молча, а ему нужен ответ «неизвестно») |
| `vorotaVetkiNochi` | ✅ **настоящий** — тело повторено дословно, и умолчания уже разошлись |
| `schyotZovushchih` | ❌ общая работа уже вынесена (`tolkoKod` + `zovyImeni`), обе дороги идут через неё |
| читалки `schyot-zamerov.mjs` | ❌ живой дороге нужны порванные строки, читалкам нет — это **разные работы** |
**242. 🔑 КРАСНОЕ НА ЧУЖОМ СТОРОЖЕ ПОСЛЕ ТВОЕЙ ПРАВКИ — НЕ ПОМЕХА, А ОТВЕТ.**
Оно говорит: место, которое ты счёл беззащитным, **охраняется — и не так, как ты собирался
его чинить**. Спроси сперва, что этот сторож бережёт, и лишь потом решай, кто из вас прав.
Куплено живой ценой. Замер показал: имя ленты `events.jsonl` написано руками в трёх местах,
хотя обёртка `eventsPath` заведена ровно затем, чтобы оно жило в одном. Свёл — и полный
прогон дал две красных, **обе у чужого сторожа, ни одной у моего**. Оказалось,
`nadziratel-obyavlyaetsya-a-pribor-chitaet.test.mjs` требует ПРОТИВОПОЛОЖНОГО:
- путь к журналу не берёт себе никто, кроме дома ленты, — потому что **взявший однажды
начнёт в журнал писать** мимо единственной пишущей руки, и сети, считающие её зовы,
ослепнут молча (а от них зависит, не запустят ли второй прогон на те же файлы);
- разъезд имён он закрывает не сведе́нием, а **сверкой**: читает оба написания и краснеет,
если они разошлись.
⇒ Беда, которую я шёл закрывать, была уже закрыта — **другим способом**. Откатил целиком,
чужого сторожа не тронул ни знаком, своего убрал.
**243. 🪤 У СПИСКА, СОБРАННОГО ПОД СВЕЖИМ ПРАВИЛОМ, ПРОВЕРЬ КАЖДУЮ СТРОКУ ОТДЕЛЬНО.**
Правило 239 записано верно, а четыре примера под ним собраны беглым взглядом — и три
оказались чужими. 🔑 Верное правило не делает верным список, собранный под него: правило
проверяют мыслью, список — замером, и это две разные работы.
### 🪤 Мелочь, стоившая тревоги: имя файла в чужом поясе
Копия утренней бумаги помечена `…prezhnyaya-2026-08-07-013624.md`, а смена 26 кончилась
в 23:25 — то есть кто-то трогал бумагу ПОСЛЕ неё. Чужой смены не было: имя пишется через
`toISOString()`, то есть **в мировом времени**, а часы на машине московские. Разница ровно
три часа, след оставил мой же прогон в 04:36.
🔑 Датчик, читающий такое имя как местное время, обвиняет несуществующую смену.
### Что сделано
🟢 **Настоящий разъезд закрыт.** `sverkaNastroek` делала «спросить хранилище и разобрать
ответ» своими руками — тем же телом, что лежит внутри ворот `vorotaVetkiNochi`. Дороги уже
начали расходиться молча: у ворот умолчание «спрашивать каждый раз», у сверки — «помнить
ответ на заход». Теперь дорога одна.
**Доказано вырезанием:** разъезд возвращён — краснеет ровно одна, названная заранее.
🟢 **Два реза сведены в один дом.** `bezPrimechaniy` перенесён к грубому `tolkoKod`
с развилкой «какой брать». Врозь они и стоили смене 26 сторожа, который физически не мог
покраснеть: искала команду, живущую строкой, а взяла рез, который строки режет.
@@ -52,6 +52,24 @@ app/vitest.config.tools.mjs:56 → globalSetup: ['../tools/night/storozh-boevo
🪤 **Четыре из них — один и тот же новый род:** «работа делается, но мимо обёртки».
Две дороги к одному файлу могут разъехаться молча — это мелкий долг, но не мёртвый код.
> ## 🔴🔴 ПОПРАВКА СМЕНЫ 27: ИЗ ЧЕТЫРЁХ РАЗЪЕЗДОВ НАСТОЯЩИЙ ОДИН
>
> Список выше собран беглым взглядом. Смена 27 проверила каждую строку замером:
>
> | кого назвали | правда |
> |---|---|
> | `readEvents` | ❌ обвинённые делают **другую работу**: судья ленту не читает вовсе, а `zhiv-li-progon.mjs` разбирает её своим путём **нарочно** — ему нужен ответ «неизвестно» на порванной строке |
> | `vorotaVetkiNochi` | ✅ **настоящий**, закрыт сменой 27 |
> | `schyotZovushchih` | ❌ общее уже вынесено в `tolkoKod` + `zovyImeni`, обе дороги идут через него |
> | читалки `schyot-zamerov.mjs` | ❌ живой дороге нужны порванные строки, читалкам нет — разные работы |
>
> 🔑 **Правило 243:** верное правило не делает верным список, собранный под него.
> Правило проверяют мыслью, список — замером. Это две разные работы.
>
> 🔴 И ещё дороже: замер нашёл рядом настоящий на вид разъезд (имя `events.jsonl` руками
> в трёх местах) — а починка его сломала **чужого сторожа**, который то же место охраняет
> наоборот. Полностью откачено. **Правило 242** — в `2026-08-02-ZAMER-metoda.md`, М-405.
### 🔴 Настоящие долги — 19
**А. Механизм «спросить владельца и принять ответ» — 11 имён, мёртв С ОБЕИХ СТОРОН**
@@ -38,27 +38,21 @@ import { REPO_ROOT } from './paths.mjs';
const NOCH = join(REPO_ROOT, 'tools', 'night');
const chitat = (imya) => readFileSync(join(NOCH, imya), 'utf8');
/**
* Вырезать ТОЛЬКО примечания, оставив строковые значения.
*
* 🔴 ПОЧЕМУ НЕ ЧУЖОЙ `tolkoKod`, ХОТЯ СПЕРВА ВЗЯЛ ИМЕННО ЕГО — И ЭТО БЫЛА ОШИБКА.
* Он вырезает и примечания, И СТРОКИ. Замерено:
* `case 'answer': return otvet();` → `case : return otvet();`
* А команда `cli.mjs` живёт ИМЕННО строкой. То есть сторож, почищенный им, не увидел бы
* заведённую команду НИКОГДА и остался бы вечно зелёным по ложной причине — сторож,
* который физически не может покраснеть, не сторожит ничего.
* ⇒ Правило 234 своими руками: у датчика, который что-то вырезает перед счётом, спрашивай
* не «что он режет», а «не режет ли он вместе с шелухой зерно».
*
* 🪤 Чего стоит этот рез, называю вслух: `//` внутри строкового значения (ссылка `https://`)
* обрежет остаток строки. Для трёх слов, которые тут ищутся, это безразлично, а полного
* разбора языка сторожу не нужно.
*/
export function bezPrimechaniy(text) {
return String(text ?? '')
.replace(/\/\*[\s\S]*?\*\//g, ' ')
.replace(/\/\/[^\n]*/g, ' ');
}
// 🔴 ПОЧЕМУ НЕ ЧУЖОЙ `tolkoKod`, ХОТЯ СПЕРВА ВЗЯЛ ИМЕННО ЕГО — И ЭТО БЫЛА ОШИБКА.
// Он вырезает и примечания, И СТРОКИ. Замерено:
// `case 'answer': return otvet();` → `case : return otvet();`
// А команда `cli.mjs` живёт ИМЕННО строкой. То есть сторож, почищенный им, не увидел бы
// заведённую команду НИКОГДА и остался бы вечно зелёным по ложной причине — сторож,
// который физически не может покраснеть, не сторожит ничего.
// ⇒ Правило 234: у датчика, который что-то вырезает перед счётом, спрашивай не «что он
// режет», а «не режет ли он вместе с шелухой зерно».
//
// 🆕 Смена 27 перенесла сам рез в `schyot-zovushchih.mjs` — К ГРУБОМУ `tolkoKod`, чтобы оба
// стояли рядом с развилкой «какой брать». Врозь они и стоили смене 26 этой ошибки. Проверка
// 1Б ниже стережёт его по-прежнему, откуда бы он ни ввозился.
import { bezPrimechaniy } from './schyot-zovushchih.mjs';
export { bezPrimechaniy };
/**
* Сходится ли примечание с правдой. Оба довода — текстом, чтобы правило можно было
@@ -0,0 +1,115 @@
// 🔴🔴 РАЗЪЕЗД: ОБЁРТКА ЕСТЬ, А РАБОТА ИДЁТ МИМО НЕЁ (правило 239, смена 26).
//
// Заведено сменой 27 после замера, который поправил саму смену 26. Она назвала четыре
// разъезда; глазами проверили каждый — настоящий оказался ОДИН, и вот он:
//
// `vorotaVetkiNochi` (`vetka-nochi-ne-otstayot.mjs:146`) — спросить хранилище и разобрать
// ответ. Ровно то же самое СВОИМИ РУКАМИ делала `sverkaNastroek`
// (`sverka-nastroek-s-resheniyami.mjs`): свой `try/catch`, свой зов `razborVetkiNochi`.
// Тела совпадали до знака.
//
// 🪤 ПОЧЕМУ ЭТО ХУЖЕ, ЧЕМ ПРОСТО ЛИШНИЕ СТРОКИ, И ПОЧЕМУ ЛОВИТЬ НАДО СТОРОЖЕМ, А НЕ ГЛАЗОМ.
// Две дороги к одному месту уже начали расходиться, и молча: у ворот умолчание
// `sprosit = sprosItHranilishche` (спрашивает хранилище КАЖДЫЙ раз), у сверки —
// `sprosItHranilishcheRazVZahod` (помнит ответ на один заход). Сегодня это не видно ничем:
// сверка всегда передаёт свой `sprosit` явно, и умолчание ворот до неё не доезжает. Но
// поправь кто-нибудь ворота — и починка не доедет до живой дороги, потому что живая дорога
// через ворота не идёт. Ровно этот класс правило 239 и называет: «не мёртвый код, а разъезд».
//
// 🔴 ЧТО ЭТОТ СТОРОЖ НЕ ЛОВИТ, ГОВОРЮ ВСЛУХ. Разъезд сегодня ЧИСТО СТРУКТУРНЫЙ: на всяком
// входе обе дороги отвечают одинаково (проверка 2 это и замеряет). Значит поведенческим
// сторожем его поймать нельзя — он был бы зелёным вслепую и не доказывал бы ничего.
// Поэтому проверка 1 читает исходник. Слабость приёма называю честно: он стережёт ИМЯ,
// а не смысл — заведи кто-нибудь третью дорогу под другим именем, сторож промолчит.
import { describe, it, expect } from 'vitest';
import { readFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { tolkoKod, zovyImeni } from './schyot-zovushchih.mjs';
import { razborVetkiNochi, vorotaVetkiNochi } from './vetka-nochi-ne-otstayot.mjs';
const DIR = dirname(fileURLToPath(import.meta.url));
// 🪤 ПРАВИЛО 234 НА ЭТОМ САМОМ МЕСТЕ. `tolkoKod` режет не только примечания, но И СТРОКИ —
// смена 26 обожглась об это, сделав сторожа, который физически не мог покраснеть. Здесь он
// годится, и вот почему: ищем ИМЯ СО СКОБКОЙ (`razborVetkiNochi(`), а имя функции внутри
// строки не живёт. Ищи мы команду или ключ, живущий строкой, — брать его было бы нельзя.
const RODNOY = 'vetka-nochi-ne-otstayot.mjs';
const IMYA = 'razborVetkiNochi';
function zovyRazbora(fayl) {
return zovyImeni(tolkoKod(readFileSync(join(DIR, fayl), 'utf8')), IMYA);
}
describe('работа «спросить ветку и разобрать» идёт ОДНОЙ дорогой', () => {
it('1. никто, кроме самих ворот, не зовёт razborVetkiNochi напрямую', () => {
const zovov = zovyRazbora('sverka-nastroek-s-resheniyami.mjs');
expect(
zovov,
`\n🔴 РАЗЪЕЗД: sverka-nastroek-s-resheniyami.mjs зовёт ${IMYA}() напрямую (${zovov} раз),`
+ `\nминуя ворота vorotaVetkiNochi(), которые ровно это и делают.`
+ `\nЧинить так: позвать vorotaVetkiNochi(imya, { sprosit, zhivoyZapusk }) вместо своего`
+ `\ntry/catch с ${IMYA}. Родной файл ворот — ${RODNOY} — зовёт по праву, он не в счёт.`,
).toBe(0);
});
// 🔴 ВСТРЕЧНЫЙ СТОРОЖ. Без него проверка 1 может стать зелёной оттого, что датчик ослеп
// (переименовали функцию, сломался рез примечаний), — и «ноль зовов» означало бы не
// «дорога одна», а «я ничего не вижу». Ноль обязан быть замеренным, а не пустым.
it('2. ВСТРЕЧНЫЙ: датчик вправду видит зов — в родном файле ворот он его находит', () => {
expect(
zovyRazbora(RODNOY),
`\n🔴 Датчик ОСЛЕП: в родном файле ${RODNOY} зов ${IMYA}() есть заведомо`
+ `\n(им живут сами ворота), а датчик его не видит. Значит ноль в проверке 1`
+ `\nничего не доказывает.`,
).toBeGreaterThan(0);
});
// Страховка починки, а не сторож разъезда — называю честно. Она была зелёной ДО починки
// и обязана остаться зелёной после: доказывает, что дорога стала одна, а ответ не изменился
// ни на знак. Проверяются оба исхода, включая тот, ради которого стоит `try`.
it('3. ворота и прямая пара отвечают ОДИНАКОВО — починка поведения не меняет', () => {
const otvet = { vetkaUgla: 'feat/noch-proba-1', otstavanie: 0, vperedi: 0 };
for (const zhivoyZapusk of [false, true]) {
expect(
vorotaVetkiNochi('feat/noch-proba-1', { sprosit: () => otvet, zhivoyZapusk }),
).toEqual(razborVetkiNochi('feat/noch-proba-1', otvet, { zhivoyZapusk }));
// Хранилище не ответило вовсе — тот самый случай, ради которого у обеих дорог стоит
// `try`: бросок обязан превратиться в «не спросили», а не в обвал.
expect(
vorotaVetkiNochi('feat/noch-proba-1', {
sprosit: () => { throw new Error('хранилище молчит'); },
zhivoyZapusk,
}),
).toEqual(razborVetkiNochi('feat/noch-proba-1', null, { zhivoyZapusk }));
}
});
});
// ━━━ 🔴🔴 ЗАПИСКА СЛЕДУЮЩЕЙ СМЕНЕ: ЗДЕСЬ БЫЛ ВТОРОЙ СТОРОЖ, И Я ЕГО УБРАЛ ━━━
//
// Не поленись прочесть, иначе пойдёшь той же дорогой и потеряешь тот же час.
//
// Смена 27 замерила: имя ленты `events.jsonl` написано РУКАМИ в трёх местах, хотя обёртка
// `eventsPath` заведена ровно затем, чтобы оно жило в одном. Замер верен. Вывод «значит
// это безнадзорный разъезд, надо свести» — НЕВЕРЕН, и цена ошибки была бы велика.
//
// 🔴 Место уже охраняется, просто ИНАЧЕ, чем я ждал. Сторож
// `nadziratel-obyavlyaetsya-a-pribor-chitaet.test.mjs` (сеть 3) требует ПРОТИВОПОЛОЖНОГО:
// · путь к журналу не берёт себе НИКТО, кроме дома ленты, — потому что взявший однажды
// начнёт в журнал ПИСАТЬ мимо единственной пишущей руки `logEvent`, и сети, считающие
// её зовы, ослепнут молча (а от них зависит, не запустят ли второй прогон на те же файлы);
// · а разъезд имён он закрывает не сведе́нием, а СВЕРКОЙ: читает оба написания и краснеет,
// если они разошлись.
//
// Моя починка ломала эту защиту: полный прогон дал две красных — обе у него, не у меня.
//
// 🔑 ПРАВИЛО 242, КУПЛЕННОЕ ЗДЕСЬ: КРАСНОЕ НА ЧУЖОМ СТОРОЖЕ ПОСЛЕ ТВОЕЙ ПРАВКИ — НЕ ПОМЕХА,
// А ОТВЕТ. Оно говорит, что место, которое ты счёл беззащитным, охраняется, и охраняется
// не так, как ты собирался. Спроси сперва, что этот сторож бережёт, и лишь потом решай,
// кто из вас двоих прав. Своего сторожа я убрал, чужого не тронул ни знаком.
//
// 🟡 Осталось открытым и ждёт слова владельца (вопрос 9 промта): развести намерения —
// «читать путь можно, писать мимо `logEvent` нельзя». Это правка ЧУЖОГО сторожа, берегущего
// дорогое, и самовольно я её не делаю.
+26
View File
@@ -101,6 +101,32 @@ function obrazetsLiTut(vydano) {
return PERED_OBRAZTSOM.test(t) || SLOVA_PERED_OBRAZTSOM.test(t);
}
// ━━━ 🔴🔴 ДВА РЕЗА, И ОНИ НЕ ВЗАИМОЗАМЕНИМЫ. РАЗВИЛКА — ЗДЕСЬ ━━━
//
// Стоят рядом НАРОЧНО. Смена 26 обожглась ровно оттого, что они лежали в разных файлах:
// искала команду, живущую строкой (`case 'answer':`), взяла грубый `tolkoKod` — и своими
// руками сделала сторожа, который физически не мог покраснеть. Правило 234.
//
// | что ищешь | какой рез |
// |---|---|
// | ИМЯ СО СКОБКОЙ (зов, `имя(`) | `tolkoKod` — грубый: срежет примечания, строки и образцы |
// | СТРОКУ (`'events.jsonl'`, команду, ключ) | `bezPrimechaniy` — режет ТОЛЬКО примечания |
//
// 🔑 Спрашивай у реза не «что он режет», а «не режет ли он вместе с шелухой зерно».
/**
* Вырезать ТОЛЬКО примечания, оставив строковые значения нетронутыми.
*
* 🪤 Чего стоит этот рез, называю вслух: `//` внутри строкового значения (ссылка `https://`)
* обрежет остаток строки. Полного разбора языка сторожам не нужно, а эта краевая грубость
* им безразлична — но знать про неё обязан тот, кто возьмёт рез для нового дела.
*/
export function bezPrimechaniy(text) {
return String(text ?? '')
.replace(/\/\*[\s\S]*?\*\//g, ' ')
.replace(/\/\/[^\n]*/g, ' ');
}
export function tolkoKod(text) {
let out = '';
let i = 0;
+3
View File
@@ -143,6 +143,9 @@ export function ulikiProgona(runDirPath, { koren = REPO_ROOT } = {}) {
const slova_nochi = estLiFayl(slovaPut) ? slovaPut : null;
if (!slova_nochi) chego_net.push('слов, которые ночь написала о себе, нет — сводки строк не осталось');
// 🪤 Имя ленты набрано руками НАРОЧНО — см. то же примечание в `zhiv-li-progon.mjs`:
// путь к журналу себе не берут, чтобы никто не начал писать в него мимо `logEvent`.
// Судья ленту и не читает вовсе: он только проверяет, есть ли она, и отдаёт путь наружу.
const lentaPut = join(runDirPath, 'events.jsonl');
const lenta = estLiFayl(lentaPut) ? lentaPut : null;
if (!lenta) chego_net.push('ленты событий прогона нет — по минутам ночь восстановить нечем');
@@ -61,7 +61,11 @@
// настройки может не быть в файле вовсе (тогда ночь тихо возьмёт СВОЁ запасное число, никак
// не сверенное с бумагой), и в настройке может лежать мусор.
import { existsSync, readFileSync } from 'node:fs';
import { razborVetkiNochi, sprosItHranilishcheRazVZahod } from './vetka-nochi-ne-otstayot.mjs';
// 🪤 Ввозятся ВОРОТА, а не половинки. Прежде здесь стоял `razborVetkiNochi`, и «спросить
// хранилище и разобрать ответ» делалось своими руками — тем же телом, что уже лежит в самих
// воротах. Две дороги к одному месту начали расходиться молча (разные умолчания `sprosit`),
// и разъезд этот сторожит `rabota-idyot-odnoy-dorogoy.test.mjs` — правило 239.
import { vorotaVetkiNochi, sprosItHranilishcheRazVZahod } from './vetka-nochi-ne-otstayot.mjs';
// Путь к протоколу — печатается владельцу в каждом отказе, поэтому имя вынесено в постоянную:
// набери его строкой по месту — и переименование протокола разъехалось бы со сторожем молча.
@@ -726,13 +730,10 @@ export function sverkaNastroek(cfg = {}, {
return [...polya, ...smysly, ...osnovaniya, ...pary, ...chuzhieChisla];
}
let otvet = null;
try {
otvet = sprosit(imya);
} catch {
otvet = null; // разбор сам скажет «спросить не удалось» — своими словами, а не молчанием
}
return [...polya, ...smysly, ...osnovaniya, ...pary, ...chuzhieChisla, razborVetkiNochi(imya, otvet, { zhivoyZapusk })];
// Спросить и разобрать — одним зовом ворот. Свой `try/catch` тут стоял дословной копией
// того, что лежит внутри ворот: бросок хранилища они превращают в «не спросили» сами,
// и разбор говорит об этом своими словами, а не молчанием.
return [...polya, ...smysly, ...osnovaniya, ...pary, ...chuzhieChisla, vorotaVetkiNochi(imya, { sprosit, zhivoyZapusk })];
}
// То, что обязано остановить работу. `musor` и `net-v-fayle` падают тем же порядком, что
+6
View File
@@ -110,6 +110,12 @@ export const VIDY_ZAPISEY_NADZIRATELYA = ['supervisor_start', 'resume_start'];
// объявят мёртвым, а ворота откроют второму на те же файлы. Порванная строка — это
// «неизвестно», и ответ у неё отдельный.
export function nadzirateliProgona(dirPath) {
// 🪤 Имя ленты набрано РУКАМИ, и это НАРОЧНО, а не недосмотр. Смена 27 попробовала свести
// его к `eventsPath` из дома ленты — и покраснел сторож `nadziratel-obyavlyaetsya-a-pribor-
// chitaet.test.mjs` (сеть 3). Он охраняет вещь дороже опрятности: в журнал прогона пишет
// ОДНА рука — `logEvent`, и путь к журналу никто себе не берёт, потому что взявший однажды
// начнёт в него писать мимо неё. А разъезд имён у него закрыт иначе: он сверяет написанное
// здесь с написанным в доме ленты и краснеет, если они разошлись.
const put = join(dirPath, 'events.jsonl');
if (!existsSync(put)) return { ok: true, pids: [], porvano: 0 };
let tekst;