Запрос
текст
Добудь факт «Патч адаптера ядра: version, base, files, оракул (значение части, не текст цели)» (kernel_adapter_patch)
owner
{"id":"egor"}
company_name
Shadums
company_oneliner
ядро решений: согласует цель, раскладывает задачу на паттерны; знакомые паттерны переиспользуются быстро через Jev и алгоритмы без вызова большой модели, незнакомое дорешивает LLM и сохраняется паттерном с условием, когда он снова нужен
edge_jev
Jev — быстрая модель TypeSafe AI, в раннем доступе с 15 сентября 2026; TypeSafe заявляет на своих workflow-тестах ускорение 193.6x и снижение стоимости 444.6x относительно сравниваемых LLM (цифры производителя, верхняя граница; собственных замеров Shadums нет — Shadums их себе не приписывает)
edge_window
новый выпуск Jev — окно быстро выйти на рынок; занять его первыми — стремление, не подтверждённый факт
edge_quality
ожидаемый эффект декомпозиции — меньше ошибок и галлюцинаций, потому что знакомое не генерируется заново, а переиспользуется проверенным; измеренного подтверждения пока нет
edge_speed
скорость, лёгкость, адаптивность: каждая решённая задача делает следующую похожую быстрее и дешевле
traction
ядро проходит цикл «задача → паттерн → повторное использование без модели»; три цели в одном графе; код ядра проходит круг код → цель → код (165/165 тестов); выручки нет
team_credential
Егор, основатель; год не пишет код руками — построил платформу агентов, которая делает это за него
round_details
ранний раунд; сумма и условия открыты; сильная дистрибуция важнее цены
deck_link
демо будет готово к понедельнику 28 сентября 2026, ссылку пришлю после
call_slots
неделя 28 сентября — 2 октября, онлайн, 20 минут
sender_signature
Егор, основатель Shadums, shadums.com
proof_roundtrip
код ядра (4 модуля, 54 функции) прошёл круг «код → одна цель → код»: 165/165 тестов, 0 ошибок типов; ранее одна функция decide — 112/112 проверок поведения
proof_reuse
одно правило, полученное от модели, применено к 70 вхождениям в 45 функциях; 2450 из 2875 конструкций собраны обратно за 26.8 с без моделей; повтор того же входа — ноль вызовов модели
proof_portable
переносимость ядра проверена на двух доменах; повторная обработка и восстановление после прерывания протестированы локально
positioning
цель должна переживать разговор с ИИ: система удерживает цель, выполняет, проверяет результат и сохраняет найденный способ как исполняемый опыт; решения объяснимы — видно основание, правило можно поменять
ask_format
15–20-минутный показ демо; персонализация под тезис/портфель адресата обязательна; просьба о личных $4k к 20 октября НЕ актуальна и в письмо не идёт
vision_shared_brain
проект — развивающийся общий мозг: каждый решённый способ (паттерн) сохраняется как исполняемый опыт, и повтор стоит ноль вызовов модели; ценность создаёт тот, кто исследовал, а потребляет тот, кто переиспользует
economy_pay_for_research
платить за время, потраченное на исследование, когда этой работой потом пользуются другие: у записи паттерна есть кто её родил (mintedBy) и цена рождения (вызовы модели, веб-вызовы, время из расписок), у каждого повтора — факт применения без модели; разница между ценой рождения и ценой повтора измерима в реестре
open_registry_as_spec
реестр паттернов открыт на чтение как исполняемая спека платформы (назначение, посылки, форма, законы, источники, цена и число повторов); это стимулирует изучать платформу: чужая запись, взятая из реестра, приносит автору отметку и повтор без модели; запись — только через допуск с проверками
karate_labs_meeting
Созвон с Karate Labs: 28 сентября 2026, 12:30 UTC (09:30 Буэнос-Айрес, 13:30 UK, 18:00 Индия), Google Meet https://meet.google.com/xjv-scuu-sju. Участники с их стороны: Kapil Bakshi (CEO, сооснователь), Peter Thomas (CTO, сооснователь, автор фреймворка Karate), Pier-Jean. Повод: моё прямое письмо основателю «Engineer who works through coding agents» (05.09.2026); Кэпил ответил 11.09 «How are you placed week of 21 Sep?», созвон был назначен на 25.09 и перенесён ими на 28.09 (принято 23.09). Формат: знакомство с основателями, роль инженера не опубликована — уточнить в разговоре.
owner_timezone
America/Argentina/Buenos_Aires, UTC−3, без летнего времени
company_jurisdiction
юридического лица нет — компания ещё не зарегистрирована (слово владельца 2026-09-25 ~17:2xZ: «компании нет никакой»)
neighbor_setting_code
["revision: HEAD = ref: refs/heads/main (.git/HEAD:1); main = 4afbc7a78f291e928cf80125f0c0d3f199e31fbc (.git/refs/heads/main:1), read now (observed)","drift from prior map 5bddb3ac7d50659d4b7f458f84612508fa91deba: 1 commit, .git/logs/refs/heads/main:7390 — 5bddb3ac7d50659d4b7f458f84612508fa91deba to 4afbc7a78f291e928cf80125f0c0d3f199e31fbc (fast-forward from the prior map's SHA, observed); files changed: UNKNOWN (packed objects, no git diff with Read/Grep only). Inferred, not verified: .git/COMMIT_EDITMSG:1-7 describes a bridge-watcher change (_bridge-hand-watch, cdp-sweep; tsc over shared and dev-platform), which would be outside token-vault and app. Because of that, every anchor below was re-read at 4afbc7a and all matched the prior map's lines","neighbor choice: pool reserve floors (poolReserve and poolBackgroundReserve, PoolReserveSettings) — like the target priorityAccount, it is a property of the whole pool, not of one account; it is live (loaded at boot, PATCHed without a restart); it lives in the same doc-service row vault_settings/pool-reserve; it is read by dispatch and by health; it has a screen control. The neighbor is not the target: grep priorityAccount in packages returns 0","port (found, observed): packages/token-vault/src/ports/IPoolReserveStore.ts:23-32 — interface IPoolReserveStore (load, save); :13-18 StoredPoolReserves (partial: interactive, background, updatedAt, updatedBy); :21 PoolReservePatch","storage (found, observed): packages/token-vault/src/infrastructure/DocServicePoolReserveStore.ts:26 — class DocServicePoolReserveStore implements IPoolReserveStore; :7-8 DB imperiaos, COLLECTION vault_settings; :15 DOC_ID = pool-reserve; :50-51 $set under upsert with returnDocument after; :68-77 function pick keeps only its own finite fields (a new field must be added here or it gets dropped)","overlay (found, observed): packages/token-vault/src/domain/policy.ts:82 let storedReserves: StoredSettingsOverlay; :85 interface StoredSettingsOverlay; :91 setStoredPoolReserves; :96 getStoredPoolReserves; :101 __clearStoredPoolReservesForTest; :179 poolReserveSetting; :184 poolReserveFraction","use-case (found, observed): packages/token-vault/src/application/PoolReserveSettings.ts:47 class PoolReserveSettings; :58-71 load (non-fatal, log.error at :66); :74-82 current returns PoolReserveView; :89-117 update: validate, then store.save at :107, then apply at :111; :119-131 apply writes the overlay and checks it back at :127-130; :24 PoolReserveRejected","wiring (found, observed): packages/token-vault/src/server.ts:12-13 imports DocServicePoolReserveStore and PoolReserveSettings; :214 new PoolReserveSettings(new DocServicePoolReserveStore(STORAGE_URL)); :215 await poolReserve.load(); :256-257 registerRoutes receives poolReserve; packages/token-vault/src/routes.ts:43 optional slot poolReserve?: PoolReserveSettings","routes (found, observed): packages/token-vault/src/routes.ts:157-163 GET /api/pool/reserve (503 'pool reserve settings not wired' at :159, otherwise ok:true plus current() at :162); :165-189 PATCH /api/pool/reserve (update at :174; PoolReserveRejected gives 400, anything else gives 500 at :184; log.error at :186)","reads/health (found, observed): routes.ts:218-226 GET /api/tokens/health spreads checkHealth.execute(); packages/token-vault/src/application/CheckHealth.ts:60-61 read poolReserveSetting() and poolBackgroundReserveSetting(); :91-94 poolReserve, poolBackgroundReserve, poolReserveSource, poolReserveLimits; packages/token-vault/src/domain/types.ts:221 HealthSummary, :280 poolReserve, :282 poolBackgroundReserve, :289 poolReserveSource, :291 poolReserveLimits; list routes.ts:192-215 GET /api/tokens, selection.rank at :208; dispatch reads the floor at packages/token-vault/src/application/GetBestToken.ts:464 poolReserveFraction(), with the 'pool reserve breached' refusal at :485-486, before ranking","shared helper and ALL callers (found, observed; grep -w rankTokens in packages returns 4 call sites plus the definition and imports): definition packages/token-vault/src/domain/selectionChain.ts:211 rankTokens(candidates, now); callers: GetBestToken.ts:362 (inside private rank at :361, which is called at :496 primary, :499 fallback and :534 last resort, where the filter is isAdministrativelyActive and not isProviderWindowFull rather than canServeRequest); CheckHealth.ts:52 bestAvailable; SwitchActiveToken.ts:105 switch to next; routes.ts:201 list rank. The imports at GetBestToken.ts:12, CheckHealth.ts:10, SwitchActiveToken.ts:6 and routes.ts:17 are not calls","tests (found, observed): packages/token-vault/src/__tests__/pool-reserve-settings.test.ts:49 fakeStore(initial: StoredPoolReserves); :113 READ; :147 WRITE; :197 'survives the restart'; :207 APPLY; packages/token-vault/src/__tests__/pool-reserve.test.ts:170 describe poolReserveFraction; :325 'GetBestToken — the floor reads WHO is asking'; route-test pattern for another route: packages/token-vault/src/__tests__/patch-metadata-route.test.ts:88 registerRoutes(app, makeStubUseCases(repo)); screen: packages/app/tests/unit/vault-account-list.test.ts:2 imports vaultGroups and vaultOrder only","proxy (found, observed): packages/app/app/api/tokens/route.ts:26 GET, fetchVault /api/tokens at :28 and /api/tokens/health at :29; :40 POST only, no PATCH export; :73-91 action pool-reserve sends a PATCH to VAULT_URL/api/pool/reserve at :75, returns 503 'Token vault unreachable' when there is no response (:89), and otherwise passes the vault's status through (:91)","screen (found, observed): packages/app/views/platform/TokenVaultView.tsx:134 health keys poolBackgroundReserve, poolReserveSource, poolReserveLimits, poolForecast; :1332 function AccountCard(token, spend, now, doAction, actionLoading); :1338 isActive = status active; :1339 rank = token.selection.rank or null; :1361 card root div with a green frame when isActive and no onClick; :1434 activate button doAction('switch'); :1544 list.map renders AccountCard; :2036 doAction; :2055 reserveError; :2075-2090 onReserveCommit does fetch('/api/tokens?action=pool-reserve') at :2082, calls setReserveError on failure at :2087 and invalidateAsyncData('platform:tokens') on success at :2088","ABSENT (grep at HEAD 4afbc7a): 'priorityAccount|api/pool/priority|pool-priority|PoolPriority' in packages, excluding node_modules — 0; 'api/pool/reserve|rankTokens' in packages/token-vault/src/__tests__ — 0 (no route test for the reserve, no direct rankTokens test); 'AccountCard|pool-reserve' in packages/app/tests — 0; PATCH export in packages/app/app/api/tokens/route.ts — 0 (only GET at :26 and POST at :40)","divergences (outside the layer model): packages/token-vault/src/application/SwitchActiveToken.ts:105 and CheckHealth.ts:52 order tokens with rankTokens directly, not through GetBestToken.rank, so a priority applied only in GetBestToken.rank at :361 would not reach switch-to-next, health bestAvailable or the list rank at routes.ts:201 (inference); GetBestToken.ts:534 last resort calls the same rank on tokens that cannot serve, so the priority must be gated on canServeRequest inside rank or kept out of that tier (inference, matches S2-14); pick in DocServicePoolReserveStore.ts:68-77 and PoolReservePatch at IPoolReserveStore.ts:21 accept numbers only, so a string or null priorityAccount in the same document needs its own field handling (inference)"]
acceptance_scenarios
["@stmt-1 @set [S1-01] Дано: priorityAccount пула = null, в пуле аккаунты acc1 и acc2. Когда: владелец записывает приоритет пула accountName = «acc2». Тогда: ответ ok:true, priorityAccount = «acc2»; повторное чтение приоритета возвращает «acc2».","@stmt-1 @set [S1-02] Дано: priorityAccount = «acc2» (самопереход). Когда: владелец записывает приоритет accountName = «acc2». Тогда: ok:true, priorityAccount = «acc2», ошибки нет; повторное чтение возвращает «acc2».","@stmt-1 @unset [S1-03] Дано: priorityAccount = «acc2». Когда: владелец записывает приоритет accountName = null. Тогда: ok:true, priorityAccount = null; повторное чтение возвращает null.","@stmt-1 @unset [S1-04] Дано: priorityAccount = null (повторное снятие, no-op). Когда: владелец записывает приоритет accountName = null. Тогда: ok:true, priorityAccount = null, ошибки нет; повторное чтение возвращает null.","@stmt-1 @toggle [S1-05] Дано: priorityAccount = «acc1». Когда: владелец записывает приоритет accountName = «acc2». Тогда: ok:true, priorityAccount = «acc2»; повторное чтение возвращает «acc2»; у пула одно значение, acc1 больше не приоритет.","@stmt-1 @toggle @sequence [S1-06] Дано: priorityAccount = null. Когда: владелец записывает accountName = «acc1», и затем записывает accountName = null. Тогда: итоговое чтение возвращает null, ровно исходное состояние.","@stmt-1 @sequence @negative [S1-07] Дано: priorityAccount = null. Когда: владелец записывает accountName = null, и затем записывает accountName = «acc1» (порядок S1-06 переставлен). Тогда: итоговое чтение возвращает «acc1», а не null.","@stmt-1 @negative [S1-08] Дано: priorityAccount = «acc1». Когда: владелец отправляет запись приоритета без ключа accountName. Тогда: отказ, код 400, ok:false, причина в поле error; save хранилища не вызывался; чтение возвращает «acc1».","@stmt-1 @negative [S1-09] Дано: priorityAccount = null. Когда: владелец записывает приоритет accountName = 42. Тогда: отказ, код 400, ok:false; save хранилища не вызывался; чтение возвращает null.","@stmt-1 @dependency-down [S1-10] Дано: priorityAccount = «acc1»; хранилище настроек отвечает error на save. Когда: владелец записывает приоритет accountName = «acc2». Тогда: отказ, код 500, ok:false, запись ошибки в журнале; чтение возвращает «acc1»; выдача продолжает ставить acc1 первым (порядок: проверка, хранилище, память).","@stmt-1 @dependency-down [S1-11] Дано: хранилище настроек unavailable на load. Когда: волт стартует. Тогда: старт не падает, в журнале ошибка загрузки; чтение приоритета возвращает null; выдача идёт без приоритета.","@stmt-1 @dependency-down [S1-12] Дано: волт собран без объекта настроек пула. Когда: владелец читает приоритет пула. Тогда: отказ, код 503, ok:false, текст «not wired» (как у маршрутов резерва).","@stmt-1 @happy [S1-13] Дано: priorityAccount = «acc2» записан в хранилище. Когда: процесс волта перезапускается с тем же хранилищем. Тогда: чтение приоритета возвращает «acc2» (образец: тест резерва «survives the restart»).","@stmt-1 @happy [S1-14] Дано: в общем документе хранилища фоновый резерв 0.08, priorityAccount = null. Когда: владелец записывает приоритет accountName = «acc2». Тогда: чтение резерва даёт background 0.08; чтение приоритета даёт «acc2».","@stmt-1 @happy [S1-15] Дано: priorityAccount = «acc2», фоновый резерв 0.05. Когда: владелец записывает резерв background = 0.08. Тогда: чтение резерва даёт background 0.08; чтение приоритета по-прежнему «acc2».","@stmt-1 @characterization [S1-16] Текущее поведение. Дано: в хранилище документ резерва в сегодняшнем виде, без поля priorityAccount, с interactive 0.05 и background 0.08. Когда: волт загружает настройки. Тогда: чтение резерва отдаёт interactive 0.05 и background 0.08, как до правки; чтение приоритета отдаёт null.","@stmt-2 @set @happy @tier-primary [S2-01] Дано: acc1 util7d 0.30, acc2 util7d 0.80, оба primary и способны обслужить запрос; при null выдаётся acc1; priorityAccount = «acc2». Когда: интерактивный вызов выдачи токена. Тогда: выдан accountName = «acc2».","@stmt-2 @happy @tier-primary [S2-02] Дано: acc1 util7d 0.30, acc2 util7d 0.50, acc3 util7d 0.80, все способны обслужить; priorityAccount = «acc3». Когда: вызов выдачи. Тогда: первый кандидат acc3; взаимный порядок acc1 и acc2 после него совпадает с порядком при null.","@stmt-2 @unset @tier-primary [S2-03] Дано: acc1 util7d 0.30, acc2 util7d 0.80; приоритет acc2 снят, priorityAccount = null. Когда: вызов выдачи. Тогда: выдан acc1; порядок кандидатов совпадает с порядком без функции.","@stmt-2 @toggle @tier-primary [S2-04] Дано: acc1 util7d 0.30, acc2 util7d 0.80; приоритет переключён с acc1 на acc2, priorityAccount = «acc2». Когда: вызов выдачи. Тогда: выдан acc2, acc1 стоит вторым.","@stmt-2 @negative @tier-primary [S2-05] Дано: acc1 util7d 0.30, acc2 util7d 1.00 (мёртв), priorityAccount = «acc2». Когда: интерактивный вызов выдачи. Тогда: выдан acc1; порядок кандидатов совпадает с порядком при null.","@stmt-2 @negative @tier-primary [S2-06] Структура с примерами. Дано: порог недели 1.00 (VAULT_TURN_HEADROOM_7D = 0), acc1 util7d 0.30, priorityAccount = «acc2». Когда: вызов выдачи при util7d acc2 из строки примеров. Тогда: примеры (одна строка — одно нарушение): 0.99 выдан acc2; 1.00 выдан acc1; 1.01 выдан acc1.","@stmt-2 @negative @tier-primary [S2-07] Дано: priorityAccount = «acc2», статус acc2 = disabled, acc1 жив. Когда: вызов выдачи. Тогда: выдан acc1, порядок как при null.","@stmt-2 @negative @tier-primary [S2-08] Дано: priorityAccount = «acc9», в пуле только acc1 и acc2. Когда: вызов выдачи. Тогда: выдан тот же аккаунт и в том же порядке, что при null; ошибки нет.","@stmt-2 @negative [S2-09] Дано: priorityAccount = «acc2», acc2 жив, acc1 жив. Когда: вызов выдачи с исключением acc2. Тогда: выдан acc1; acc2 не выдан (приоритет упорядочивает только выживших после жёстких фильтров).","@stmt-2 @negative [S2-10] Дано: priorityAccount = «acc2», оба живы. Когда: вызов выдачи с привязкой к acc1. Тогда: выдан acc1.","@stmt-2 @negative [S2-11] Дано: priorityAccount = «acc2», лучший остаток недели 0.03 при интерактивном полу 0.05. Когда: интерактивный вызов выдачи. Тогда: отказ с текстом «pool reserve breached», токен не выдан.","@stmt-2 @negative @tier-fallback [S2-12] Дано: acc1 роль primary, жив; acc3 роль fallback, жив; priorityAccount = «acc3». Когда: вызов выдачи. Тогда: выдан acc1 (роль сильнее приоритета: fallback не соревнуется с живым primary).","@stmt-2 @happy @tier-fallback [S2-13] Дано: primary acc1 и acc2 с util7d 1.00; fallback acc3 util7d 0.30 и acc4 util7d 0.60, оба живы; priorityAccount = «acc4». Когда: вызов выдачи. Тогда: выдан acc4.","@stmt-2 @negative @tier-last-resort [S2-14] Дано: порог недели 0.80 (VAULT_TURN_HEADROOM_7D = 0.20), acc1 util7d 0.85, acc2 util7d 0.90, ни один не способен обслужить, окно провайдера не выбрано, fallback нет, requireUsable не задан; priorityAccount = «acc2». Когда: вызов выдачи. Тогда: выдан тот же аккаунт и порядок кандидатов тот же, что при null в этой конфигурации; acc2 не поднят приоритетом.","@stmt-2 @happy @tier-model-aware [S2-15] Дано: model-aware включён, запрошенная модель не капнута ни на acc1, ни на acc2; acc1 util7d 0.30, acc2 util7d 0.80; priorityAccount = «acc2». Когда: вызов выдачи с этой моделью. Тогда: выдан acc2.","@stmt-2 @negative @tier-model-aware [S2-16] Дано: model-aware включён, запрошенная модель капнута на acc2 и не капнута на acc1; priorityAccount = «acc2». Когда: вызов выдачи с этой моделью. Тогда: выдан acc1.","@stmt-2 @sequence @set [S2-17] Дано: экземпляр выдачи создан при priorityAccount = null, acc1 util7d 0.30, acc2 util7d 0.80. Когда: владелец записывает приоритет «acc2», и затем тот же экземпляр выполняет вызов выдачи. Тогда: выдан acc2, без перезапуска (образец: тест резерва APPLY).","@stmt-2 @sequence @negative [S2-18] Дано: экземпляр выдачи создан при priorityAccount = null, acc1 util7d 0.30, acc2 util7d 0.80. Когда: тот же экземпляр выполняет вызов выдачи, и затем владелец записывает приоритет «acc2» (порядок S2-17 переставлен). Тогда: этот вызов выдал acc1.","@stmt-2 @dependency-down [S2-19] Дано: хранилище настроек unavailable на load при старте; acc1 util7d 0.30, acc2 util7d 0.80. Когда: вызов выдачи. Тогда: выдан acc1, порядок как при null, отказа выдачи нет.","@stmt-2 @characterization [S2-20] Текущее поведение. Дано: priorityAccount = null. Когда: полный прогон существующих тестов выдачи (привязка, исключение, фолбэк, модельные капы, резерв). Тогда: 0 упавших; выбор и порядок совпадают со снимком, записанным на ревизии 5bddb3a до правки.","@stmt-3 @set @happy [S3-01] Дано: priorityAccount = «acc2». Когда: экран читает сводку здоровья волта. Тогда: ok:true и priorityAccount = «acc2».","@stmt-3 @set @happy [S3-02] Дано: priorityAccount = «acc2». Когда: экран читает список токенов. Тогда: ok:true и priorityAccount = «acc2».","@stmt-3 @unset [S3-03] Дано: priorityAccount только что снят в null. Когда: экран читает сводку здоровья. Тогда: ключ priorityAccount присутствует со значением null.","@stmt-3 @unset [S3-04] Дано: priorityAccount только что снят в null. Когда: экран читает список токенов. Тогда: ключ priorityAccount присутствует со значением null.","@stmt-3 @toggle [S3-05] Дано: приоритет переключён с acc1 на acc2. Когда: экран читает сводку здоровья. Тогда: priorityAccount = «acc2».","@stmt-3 @negative [S3-06] Дано: priorityAccount = «acc2», acc2 util7d 1.00. Когда: экран читает список токенов. Тогда: priorityAccount = «acc2», а selection.rank у acc2 = null (исчерпанный не имеет места в выдаче).","@stmt-3 @dependency-down [S3-07] Дано: хранилище настроек unavailable на load при старте. Когда: экран читает сводку здоровья. Тогда: ok:true, priorityAccount = null; поля poolReserve, poolBackgroundReserve, poolReserveSource, poolReserveLimits присутствуют.","@stmt-3 @characterization [S3-08] Текущее поведение. Дано: priorityAccount = null, сохранён interactive резерв 0.05. Когда: экран читает сводку здоровья и список токенов. Тогда: poolReserve = 0.05; poolBackgroundReserve, poolReserveSource, poolReserveLimits и selection.rank каждого токена совпадают со снимком до правки; новое только поле priorityAccount.","@stmt-4 @set [S4-01] Дано: приоритета нет, карточки acc1 и acc2 в группе с недельной квотой. Когда: владелец выбирает карточку acc1. Тогда: уходит запись priority = «acc1»; подсвечена только acc1; после обновления данных экрана подсветка у acc1.","@stmt-4 @unset [S4-02] Дано: подсвечена acc1. Когда: владелец снова выбирает карточку acc1. Тогда: уходит запись priority = null; подсвеченных карточек 0; после обновления данных тоже 0.","@stmt-4 @toggle [S4-03] Дано: подсвечена acc1. Когда: владелец выбирает карточку acc2. Тогда: уходит запись priority = «acc2»; подсвечена только acc2; подсвеченных карточек ровно 1.","@stmt-4 @toggle @sequence [S4-04] Дано: приоритета нет, карточки acc1 и acc2. Когда: владелец выбирает acc1, и затем снова выбирает acc1. Тогда: записи ушли в порядке «acc1», null; подсвеченных карточек 0, ровно исходное состояние.","@stmt-4 @negative [S4-05] Дано: подсвечена acc1. Когда: владелец нажимает кнопку «активировать» внутри карточки acc2. Тогда: уходит действие switch; запись приоритета не уходит; подсветка остаётся у acc1.","@stmt-4 @dependency-down [S4-06] Дано: подсвечена acc1; волт отвечает на запись приоритета отказом с кодом 503. Когда: владелец выбирает карточку acc2. Тогда: подсветка остаётся у acc1; на экране текст отказа (образец: прокси резерва передаёт статус отказа экрану).","@stmt-4 @dependency-down [S4-07] Дано: прокси экрана получает reachable = false и health = null. Когда: экран обновляет данные. Тогда: подсвеченных приоритетом карточек 0.","@stmt-4 @characterization [S4-08] Текущее поведение. Дано: priorityAccount = null. Когда: экран отрисовывает карточки. Тогда: рамка и порядок карточек совпадают со снимком до правки; зелёная рамка только у карточки со статусом active.","@stmt-4 @happy [S4-09] Дано: карточки acc1, acc2, acc3; priorityAccount = «acc3». Когда: экран отрисовывает карточки. Тогда: подсвечена ровно 1 карточка — acc3.","@stmt-4 @sequence [S4-10] Дано: приоритета нет, карточки acc1 и acc2. Когда: владелец выбирает acc1, затем acc2, затем acc2. Тогда: записи ушли в порядке «acc1», «acc2», null; после третьего выбора подсвеченных карточек 0.","@stmt-4 @sequence @negative [S4-11] Дано: приоритета нет, карточки acc1 и acc2. Когда: владелец выбирает acc2, затем acc2, затем acc1 (порядок S4-10 переставлен). Тогда: записи ушли в порядке «acc2», null, «acc1»; подсвечена только acc1.","@stmt-5 @happy [S5-01] Дано: набор из двух аккаунтов, priorityAccount = «acc2». Когда: прогон тестов пакета token-vault. Тогда: зелёные тесты «жив — первый» и «мёртв (util7d 1.00) — порядок как без приоритета».","@stmt-5 @negative [S5-02] Дано: мутант, в котором rank ставит приоритет первым без проверки способности обслужить. Когда: прогон тестов пакета token-vault. Тогда: тест «мёртв (util7d 1.00) — порядок как без приоритета» красный.","@stmt-5 @negative @tier-last-resort [S5-03] Дано: мутант, в котором приоритет поднимается и в ярусе last resort. Когда: прогон тестов пакета token-vault. Тогда: тест сценария S2-14 красный.","@stmt-5 @happy [S5-04] Дано: волт с поддельным хранилищем в памяти. Когда: прогон тестов маршрутов. Тогда: зелёные set, unset, switch с повторным чтением после каждой записи и отказ с кодом 400 на пустое тело.","@stmt-5 @negative [S5-05] Дано: мутант маршрута, вызывающий save хранилища до проверки тела. Когда: прогон тестов маршрутов. Тогда: тест «запись не выполнялась» для тела без accountName красный.","@stmt-5 @dependency-down [S5-06] Дано: поддельное хранилище в памяти бросает error на save, реальная сеть не используется. Когда: прогон тестов маршрутов. Тогда: зелёный тест: отказ с кодом 500 и повторное чтение возвращает прежнее значение «acc1».","@stmt-5 @sequence [S5-07] Дано: приоритета нет, карточки acc1 и acc2. Когда: проверка экрана выбирает acc1, затем acc2, затем acc2. Тогда: проверка зелёная: записи ушли в порядке «acc1», «acc2», null, подсвеченных карточек 0.","@stmt-5 @sequence @negative [S5-08] Дано: экран-мутант, который на повторный выбор шлёт priority = «acc2» вместо null. Когда: проверка экрана выбирает acc1, затем acc2, затем acc2. Тогда: проверка красная — после третьего выбора acc2 осталась подсвеченной.","@stmt-5 @characterization [S5-09] Текущее поведение. Дано: набор тестов token-vault и app на ревизии 5bddb3a (включая vault-account-list.test.ts). Когда: прогон до и после правки. Тогда: 0 упавших прежних тестов; число прежних тестов не уменьшилось."]
reproducer_test
packages/app/tests/unit/vault-card-tooltip-owner.test.tsx: F2P — открываем ⓘ-панель карточки acc1. Панель видна, но над кнопкой ⓘ всплывает подсказка всей карточки «click to make this account the pool priority — served first while it has headroom». Ожидается, что подсказки нет. Красный предсказан, не запущен
work_screen_tree
["ЦЕЛЬ (мета-характеристика): дерево рабочих экранов (не лендингов), на которых человек ставит задачу и видит, как она делается; нужно, чтобы найти в нём узел экрана shadums.com (ввод, вывод, дерево классификации цели)","КОРЕНЬ (N=11: ChatGPT, Claude, Manus, Devin, Cursor, Lindy, Dust, n8n, LangGraph Studio/LangSmith, Relevance AI, Perplexity): (1) вывод результата виден на рабочем экране, 11/11 = 1.00; причина по принципу: человек отдаёт работу, чтобы получить результат, и принять его или возразить может только тогда, когда видит его там же, где поставил задачу · (2) ход работы виден, 10/11 = 0.91 в широком прочтении (включая статус «Thinking»); в узком прочтении (только пошаговый след) 9/11 = 0.82; причина по принципу: работа, отданная другому исполнителю, скрыта от человека, и без видимого хода он не может ни проверить результат, ни вмешаться вовремя. Решение по нормализации: в корень идёт широкое прочтение; узкое тоже ≥ 0.8, поэтому состав корня от этого выбора не меняется. Какой 1 сайт не показывает ход работы, в записях не названо (пробел)","НЕ В КОРНЕ: «вывод в ленте разговора или треда» 6/11 = 0.55 (отсутствие, различие ветвей); «вывод на холсте или в графе» 3/11 = 0.27 (отсутствие); «вывод в файлах кода» 2/11 = 0.18 (отсутствие); место поля ввода, вложения и голос, панель истории, источники и цитаты, действия над результатом, показ ошибки и ожидания, поведение при повторе задачи — в записях не заполнены, это пробел [—], а не отсутствие. Их нельзя ни отклонить, ни использовать для деления. Отклонённых признаков с долей ≥ 0.8 нет","КОРЕНЬ → ребро «вывод: где показан = холст или граф сценария» (внешняя причина: сегмент и бизнес-модель — продают сборку повторяемой автоматизации, а не ответ на разовый запрос) → ПЛАТФОРМА СЦЕНАРИЕВ [n8n, LangGraph Studio/LangSmith, Lindy], лист из 3; остановка: в записях нет следующего документированного свойства с внешней причиной различия","КОРЕНЬ → ребро «вывод: где показан = файлы кода в IDE или редакторе» (внешняя причина: платформа и сегмент — результат для разработчика это изменение репозитория) → КОД В СРЕДЕ [Devin, Cursor]","КОД В СРЕДЕ → ребро «среда: где запущена = боковая панель редактора пользователя (Cmd+I)» (внешняя причина: канал — работает внутри локального редактора владельца) → ИНСТРУМЕНТ В РЕДАКТОРЕ [Cursor], лист из 1 (меньше 2 записей)","КОД В СРЕДЕ → ребро «среда: где запущена = сессия агента в веб-приложении app.devin.ai» (внешняя причина: канал и бизнес-модель — облачная песочница агента, работа отдаётся целиком) → АГЕНТ-РАЗРАБОТЧИК [Devin], лист из 1 (меньше 2 записей)","КОРЕНЬ → ребро «вывод: где показан = лента разговора или треда задачи» (внешняя причина: сегмент — широкий круг работников умственного труда, привычный канал — переписка) → РАЗГОВОР [ChatGPT, Claude, Dust, Perplexity, Manus, Relevance AI]","РАЗГОВОР → ребро «вывод: единица = задача (разговор задачи, статусы, шаринг задачи)» (внешняя причина: бизнес-модель — продают делегирование автономной работы, а не ответ) → ДЕЛЕГИРОВАННАЯ ЗАДАЧА [Manus, Relevance AI]","ДЕЛЕГИРОВАННАЯ ЗАДАЧА → ребро «ход работы: где показан = живая среда агента (браузер, VS Code), управление можно перехватить» (внешняя причина: платформа — агент работает в своём компьютере или браузере) → [Manus], лист из 1 (меньше 2 записей)","ДЕЛЕГИРОВАННАЯ ЗАДАЧА → ребро «ход работы: где показан = шаги и запуски инструментов в треде, одобрение вызова инструмента» (внешняя причина: сегмент и регуляция — корпоративная «рабочая сила» агентов, где действия требуют надзора человека) → ОЧЕРЕДЬ ЗАДАЧ АГЕНТА [Relevance AI], лист из 1 (меньше 2 записей)","РАЗГОВОР → ребро «вывод: единица = ответ-сообщение в разговоре» (внешняя причина: бизнес-модель — ассистент «вопрос → ответ») → ЧАТ-АССИСТЕНТ [ChatGPT, Claude, Dust, Perplexity], лист из 4; остановка: следующий возможный делитель (например, источники и цитаты у Perplexity) в записях не заполнен, это пробел, поэтому делить нельзя","КОНВЕРГЕНЦИЯ (convergent=true, для объединения ветвей не используется): «живая среда агента, управление можно перехватить» независимо возникла у Manus (ветвь РАЗГОВОР) и у Devin (ветвь КОД В СРЕДЕ, по документации Devin: IDE с перехватом управления); чат-ввод поверх холста (n8n — чат агента; Lindy — «Ask Agent Builder») независимо повторяет поле ввода ветви РАЗГОВОР","ПРОВЕРКА РАЗБИЕНИЯ: листы 3 (ПЛАТФОРМА СЦЕНАРИЕВ) + 1 (Cursor) + 1 (Devin) + 1 (Manus) + 1 (Relevance AI) + 4 (ЧАТ-АССИСТЕНТ) = 11 = N; каждая запись лежит ровно в одном листе, пересечений нет"]
statement_coverage_verdicts
["Случай 1 «работало только после выкатки, а ядро сказало принято»: утверждения 122 (task-target.json:412), 123 (:413), 124 (:414). По тексту — частично: 123 и 124 требуют выкатку и живую пробу, а исход admitted только по зелёной внешней пробе; но зелёная дверь с 0/0 проверок нигде не запрещена. По коду — частично: proveOutward task.ts:4947–4992, liveDeployPort :7079, liveProbePort :7129, подключены в CLI :7305–7306, вопрос observed :2987–3001; проверки [s123:8ef5acdb] и [s124:ba568455] есть, но только на подставных портах. Итог — частично. Остаток: R1, R2, R3, R4, R5","Случай 2 «клик по карточке перекрыл тултипы»: утверждения 125 (:415), 126 (:416), а также 124 (:414) — проба экрана взаимодействием. По тексту — целиком: 125 прямо называет «hover ребёнка под новым кликом родителя» и требует вопроса владельцу, 126 судит свойство родителя проверками частей. По коду — нет: в task.ts и packages по hover, tooltip, interaction, stopPropagation, statement 125/126 найдено 0; проверок s125 и s126 в statement-checks 0. Итог — частично (есть только текст). Остаток: R1, R6, R7, R8","Случай 3 «клик мигает весь экран»: ни одно утверждение в 0–126 это свойство не называет; соседние — 125 (:415, проверки взаимодействия render+event+assert, но только для уже существующих взаимодействий) и 126 (:416). Утверждение 127 (:417) называет этот спецймен, но оно вне диапазона. По тексту — нет, по коду — нет (тот же пустой grep), проверок 0. Итог — нет. Остаток: R9, R10"]
kernel_statement_drafts
["R1 · случаи 1, 2, 3 · prevent · НОВОЕ 129: ДВЕРЬ, НЕ ВЫПОЛНИВШАЯ НИ ОДНОЙ ПРОВЕРКИ, НЕ ЗЕЛЁНАЯ (runs/01bd9e17:27 «проверки 0/0», :29 check null, :555 outcome admitted; runs/0c28c88c:59 «проверки 0/0, заландено f5ed68b72»; task.ts:4822–4824: при check null значение total по умолчанию равно 0, а green при этом не снимается). Свойство: любой ответ двери с green = true и check.total, равным 0 или отсутствующим, даёт исход цели refused с cause 'door-no-checks'. Специмен: ответ двери green true, check null, changed = TokenVaultView.tsx и PoolReserveSettings.ts; ожидается outcome.kind = 'refused', cause = 'door-no-checks'; наблюдалось 'admitted' (runs/01bd9e17:555). Проверка: блок [s129] в runtime/statement-checks/task/task.statements.test.ts: run() с заглушкой двери green true и check null, затем assert.equal(outcome.cause, 'door-no-checks'). Мутант: убрать отказ при total = 0, блок краснеет. Статус: проверка не запускалась; красный на HEAD только предсказан (в task.ts нет отказа при 0/0).","R2 · случай 1 · prevent · ПРАВКА 124 (ветка [s124] «запрос выкатки несёт sha»): ЗАПРОС ВЫКАТКИ НАЗЫВАЕТ SHA ЛЕНДА (task.ts:7084: POST /deploy/run?trigger=kernel уходит без sha; [s124:ba568455] в task.statements.test.ts:7077–7085 проверяет только подставной порт, а liveDeployPort в нём не вызывается). Свойство: при любом вызове liveDeployPort(config) с sha HTTP-запрос к координатору несёт этот sha в поле sha тела JSON. Специмен: вход sha 'cec8230e7' (ленд runs/01bd9e17:115); ожидается поле sha = 'cec8230e7' в теле запроса; наблюдалось пустое тело. Проверка: ветка блока [s124] поднимает node:http на 127.0.0.1 порт 0 как координатор, который отвечает ok false; вызывается настоящий liveDeployPort с paths.deploy = адрес стаба, затем assert.equal(JSON.parse(body).sha, 'cec8230e7'). Мутант: POST без тела, ветка краснеет. Статус: проверка не запускалась; красный на HEAD только предсказан.","R3 · случай 1 · prevent · ПРАВКА 124 (ветка [s124] «выкачен именно этот sha»): DEPLOYED ТОЛЬКО ДЛЯ ЗАПРОШЕННОГО SHA (task.ts:7113–7115: при latest.status 'done' порт возвращает deployed true и sha = request.sha, не сверяя, что координатор выкатил именно его). Свойство: liveDeployPort возвращает deployed = true, только если sha, который /deploy/status называет выкаченным, совпадает с запрошенным; иначе deployed = false и why «выкачен другой sha». Специмен: запрошен 'cec8230e7', стаб статуса отвечает status 'done' и sha '5bddb3ac7'; ожидается deployed = false; наблюдалось бы deployed = true. Пробел: есть ли поле sha в ответе /deploy/status, не проверено. Проверка: ветка блока [s124], настоящий liveDeployPort против стаба node:http; из-за DEPLOY_POLL_MS = 15000 одна итерация займёт около 15 с. Мутант: убрать сверку sha, ветка краснеет. Статус: проверка не запускалась.","R4 · случай 1 · detect · ПРАВКА 124 (ветка [s124] «проба судит тело примера»): ЗЕЛЁНАЯ ПРОБА СОВПАДАЕТ С ПРИМЕРОМ УТВЕРЖДЕНИЯ (task.ts:7143: green = статус меньше 400, тело не сравнивается; утверждение 124 требует сверять «status and body fields»). Свойство: liveProbePort возвращает green = true, только если JSON-тело ответа содержит каждое поле примера утверждения с тем же значением. Специмен: PATCH /api/pool/priority с accountName = 'acc2', стаб отвечает 200 с priorityAccount = null; ожидается green = false; наблюдалось бы green = true. Проверка: ветка блока [s124], настоящий liveProbePort против стаба node:http на 127.0.0.1. Мутант: вернуть условие «статус меньше 400», ветка краснеет. why_not_prevent: живую пробу можно выполнить только над уже выкаченным сервисом, а предотвращение для случая 1 дают R1 и R5. Статус: проверка не запускалась.","R5 · случай 1 · prevent · ПРАВКА 123 (ветка [s123] «неотвеченное место наблюдения не даёт admitted»): НЕИЗВЕСТНОЕ МЕСТО НАБЛЮДЕНИЯ НЕ ДОПУСКАЕТ ЦЕЛЬ (task.ts:2997–2999: если классификатор observed бросил ошибку или не ответил, observed = null и корень завершается по оракулу кода; proveOutward на :4948 возвращает null, гейт на :6815 оставляет admitted). Свойство: корневая цель с artifact:code, чей текст называет маршрут, URL или экран, при observed = null получает исход partial, а не admitted. Специмен: текст цели с dev.imperiaos.com/platform/admin/token-vault, транспорт бросает ошибку на стадии task-observed; ожидается outcome.kind = 'partial'; наблюдалось бы 'admitted'. Проверка: ветка блока [s123:8ef5acdb] в task.statements.test.ts (рядом с :7043), modelRequest бросает ошибку на стадии 'task-observed'. Мутант: вернуть null при observed = null, ветка краснеет. Статус: проверка не запускалась.","R6 · случай 2 · prevent · ПРАВКА 125 (ветка [s125a] «существующие взаимодействия входят в цель двери»): ВЗАИМОДЕЙСТВИЯ ЭКРАНА ИЗВЛЕКАЮТСЯ ИЗ КОДА (по вердикту grep hover, tooltip и interaction в task.ts дал 0 совпадений; проверок s125 в statement-checks 0). Свойство: для любой цели двери, среди файлов которой есть .tsx или .vue, doorGoalOf добавляет по одному утверждению на каждый существующий атрибут title и на каждый обработчик onClick, onMouseEnter и onKeyDown в форме «элемент: взаимодействие → эффект». Специмен: TokenVaultView.tsx:903, кнопка ⓘ с title = lines.join('\\n') при закрытой панели; ожидается строка утверждений «button ⓘ: hover → title» в goal.statements; наблюдалось 0 таких строк (прогон 85bb85d1). Проверка: блок [s125a] вызывает doorGoalOf на фикстуре tsx с button onClick и title 'info', затем assert.ok(statements.some(s => s.includes('hover → title'))). Мутант: пропустить извлечение, блок краснеет. Статус: проверка не запускалась.","R7 · случай 2 · prevent · ПРАВКА 125 (ветка [s125b] «перекрытие hover ребёнка — вопрос владельцу»): ТЕНЬ НА ВЗАИМОДЕЙСТВИЕ РЕБЁНКА ОСТАНАВЛИВАЕТ ДВЕРЬ ВОПРОСОМ (patch.after прогона 85bb85d1 ставит title = priorityTip на корневой div с role=button, TokenVaultView.tsx:1378; ⓘ снимает свой title при open, :903, и по MDN наследует title предка; ленд 6b9942dcb, runs/6aa2039f:2216, прошёл без вопроса). Свойство: кандидат, который ставит title или onClick на предка элемента, у которого в исходной версии был свой title, получает исход ask с одним вопросом «оставить оба / заменить». Специмен: patch.before и patch.after прогона 85bb85d1; ожидается outcome.kind = 'ask', и вопрос содержит «оставить оба»; наблюдались admitted и ленд. Проверка: блок [s125b], заглушка двери возвращает этот patch. Мутант: отключить поиск конфликта, блок краснеет. Статус: проверка не запускалась.","R8 · случай 2 · prevent · ПРАВКА 126 (ветка [s126] «свойство родителя судят проверки частей»): ДВЕРЬ ЭКРАНА ГОНЯЕТ ПРОВЕРКИ ВСЕХ ЧАСТЕЙ (runs/01bd9e17:27 «проверки 0/0»; :71–78 change-flow без рендера; у дочерних элементов AccountCard свои title на TokenVaultView.tsx:903, 1387, 1421, 1435, 1438, 1440, 1444, 1456). Свойство: изменение экрана зелёное, только если check.total не меньше числа существующих взаимодействий, извлечённых по ветке [s125a]. Специмен: карточка AccountCard, 8 взаимодействий с title; ожидается check.total ≥ 8; наблюдалось 0. Проверка: блок [s126]; на уровне продукта в пару к нему — репродьюсер packages/app/tests/unit/vault-card-tooltip-owner.test.tsx (открыть ⓘ карточки acc1 и убедиться, что подсказка карточки «click to make this account the pool priority» не всплывает). Мутант: засчитывать 0 проверок частей, блок краснеет. Статус: не запускались ни проверка, ни репродьюсер; красный на 6b9942dcb только предсказан.","R9 · случай 3 · prevent · НОВОЕ 130: ПОКАЗАННЫЙ ЭКРАН ПЕРЕЖИВАЕТ ВЗАИМОДЕЙСТВИЕ (на TokenVaultView.tsx:2186 onPriority вызывает invalidateAsyncData('platform:tokens'); DomainData.ts:95–96 делает liveCache.delete; на :527 и :539 чтение бросает промис; Suspense вне transition показывает фоллбек; починка f5ed68b — keepShownFrame на :1524–1535 с вызовом на :1878, runs/0c28c88c:143). Свойство: для каждого обработчика экрана, который сбрасывает кэш уже показанных данных, дверь выводит interaction-проверку: между событием и следующим кадром данных фоллбек границы Suspense отрисован 0 раз. Специмен: клик по карточке acc1 на 6b9942dcb; ожидается 0 отрисовок фоллбека; наблюдалось мигание всего экрана (слово владельца). Проверка: блок [s130]: doorGoalOf на фикстуре tsx с обработчиком, вызывающим invalidateAsyncData, выводит проверку 'shown-frame-survives'; в пару к нему тест продукта рендерит TokenVaultView со стабом ds, кликает по карточке и считает фоллбеки. Мутант: убрать keepShownFrame на :1878, тест краснеет. Пробел: какая граница Suspense показывала фоллбек, не установлено. Статус: проверка не запускалась.","R10 · случай 3 · prevent · НОВОЕ 131: ПОЧИНКА ОШИБКИ РЕЗУЛЬТАТА ДОПУСКАЕТСЯ ТОЛЬКО С РЕПРОДЬЮСЕРОМ, КРАСНЫМ ДО И ЗЕЛЁНЫМ ПОСЛЕ (runs/0c28c88c:59 «проверки 0/0, заландено f5ed68b72»: починку мигания заландили, не прогнав репродьюсер на df15846). Свойство: цель вида «ошибка результата» (утв. 127) получает admitted, только если расписка содержит прогон репродьюсера с red на родительском sha и с green на sha ленда. Специмен: родитель df15846, ленд f5ed68b; ожидается «репродьюсер: red на df15846, green на f5ed68b»; наблюдалась расписка без репродьюсера. Проверка: блок [s131], заглушка двери отдаёт репродьюсер с pass на обеих версиях, затем assert.equal(outcome.cause, 'reproducer-not-red'). Мутант: не проверять прогон до починки, блок краснеет. Статус: проверка не запускалась."]
kernel_statement_draft
ПРАВКА 81
glossary_term_lines
[" | 'attribute'\n | 'fact'\n | 'law'"," // Имя — утв. 67 (task-target.json:357, ATTRIBUTES записи); подъём к родителю — утв. 126 (:416); поправка имён 2026-09-27 ~14:1xZ: «свойство = АТРИБУТ записи».\n attribute: {\n definition:\n 'Признак записи паттерна, по которому строится дерево классификации: производимый ключ output и kind, ключи needs, требования из checks, вид artifact и сегменты пути parent. ' +\n 'Признаки частей поднимаются к родителю метками (утв. 126; в коде ядра этого пока нет).',\n legalIn:\n 'Дерево классификации ядра (решётка «записи × атрибуты», утв. 67) и подъём от частей к родителю (утв. 126). ' +\n 'НЕ факт: атрибут описывает запись и пустоту значением не закрывает. НЕ закон: атрибут с префиксом law: только называет закон, который запись держит; судит закон. ' +\n 'Слово «свойство» из утв. 126 — это же понятие, отдельной статьи у него нет.',\n ...forms(['attribute', 'атрибут', 'atributo'], ['attributes', 'атрибуты', 'atributos'], ['attributes', 'атрибутов', 'atributos']),\n },"," // Имя — утв. 111 (task-target.json:401, A FACT IS A RECORD OF THE ONE DOMAIN TREE).\n fact: {\n definition:\n 'Запись паттерна без посылок и пустот: kind form, output — ключ, bestForm — значение, которое подставляется без вызова модели; владелец записи — mintedBy, место — путь parent в дереве домена. ' +\n 'Значение по ключу закрывает пустоту (посылку) другой записи.',\n legalIn:\n 'Реестр паттернов (утв. 111; отдельный файл runtime/state/facts выведен из обращения), заполнение посылок по ключу (утв. 29, 30) и спуск, который решает, что показать модели. ' +\n 'НЕ атрибут: факт несёт значение, а не описывает запись. НЕ закон: факт ничего не требует и сам не проверяется. Факты — владельца (mintedBy), паттерны — общие.',\n ...forms(['fact', 'факт', 'hecho'], ['facts', 'факты', 'hechos'], ['facts', 'фактов', 'hechos']),\n },"," // Имя — утв. 64 (task-target.json:354, A LAW IS A REQUIREMENT OF THE GOAL); практики узла — утв. 75 (:365); поправка имён 2026-09-27 ~14:1xZ: «ограничение = ЗАКОН».\n law: {\n definition:\n 'Требование цели, по которому судится ответ: объект из текста требования, исполнимой проверки test и источника source (request, owner, domain, observed). ' +\n 'Требования, общие всем записям узла решётки, составляют практики этого узла (утв. 75).',\n legalIn:\n 'Цель ядра (утв. 64), допуск записи и суд ответа; «утверждение» цели ядра (goals.task.statements) — это закон, второго слова нет. Узел у закона и наследование вниз по спуску — задача текущей цели, в коде этого пока нет. ' +\n 'НЕ атрибут: атрибут описывает запись, закон требует и судит над атрибутами. НЕ практика: практика — «как», закон — «что обязано выполняться». НЕ факт: у закона нет значения, есть проверка.',\n ...forms(['law', 'закон', 'ley'], ['laws', 'законы', 'leyes'], ['laws', 'законов', 'leyes']),\n },"]
law_node_classification
["ИТОГ 129 = 95 по узлам + 1 в корне по построению + 26 схлопнуты в корень + 7 дефектов «нет блока проверки»; каждый id 0–128 стоит ровно в одной корзине, множества id сверены","kernel/adapter/record (10): 1,3,6,7,8,21,30†,49,64,73†","kernel/adapter/input (9): 5,10,13,14,15,16,17,52,86","kernel/adapter/transport (2): 18,19","kernel/adapter/descent (10): 26,54,67,98,99,100,101,102,104,105","kernel/adapter/cycle (6): 12,20,22,23,27,112","kernel/adapter/cycle/mint (12): 24,33,35,36,38,50,55,69,70,74†,76,113","kernel/adapter/cycle/mint/research (3): 45,75,116","kernel/adapter/cycle/experience (5): 25,37,40†,60,62","kernel/adapter/composition (2): 94†,117","kernel/adapter/composition/premises (17): 4,29,44,57,61,63,66,71,72†,77,78,83†,90†,97†,106,119,120","kernel/adapter/composition/compose (4): 2,46,93,96","kernel/adapter/executors/door (6): 53,59,85,108,122,123","kernel/adapter/executors/door/deploy (1): 124","kernel/adapter/executors/deliver (3): 81†,82†,89†","kernel/adapter/report (5): 39,41,42,91,92†","kernel/adapter, в корне по построению (1): 51 — один производитель, склейки нет","СХЛОПНУТЫ В КОРЕНЬ, склейки (26): 0,11†,28,31,32,34,43,47,56,65,68†,79,80†,84†,87†,88†,95†,103,107,109,110,111,114,115,118,121","ДЕФЕКТ — нет своего блока проверки (7): 9,48,58,125,126,127,128","ДУБЛИ (канон ← дубли): 79←80; 86←87; 91←92; 49←30; 65←40; 71←72; 76←77, 90, 94; 5←0, 11; 1←0, 11; 3←0, 21; 4←0; 6←0; свойство 9 судится внутри блока s0","ДРЕЙФ ТЕГА — блок с тегом N судит свойство соседнего закона (20): 11,30,40,68,72,73,74,80,81,82,83,84,87,88,89,90,92,94,95,97; собственное свойство законов 11, 30, 40 и 89 не судит ни один блок"]
node_laws_change_patch
["Черновик правки ядра (статус: не применено и не запущено; дверь на этом шаге не запускалась, в рабочее дерево ничего не записано; ленд только через дверь после accepted от стороны, отличной от автора).","БАЗА, опоры перечитаны сейчас: imperiaos main = 0ba0bab522abbd4e64056e21f570bd71553a70c2 (.git/refs/heads/main:1). Это новее 4afbc7a из соседней карты, поэтому номера строк task.ts сдвинулись: место из RCA task.ts:4822–4824 теперь task.ts:4846 (doorReceiptText: total ?? 0) и :4897 (cause = null при green=true). Остальные опоры на 0ba0bab: DoorGoal task.ts:117–128; DoorResult :130–147; conceptPractices :2053; спуск practices по уровням run.classified.path в researchMethod :2140–2167; doorGoalOf :4814–4841; runDoor :4865–4920; ORACLE_RED_CAUSE :744, DOOR_IO_CAUSE :747; glossary.ts: TermId :32–47 (последний член 'codex' :47), GLOSSARY закрывается на :325. door-ts (…/opus-pattern-catalog/door-ts, вне репозитория imperiaos): targetGoals run-target.ts:4220, given :4231, :4234 уже разворачивает объект-закон с полем text, runTarget :4296, обходчик :4463–4464 — совпали с входом. Пробел: sha door-ts не назван (Read/Grep не дают).","ЧИТАТЕЛИ И ФОРМА ЗАПИСИ (первая часть отчёта). Выбран вариант «запись-объект text+parent», а не параллельный goals.task.nodes[i] (второй склад, привязанный к индексу). Поле называется parent, как у записей паттернов и фактов: дерево то же. Читатели goals.task.statements: 1 вход (target.ts:70–71) и 1 переход (main.ts:128–130) — не меняются; нормализатор run-target.ts:4231–4238 — обновлён: читает text как сейчас, поле parent пропускает, наружу отдаёт string[]; обходчик run-target.ts:4463 — обновлён, первым (expand): const goals = targetGoals(TARGET.goals), иначе сырые объекты доходят до repair.ts:889/968/1106, а statementSeeds (repair.ts:776–777) молча их отбрасывает; 12 точек после нормализатора (run-target.ts:1328, 2608, 2684, 3316, 4125, 4279, 4289, 4490; plan.ts:159; repair.ts:889, 968, 1106) — не меняются, получают string[]; передача цели целиком (plan.ts:375/408/414, sharpen.ts:213, repair.ts:511/821/829/1333/1342, judge.ts:636, goal-m.json) — не меняется, получает нормализованную цель; сюита statement-checks — не меняется: 6 мест читают DoorGoal.statements из doorCalls (task.statements.test.ts:4199, 5083, 5084, 5101, 5912, 6605), а не task-target; task-oracle2.sh — 0 совпадений «statements», не меняется; goals.pattern.statements (task-target.json:432) — мигрирует позже. Итого 17 мест: 2 обновлены, 14 не меняются, 1 мигрирует позже.","ПОРЯДОК: (1) expand — door-ts: обходчик :4463 и нормализатор :4231–4238; (2) migrate — task-target.json:289, строка → объект text+parent; (3) contract — строковую форму в нормализаторе не убирать, пока goals.pattern не мигрирован.","СТРОКИ ГЛОССАРИЯ (glossary.ts): в TermId после :47 добавить | 'attribute' | 'fact' | 'law'; перед закрывающей скобкой GLOSSARY на :325 добавить три статьи attribute, fact и law дословно по glossary_term_lines: утв. 67 и 126 → атрибут; утв. 111 → факт; утв. 64 и 75 → закон. Синонима «утверждение» и отдельной статьи «свойство» нет.","УЗЛЫ ЗАКОНОВ (данные миграции task-target.json, parent у закона i): kernel/adapter/record — 1,3,6,7,8,21,30,49,64,73; kernel/adapter/input — 5,10,13,14,15,16,17,52,86; kernel/adapter/transport — 18,19; kernel/adapter/descent — 26,54,67,98,99,100,101,102,104,105; kernel/adapter/cycle — 12,20,22,23,27,112; kernel/adapter/cycle/mint — 24,33,35,36,38,50,55,69,70,74,76,113; kernel/adapter/cycle/mint/research — 45,75,116; kernel/adapter/cycle/experience — 25,37,40,60,62; kernel/adapter/composition — 94,117; kernel/adapter/composition/premises — 4,29,44,57,61,63,66,71,72,77,78,83,90,97,106,119,120; kernel/adapter/composition/compose — 2,46,93,96; kernel/adapter/executors/door — 53,59,85,108,122,123; kernel/adapter/executors/door/deploy — 124; kernel/adapter/executors/deliver — 81,82,89; kernel/adapter/report — 39,41,42,91,92; kernel/adapter — 51 (корень по построению) и 26 склеек 0,11,28,31,32,34,43,47,56,65,68,79,80,84,87,88,95,103,107,109,110,111,114,115,118,121; parent = null и дефект no-check-block, названы в отчёте по имени — 9,48,58,125,126,127,128. Итог 95+1+26+7 = 129. Дубли и дрейф тегов (20 законов) этой правкой не сливаются — одна логическая правка, отдельный шаг.","ЗАКОНЫ РАЗБОРА НА УЗЛАХ: новые записи 129 (R1: дверь без проверок не зелёная, cause door-no-checks), 130 (R9: фоллбек Suspense 0 раз между событием и кадром) и 131 (R10: репродьюсер red на родителе и green на ленде) — parent kernel/adapter/executors/door. Ветки правок: 124 (R2 sha в теле запроса выкатки, R3 deployed только для запрошенного sha, R4 проба сверяет тело) — parent kernel/adapter/executors/door/deploy; 123 (R5 observed=null → partial) и 125/126 (R6 извлечение взаимодействий, R7 ask при перекрытии ребёнка, R8 total ≥ числа взаимодействий) — parent kernel/adapter/executors/door. Расхождение входов: в классификации 125 и 126 стоят в дефектах, а по RCA они на двери; в черновике у них parent двери, а дефект no-check-block остаётся, пока не написаны блоки s125a, s125b и s126. Ответ «почему допустило»: на узле kernel/adapter/executors/door не было закона 129.","ПРАВКА КОДА task.ts: (а) DoorGoal :117–128 — добавить опциональное поле practices?: DoorPractice[], где DoorPractice = law, parent, test? (expand: старые двери поле не читают); (б) вынести цикл уровней из researchMethod :2148–2167 в один помощник pathLaws(run): законы conceptPractices для каждого уровня run.classified.path, class = ключ уровня; researchMethod и runDoor зовут его оба, второго механизма нет; (в) runDoor после doorGoalOf на :4871 — goal.practices = await pathLaws(run), если список не пуст; (г) вердикт: type DoorVerdict = 'pass' | 'fail' | 'not-judged'. doorVerdict(result, practices): green !== true → fail; check отсутствует или total = 0 → not-judged; total < practices.length (закон узла, чей атрибут не поднят) → not-judged; иначе pass. На :4897 тернарник заменяется исчерпывающим switch: pass → cause null; fail → DOOR_IO_CAUSE при io, иначе ORACLE_RED_CAUSE; not-judged → новая константа DOOR_NO_CHECKS_CAUSE = 'door-no-checks' рядом с :747, run.refusal kind refused; default: const unreachable: never = verdict. report.green = verdict === 'pass', плюс report.verdict; (д) doorReceiptText :4847 печатает слово вердикта вместо green/red, и проверки 0/0 больше не читаются как зелёные. door-ts: 2 ханка (:4463, :4231–4238). glossary.ts: 2 ханка. Код без данных миграции — порядка 90 строк.","ПРОВЕРКА (verify): блок [s129] в runtime/statement-checks/task/task.statements.test.ts, заглушки двери: green и total 3 → pass, cause null; green false → fail, oracle-red; green true и check null → not-judged, door-no-checks; 2 закона practices и total 1 → not-judged. Мутант: убрать ветку not-judged, и блок краснеет. На базе 0ba0bab красный только предсказан: сегодня cause = null при green=true, :4897. door-ts: тест, что цель с объектами-законами доходит до repair строками через :4463. tsc --noEmit и тесты гоняет шлюз, а не автор черновика. why — R1 (runs/01bd9e17:27, :29, :555; runs/0c28c88c:59); what — поле parent, три статьи глоссария, practices по пути и трёхзначный вердикт; verify — s129.","ПРОБЕЛЫ: sha door-ts; как вход edit-режима door-ts читает goal.practices, не инвентаризовано — до migrate законы практик дают not-judged, а не зелёный; есть ли sha в ответе /deploy/status (R3), не проверено; какая граница Suspense показывала фоллбек (R9), не установлено.","Статус: не применено и не запущено."]
parent_task
Добудь факт «Ленд правки через дверь: {version, files, oracle} и mergedSha == main» (door_receipt). Выбирать, когда: Патч готов для двери. Нужны: ["kernel_adapter_patch"]
intent
kernel_adapter_patch_in_cause_seam_extend_not_add_lookup
Классификация
вердикт
none
причина
—
известных записей
0
parent_task
источник
input
статус
ok
result_error_root_causes
источник
procedure
статус
ok
kernel_statement_edits
источник
alias:kernel_statement_drafts
статус
ok
Исход
вид
used-experience
вызовов модели
2
Результат
вид
answer
Ответ
текст
kernel_adapter_patch = ["Правка адаптера — черновик, не применена и не запускалась; ленд только через дверь. Задача-родитель: добыть door_receipt (ленд через дверь: version, files, oracle и mergedSha == main); её посылка — этот kernel_adapter_patch.", "БАЗА (перечитано сейчас): imperiaos main = 0ba0bab522abbd4e64056e21f570bd71553a70c2 (.git/HEAD:1 ref main, .git/refs/heads/main:1). Файл правки — packages/shared/src/core/instruction/task.ts. Все якоря диагноза перечитаны и совпали без сдвига: 1228–1229, 1285–1286, 1481, 1486–1501 (цикл 1490–1498), 3313–3316, 3377–3378, 3483, 3496, 3552, 3680–3681, 3700, 3765–3785, 4264–4285, 4295–4299, 4329–4330, 4335–4355, 5677–5681, 5686, 5697, 5712–5716, 5746, 6738, 6849–6853. Пробел: sha256 адаптера в прогоне 684c7552 (runs/684c7552:20 — 71c89721…) со снимком файла не сверялся, потому что Read хеш не считает. Не проверено и то, что рабочее дерево совпадает с HEAD: Read читает рабочее дерево.", "ID ПРИЧИН (из result_error_root_causes, по порядку): C1 — ветвь 1, возникновение; C2 — ветвь 1, утечка A; C3 — ветвь 1, утечка B; C4 — ветвь 2, возникновение; C5 — ветвь 2, утечка; C6 — ветвь 3; C7 — ветвь 4, латентная; C8 — следствия, не корень. C1–C7 считаются prevent.", "H1 · C1, C4, C6 · шов: ступень 1b fillPremise (task.ts:3681). Что: общий помощник goalTextOf(subject) — строки subject.text и subject.parent_task, соединённые переводом строки. Такое соединение уже есть в mechanicalDoorFact на :1481, его копия там заменяется вызовом помощника. На :3681 вместо чтения одного subject.text вызывается goalTextOf(subject). У помощника 2 вызова, старая копия удалена, второго механизма нет. Почему: parent_task задаётся на :3496, но ступень 1b его не читает, из-за этого cdp_endpoint и specimen_run_id получили reason none (runs/684c7552:113–125; :401–415). Размер около 6 строк.", "H2 · C3, C5 · шов: исключения ступени 1b (task.ts:3680) и отбор alias (task.ts:3313–3316). Что: общий помощник notFromTextOrAlias(run, fact), который истинен, когда fact — факт двери (DOOR_NEEDS) или выход части композиции (run.compositionParts содержит часть с этим output). Две копии DOOR_NEEDS.some на :3315 и :3680 заменяются этим помощником. Так выход части не берётся ни фрагментом текста цели (runs/684c7552:686–693), ни чужим фактом через alias (runs/684c7552:644–649; :3377–3378). Проверка на :1491 (пропуск в filesOf) не трогается, у неё другой смысл. Размер около 8 строк.", "H3 · C2, C3, C6 · шов: composeParts, точка решения «часть провалена» (task.ts:5686 и 5712) и attemptOf (task.ts:5677–5681). Что: помощник partSettled(sub, result) — исход в SETTLED_OUTCOMES и result.ok. Он заменяет оба условия, на :5686 и на :5712. Часть с исходом admitted, но без значения (ask, empty), теперь один раз перезапускается с названным отказом (утв. 117), а после второго отказа даёт part-failed. Раньше она становилась minted, а значение молча выпадало на :5746. В attemptOf: если исход settled, а result не ok, то cause = result.reason, а why дополняется ключами sub.missing, чтобы повтор называл недостающие факты. Размер около 10 строк.", "H4 · C7 · шов: filesOf внутри mechanicalDoorFact (task.ts:1486–1501, цикл :1490–1498). Что: mechanicalDoorFact получает четвёртый аргумент params — нужды записи. Единственный вызывающий — fillPremise на :3711, где params уже есть. Цикл берёт пути только из ключей, которые названы в params, и из выходов частей композиции (тот же предикат, что в H2). Хранимые факты владельца вне нужд, например neighbor_setting_code, файлы двери больше не питают (runs/684c7552:839–883, :901–907). Ветка oracle на :1508 читает тот же filesOf и меняется вместе с ним. Размер около 8 строк.", "C2 не закрыт в гейте codePartDraft (task.ts:1284–1296) — это пробел и вопрос владельцу. Расширить гейт до чтения stripped.artifact значило бы пойти против действующих законов 114 (task-target.json:404) и 118 (:408), а они требуют: часть, чей step-0 ответил made:fact, срезается по утв. 72 и в дверь не идёт; блоки [s114:030df862] (task.statements.test.ts:5871) и [s118:f531d356] (:6528). В специмене утечку A закрывает H3: черновик с итогом ask больше не проходит admitted. Черновик-проза с made:fact по-прежнему проходит как значение-факт.", "C8 — следствие, а не корень, и эта правка его не закрывает. Правило спана textSpanCandidates (task.ts:1228–1259) форму значения не проверяет, поэтому брало битые спаны (runs/684c7552:650–666, :677–685). Проверка формы — отдельный шаг.", "ЧИТАТЕЛИ И ВЫЗЫВАЮЩИЕ (grep по task.ts на 0ba0bab). DOOR_NEEDS.some: :1478 — не меняется (отбор фактов двери); :1491 — не меняется (другой смысл); :3315 и :3680 — обновлены (H2). SETTLED_OUTCOMES.includes: :5686 и :5712 — обновлены (H3); :2540, :3522, :6785, :6849 — не меняются, они судят исход задачи, а не значение части. mechanicalDoorFact: 1 вызов (:3711) — обновлён (H4). run.compositionParts?.find: :4430, :5658, :5730, :6355 — не меняются, только чтение записи части. subject.parent_task: :1481 — обновлён (H1); :3496 — не меняется (там он задаётся); :5411 — не меняется (читает run.payload через пробел для поиска дома). Мест с пометкой «мигрирует позже» нет.", "СОВМЕСТИМОСТЬ И РАЗМЕР: форма данных и типы не меняются, новых полей нет. У внутренней функции mechanicalDoorFact один вызывающий, он обновляется в том же ханке, поэтому expand → migrate → contract здесь не нужен. Меняется поведение: часть с admitted и ask теперь перезапускается, а не молча считается minted. Около 32 строк кода в одном файле и 4 ветки проверок. Новых файлов нет. Дубли и дрейф тегов в эту правку не входят.", "ПРАВКИ ЗАКОНОВ И ПРОВЕРКИ ЭТОЙ ПРАВКИ (runtime/statement-checks/task/task.statements.test.ts). (а) ПРАВКА 106 (task-target.json:396), ветка блока [s106:3a7dc320] (:3665), parent kernel/adapter/composition/premises: подзадача с текстом чеканки без адреса CDP и с parent_task, где назван http://127.0.0.1:9226, заполняет cdp_endpoint через text с from input. Мутант: вернуть на :3681 чтение одного subject.text — ветка краснеет. (б) ПРАВКА 117 (:407), ветка блока [s117:cee14244] (:6108), parent kernel/adapter/composition/premises: заглушка части отдаёт admitted и ask с missing cdp_endpoint; ожидаются повтор с priorFailure, где назван cdp_endpoint, после второго отказа — part-failed, а ключа нет ни в subject, ни в memo. Мутант: partSettled без result.ok — ветка краснеет. (в) ПРАВКА 108 (:398), ветка блока [s108:5fc1a644] (:5065), parent kernel/adapter/executors/door: в subject есть neighbor_setting_code с существующим путём, в нуждах записи его нет — в files этого пути нет; если нужда называет выход соседней части — путь есть. Мутант: цикл по всем ключам — ветка краснеет. (г) НОВОЕ 134 — номер не сверен: 129–131 заняты черновиками R1, R9, R10, 132–133 — черновиками прогона 684c7552. Закон: выход части композиции получает значение только от своей подзадачи и никогда — фрагментом текста цели или alias. Блок [s134], parent kernel/adapter/composition/premises: корень с проваленной частью X, в тексте цели есть слова подписи X со значением рядом; ожидается, что у посылки X нет ни via text, ни via alias. Мутант: убрать выход части из notFromTextOrAlias — блок краснеет. Черновики R1–R10 из kernel_statement_edits переносятся без изменений; ханки этой правки их не касаются. Наблюдение: для частей вариант R1 (дверь зелёная без проверок) уже закрыт в codePartDraft на :1292–1294, у корня — нет. Статус всех блоков: не запускались, краснота на 0ba0bab только предсказана.", "ПРЕДСКАЗАННЫЙ ИСХОД ПЕРЕЧЕКАНКИ 684c7552 (это предсказание, а не наблюдение). render_device_patch: cdp_endpoint найден в тексте родителя, и часть идёт в act. Но step-0 части ответил made:fact, поэтому значением будет черновик-проза, а не расписка двери (C2 не закрыт); экраны живьём не откроются. render_statement_draft: specimen_run_id найден в тексте родителя, часть идёт в act и в дверь (step-0 artifact:code, runs/684c7552:475–479); исход двери не предсказан. target_work_screens: specimen_run_id найден. Ответ с шаблонами маршрутов в фигурных скобках, как и раньше, отклоняется как empty, и это верно. live_screen_records без живого устройства Render не добывается. Итог корня — part-failed или ask с названными недостающими фактами, без маскировки чужим фактом; admitted не ожидается.", "ПРОБЕЛЫ: sha256 адаптера прогона не сверен с базой; равенство рабочего дерева и HEAD не проверено; называла ли часть пробы 11 (runs/6aa2039f) выход соседа в своих нуждах, не проверено — от этого зависит, не срежет ли H4 якоря соседа; C2 ждёт решения владельца — должна ли часть made:fact, у которой срезан artifact code, отказывать как code-part-draft вопреки 114/118; C8 не закрыт; что empty у target_work_screens вызвано именно скобками — только probable; tsc, тесты и мутанты гоняет шлюз двери, автор черновика их не запускал.", "why / what / verify: C1, C4, C6 → H1 → [s106]; C3, C5 → H2 → [s134]; C2, C3, C6 → H3 → [s117]; C7 → H4 → [s108]. Статус: не применено, не запускалось."] Как проверены места правки: якоря перечитаны на 0ba0bab522abbd4e64056e21f570bd71553a70c2 в /home/deploy/apps/imperiaos/packages/shared/src/core/instruction/task.ts; законы — по runtime/task-target.json:396, 398, 404, 407, 408; блоки проверок — по runtime/statement-checks/task/task.statements.test.ts; прогон — по runtime/runs/684c7552-77c5-4e30-afec-06e9aa064b00.json. Источники: - [bliki: Legacy Seam — Martin Fowler](https://martinfowler.com/bliki/LegacySeam.html): шов — место, где поведение меняется без правки в этом месте, с точкой включения. Отсюда правки в существующих гейтах: ступень 1b, отбор alias, composeParts, filesOf. - [Expand/Contract: making a breaking change without a big bang — Pete Hodgson](https://blog.thepete.net/blog/2023/12/05/expand/contract-making-a-breaking-change-without-a-big-bang/): expand → migrate → contract нужен только при несовместимом изменении. Здесь у изменённой сигнатуры один внутренний вызывающий, форма данных не меняется. - [Mutation testing — Wikipedia](https://en.wikipedia.org/wiki/Mutation_testing): мутант убит, если падает хотя бы один тест; выживший мутант означает пробел в проверках. Поэтому у каждой ветки есть свой мутант.