Запрос
текст
Добудь факт «Патч, который возвращает прежнее поведение рядом с новым на том же существующем элементе, без нового слоя, с клавиатурным паритетом» (coexistence_fix_patch). Выбирать, когда: Причина локализована строками и механизмом. Нужны: ["regression_root_cause","text"]
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 упавших прежних тестов; число прежних тестов не уменьшилось."]
parent_task
В репозитории /home/deploy/apps/imperiaos на экране packages/app/views/platform/TokenVaultView.tsx после правки «приоритетный аккаунт» (коммиты 6b9942dcb, 2238c8ba1, e54779ca9, cec8230e7 — все сделаны ядром) нажатие по карточке аккаунта стало перекрывать тултипы при наведении (слово владельца 2026-09-27 ~12:1xZ: «нажатие стало перекрывать тултипы при наведении — бага на уровне архитектуры, которую нельзя пропускать»). Требуется: (1) найти в коде экрана, как именно клик перекрыл наведение (обёртка карточки в кликабельный слой, stopPropagation, слой подсветки поверх триггера тултипа, замена элемента) — назвать строки; (2) починить так, чтобы у карточки жили ОБА взаимодействия: наведение показывает тултип как до правки, клик ставит/снимает приоритет; никакого второго слоя над карточкой — расширить существующий элемент карточки, не накрывать его; (3) закрепить оба взаимодействия проверками экрана (тест взаимодействия: наведение → тултип виден; клик → PATCH priority; наведение после клика → тултип виден) в существующей сюите экрана packages/app; (4) назвать, почему это не поймал оракул прошлой правки — какого вида проверки не было у экрана. Оракул: pnpm --filter @imperiaos/app test:unit:run. Наблюдаемый интерфейс — экран dev.imperiaos.com/platform/admin/token-vault.
Классификация
вердикт
artifact:code
причина
new: no candidate
известных записей
222
Понятие c0
признаки
—
записи
jobs:letter:ats-form, jobs:letter:cold-founder, jobs:letter:money-system, jobs:letter:agent-tooling, jobs:letter:follow-up, jobs:letter:third-touch, compute_arithmetic, find_investor_fund_match, fix_code_defect_until_oracle_passes, build_goal_achievement_plan, find_goal_first_step, build_goal_milestones, build_goal_monitoring, find_goal_obstacle_plans, produce_code_patch, build_meeting_call_brief, find_meeting_local_time, find_role_requirements, find_meeting_likely_questions, find_org_profile, find_org_recent_news, find_owner_timezone, find_meeting_questions_to_ask, find_investor_decision_partner_name, find_investor_contact_channel, find_investor_opener, find_investor_thesis_fit, find_investor_signal_url, find_investor_signal, find_investor_thesis_source_url, find_company_oneliner_en, find_investor_thesis_quote, find_investor_thesis_bridge, find_counterparty_profile, build_investor_outreach_pack_for_named_fund, find_product_fit_usecase_goals, find_research_date, find_research_limits, find_excluded_usecases_by_hard_criteria, find_excluded_usecases, find_analog_usecase_catalog, build_inbox_digest_with_reply_drafts, find_customer_prospects_with_contacts, find_prospect_selection_criteria, find_prospect_gaps_and_assumptions, write_cold_email_with_org_news_hook, find_email_subject_from_org_news, find_org_news_bridge_en, find_org_news_decision_maker_name, find_org_recent_news_source_url, compare_vendors_and_recommend_one, find_research_unverified_gaps, find_recommendation_rationale, find_unverified_gaps_and_assumptions, find_options_reviews_summary, build_weighted_decision_matrix, build_weighted_decision_matrix_with_sensitivity, build_weighted_decision_matrix_with_robustness, find_options_tco_table, find_recommended_option, find_reproducer_test, find_investor_criteria, find_investor_shortlist, write_investor_first_emails_by_thesis, find_investors_and_draft_first_emails, run_oracle_before_fix_and_save_red_output, find_defect_root_cause_by_pass_fail_diff, rerun_oracle_after_patch_compare_to_baseline, find_investor_email_addressee_partner_name, find_investors_then_write_first_emails_per_partner, find_competitor_feature_catalog, find_analysis_date_cutoff, build_feature_fit_gap_table, find_rejected_features_with_reasons, select_features_by_kano_confidence_effort_as_goals, analyze_competitor_features_fit_gap_select_goals, select_features_by_declared_formula_as_goals_with_acceptance, select_fit_gap_features_by_rice_pert_as_goals_with_acceptance, select_features_by_rice_pert_as_goals_with_acceptance, select_fit_gap_features_by_value_confidence_pert_as_goals, select_features_by_rice_pert_formula_as_goals, select_fit_gap_features_by_rice_as_goals_with_acceptance, select_features_by_rice_as_goals_with_acceptance, select_features_by_value_confidence_effort_as_goals, select_features_by_formula_as_goals_with_acceptance, select_features_by_rice_capacity_as_goals_with_acceptance, select_fit_gap_features_by_rice_records_as_goals, fix_kernel_door_defect_until_oracle_green, rerun_oracle_after_patch_and_diff_per_case, write_minimal_kernel_patch_from_statements_until_oracle_green, extract_gap_core_from_review_item, write_measurable_acceptance_criterion_from_gap_core, design_missing_record_interfaces_from_gap_and_criterion, derive_executable_module_assertions_from_interfaces_and_acceptance, derive_red_green_readiness_scenario_from_done_criterion, implement_review_feature_as_records_with_readiness_test, write_gwt_acceptance_criteria_list_from_gap_core, design_prov_provenance_schema_and_migrate_text_records, find_competitor_feature_user_facing_reference, rewrite_done_criterion_into_red_given_when_then_scenarios, find_kernel_exit_points_sink_inventory, find_mail_inbound_producer_status_in_registry, write_secret_never_in_model_invariant_from_gap, find_webhook_door_contract, write_minimal_kernel_patch_from_interfaces_and_scenarios_until_green, write_gwt_acceptance_criteria_for_inbound_channel_with_abuse_cases, write_red_canary_sink_acceptance_test_before_patch, run_readiness_scenarios_and_cite_journal_seq_with_unverified, find_secret_typed_fact_keys_from_type_registry, write_gwt_acceptance_criteria_for_review_feature_with_e2e_done, write_gwt_acceptance_criteria_for_owner_fact_memory_view_find_forget, write_gwt_acceptance_criteria_for_review_feature_with_done_as_e2e, design_record_ops_list_inspect_forget_put_with_tombstone_journal, write_e2e_gwt_acceptance_criteria_for_review_feature_from_gap_core, write_3_5_gwt_acceptance_criteria_with_end_to_end_done_from_feature_task, design_record_store_interfaces_with_tombstone_and_journal, derive_record_store_interfaces_with_tombstone_and_journal, find_steps_that_must_run_without_model_call, design_list_inspect_forget_put_with_tombstone_and_journal, rewrite_gap_core_and_done_criterion_into_given_when_then_readiness_scenarios, write_gwt_acceptance_criteria_for_review_feature_with_done_e2e, design_mail_forward_to_task_records_with_readiness_test, write_minimal_kernel_patch_records_from_gap_core_and_gwt_scenarios, draft_minimal_feature_records_patch_from_gap_core_and_scenarios, draft_minimal_kernel_records_patch_from_gap_core_and_readiness_scenarios, write_minimal_schedule_tick_records_patch_from_gap_and_scenarios, write_recurring_goal_and_schedule_list_records_patch_in_kernel_repo, write_recurring_goal_schedule_tick_kernel_patch_as_records, write_schedule_tick_recurring_goal_records_patch_with_occurrence_id, write_recurring_goal_schedule_records_patch_with_misfire_policy, write_feature_records_kernel_patch_from_gap_and_scenarios, propose_kernel_patch_records_from_gap_core_and_readiness_scenarios, write_feature_records_patch_from_gap_and_scenarios_with_idempotent_tick, implement_recurring_schedule_goal_records_with_replay_acceptance, write_secret_handle_redaction_and_gate_substitution_kernel_patch_with_canary_test, report_test_and_regression_rerun_verified_vs_unverified, formulate_scoped_never_invariant_from_gap_with_refutation, identify_executed_kernel_patch_by_commit_patch_id_and_dirty_flag, implement_trigger_feature_from_review_item_as_records_with_replay_journal_acceptance, run_oracle_on_full_bench_before_patch_and_verify_target_red_reason, find_unreconciled_composition_acceptance_point_in_allowed_files, write_substitution_composition_patch_with_grounding_gate_naming_law, rerun_full_bench_oracle_after_patch_diff_per_check_vs_baseline_with_flaky_and_input_variants, identify_applied_kernel_patch_by_sha_patch_id_dirty_and_confirm_build_exit_code, patch_kernel_composition_to_assemble_only_from_part_values_until_oracle_green, write_closed_selection_policy_laws_and_decision_table_from_intent_and_incidents, find_counterparty_product_quote_and_bridge_to_demo_thesis, compose_c4_context_container_and_2_4_adr_decisions_with_honest_status, build_meeting_frame_utc_local_smart, inventory_live_decision_points_by_code_config_and_ledger_crosscheck, write_one_executable_pass_fail_unknown_check_per_law_over_source_facts, map_each_law_to_single_pap_pdp_and_role_tagged_enforcement_points, derive_timeboxed_demo_timeline_from_meeting_frame_with_live_share_and_reserve_flags, build_reverse_dated_prep_checklist_from_meeting_anchor_with_freeze_backup_and_rehearsal, find_verbatim_counterparty_product_quote_matching_demo_thesis_with_url, build_demo_qa_bank_bluf_from_owner_proofs_with_counterparty_bridge_and_honest_gaps, compose_interview_demo_plan_from_frame_bridge_timeline_architecture_qa_prep_and_fallback, decompose_numbered_feature_statements_into_traced_gwt_scenarios_with_boundary_forbidden_and_open_questions, write_bottom_up_feature_patch_storage_logic_api_ui_by_neighbor_analog_with_red_first_tests, trace_scenarios_to_tests_run_full_gates_fail_to_pass_land_and_list_unverified, retrieve_verbatim_prior_step_patch_with_full_base_sha_and_apply_check, derive_fail_to_pass_scenarios_from_patch_requirement_plus_pass_to_pass_regression_from_owner_proofs, implement_repo_feature_from_numbered_statements_via_edit_door_and_change_flow, derive_traced_gwt_scenarios_from_parent_task_numbered_statements_with_open_decisions, draft_bottom_up_storage_logic_api_ui_patch_with_red_first_tests_traced_to_owner_statements, draft_bottom_up_storage_logic_api_ui_patch_with_red_first_tests_per_layer_and_open_owner_decisions, decompose_owner_numbered_feature_statements_into_traced_gwt_set_unset_switch_rollback_invalid_characterization_with_open_questions, derive_traced_gwt_scenarios_set_unset_switch_rollback_invalid_from_owner_numbered_statements_with_assumptions_and_open_questions, decompose_owner_toggle_setting_statements_into_traced_gwt_set_unset_switch_invalid_rollback_characterization_ui_sequence_with_questions, write_bottom_up_storage_domain_api_toggle_ui_patch_with_red_first_tests_traced_to_scenarios_by_neighbor_setting, draft_bottom_up_single_choice_toggle_setting_patch_storage_rank_api_ui_with_stub_first_red_tests_and_owner_questions, draft_bottom_up_single_choice_setting_patch_storage_logic_api_ui_with_red_first_tests_and_owner_decisions, draft_bottom_up_single_choice_setting_patch_storage_rank_api_toggle_ui_red_first_with_open_decisions, draft_bottom_up_nullable_single_pick_setting_patch_storage_rank_api_toggle_ui_with_red_first_tests, draft_bottom_up_single_choice_setting_patch_storage_rank_api_ui_with_stub_first_red_tests_and_characterization_guard, draft_layered_storage_logic_api_ui_patch_with_assert_red_first_tests_per_statement_and_flagged_assumptions, draft_bottom_up_single_select_priority_patch_storage_rank_api_toggle_card_ui_with_red_first_tests_and_outline_clicks, draft_bottom_up_single_select_priority_toggle_patch_storage_rank_api_aria_pressed_ui_with_red_first_tests_by_neighbor, draft_bottom_up_single_choice_toggle_patch_storage_rank_api_ui_with_red_first_tests_by_neighbor_setting, draft_layered_storage_logic_api_ui_patch_with_red_first_tests_traced_to_statements_and_open_owner_decisions, draft_bottom_up_storage_logic_api_ui_patch_with_stub_then_red_assert_tests_traced_to_statements_and_scenarios, draft_bottom_up_storage_logic_api_ui_patch_with_red_first_tests_per_statement_and_open_decisions, draft_bottom_up_storage_rank_api_ui_priority_toggle_patch_with_stub_first_red_tests_and_open_owner_decisions, draft_bottom_up_setting_storage_rank_api_toggle_ui_patch_with_assertion_red_stubs_traced_to_statements_and_open_decisions, write_bottom_up_storage_logic_api_ui_patch_with_red_first_tests_traced_to_statements_and_scenarios, draft_bottom_up_storage_logic_api_ui_patch_red_first_traced_to_parent_statements_with_open_decisions, read_neighbor_setting_storage_route_test_via_code_door_with_path_line_quotes, measure_kernel_baseline_head_sha_file_digests_dirty_utc_and_preregistered_run_selection, audit_every_outbound_channel_log_over_run_window_with_coverage_positive_control_and_weakest_link_verdict, derive_utc_run_window_from_observed_start_end_receipts_with_bounded_clock_skew_margin, map_each_kernel_exit_point_to_witness_log_by_code_and_real_record_with_no_witness_flag, derive_traced_gwt_scenarios_for_nullable_single_select_setting_storage_rank_api_ui_with_characterization_baseline_and_open_questions, decompose_owner_numbered_criteria_into_atoms_read_run_door_registry_code_evidence_and_verdict_pass_fail_nei_with_address, verify_kernel_against_numbered_criteria_with_three_valued_verdicts_and_evidence_locators_read_only, draft_bottom_up_single_select_priority_toggle_patch_storage_rank_api_aria_pressed_ui_with_stub_first_red_tests_and_owner_decisions, check_every_outbound_channel_log_over_utc_run_window_with_liveness_positive_control_and_three_valued_verdict, draft_bottom_up_single_choice_setting_patch_storage_rank_api_aria_pressed_ui_red_first_with_characterization_guard_and_owner_decisions, draft_bottom_up_single_choice_setting_patch_storage_rank_api_toggle_ui_red_first_resolved_from_statements, draft_bottom_up_baseline_storage_logic_api_ui_patch_with_assertion_red_first_tests_per_statement_and_owner_open_decisions, draft_bottom_up_storage_rank_api_ui_priority_toggle_patch_with_stub_first_red_tests_and_stated_defaults, draft_bottom_up_storage_logic_api_ui_patch_with_stub_then_red_assert_tests_traced_to_statements_and_open_decisions, draft_bottom_up_storage_rank_api_toggle_ui_patch_red_first_by_neighbor_setting_with_open_decisions_and_unverified_gaps, draft_bottom_up_setting_storage_rank_api_aria_pressed_toggle_ui_patch_with_assertion_red_first_tests_by_neighbor_and_owner_decisions, draft_bottom_up_storage_rank_api_aria_pressed_ui_patch_with_assert_red_tests_per_statement_characterization_guard_and_owner_defaults, draft_bottom_up_storage_logic_api_ui_patch_with_assert_red_tests_characterization_guards_and_server_confirmed_toggle_ui, read_neighbor_setting_all_layers_with_path_line_quotes_wiring_rank_callsites_tests_absent_and_revision, derive_traced_f2p_gwt_scenarios_with_p2p_repo_regression_baseline_and_open_questions, read_neighbor_setting_port_store_overlay_usecase_wiring_routes_health_rank_callsites_tests_proxy_ui_with_path_line_quotes_gaps_and_revision, derive_traced_gwt_scenarios_per_parent_statement_with_set_unset_switch_unavailable_neighbor_grounded_and_open_questions, read_door_receipts_main_ref_and_repo_tree_to_attest_red_green_full_suite_land_or_mark_not_obtained, derive_utc_run_window_from_run_at_reflog_oracle_journal_with_anchor_owner_zone_skew_margin_and_boundary_events, compose_kernel_self_check_report_from_baseline_run_window_criterion_verdicts_and_outbound_audit, draft_bottom_up_setting_patch_by_neighbor_storage_rank_api_server_confirmed_toggle_ui_with_assert_red_tests_traced_to_scenarios, derive_utc_run_window_min_run_at_max_receipt_at_over_selected_run_ids_with_line_evidence_and_open_end_flag, derive_tight_utc_run_window_from_run_at_reflog_door_journal_excluding_own_attempts_with_open_edge_and_margin_variant, derive_utc_run_window_from_earliest_anchor_run_at_reflog_oracle_journal_with_owner_zone_night_frame_and_open_right_edge, derive_utc_run_window_from_run_at_reflog_door_verdicts_anchored_on_parent_task_night_in_owner_zone_with_skew_margin_self_runs_flagged, derive_tight_utc_run_window_from_run_at_reflog_oracle_journal_by_owner_local_night_anchor_with_open_edge_flag, retrieve_latest_prior_code_patch_draft_from_run_reports_with_full_base_sha_anchor_check_and_appliability_verdict, derive_utc_run_window_from_run_at_session_gap_anchored_on_named_runs_with_open_right_bound, draft_file_grounded_bottom_up_patch_by_neighbor_setting_with_scenario_tagged_tests_commit_order_and_unapplied_status, draft_bottom_up_storage_rule_api_ui_patch_by_neighbor_setting_with_scenario_traced_tests_and_honest_unapplied_status, reverify_neighbor_setting_layer_map_at_current_ref_with_corrections_all_rank_helper_callers_and_absence_greps, draft_rebased_neighbor_grounded_bottom_up_setting_domain_storage_usecase_api_toggle_ui_patch_with_scenario_tagged_assert_red_stubs_bisectable_commit_series_and_unapplied_status, read_code_door_run_receipts_and_main_reflog_to_attest_red_green_full_suite_land_per_claim_or_mark_not_obtained, draft_neighbor_grounded_bottom_up_storage_rule_api_ui_patch_with_scenario_tagged_tests_stub_red_reasons_commit_series_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_storage_rule_usecase_api_proxy_ui_patch_with_scenario_tagged_red_first_tests_commit_order_open_decisions_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_patch_with_scenario_tagged_red_first_tests_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_patch_anchor_edits_single_rank_seam_scenario_tagged_assert_red_tests_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_storage_rule_api_proxy_ui_patch_with_scenario_tagged_tests_commit_series_red_expectations_defaults_and_unapplied_status, draft_neighbor_grounded_bottom_up_storage_rule_api_ui_patch_with_scenario_tagged_red_first_tests_derived_decisions_and_unapplied_status, draft_bottom_up_storage_rule_api_ui_patch_stub_red_green_per_scenario_with_characterization_guards_open_decisions_and_unapplied_status, draft_neighbor_grounded_bottom_up_storage_rule_api_ui_patch_with_scenario_tagged_assertion_red_tests_and_unapplied_status, draft_neighbor_grounded_bottom_up_storage_usecase_rank_api_ui_patch_with_scenario_tagged_red_first_tests_guard_split_and_unapplied_status, draft_neighbor_grounded_bottom_up_storage_rule_usecase_rank_seam_api_proxy_ui_patch_with_scenario_tagged_red_first_tests_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_patch_single_dispatch_rank_seam_scenario_traced_assert_red_tests_and_unapplied_status, draft_rebased_neighbor_grounded_bottom_up_store_rank_api_toggle_ui_patch_with_scenario_tagged_assert_red_tests_traceability_and_unapplied_status, draft_rebased_neighbor_grounded_bottom_up_storage_domain_rank_api_proxy_ui_patch_with_scenario_tagged_assert_red_tests_stub_red_step_guards_mutant_checks_and_unapplied_status, draft_reverified_neighbor_grounded_bottom_up_setting_patch_store_usecase_single_rank_seam_api_confirmed_toggle_ui_with_scenario_tagged_assert_red_tests_mutation_check_and_unapplied_status, draft_rebased_bottom_up_setting_patch_overlay_carry_single_rank_seam_api_server_confirmed_toggle_ui_with_scenario_tagged_assert_red_tests_and_unapplied_status, draft_rebased_neighbor_grounded_bottom_up_setting_storage_rule_usecase_api_proxy_toggle_ui_patch_with_scenario_tagged_assert_red_tests_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_patch_storage_rank_api_toggle_ui_with_scenario_tagged_tests_red_stub_table_and_unapplied_status, draft_rebased_neighbor_grounded_bottom_up_setting_patch_single_rank_seam_scenario_tagged_red_first_tests_mutant_guards_and_unapplied_status, draft_reverified_bottom_up_storage_rule_api_ui_patch_with_stub_red_tests_per_scenario_tag_server_confirmed_toggle_mutants_and_unapplied_status, read_neighbor_setting_all_layers_at_current_main_head_with_drift_note_all_rank_helper_callers_and_absence_grep, derive_tagged_traced_gwt_scenarios_per_parent_statement_with_state_transitions_all_rank_tiers_unavailable_characterization_click_sequence_and_open_questions, read_main_ref_and_reflog_tail_count_goal_statement_arrays_pick_latest_t_run_with_result_verdict_and_times_read_only, draft_reverified_bottom_up_commit_series_by_neighbor_map_with_scenario_tagged_tests_it_fails_stubs_manual_diff_mutants_and_unapplied_status, inventory_kernel_exit_points_from_code_then_query_run_files_and_git_reflogs_over_run_window_with_three_valued_verdict_and_named_uncovered_channels, read_door_state_run_effect_applied_changeflow_and_main_ref_to_grade_each_statement_red_green_suite_land_or_not_obtained, compose_neighbor_map_tagged_scenarios_bottom_up_patch_red_first_and_door_receipts_status_per_statement, reverify_prior_neighbor_setting_anchor_map_at_current_main_ref_with_reflog_drift_all_shared_helper_callers_and_absence_greps, draft_head_reverified_bottom_up_commit_series_by_neighbor_map_with_scenario_tagged_stub_red_tests_manual_mutant_journal_and_unapplied_status, grade_each_goal_statement_from_door_effect_check_patch_after_changeflow_author_check_land_and_main_ref_or_not_obtained, compose_head_reverified_neighbor_map_tagged_scenarios_bottom_up_red_first_patch_and_door_receipt_status_per_statement, reread_main_ref_and_reflog_tail_count_drift_from_prior_map_sha_reverify_every_layer_anchor_all_shared_helper_callers_and_absence_greps_read_only, take_given_scenarios_verbatim_or_derive_tagged_gwt_per_statement_by_neighbor_map_then_trace_matrix_na_reasons_form_deviations_and_open_questions, draft_head_reverified_single_seam_bottom_up_commit_series_with_refactor_split_title_tagged_red_first_tests_manual_mutant_journal_equivalence_notes_and_unapplied_status, read_door_effect_changeflow_author_check_land_and_main_ref_reflog_then_grade_each_statement_monotonic_patch_f2p_applied_landed_or_not_obtained_with_code_gap_flags, compose_head_reverified_neighbor_map_scenarios_bottom_up_patch_and_per_statement_door_receipt_status, read_main_ref_reflog_tail_and_door_land_receipts_then_reresolve_every_layer_anchor_by_symbol_flip_absence_greps_to_present_per_layer_and_flag_live_tree_edits_read_only, grep_feature_vocabulary_all_cases_then_layer_hits_by_neighbor_chain_trace_callers_and_name_unreached_server_non_durable_untested_defects_with_path_line_and_empty_query_evidence_read_only, take_input_gwt_scenarios_verbatim_else_derive_stmt_tagged_gwt_from_parent_statements_by_neighbor_map_with_bidirectional_trace_and_open_questions, reverify_head_then_split_inventory_into_present_gap_defect_rows_and_draft_bottom_up_atomic_commits_with_scenario_tagged_f2p_red_on_base_p2p_guards_mutants_rollback_and_unapplied_status, reread_main_ref_and_reflog_tail_then_grep_feature_vocabulary_per_layer_classify_present_unwired_absent_broken_unknown_by_callers_and_data_path_map_rows_to_scenario_tags_with_orphans_and_counts_read_only, match_door_run_by_patch_version_then_ladder_green_author_check_land_mergedsha_eq_main_ref_and_reflog_line_then_grep_tree_per_statement_with_not_obtained_subitems, reverify_head_inventory_in_tree_partial_feature_find_defects_then_gap_only_bottom_up_patch_with_scenario_tests_and_per_statement_door_status, collect_or_verify_named_analogs_tiered_direct_adjacent_with_own_domain_homepage_and_product_page_urls, live_read_each_competitor_home_and_product_page_fill_fixed_axes_row_with_url_date_status_mark_unavailable_and_derive_take_notours_against_own_positioning, read_live_homepage_and_one_product_page_per_input_url_fill_fixed_codebook_record_with_typed_not_read_reasons_and_provenance, read_symptom_screen_and_commit_range_then_quote_new_lines_name_suppression_mechanism_chain_refute_alternatives_and_flag_static_or_unattributed
Понятие c8
признаки
artifact:code
записи
fix_code_defect_until_oracle_passes, fix_kernel_door_defect_until_oracle_green, implement_review_feature_as_records_with_readiness_test, design_mail_forward_to_task_records_with_readiness_test, implement_recurring_schedule_goal_records_with_replay_acceptance, implement_trigger_feature_from_review_item_as_records_with_replay_journal_acceptance, patch_kernel_composition_to_assemble_only_from_part_values_until_oracle_green, retrieve_verbatim_prior_step_patch_with_full_base_sha_and_apply_check, derive_fail_to_pass_scenarios_from_patch_requirement_plus_pass_to_pass_regression_from_owner_proofs, implement_repo_feature_from_numbered_statements_via_edit_door_and_change_flow, draft_bottom_up_storage_logic_api_ui_patch_with_red_first_tests_traced_to_owner_statements, draft_bottom_up_storage_logic_api_ui_patch_with_red_first_tests_per_layer_and_open_owner_decisions, write_bottom_up_storage_domain_api_toggle_ui_patch_with_red_first_tests_traced_to_scenarios_by_neighbor_setting, draft_bottom_up_single_choice_toggle_setting_patch_storage_rank_api_ui_with_stub_first_red_tests_and_owner_questions, draft_bottom_up_single_choice_setting_patch_storage_logic_api_ui_with_red_first_tests_and_owner_decisions, draft_bottom_up_single_choice_setting_patch_storage_rank_api_toggle_ui_red_first_with_open_decisions, draft_bottom_up_nullable_single_pick_setting_patch_storage_rank_api_toggle_ui_with_red_first_tests, draft_bottom_up_single_choice_setting_patch_storage_rank_api_ui_with_stub_first_red_tests_and_characterization_guard, draft_layered_storage_logic_api_ui_patch_with_assert_red_first_tests_per_statement_and_flagged_assumptions, draft_bottom_up_single_select_priority_patch_storage_rank_api_toggle_card_ui_with_red_first_tests_and_outline_clicks, draft_bottom_up_single_select_priority_toggle_patch_storage_rank_api_aria_pressed_ui_with_red_first_tests_by_neighbor, draft_bottom_up_single_choice_toggle_patch_storage_rank_api_ui_with_red_first_tests_by_neighbor_setting, draft_layered_storage_logic_api_ui_patch_with_red_first_tests_traced_to_statements_and_open_owner_decisions, draft_bottom_up_storage_logic_api_ui_patch_with_stub_then_red_assert_tests_traced_to_statements_and_scenarios, draft_bottom_up_storage_logic_api_ui_patch_with_red_first_tests_per_statement_and_open_decisions, draft_bottom_up_storage_rank_api_ui_priority_toggle_patch_with_stub_first_red_tests_and_open_owner_decisions, draft_bottom_up_setting_storage_rank_api_toggle_ui_patch_with_assertion_red_stubs_traced_to_statements_and_open_decisions, write_bottom_up_storage_logic_api_ui_patch_with_red_first_tests_traced_to_statements_and_scenarios, draft_bottom_up_storage_logic_api_ui_patch_red_first_traced_to_parent_statements_with_open_decisions, draft_bottom_up_single_select_priority_toggle_patch_storage_rank_api_aria_pressed_ui_with_stub_first_red_tests_and_owner_decisions, draft_bottom_up_single_choice_setting_patch_storage_rank_api_aria_pressed_ui_red_first_with_characterization_guard_and_owner_decisions, draft_bottom_up_single_choice_setting_patch_storage_rank_api_toggle_ui_red_first_resolved_from_statements, draft_bottom_up_baseline_storage_logic_api_ui_patch_with_assertion_red_first_tests_per_statement_and_owner_open_decisions, draft_bottom_up_storage_rank_api_ui_priority_toggle_patch_with_stub_first_red_tests_and_stated_defaults, draft_bottom_up_storage_logic_api_ui_patch_with_stub_then_red_assert_tests_traced_to_statements_and_open_decisions, draft_bottom_up_storage_rank_api_toggle_ui_patch_red_first_by_neighbor_setting_with_open_decisions_and_unverified_gaps, draft_bottom_up_setting_storage_rank_api_aria_pressed_toggle_ui_patch_with_assertion_red_first_tests_by_neighbor_and_owner_decisions, draft_bottom_up_storage_rank_api_aria_pressed_ui_patch_with_assert_red_tests_per_statement_characterization_guard_and_owner_defaults, draft_bottom_up_storage_logic_api_ui_patch_with_assert_red_tests_characterization_guards_and_server_confirmed_toggle_ui, draft_bottom_up_setting_patch_by_neighbor_storage_rank_api_server_confirmed_toggle_ui_with_assert_red_tests_traced_to_scenarios, retrieve_latest_prior_code_patch_draft_from_run_reports_with_full_base_sha_anchor_check_and_appliability_verdict, draft_file_grounded_bottom_up_patch_by_neighbor_setting_with_scenario_tagged_tests_commit_order_and_unapplied_status, draft_bottom_up_storage_rule_api_ui_patch_by_neighbor_setting_with_scenario_traced_tests_and_honest_unapplied_status, draft_rebased_neighbor_grounded_bottom_up_setting_domain_storage_usecase_api_toggle_ui_patch_with_scenario_tagged_assert_red_stubs_bisectable_commit_series_and_unapplied_status, draft_neighbor_grounded_bottom_up_storage_rule_api_ui_patch_with_scenario_tagged_tests_stub_red_reasons_commit_series_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_storage_rule_usecase_api_proxy_ui_patch_with_scenario_tagged_red_first_tests_commit_order_open_decisions_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_patch_with_scenario_tagged_red_first_tests_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_patch_anchor_edits_single_rank_seam_scenario_tagged_assert_red_tests_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_storage_rule_api_proxy_ui_patch_with_scenario_tagged_tests_commit_series_red_expectations_defaults_and_unapplied_status, draft_neighbor_grounded_bottom_up_storage_rule_api_ui_patch_with_scenario_tagged_red_first_tests_derived_decisions_and_unapplied_status, draft_bottom_up_storage_rule_api_ui_patch_stub_red_green_per_scenario_with_characterization_guards_open_decisions_and_unapplied_status, draft_neighbor_grounded_bottom_up_storage_rule_api_ui_patch_with_scenario_tagged_assertion_red_tests_and_unapplied_status, draft_neighbor_grounded_bottom_up_storage_usecase_rank_api_ui_patch_with_scenario_tagged_red_first_tests_guard_split_and_unapplied_status, draft_neighbor_grounded_bottom_up_storage_rule_usecase_rank_seam_api_proxy_ui_patch_with_scenario_tagged_red_first_tests_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_patch_single_dispatch_rank_seam_scenario_traced_assert_red_tests_and_unapplied_status, draft_rebased_neighbor_grounded_bottom_up_storage_domain_rank_api_proxy_ui_patch_with_scenario_tagged_assert_red_tests_stub_red_step_guards_mutant_checks_and_unapplied_status, draft_reverified_neighbor_grounded_bottom_up_setting_patch_store_usecase_single_rank_seam_api_confirmed_toggle_ui_with_scenario_tagged_assert_red_tests_mutation_check_and_unapplied_status, draft_rebased_bottom_up_setting_patch_overlay_carry_single_rank_seam_api_server_confirmed_toggle_ui_with_scenario_tagged_assert_red_tests_and_unapplied_status, draft_rebased_neighbor_grounded_bottom_up_setting_storage_rule_usecase_api_proxy_toggle_ui_patch_with_scenario_tagged_assert_red_tests_and_unapplied_status, draft_neighbor_grounded_bottom_up_setting_patch_storage_rank_api_toggle_ui_with_scenario_tagged_tests_red_stub_table_and_unapplied_status, draft_rebased_neighbor_grounded_bottom_up_setting_patch_single_rank_seam_scenario_tagged_red_first_tests_mutant_guards_and_unapplied_status, draft_reverified_bottom_up_storage_rule_api_ui_patch_with_stub_red_tests_per_scenario_tag_server_confirmed_toggle_mutants_and_unapplied_status, draft_reverified_bottom_up_commit_series_by_neighbor_map_with_scenario_tagged_tests_it_fails_stubs_manual_diff_mutants_and_unapplied_status, compose_neighbor_map_tagged_scenarios_bottom_up_patch_red_first_and_door_receipts_status_per_statement, draft_head_reverified_bottom_up_commit_series_by_neighbor_map_with_scenario_tagged_stub_red_tests_manual_mutant_journal_and_unapplied_status, compose_head_reverified_neighbor_map_tagged_scenarios_bottom_up_red_first_patch_and_door_receipt_status_per_statement, draft_head_reverified_single_seam_bottom_up_commit_series_with_refactor_split_title_tagged_red_first_tests_manual_mutant_journal_equivalence_notes_and_unapplied_status, compose_head_reverified_neighbor_map_scenarios_bottom_up_patch_and_per_statement_door_receipt_status, reverify_head_then_split_inventory_into_present_gap_defect_rows_and_draft_bottom_up_atomic_commits_with_scenario_tagged_f2p_red_on_base_p2p_guards_mutants_rollback_and_unapplied_status, reverify_head_inventory_in_tree_partial_feature_find_defects_then_gap_only_bottom_up_patch_with_scenario_tests_and_per_statement_door_status
regression_root_cause
источник
subgoal: ask
статус
subgoal: ask
Добудь факт «Локализованная причина регрессии: файл:строки, механизм подавления, диапазон коммитов» (regression_root_cause)
исход
admitted
ответ
regression_root_cause = packages/app/views/platform/TokenVaultView.tsx:1377-1378 в коммите 6b9942dcb6fe8719100e6ef5bde69de860f7aaa0 (good 4afbc7a78f29 → bad 6b9942dcb; в HEAD df15846580 строки те же). Корневой `<div>` карточки AccountCard получил сразу `role="button" aria-pressed={priority}`, `onCli
text
источник
input
статус
ok
files
источник
derived
статус
ok
statements
источник
derived
статус
ok
oracle
источник
derived
статус
ok
Исход
вид
admitted
починка
{"rounds":1,"first":"проверка «причины нет → спросить посылку» не сошлась: ждали «ask», наблюдали «act»"}
вызовов модели
7
Результат
вид
ask
не хватает
regression_root_cause
вопрос
Не хватает: Локализованная причина регрессии: файл:строки, механизм подавления, диапазон коммитов
Ответ
текст
coexistence_fix_patch = Патч на тот же корневой div карточки AccountCard (TokenVaultView.tsx). С корня снимается `title` (:1378) — именно его наследовали все потомки, у которых нет своей подсказки. `onClick={onPriority}` остаётся на месте. Рядом на том же элементе добавляются `tabIndex={0}` и `onKeyDown`: Enter и Space вызывают тот же onPriority, если фокус на самой карточке. Подсказка о приоритете переезжает на её собственный атом — чип «★» (:1383). В сюиту packages/app добавляется новый тест packages/app/tests/unit/vault-account-card.test.tsx: наведение, клик, наведение после клика, клавиатура. Статус: патч не применён и не прогнан, доступ только на чтение. **Коротко: как клик перекрыл наведение и что делает патч** Причина взята из прогона ядра runtime/runs/b6c92387-c879-424d-89e1-9252b75f3326.json (regression_root_cause), строки перепроверены на HEAD 4afbc7a. - Правка «приоритетный аккаунт» повесила на корневой `<div>` карточки `role="button" aria-pressed onClick={onPriority}` и `title={priority ? t.priorityOnTip : t.priorityTip}` (:1377–1379). - Нативный `title` наследуется: если у элемента нет своего `title`, браузер показывает `title` ближайшего предка. Поэтому текст о клике стал подсказкой всей плитки: имени (:1381), чипа ранга (:1382), статуса (:1384), ошибки (:1458) и промежутков между ними. - Раскрытая ⓘ тоже его показывает: InfoDot на :903 пишет `title={open ? undefined : …}`, то есть в открытом состоянии удаляет свой атрибут. - Второго слоя, stopPropagation на наведении и замены элемента нет. stopPropagation на :1391 и :1454 стоит только на click. - Коммит, который внёс :1378, из четырёх (6b9942dcb, 2238c8ba1, e54779ca9, cec8230e7) не установлен: объекты упакованы, `git show` недоступен. **Почему не откат.** Откат четырёх коммитов убрал бы саму функцию приоритета. Частичный откат ровно одной строки :1378 — это и есть этот патч. Клик, подсветка и PATCH остаются как есть. ```diff --- a/packages/app/views/platform/TokenVaultView.tsx +++ b/packages/app/views/platform/TokenVaultView.tsx @@ -1339,7 +1339,7 @@ * old selection score was standing in for. Capped accounts say so instead of * carrying a number that ranks them against nothing. */ -function AccountCard({ token, spend, now, doAction, actionLoading, priority, onPriority }: { +export function AccountCard({ token, spend, now, doAction, actionLoading, priority, onPriority }: { token: TokenInfo; spend: number | null; now: number doAction: (action: string, body: Record<string, unknown>) => void actionLoading: string | null @@ -1374,10 +1374,17 @@ // «active»: у активного статус уже сказан рамкой, чип был бы шумом. // ПРИОРИТЕТ — клик по карточке: один приоритет на пул, повторный клик по // подсвеченной снимает. Кнопки внутри карточки клик не пропускают. + // Подсказки на корне НЕТ: нативный title наследуется всеми потомками без + // своего title, и подсказка о клике накрывала всю плитку и раскрытую ⓘ + // («нажатие стало перекрывать тултипы при наведении», владелец 2026-09-27). + // Подсказка о приоритете — только у своего атома, чипа «★». Клавиатура — + // тот же onPriority на том же элементе (Enter/Space), и только когда фокус + // на самой карточке, а не на кнопке внутри неё. return <div role="button" aria-pressed={priority} data-priority={priority ? 'true' : undefined} - title={priority ? t.priorityOnTip : t.priorityTip} onClick={onPriority} + tabIndex={0} onClick={onPriority} + onKeyDown={e => { if (e.target === e.currentTarget && (e.key === 'Enter' || e.key === ' ')) { e.preventDefault(); onPriority() } }} style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: priority ? 11 : 12, background: isActive ? `${SCHEME.success}08` : SCHEME.cardBg, border: priority ? `2px solid ${SCHEME.accent}` : `1px solid ${isActive ? `${SCHEME.success}44` : SCHEME.border}`, boxShadow: priority ? `0 0 0 2px ${colorMix(SCHEME.accent, 25)}` : undefined, borderRadius: 8, cursor: 'pointer' }}> <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}> <span style={{ fontWeight: 600, fontSize: 15 }}>{token.metadata.accountName}</span> <span style={{ padding: '2px 6px', borderRadius: 4, fontSize: 11, fontWeight: 600, background: `${rankColour}22`, color: rankColour }}>{rankLabel}</span> - {priority && <span style={{ padding: '2px 6px', borderRadius: 4, fontSize: 11, fontWeight: 600, background: colorMix(SCHEME.accent, 18), color: SCHEME.accent }}>★ {t.priority}</span>} + {priority && <span title={t.priorityOnTip} style={{ padding: '2px 6px', borderRadius: 4, fontSize: 11, fontWeight: 600, background: colorMix(SCHEME.accent, 18), color: SCHEME.accent }}>★ {t.priority}</span>} --- /dev/null +++ b/packages/app/tests/unit/vault-account-card.test.tsx @@ -0,0 +1,81 @@ +/** @vitest-environment jsdom + * Карточка аккаунта: наведение и клик живут на ОДНОМ элементе (владелец + * 2026-09-27: «нажатие стало перекрывать тултипы при наведении»). + * Подсказки экрана — нативный title, и то, что покажет браузер при наведении, + * определено атрибутами: ближайший title вверх по дереву, пустой — ничего. + */ +import React from 'react' +import { createRoot, type Root } from 'react-dom/client' +import { flushSync } from 'react-dom' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { AccountCard } from '@/views/platform/TokenVaultView' +vi.mock('@imperiaos/shared/core/lib/i18n', () => ({ useLocale: () => 'ru' })) + +type Props = React.ComponentProps<typeof AccountCard> +const PRIORITY_TIP = 'клик — сделать аккаунт приоритетным в пуле: выдаётся первым, пока у него есть запас' +const PRIORITY_ON_TIP = 'приоритет пула — выдаётся первым, пока у него есть запас; повторный клик снимает' +const NOW = Date.UTC(2026, 8, 27, 12) +const token = { + id: 'acc1', provider: 'anthropic', accessToken: 'x', expiresAt: null, status: 'active', + metadata: { accountName: 'acc1', email: 'acc1@example.com', tier: 'max_20x', tokenType: 'oauth_pkce', rateLimitMultiplier: 20 }, + lifetimeFraction: 0, isUsable: true, needsRefresh: true, lastUsedAt: null, lastRefreshedAt: null, errorMessage: null, + rateLimit: { util5h: 0.2, util7d: 0.4, reset5h: 0, reset7d: 0, probedAt: NOW }, + selection: { rank: 1, paidUntil: null, weeklyResetInMs: 3_600_000, fiveHResetInMs: 600_000, burnInMs: 7_200_000, burnSource: null }, +} as unknown as Props['token'] + +/** Что покажет нативная подсказка при наведении на el. */ +const tipAt = (el: Element) => el.closest('[title]')?.getAttribute('title') ?? '' + +let host: HTMLDivElement, root: Root +const onPriority = vi.fn(), doAction = vi.fn() +const render = (priority: boolean) => flushSync(() => root.render( + <AccountCard token={token} spend={12.5} now={NOW} doAction={doAction} actionLoading={null} priority={priority} onPriority={onPriority} />)) +const card = () => host.querySelector<HTMLElement>('[role="button"]')! +const name = () => [...card().querySelectorAll('span')].find(s => s.textContent === 'acc1')! +const ownTitled = () => [...card().querySelectorAll('[title]')] +const press = (el: Element, key: string) => flushSync(() => el.dispatchEvent(new KeyboardEvent('keydown', { key, bubbles: true }))) + +beforeEach(() => { + onPriority.mockClear(); doAction.mockClear() + host = document.createElement('div'); document.body.appendChild(host); root = createRoot(host) + render(false) +}) +afterEach(() => { flushSync(() => root.unmount()); host.remove() }) + +describe('AccountCard — наведение и клик сосуществуют', () => { + it('наведение: пустые места карточки без подсказки, атомы — со своей (как до правки приоритета)', () => { + expect(tipAt(name())).toBe('') + expect(tipAt(card())).toBe('') + expect(ownTitled().length).toBeGreaterThan(0) + for (const el of ownTitled()) expect(tipAt(el)).not.toBe(PRIORITY_TIP) + }) + it('раскрытая ⓘ не отдаёт место подсказке карточки', () => { + const dot = [...card().querySelectorAll('button')].find(b => b.textContent === 'i')! + flushSync(() => dot.click()) + expect(tipAt(dot)).toBe('') + expect(onPriority).not.toHaveBeenCalled() + }) + it('клик по карточке → onPriority (PATCH priority), кнопки внутри — нет', () => { + flushSync(() => name().click()) + expect(onPriority).toHaveBeenCalledTimes(1) + const refresh = card().querySelector<HTMLButtonElement>('button[title^="перевыпустить"]')! + flushSync(() => refresh.click()) + expect(doAction).toHaveBeenCalledWith('refresh', { tokenId: 'acc1' }) + expect(onPriority).toHaveBeenCalledTimes(1) + }) + it('наведение после клика: подсказки те же, приоритет назван только чипом «★»', () => { + flushSync(() => name().click()) + render(true) + expect(tipAt(name())).toBe('') + const star = [...card().querySelectorAll('span')].find(s => s.textContent?.startsWith('★'))! + expect(tipAt(star)).toBe(PRIORITY_ON_TIP) + for (const el of ownTitled().filter(e => e !== star)) expect(tipAt(el)).not.toBe(PRIORITY_ON_TIP) + }) + it('клавиатура: Enter/Space на карточке → тот же onPriority; Enter на кнопке внутри — нет', () => { + expect(card().tabIndex).toBe(0) + press(card(), 'Enter'); press(card(), ' ') + expect(onPriority).toHaveBeenCalledTimes(2) + press(card().querySelector('button[title^="перевыпустить"]')!, 'Enter') + expect(onPriority).toHaveBeenCalledTimes(2) + }) +}) ``` **Ожидаемые статусы тестов (не прогонялись)** Базой считаем HEAD 4afbc7a плюс только первый hunk с `export`. Без него тестовый файл не импортируется вовсе. | Тест | На базе | После патча | Вид | |---|---|---|---| | 1. наведение | красный: имя получает PRIORITY_TIP | зелёный | FAIL_TO_PASS | | 2. раскрытая ⓘ | красный: `undefined` на :903 отдаёт место подсказке карточки | зелёный | FAIL_TO_PASS | | 3. клик | зелёный | зелёный | PASS_TO_PASS, характеризует новое поведение | | 4. наведение после клика | красный | зелёный | FAIL_TO_PASS | | 5. клавиатура | красный: `tabIndex` −1, keydown не обработан | зелёный | FAIL_TO_PASS | Контрольная проверка: вернуть одну строку `title=…` на корень — тесты 1, 2 и 4 снова должны покраснеть. Оракул после применения: `pnpm --filter @imperiaos/app test:unit:run`. vault-account-list.test.ts не затронут. Сама отправка PATCH (`fetch('/api/tokens?action=pool-priority', { method: 'PATCH' })`, :2150–2167) не менялась. Тест проверяет её шов — вызов `onPriority`. Рендера всего экрана с `fetch` в тесте нет: это пробел. **Пары «указатель ↔ клавиатура» на одном элементе** - Клик по карточке ↔ Enter или Space на той же карточке, когда фокус на ней. - Клик по ⓘ, «Активировать», «Обновить» ↔ их нативные `<button>`, как и раньше. Их Enter не всплывает в onPriority благодаря проверке `target === currentTarget`. **Почему оракул прошлой правки это не поймал** В сюите экрана, vault-account-list.test.ts:2, проверяются только чистые функции (`nextPriority`, `vaultGroups`, `vaultOrder`). AccountCard там не рендерится. Не было трёх видов проверок экрана: - проверки взаимодействия в DOM (наведение, клик, клавиатура); - характеризационного снимка подсказок `title` до правки; - проверки клавиатурной достижимости. Сценарий S4-08 фиксировал только рамку и порядок карточек. **Что остаётся за владельцем** 1. `role="button"` на корне, внутри которого есть кнопки (ⓘ, «Активировать», «Обновить»), — это вложенные интерактивные элементы. Нарушение появилось вместе с правкой приоритета, этот патч его не создаёт и не лечит. Лечить его — менять семантику (перенести `role` и `aria-pressed` на чип «★» или отдельную кнопку), а это за пределами минимального диффа. 2. Ключ `priorityTip` в словаре (:266, :407) становится неиспользуемым. Я его не трогал. 3. Нативный `title` не всплывает при фокусе с клавиатуры. Это свойство всех подсказок экрана до правки, патч его не менял. Источники: - [MDN — title](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/title): элемент без `title` наследует подсказку предка, пустой `title` это наследование отключает. - [W3C APG — Button pattern](https://w3.org/WAI/ARIA/apg/patterns/button): в фокусе кнопку активируют Space и Enter; переключатель задаётся через `aria-pressed`. - [MDN — ARIA button role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/button_role): элементу с `role="button"` нужны фокусируемость и обработчики click и keydown для Enter и Space. - [Deque axe — nested-interactive](https://dequeuniversity.com/rules/axe/4.7/nested-interactive): у интерактивного элемента не должно быть фокусируемых потомков.

Не хватает: Локализованная причина регрессии: файл:строки, механизм подавления, диапазон коммитов