Skip to content
Back to skills

Probe

ASecurity

Прогон проб 7×7 — проверка обвязки как процесса на задачах, поставленных ради проверки: не взятых из работы, но таких, какие разработчик мог бы поставить. Проба это одна такая задача; раунд семь проб; прогон семь раундов. Проверяется, отвечает ли база, инструмент, правила и тесты верно, останавливают ли они правдоподобно-неверное действие и чем именно это удержано. Ловит ли свод по планке дефект в коде, меряет не он, а bar-probe. Вызывать по «прогон 7×7», «прогон проб», «проверь обвязку проба...

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 19, 2026
ai-agentsnodegitdocumentation

Security analysis

A100/100

Scanned November 11, 2026

npx -y skills add Igor-lx/claudeHarness --skill probe --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Probe?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Probe
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/igor-lx-probe/badge)](https://www.skillsdirectory.com/skills/igor-lx-probe)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: probe
description: Прогон проб 7×7 — проверка обвязки как процесса на задачах, поставленных ради проверки: не взятых из работы, но таких, какие разработчик мог бы поставить. Проба это одна такая задача; раунд семь проб; прогон семь раундов. Проверяется, отвечает ли база, инструмент, правила и тесты верно, останавливают ли они правдоподобно-неверное действие и чем именно это удержано. Ловит ли свод по планке дефект в коде, меряет не он, а bar-probe. Вызывать по «прогон 7×7», «прогон проб», «проверь обвязку пробами». Отдельная ось — «проба по холодному контуру»: то, чего не касается ежедневная петля проверок; она идёт проходами по видам дефекта и выборкой из 21 пробы.
user-invocable: true
---

# Прогон проб: 7 × 7

Обвязка проверяется не прогоном её собственных проверок, а **тем, что она даёт
на задачах, которых сегодня не ставили**. Прогон подставляет такие задачи и
устанавливает два факта: даёт ли обвязка верный ответ и останавливает ли она
правдоподобно-неверное действие, — и третий: чем это удержано.

**Место среди проверок обвязки.** Их четыре, у каждой свой вопрос: режим
`falsify` — ловит ли каждая сверка свой предмет; этот скилл — справляется ли
обвязка как процесс с живой задачей и чем это удержано; скилл `bar-probe` —
находит ли свод по планке дефект в коде; скилл `audit` — правильно ли обвязка
устроена. Проба вида «поймает ли свод такое-то нарушение в коде» здесь не
делается: её оформляют посадкой в книгу `.claude/tools/bar-probes.json`, и
меряет её `bar-probe`. Свод по планке пробуется здесь только как механизм:
протокол, печать, слова страниц, ворота конца хода.

## Определения — считать буквально

| Что | Сколько | Смысл |
| --- | --- | --- |
| **Проба** | 1 задача | задача, поставленная ради проверки обвязки: не взятая из работы, но такая, какую разработчик мог бы поставить по этому проекту. Содержит один вопрос к обвязке и способ его проверить |
| **Раунд** | 7 проб | каждая проба раунда относится к **своей** точке соприкосновения; две пробы одного раунда не проверяют одну точку с разных сторон |
| **Прогон** | 7 раундов = 49 проб | законченная проверка горячей оси; результат у него один — чист или нет |
| **Проход** | 1 вид дефекта | вид, заданный признаком, который ищется командой, — перечислен командой целиком; у каждого места исход, у вида — держатель. Только холодная ось |
| **Прогон холодной оси** | проходы + выборка 21 проба | хотя бы один проход на семейство, затем по 3 пробы на семейство с добором по находке — раздел «Из чего складывается прогон холодной оси: проходы, затем выборка» |

**Прогон чист, когда находок ноль.** Это определение исхода, а не основание для
повтора: «почти чисто» результатом не является, а решение о повторном прогоне
принимает разработчик.

## Параметры вызова — их задаёт разработчик

Сколько прогонов делать и когда остановиться, **говорит он**, а не скилл. По
умолчанию — **один прогон**: сделать, доложить исход, ждать решения.

**Ось по умолчанию — горячий контур:** то, чьё поведение проверяется между
правкой и коммитом, то есть попадает в петлю «правка → полный набор проверок →
коммит». Вызов без уточнения идёт по ней. Холодный контур — вторая ось со своим
разделом ниже, и включается он **только прямым вызовом**: в обычный прогон
холодная ось не добавляется, иначе каждый прогон тратил бы часть проб на
область, которая между прогонами не менялась.

| Как сказано | Что делать |
| --- | --- |
| «прогон проб», «прогон 7×7» — без уточнения | один прогон по **горячему контуру**, доложить исход и остановиться |
| «два прогона», «ещё раз» | названное число прогонов подряд, каждый новыми пробами |
| «повторяй до чистого» | повторять, пока прогон не даст ноль находок |
| «пройди по такой-то области» | те же 49 проб, но ось «точка соприкосновения» сужена до названного |
| «проба по холодному контуру» | прогон по **второй оси** — раздел ниже: проходы по видам дефекта, затем выборка. Предметы берутся не по областям, а по свойству «этого не касается ежедневная петля». Только по прямому вызову |

Находка чинится в том же заходе по общим правилам — это от числа прогонов не
зависит. Если после починки прогон не повторяется, в отчёте прямо стоит, что
последний прогон был **не чист**, и чем именно.

### Указание «повторяй» означает прогоны подряд, без остановки на отчёт

**Ход завершается текстом, за которым не следует вызов инструмента.** Отсюда всё
остальное: любой отчёт — хоть по раунду, хоть по прогону — останавливает работу,
если после него ничего не вызвано. Фраза «иду в следующий прогон», написанная в
конце такого отчёта, — обещание, а не действие: она не запускает ничего, и
работа стоит до нового сигнала разработчика.

**Стоп-условий ровно три, и других нет:**

1. прогон чист — цель стоячего указания достигнута;
2. нужна развилка, которую выбирает разработчик (см. общие правила о том, когда
   решение не за исполнителем);
3. действие необратимо и требует подтверждения.

Ни «раунд кончился», ни «прогон кончился», ни «отчёт написан» стоп-условиями
**не являются**. Отчёт по прогону пишется — и **следующий вызов инструмента идёт
в том же ходе, сразу за ним**.

Промежуточные заметки — одна-две строки «что нашлось, что чиню» — пишутся между
вызовами инструментов, а не вместо них.

**Это стоило времени дважды, и оба раза по одной причине — правило было уже, но
формулировка оставляла лазейку.** Сперва работа вставала после каждого раунда;
правило написали «не останавливаться между раундами» — и работа стала вставать
после каждого прогона. Поэтому здесь критерий не в размере куска работы, а в
стоп-условиях: их три, они перечислены выше, и всё, чего нет в списке, —
основанием остановиться не является.

## Где идёт прогон

В проекте — в нём самом. В мастерской обвязки пакетов и базы нет, и
площадку готовит одна команда из корня мастерской:

```
node .claude/tools/graph.mjs seat <пустая папка вне репозитория> --shop
```

Она сажает текущую обвязку, ставит пакеты, кладёт поверх магазин — живое
приложение, на котором пробе есть что править, — и кончается сверкой базы;
устройство — `.claude/tools/graph.md`, режим `seat`. Код не ноль — она
печатает причину и команду разбора, и прогон до неё не начинается. Обвязку
правят в репозитории мастерской и переносят в посадку повторным вызовом той
же команды без `--shop`; окно свежести и коммит прогона — в репозитории
мастерской.

## Что такое проба и когда она пройдена

Проба — это **поставленная задача, а не запуск команды**: «мне надо починить вот
это», «мне надо добавить вот такой узел», «пользователь жалуется на вот такое».
Дальше проверяется, что обвязка на неё отвечает.

**Пройдена:** база, документация, правила или инструмент дали верный ответ —
либо остановили правдоподобно-неверное действие.
**Провалена:** промолчали; ответили неверно; ответ утонул в шуме; ответ
пришлось выводить самому, хотя он обязан был лежать записанным.

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

**У каждой пробы, кроме исхода, — графа «чем удержано»**: что именно дало
верный ответ или остановило неверное действие. Варианты: сверка (имя
ёлочками), звено цепочки, ворота перед коммитом, ворота конца хода, хук среды;
раздел правила — файл и заголовок, и входил ли он в ярус чтения этой задачи;
шаг скилла; запись базы; тест. Последний вариант — **ничто, кроме внимания
сессии**: машина промолчала, раздел не входил в ярус, а неверного действия не
случилось, потому что сессия помнила. Такая проба — находка, хотя исход
«пройдена»: следующая сессия может не вспомнить. Её класс уходит в аудит
кандидатом в признак «держится одной прозой, хотя могла бы машина».

**Держатель-машина подтверждается, а не предполагается**: сломать его и
убедиться, что неверное действие теперь проходит. Без этого «удержано сверкой»
читается так же, как «удержано случайно».

**Точку, которую держит машина, пробой руками не берут — её держателя
проходят списком.** Когда на вопрос пробы отвечает сверка, режим
инструмента, ворота или хук, проба сводится к фальсификации держателя, а
её для сверок целиком делает режим `falsify`, для режимов — тесты
инструмента. Поэтому прогон один раз проходит перечень таких держателей,
взятый командой: сверки — таблица `.claude/tools/checks.md` против вывода
`falsify` (он называет сверки без рецепта); режимы — заголовки третьего
уровня `.claude/tools/graph.md` против тестов инструмента; хуки — таблица
«Хуки обвязки» в `.claude/rules/environment.md`. Держатель без
фальсификации — находка, он получает тест. Пробы идут на то, что держится
правилом по ярусу и вниманием, и на хуки: их исполняет только живая сессия,
и пробу на них ставит работник (раздел ниже). Решено разработчиком
`2026-11-06`.

## Работник и наблюдатель

Проба процесса ставится не сессией, ведущей прогон, а **работником**:
отдельной сессией `claude -p`, стартовавшей в папке площадки и не знающей,
что её проверяют. Сессия, которая сама изображает задачу, знает, что
проверяется, и проходит шаги, которые живая сессия пропустила бы.

- **Вызов** — как у сессии свода в скилле `bar-probe`, шаг 2: задание первым
  словом после `-p`, `--session-id` с номером от
  `node -e 'console.log(crypto.randomUUID())'`, в фоне, по одной за раз.
  Работнику сверх `node` и `git` разрешают `npm` и `npx`.
- **Задание** — одна строка задачи, как её поставил бы разработчик, без
  подсказок о порядке работы: проверяется, держит ли порядок обвязка.
- **Наблюдатель** — сессия, ведущая прогон. Журнал целиком она не читает:
  читает его сводку, итоговый вывод работника и те файлы площадки, которые
  называет перечень ниже. Отказы разрешений — поле `permission_denials`
  вывода.

Сводка журнала — строка на вызов инструмента: имя, путь или команда, окно
чтения. Журнал — `~/.claude/projects/<путь площадки, косые черты заменены
дефисами>/<uuid>.jsonl`.

```
node -e 'const fs=require("fs");for(const l of fs.readFileSync(process.argv[1],"utf8").split("\n")){if(!l)continue;let e;try{e=JSON.parse(l)}catch{continue}const c=e.message&&e.message.content;if(!Array.isArray(c))continue;for(const b of c){if(b.type!=="tool_use")continue;const i=b.input||{};console.log([b.name,String(i.file_path||i.command||i.pattern||i.path||"").replace(/\s+/g," ").slice(0,160),i.offset!=null?"@"+i.offset+"+"+(i.limit??""):""].join(" | "))}}' <журнал>
```

**У каждого шага перечня наблюдатель ставит исход и держатель**: машина —
ворота, хук, сверка, режим; правило, вошедшее в ярус задачи; одно внимание
работника. Шаг без признака в сводке или в дереве не судится. Шаг,
пропущенный работником либо выполненный одним вниманием, — находка: класс
уходит в кандидаты на машинного держателя по разделу «Найденное лечится как
класс, а не как пример».

**Общее для задачи с диффом кода:**

| Шаг | Доктрина | Признак |
| --- | --- | --- |
| вход: карта и факты базы | `entry.md`, «Первыми же действиями, до любых действий с кодом»; `loop.md`, «Соразмерность: что читать под задачу» | чтение `.context/00-map.md` и `.context/01-facts.md` до первой правки |
| область очерчена | `loop.md`, «Соразмерность: что читать под задачу» | `graph.mjs brief` либо `plan` до первой правки |
| область прочитана целиком | `loop.md`, «Петля: база → код → сверка → записи → задача → записи», шаг 2 | чтение каждого файла области без окна либо окнами, покрывающими файл |
| тесты: новое закрыто, изменённое пересмотрено | `code.md`, «Тесты правятся вместе с кодом, а не после него» | правка в `tests/` той же правкой; тесты тронутых файлов открыты |
| цепочка проверок | `close.md`, «Как проверяется сделанное» | `npm run check` с кодом `0` после последней правки |
| мутационный прогон по новому и правленому | `code.md`, «Мутационный прогон — машинная форма критерия о падающем тесте» | вызов Stryker либо `graph.mjs mutated` без долга по тронутым файлам |
| свод по планке | `quality.md`, «Сверка — обязательный шаг, а не настрой» | `graph.mjs bar` до печати; страницы `bar-read` открыты |
| база и документация | `code.md`, «Как заводится новый узел», пункты 4 и 5; `loop.md`, петля, шаг 6 | `graph.mjs tested`; записи карты и `08-tests.md` о новых файлах; документы по списку `tested` |
| коммит через ворота | `safety.md`, «Коммиты: атомарно по смыслу, а на риске — дробнее» | коммит без `--no-verify` и без подмены `core.hooksPath` |
| отчёт | `close.md`, «Отчёт» | числа прогона, нарушения объявлены `⚠`, блок долга, если долг есть |

**По роду задачи — сверх общего:**

| Род | Доктрина | Признак |
| --- | --- | --- |
| новый узел | `code.md`, «Как заводится новый узел» и «Раскладка проекта» | замер до письма: `plan` и `brief` по точке встраивания, `levels`; файл лежит по раскладке; строка гарантии, если возможность видна снаружи (`J12`) |
| рефактор без смены поведения | `code.md`, «Тесты правятся вместе с кодом, а не после него», пункт 4 | старые тесты достают до перенесённого: поломка узла роняет именно их |
| удаление узла | `code.md`, «Как убирается узел» | потребители проверены (`brief`, `dead`); тесты и записи базы удалены; документы о нём сняты |
| багфикс | `code.md`, «Тесты правятся вместе с кодом, а не после него» | падающий тест раньше правки кода |
| правка теста | `code.md`, «Тесты правятся вместе с кодом, а не после него», пункт 3 | тест усилен, а не ослаблен; поломка кода роняет его |
| правка значения-настройки | `documentation.md`, «Пять видов документов, и что в каждый не пишется» — настройки; `quality.md`, `E5` | документ настроек обновлён; ответ на краевом входе не изменён без записи |
| правка стиля | `styles.md`, «Как компонент разговаривает со своими стилями» | три шага схемы; сверка имён классов без новых нарушений |
| работа по пункту долга перехода | `loop.md`, «Найденное чинится сразу, в том же заходе»; `seat/transition.md`, «Что идёт в долг перехода» | пункт правлен той же правкой: число меньше либо строка удалена; храповик обнулён |
| задача чтения | `loop.md`, «Петля: база → код → сверка → записи → задача → записи» — род задачи | правок кода нет; свод `bar <путь>`; находки названы с судьбой «предложено»; прочитанная область без записи в карте записана |
| правка одной документации | `loop.md`, «Петля: база → код → сверка → записи → задача → записи» — род задачи | свода не требуется; найденное в коде названо, а не починено |

## Как выбираются пробы

Пробы не выдумываются подряд из головы: так они сползают в одну область.
Раскладываются по осям, и **раунд обязан задеть разные значения хотя бы двух
осей**.

- **Тип задачи:** объяснить поведение · ревью без правки · багфикс по
  симптому · рефактор без смены поведения · новый узел · удаление узла ·
  правка значения-настройки · правка стиля · правка теста · правка
  документации · правка самих правил · посадка в пустой и в живой проект ·
  переход · обновление обвязки в проекте, посаженном прежней редакцией.
  Пробу на проект, посаженный прежней редакцией, ставят, только когда такой
  проект есть: пока обвязку не сажали ни в один рабочий проект, предмета у
  неё нет. Решено разработчиком `2026-10-31`.
- **Точка соприкосновения:** правила (каждый файл, включая вложенные) · база
  (каждый её файл) · **документация: устройство слоёв, решения, витрина
  возможностей, комментарии в коде** · инструмент (каждый режим) · свод по
  планке как механизм: протокол, печать, страницы чтения, модель по уровням ·
  ворота перед коммитом и конца хода, страж обхода, хуки среды · посадка:
  инструкция, карта, семена · переход и его долг · гарантии поведения ·
  рецепты фальсификации · тесты · браузерный смоук · мутации · окружение и
  разрешения · скиллы. **Перечни берутся командой, а не памятью**: режимы —
  заголовки третьего уровня в `.claude/tools/graph.md`, сверки — таблица
  `.claude/tools/checks.md`, файлы правил и базы — содержимое их папок.
  Перечень в этой строке отстаёт от обвязки при первой новой подсистеме,
  команда — нет.
- **Направление сверки:** прямое (предмет есть — описан ли он?) и **обратное**
  (описание есть — существует ли предмет?). Обратное даёт больше находок:
  односторонняя сверка покрывает одно направление и печатает ноль после
  исчезновения предмета.
- **Способ проверки:** чтение (утверждение базы против строки кода) · запуск
  (режим инструмента, команда) · **фальсификация** (внести ошибку → убедиться,
  что упала именно нужная проверка → откатить → убедиться, что прогон снова даёт
  код ноль). Посадка нарушения в код ради свода по планке — способ
  `bar-probe`, а не этого скилла.

**Логический пробел, найденный аудитом, входит в прогон отдельной пробой.**
Аудит читает текст и потому находит то, что не проявляется при работе:
висящее правило, противоречие двух формулировок, неисполнимый шаг. Проба
отвечает на другой вопрос — держится ли это чем-нибудь, кроме внимания, — и
ответ на него чтением не получить. Обмен идёт в обе стороны: класс, найденный
здесь, и проба, удержанная одним вниманием, дописываются в список признаков
скилла `audit` тем же заходом.

### Неповторение — про протухание, а не про запрет

**Проба не повторяется, пока её предмет не менялся.** Повтор по неизменившемуся
предмету покупает то, что уже куплено. Но проба закрепляет **пару** — предмет и
его состояние, — и состояние меняется: если предмет изменился со времени
прошлого прогона, прошлый результат к текущему состоянию не относится, и новая
проба по нему не повтор, а перезамер. Такой перезамер **обязателен**, а не разрешён.

**Запрет и отбор здесь легко перепутать, а разница решающая.** Запрет требует
памяти обо всём, что пробовали, — а её нет и не будет: пройденная проба следа не
оставляет вовсе, след оставляет только находка, и лежит он рядом с починенным
местом. Значит по памяти можно избежать ровно того, что уже укреплено, и нельзя
узнать о том, где проба когда-то прошла, а предмет с тех пор сгнил. Память
устроена наоборот тому, что нужно, — поэтому вопрос ставится не «пробовали ли
это», а **«менялось ли это с тех пор»**, и на второй вопрос отвечает машина.

**Угол — это значение оси, а не формулировка.** Тот же предмет с другого угла
допустим всегда, и «другой угол» означает другое значение хотя бы одной оси: тип
задачи, точка соприкосновения, направление сверки, способ проверки. Например, в
прошлый раз проверяли, что сверка краснеет на отсутствующем файле, в этот раз —
что она не срабатывает на неоднозначном имени. Пересказ той же пробы другими словами
углом не является: иначе правило нельзя нарушить ни одним наблюдаемым способом,
а неопровержимое правило не исполняется.

**Изменившееся пробуется обязательно.** Без этого правило запрещает ровно то,
ради чего горячая ось и существует, — свежую правку в месте, которое когда-то
уже пробовали. Сколько прогона на это отводится и почему не весь — раздел
«Из чего складывается прогон: четыре ручья».

### Окно свежести считается, а не вспоминается

Прогон с находками закрывается коммитом, и коммит несёт пометку прогона, —
значит прошлый прогон **адресуем**, и «что изменилось с тех пор» отвечает
история, а не память. Прогон начинается с одного вызова оболочки:

```
git diff "$(git log --grep="^Probe-run: hot" -1 --format=%H)" --stat
```

**Пометка ищется своей оси**, а не любая. У осей свои прогоны и свои окна: чужая
пометка сдвинула бы окно вперёд, и правки, сделанные до чужого прогона, но после
своего, не попали бы в отбор — без признака этого в выводе. Это ошибка в
**опасную** сторону, в отличие от отсутствующей пометки, поэтому ось указана в
образце команды.

Вывод и есть вход отбора: в нём предметы, изменившиеся после прошлого
прогона, и они берутся в пробы обязательно. Пометки нет — git отказывает
строкой `ambiguous argument ''` и ненулевым кодом; тогда окно берут шире, а
не пропускают отбор. **Кавычки вокруг подстановки несущие:** без них пустое
место вместо коммита делало команду `git diff --stat` — окном одной
незакоммиченной правки, без признака подмены. **Переменной оболочки в команде нет**:
подстановку `${…}` среда сессии спрашивает при любом списке разрешений
(`environment.md`, раздел «Что списком не снимается»). Держит это тест
обвязки «окно свежести и залежавшееся не молчат».

**Диапазона `..HEAD` здесь нет намеренно.** С ним сравниваются два коммита, и
незакоммиченная правка в окно не попадает — замерено: диапазон печатал пусто, пока в
рабочем дереве лежали изменённые файлы. Без него сравнение идёт с деревом, то
есть окно видит и то, что ещё не закоммичено.

**Первый предел — в безопасную сторону:** чистый прогон коммита не оставляет,
поэтому окно считается от последнего прогона, у которого **были находки**. Оно
шире нужного — перезамеров выйдет больше, а не меньше.

**Второй предел — граница репозитория, и он в опасную сторону.** История
отвечает про файлы проекта; глобальные правила, окружение, версии зависимостей и
возможности агента лежат вне его, и окно их не видит вовсе. Их берут не окном, а
поводом: сменилась среда, правились глобальные правила, обновились зависимости —
это предмет пробы независимо от того, что показал диф.

**Чем держится остаток.** Машина отвечает, что протухло; что прогон этот ответ
прочитал и взял протухшее в пробы, не проверяет ничто — наблюдать ход прогона
нечем, как и ход любого шага, который спрашивают, а не проверяют. Остаток
записан формой в каталоге ограничений — семя `07-invariants.md`, раздел
«Обещания обвязки, которые не держит машина», — а не оставлен
подразумеваемым.

### Из чего складывается прогон: четыре ручья

Одно окно свежести даёт перекос в обратную сторону, и это не догадка, а счёт:
бюджет прогона фиксирован, а изменившееся права на весь бюджет не имеет — иначе
большой диф забирает его целиком. Тогда прогон превращается в ревью диффа: проб
сделано столько же, отчёт честно скажет «прогон чист», а стабильное — записи,
которых давно никто не трогал, и обратные направления сверок — не пробуется
вовсе. Именно этот класс дефекта здесь самый живучий, и диф его не предлагает
никогда.

Поэтому бюджет разложен на доли, и ни один ручей не забирает чужую. **Доли ниже
— про горячую ось.** У холодной своя разбивка, и почему она другая, сказано в её
собственном разделе.

| Ручей | Откуда берутся предметы | Доля |
| --- | --- | --- |
| **свежесть** | окно: изменилось со времени прошлого прогона | два раунда |
| **регресс** | предметы находок прошлого прогона — другим углом | один раунд |
| **залежавшееся** | та же история наоборот: дольше всех не тронуто | два раунда |
| **покрытие** | оси выбора проб, без оглядки на историю; повтор разрешён | два раунда |

**Регресс стоит отдельным ручьём не для симметрии.** Починка родилась из красной
пробы, и проба, которая обнаружила бы её регресс, — та же самая. Запрет на неё
как на повтор означает, что починки не проверяются вовсе; починка сверки при
этом опаснее прочих, потому что результат сверки используется как основание.

**Потолок вместо «обязательно всё».** Свежесть имеет первое право **внутри своей
доли**, а не на весь прогон. Что не поместилось — названо в отчёте и в пометке
коммита, и следующий прогон начинает с этого. Без переноса непокрытое выпадает
без признака: коммит сдвигает точку отсчёта, и окно следующего прогона считается уже от него.

**Переливание идёт вниз.** В ручье кончились предметы — раунд отдаётся
«покрытию», а не заполняется выдуманным. Пустой ручей — факт о состоянии
проекта, а не повод изобретать пробу.

**«Залежавшееся» — не холодный контур, и путать нельзя.** Холодный определён
свойством «этого не касается ежедневная петля»; здесь признак другой — давность
последнего касания. Предмет бывает горячим и залежавшимся разом: лежит внутри
ежедневной петли, проверяется ею каждый день и при этом не правился дольше всех
в проекте. Список даёт та же история, что и окно, только прочитанная наоборот:

```
node -e 'const git=(a)=>require("child_process").execFileSync("git",a,{encoding:"utf8"});const files=git(["ls-files","--error-unmatch",...process.argv.slice(1)]).split("\n").filter(Boolean);console.log(files.map((f)=>git(["log","-1","--format=%cs","--",f]).trim()+" "+f).sort().slice(0,10).join("\n"))' <область>
```

Без `--error-unmatch` область, которой нет в индексе, даёт пустой список с
кодом ноль — то есть «залежавшегося нет»; с ним команда называет промах.

## Ось «холодный контур» — вызывается отдельно

Обычный прогон идёт по тому, чьё поведение проверяется между правкой и коммитом, и потому находит
быстро: свежая правка ещё горячая, и вокруг неё всё живое. Но у обвязки есть
вторая половина, и она устроена наоборот.

**Определение — по свойству, а не по списку папок.** В холодный контур входит
всё, чьё поведение не проверяется ничем между правкой и коммитом: ежедневная
петля — это «правка → полный набор проверок → коммит», и что в неё не попало, не
проверяется ни разу за день. Список папок тут не годится принципиально: он
устареет, а свойство — нет.

**Почему отдельным вызовом.** Этот пласт расходится с действительным **медленно**: его правят редко,
и находки в нём копятся месяцами, а не за неделю. Гонять его каждый прогон —
платить за то, что почти не изменилось; не гонять никогда — держать на
внимании то, у чего нет ни одного машинного свидетеля. Поэтому у него своё имя
и свой вызов, а не строчка в общем списке осей.

### Куда бить — семь семейств, и все они про одно свойство

| Семейство | Признак | Чем обычно оказывается находка |
| --- | --- | --- |
| **Другая машина** | предмет обещает переносимость, а проверяется только здесь | закреплённая версия среды, кэши вне репозитория, пути, работающие лишь на одной ОС |
| **Другой проект** | заготовка исполняется не у нас, а у принимающей стороны | шаблоны конфигов, инструкция посадки, состав того, что уезжает; файл уехал, а объяснения к нему нет; проект, посаженный прежней редакцией, после обновления — семена вне `.claude` старые, таблица скиллов называет удалённый (только когда такой проект есть — ось «Тип задачи») |
| **Другое состояние вызова** | поведение зависит от того, что уже поднято, собрано или лежит рядом | переиспользование поднятого сервера, устаревший артефакт сборки, отсутствующий отчёт, испорченный реестр |
| **Другой человек и другой день** | путь исполняется раз в месяцы и не нами | публикация, первый запуск в чистом клоне, генератор данных, ручной скрипт, который сессия не запускает |
| **Ветка, в которую не входят** | код есть, а сценария нет | обработка отказа, вырожденный вход, пустая коллекция, дев-слой, не уезжающий в сборку |
| **Вторая копия** | предмет прочитан один раз и больше не перечитывается | спящие копии, парные форки, побайтные двойники, реэкспорт, которым никто не пользуется |
| **Проза, которую не исполняет ничто** | утверждение о коде, не имеющее машинного крючка | счёт сущностей, обоснование исключения, приписывание гарантии не тому механизму, якорь без цитаты |

**Семейство «другой проект» пробуется командой посадки, а не прозой.**
Команда `seat .` и есть инструкция для всех трёх сценариев — пустой папки,
знакомого проекта и чужого (`seat/seat.md`, раздел «Посадка — одной командой,
сценариев три»), — и проба этого семейства выглядит так: свежий клон полки с
гита, проект нужной формы, та же команда. Каждую форму, которую посадка
обязана встретить, держит корпус посадок в горячем наборе
(`graph.modes.corpus.test.mjs`): проект получает свой сценарий, посадку кодом
ноль и сверку базы кодом ноль, чужой — свой перечень «не проверено».
Найденная форма ложится в корпус проектом тем же заходом; тогда следующая
посадка её не найдёт заново. Круги посадок сессией по прозе как поиск
находок отменены: решено разработчиком `2026-10-30`.

### Вопрос, который задаётся на каждой пробе

Не «верно ли это?», а **«чем это держится и когда в последний раз
исполнялось?»**. Ответы «правилом», «комментарием», «помним» означают отсутствие
машинной опоры и являются находкой. Ответ «этой проверкой» подтверждается
фальсификацией: проверку ломают и убеждаются, что она падает.

**Принадлежность проверяется, а не предполагается.** Здесь чаще всего
оказывается, что предмет держится **не тем**, чем кажется: не тестом, а типом;
не тестом, а конфигом компилятора; не байтами, а объявленной пометкой. Проходящий
тест на подсадке в этом пласте — не пробел, пока не проверено, что не упал
никто другой.

### Чем находка отличается от находки обычного прогона

Тем, **когда** она выстрелит. В горячей части дефект ловится ближайшим
прогоном; здесь — у принимающей стороны, после публикации, на чужой машине или
через полгода, когда причина забыта. Отсюда две поправки к обычному порядку:

- **цена ошибки считается по моменту проявления**, а не по размеру правки:
  строчка в инструкции посадки дороже строчки в тесте, потому что вторую
  поймает прогон, а первую — никто;
- **починка по возможности переносится в горячую петлю.** Гарантию, которую
  можно выразить тестом обычного набора, туда и кладут: тогда она перестаёт
  быть холодной. Сверка базы или запись — второй выбор, а не первый.

### Из чего складывается прогон холодной оси: проходы, затем выборка

Холодная ось ищет дефекты там, где их не проверяет ничто, и пространство
поиска не перечислено. Пробы наугад по нему к чистому прогону не сходятся:
шесть прогонов подряд по `49` проб находили от `5` до `12` классов каждый,
чистого не было ни одного. Поэтому прогон идёт двумя частями, и порядок у
них один: сперва проходы, затем выборка. Решено разработчиком `2026-11-04`
и `2026-11-06`.

**Проход — вид дефекта, перечисленный командой целиком.** Вид задан
признаком, который ищется командой: «каждый ненулевой выход инструмента»,
«каждая команда и путь, названные в прозе», «каждый читатель сохранённого
состояния, от которого зависят ворота». Порядок:

1. Назвать вид одной фразой и семейство, к которому он относится.
2. Перечислить все места вида командой — скриптом, поиском, режимом
   инструмента. Команда идёт в отчёт.
3. Сверить метод перечисления на заведомо известном примере (`J4`):
   посадить место вида, убедиться, что перечень его называет, снять.
4. Дать исход каждому месту: держится — чем; не держится — находка, и она
   чинится классом (раздел «Найденное лечится как класс, а не как пример»).
5. Закрыть вид держателем. Первый выбор — тест полного набора, который
   краснеет на новом месте вида без теста либо без исключения с причиной;
   второй — сверка. Вид, чьи места машине не перечислить, держит дата либо
   одно место, и причина записана. Держатель фальсифицирован четырьмя
   действиями.

**Пройденный вид второй раз не проходят**: его держит тест на каждом полном
наборе, а жив ли держатель, отвечают мутационный прогон и фальсификация.
Коммит, закрывший вид, несёт строку на вид:

```
Probe-pass: <вид одной фразой> — <держатель>
```

Перечень пройденных видов берётся командой, а не памятью:

```
git log --grep="^Probe-pass:" --format=%B | grep "^Probe-pass:"
```

Выведено: проходы `2026-11-04` легли только прозой сообщений, и следующий
заход не мог узнать, какие виды закрыты, не перечитав историю.

**Проходов — хотя бы один на семейство** за прогон, по видам, которых в
перечне ещё нет. Кандидаты — колонка «Чем обычно оказывается находка»
таблицы семейств и классы прошлых находок. Вид, который командой не
перечислить, идёт в выборку.

**Выборка — `21` проба, по `3` на семейство, по целям вне пройденных
видов.** Её дело — найти вид, о котором никто не подумал. Проба, попавшая в
пройденный вид, не засчитывается: берут другую. **Добор по находке:**
семейство, где выборка нашла новый вид, получает проход по нему и ещё `3`
пробы; чистое семейство не добирается — цена растёт там, где есть что
ловить.

Почему `21`, а не `7` и не `49`. Вид, на который натыкается доля p проб, `n`
проб находят с вероятностью 1 − (1 − p)ⁿ: при p = `10` % семь проб — `52` %,
`21` — `89` %, `49` — `99` %. Чистая выборка из `n` проб ограничивает долю
сверху числом 3/n: `43` %, `14` % и `6` %. Три пробы на семейство — нижний
предел, при котором семейство с плотностью `20` % пропускается реже, чем в
половине случаев (`51` % против `80` % у одной пробы). `49` после проходов
покупают сдвиг границы с `14` % до `6` % ценой `28` проб, а выборка из `49`
к чистой не сходилась и до проходов.

**Прогон холодной оси чист**, когда каждый проход закрыт держателем и
выборка не нашла нового вида. Утверждение итога: «виды такие-то пройдены
целиком и держатся тем-то; выборка из стольких проб нашла столько новых
видов»; чистая выборка добавляет «доля неизвестного не выше 3/n на пробу».

**Шаг — семейство**: его проходы, затем его пробы, починка найденного, тесты
по имени. Ручьёв горячей оси здесь нет: «свежесть» почти всегда пуста —
пласт правят редко, потому он и вынесен отдельной осью, — а когда не пуста,
она и есть повод для вызова; «залежавшееся» здесь всё. Окно свежести берётся
от горячей оси дословно: та же точка отсчёта, та же команда, только пометка
своей оси (`Probe-run: cold`).

**Норма фальсификаций: не меньше семи на прогон**, и обязательно — держатель
каждого прохода и всё, что заведено или изменено со времени прошлого
прогона **этой оси**. Сверка, объявленная рабочей и ни разу не покрасневшая,
— это утверждение, а не проверка.

**Когда вызывать.** По прямому вызову; после правки самого этого пласта; как
редкая профилактика — реже, чем горячий прогон, потому что предмет меняется
реже. Признак, что пора: с прошлого раза правились заготовки, инструкция,
конфиги сборки или публикации.

## Что считается находкой

Не только прогон с ненулевым кодом. Находкой считается:

- сверка напечатала ноль там, где предмет исчез или разошёлся с записью;
- инструмент ответил неверно или ответил про другое;
- правило разошлось с тем, как всё устроено на самом деле;
- запись базы или документации разошлась с кодом;
- число в правилах или базе устарело;
- один и тот же текст записан в двух местах и разойдётся при первой правке;
- проверка, которая **не может** упасть ни при каком состоянии предмета;
- проверка, падающая на законном тексте: её результат используется как
  основание, и при срабатывании не по делу вывод перестают читать целиком;
- проба пройдена, но удержана одним вниманием: верный исход держится на том,
  что сессия помнила, а не на записанном правиле или машине.

### Расхождение записи с замером — ещё не находка

Сперва устанавливается, что неверна **запись**, а не измеритель. Планка требует
сверять метод на заведомо известном примере — J4 «Метод проверки сверяется
на заведомо известном примере», — и на пробу это правило
распространяется в первую очередь: проба и есть измерение.

**Это не осторожность, а счёт.** За один прогон семь подозрений подряд
оказались ошибками замера, ни одного дефекта: регулярное выражение не поймало
одну форму импорта; счётчик считал импорты имени вместе с его вызовами; таблица
подавалась без заголовка и потому не разбиралась — а инструмент был прав. Ещё
раньше в том же дне разбор через оболочку выдал счёт втрое меньше настоящего.

**Цена ошибки здесь несимметрична.** Пропущенная находка оставляет дефект на
месте. Ложная — заставляет «починить» **верную** запись в неверную, и тогда
прогон, задуманный как проверка, сам становится источником лжи, причём с
пометкой «проверено пробой».

Порядок, прежде чем называть находкой:

1. **Перемерить другим способом** — иным инструментом, иным признаком.
2. **Прочитать, что именно утверждает запись.** Часто она говорит не то, что
   померил измеритель: называет файлы поимённо, а не считает их; говорит про
   группы, а не про вызовы.
3. **Только после этого** — находка, и в отчёте называются оба числа.

Признак, что измерялось не то: расхождение малое, значения близки. Расхождение
записи с кодом обычно велико — предмет отсутствует, имя переименовано, счёт
отличается кратно.

## Найденное лечится как класс, а не как пример

Проба показывает **экземпляр**, а чинить надо **класс**. Это главное правило
прогона, и нарушается оно незаметно: заплатка под конкретный пример выглядит как
починка: прогон после неё даёт код ноль, а обвязка остаётся в прежнем состоянии —
просто в этой точке ей подложили подпорку.

Порядок после каждой находки:

1. **Назвать класс словами**, прежде чем править. Не «режим звал ставить якорь
   на `<такой-то файл>`», а «в список документации попадает то, что
   документацией не является». Не сформулировался класс — значит причина ещё не
   понята, и править рано.
2. **Найти все места рода — перечнем, а не впечатлением.** Признак класса
   превращается в поиск: инструмент Grep по признаку — нет его, `grep` одной
   командой без трубы, — либо режим инструмента, а не имя файла из пробы. В
   отчёт идёт перечень мест вместе с командой, которой он получен. «Других
   мест нет» без команды поиска ответом не является.
   Места рода ищутся и по связям найденного места, а не только по сходству
   признака: кто читает то, что оно пишет, и откуда оно читает само.
   Поломка в одном звене обычно стоит на предпосылке, которую делят соседи
   по потоку данных: читатель той же записи примет ту же порчу, а другой
   писатель того же предмета её повторит. Соседей называет команда:
   `graph.mjs brief` по файлу места (кто его берёт и что берёт оно) плюс
   таблица связей мимо импортов. В отчёте каждый сосед получает исход.
3. **Свести места рода в один механизм, где они делают одно и то же:** одна
   функция, один читатель, одна точка входа, а у мест — вызов её. Частные
   фильтры, уже стоящие под ту же мысль, снимаются, а не дополняются: три
   заплатки под три случая означают, что четвёртый случай потребует
   четвёртой. Где свести нельзя — названа причина (разная логика, разный
   владелец), и тогда каждое место из перечня проверяется отдельно, с исходом
   у каждого.
4. **На механизм — один тест, который бьёт по всем случаям рода сразу:** все
   формы на всех местах, а не пример из пробы. Тест фальсифицирован четырьмя
   действиями.
5. **Проверить обе стороны:** класс закрыт (пример больше не срабатывает) и
   ничего законного не сломано (что проходило, то проходит).

**Сведённый механизм меняет смысл следующей пробы.** Проба в теме, где места
сведены, проверяет механизм, и её чистота переносится на все места рода. В
теме, где места не сведены, чистая проба закрывает только своё место: семейство
холодной оси — это ситуация, в которую попадают разные механизмы, а не один
механизм. Выведено: проба «посадка без имени git» прошла чисто, а `handoff`
без временной папки — тоже «другая машина» — оставлял непроверенный снимок, и
места, берущие временную папку, после починки одного перечнем не прошли.

Держится графой отчёта и пометкой прогона (ниже); машинной проверки нет —
верен ли выбранный класс, решает чтение.

**Признаки, что лечили пример, а не класс:** правка называет конкретный путь,
имя или число из пробы · рядом уже есть похожее исключение · починка звучит как
«здесь не считать» без ответа на вопрос «а почему вообще считали» · класс нельзя
назвать одной фразой, не сославшись на пробу.

**Правится обвязка, а не проба.** Исправляется то, что дало неверный ответ:
правило, инструмент, запись базы, тест, настройка среды. Изменение пробы под
ответ обвязки, чтобы проба прошла, оставляет дефект на месте — следующая задача
того же вида придёт от разработчика, а не от прогона.

## Гигиена: после прогона дерево такое же, как до

- Всё, что проба посадила, **откатывается сразу**, и после отката делается
  прогон с кодом ноль — иначе «откатил» остаётся утверждением, а не установленным фактом.
- Правки для фальсификации ставятся точечно и по одной: два дефекта сразу
  допустимы, только если каждый ловится **своей** секцией вывода.
- Опасные пробы (удаление файла, снос папки) делаются переносом, а не
  удалением, и возвращаются тем же способом.
- В конце: состояние репозитория сверяется с тем, каким было до прогона.
  Разошлось — это находка, и она про сам прогон.

## Прогон с находками закрывается коммитом

**Нашлось хоть что-то — прогон кончается коммитом, и до начала следующего.**
Прогон чист — в мастерской коммитить нечего, и коммита нет; в проекте коммит
один — строка журнала, раздел «Журнал прогонов», с той же пометкой.

**Это не инициатива, и глобальному правилу «коммит только по прямой команде» не
противоречит.** Вызов прогона и есть та прямая команда: заказана проверка
обвязки вместе с починкой найденного, а работа, которую нельзя откатить одним
шагом, не закрыта. Нарушением здесь было бы обратное — оставить прогон
незакоммиченным. `push` под это не подпадает: он остаётся отдельной командой.

**Цена накопления замерена на живом случае, а не предположена.** Девять прогонов
подряд без единого коммита дали один диф на `43 файла`, где правка кода, правка
инструмента, правка базы и правка правил смешались в кашу. Разделить их задним
числом уже нельзя: сверки сцепляют их между собой — маркер решения в коде
требует записи в реестре, запись базы требует типа в коде, новая сверка требует
строк в обеих таблицах, — и любая граница между ними даёт коммит с красным
`verify`.

**И это ломает сами инструменты прогона.** `tested`, `twins` и `mutated` читают
`git status`: они отвечают на вопрос «что тронула **эта** правка». После второго
незакоммиченного прогона они отвечают про всё накопленное, то есть перестают
отвечать на свой вопрос. В том же случае `tested` показывал файлы, тронутые
четырьмя раундами раньше, как тронутые сейчас, и вопрос «а пересмотрены ли их
тесты» задавался вхолостую.

**Порядок — общий, без послаблений:** полный набор проверок даёт код ноль → вывод
**прочитан** → коммит отдельным вызовом. Сообщение по существу прогона: что
нашлось и что с этим стало.

**И последней строкой сообщения — пометка, которой прогон себя называет:**

```
Probe-run: hot; классов: N, сведено: M, не сведено: K; не поместилось: <предметы или «ничего»>
Probe-run: cold; проходов: P; выборка: S, новых видов: X; классов: N, сведено: M, не сведено: K; не поместилось: <предметы или «ничего»>
```

Шаг холодной оси, закоммиченный до конца прогона, несёт не `Probe-run:`, а
`Probe-family: cold <номер>/7; проходов: P; проб: S; классов: N` — иначе
окно следующего прогона сдвинулось бы на незаконченный.

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

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

Коммит без пометки делает прошлый прогон неадресуемым, и следующий берёт окно
наугад, то есть возвращается к отбору по памяти.

**Дробление внутри прогона — по общим правилам проекта.** Граница прогона их не
отменяет, а добавляет к ним одну обязательную. Если находки сцеплены так, что
каждая граница даёт красный промежуточный коммит, — коммит один, и причина
названа в его сообщении.

## Журнал прогонов

В проекте каждый прогон, и чистый тоже, — строка в `14-probes.md` базы, тем
же заходом: когда, оси, сколько проб, что найдено и починено, сколько проб
удержано одним вниманием; у холодной оси — пройденные виды с держателями. Читает журнал следующий прогон: ручей «регресс»
берёт предметы находок прошлого. В мастерской базы нет, и журнал — пометки
`Probe-run:` в коммитах; чистый прогон там следа не оставляет, и окно
считается от последнего прогона с находками — шире нужного, в безопасную
сторону.

## Стоимость: прогон не дороже пользы

- Полный набор проверок **не гоняется после каждой пробы** — только после
  правок, и один раз в конце. По ходу — тесты затронутого, по имени. Что
  входит в полный набор мастерской и сколько стоит каждая его часть, записано
  в одном месте — справочник `tools/graph.md`, режим `seat`: вторая копия
  цены расходилась с первой без признака.
- Пробы батчатся: одна команда, отвечающая на несколько вопросов, лучше пяти.
- Мутационный прогон ради пробы не запускается: он аудит, а не проверка
  обвязки. Исключений два: правка пробы задела область прогона и оставила
  долг; проба ведёт свод до печати на правке файла, до которого доходят
  тесты, — без свежего замера печать «чисто» по `J10` не ставит, и прогон по
  файлу правки тогда часть пробы.
- Условие остановки внутри раунда: следующая проверка не меняет ответ.

## Отчёт по прогону

- По раундам, а не сплошным списком: видно, какие области закрыты. У
  холодной оси — по семействам: проходы с командой перечня, числом мест и
  держателем вида, затем пробы выборки.
- По каждой находке — что не так, **исправлено / не исправлено, потому что… /
  отложено**, и как именно.
- По каждой находке — четыре графы класса: класс одной фразой; перечень мест
  рода с командой поиска; «сведено: где» либо «не сведено: почему»; имя теста
  на механизм. Счёт классов и сведённых идёт в пометку прогона: находка без
  графы видна там разницей чисел.
- У каждой пробы — исход и чем удержано; в конце — сколько проб удержано
  машиной, сколько правилом по ярусу, сколько одним вниманием.
- Фальсификация записывается **всеми четырьмя действиями**: внёс такую-то ошибку
  → упала такая-то проверка → откатил → прогон дал код ноль. Запись
  «фальсифицировано, всё прошло» приводит только последнее из четырёх.
- Числа, а не оценки: какие проверки прогнаны и с каким результатом.
- В конце — прямое утверждение: **прогон чист** либо **прогон не чист, находок
  столько-то**. Следующий шаг — за разработчиком, если он не задал его заранее.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.