8.5 KiB
8.5 KiB
title, type, tags, sources, related, updated
| title | type | tags | sources | related | updated | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| sched F&F r8 — стенд верификации (schedule-as-entity) | concept |
|
|
2026-08-18 |
sched F&F r8 — стенд верификации
Кросс-агентный цикл F&F (findings & fixes): sched-команда публикует пакеты в
verdaccio, admin-сессия верифицирует на стенде и репортит находки через
инбокс (sched/.agents/inbox/). Раунд r8 = «schedule-as-entity» (движок тикает
по schedule-строкам). Цикл идёт письмами: intro → отчёт → фикс → перепроверка →
следующий пункт.
Стенд
- Путь:
C:\Users\vitya\projects\.admin\.tmp\sched-r8\(gitignored, живёт на диске). - package.json: @sched/core 0.40.2 / daemon 0.3.0 / storage-{mysql,postgres,mongo} 0.3.1 / ui 0.2.0 из verdaccio (
npm install --registry=https://verdaccio.kzntsv.site/).legacy/— старый core 0.35.1 для генерации v0.6-БД. - Docker-контейнеры (как в CI sched):
sched-mysql-test:3308,sched-mariadb-test:3307,sched-postgres-test:5433,sched-mongo-test:27017; root:test / postgres:test.
Репро-скрипты (15 шт., .tmp/sched-r8/*.mjs)
Миграции / адаптеры (№1):
migration-test.mjs— sqlite v0.6→v0.7 (эталон синтеза)adapter-migration-test.mjs— F2: mysql/pg v3→v5, синтез легаси-строки, due стреляетmongo-synthesis-test.mjs— F2 mongo: first-open синтез, no-dup, non-empty gate. Легаси-док: коллекцияsched_tasks,config.data(неdata),paused/disabledобязательны (иначе null → не в due)priority-order-test.mjs— F1: task priority 10 наследуется на строкуadapters-spotcheck.mjs— 12/12 CRUD+dedupKey-upsert на 4 адаптерахtasks-json-test.mjs— модель tasks.json (schedules:[...], fail-fast legacy key)contract-parity.test.mjs— vitest contract-сьют 5 адаптеров (см. гочу №2)
Движок (№2, 75 проверок):
engine-runs-test.mjs(16) — scheduleId/data/trigger на schedule-ранах; manual (null+дефолты); retryRun (снапшот+retryOf)engine-due-claim-test.mjs(10) — priority-порядок, ceiling с блокирующим раннером, pause, once, catch-upengine-retry-test.mjs(27) — ретраи на строках (retryCount/backoff×multiplier/failCount/onRunFinal), override, retryOf-цепочкаengine-watchdog-test.mjs(14) — reap обоих наборов локов, heartbeat real-clock, recoverOrphanRunsengine-async-test.mjs(8) — async poll через schedule-раны, poll timeout
Политики (№3, 21 проверка):
engine-policy-test.mjs— whole-no-merge (override не наследует поля дефолта), snapshot-семантика пендинг-ретрая, pause AND два уровня, manual=дефолты задачи, priority-микс
Admin API (№4, 52 проверки):
admin-api-test.mjs— живьём по HTTP противcreateAdminApi(in-process, listen(0), fetch): POST /schedules dedupKey-upsert 201/200 (UUID id, fileManaged=false, sync не дизаблит), tz ?? task.tz, GET /schedules first-class + lastRunStatus + effectiveStatus (no N+1 — ровно 3 чтения через счётчик storage-методов), GET/DELETE /:id (раны переживают delete), pause/resume (гейтит только строку), hard cut POST /tasks/:name/schedule → 404 с указателем, POST /tasks runtime (fileManaged=false, переживает sync, state сохраняется), PATCH merge, MCP list_schedules (runTool → новая форма).
UI (№5, 13/13 зелёных + U1/U2):
ui-backend.mjs— бэкенд :8080 (createAdminApi, монтируется на /api/* как daemon — sched-ui serve проксирует путь verbatim), датасет books-паттерна: 4 строки × (active/failed, paused-schedule/succeeded, paused-task/без ранов, runtime-строка) + auth по SCHED_ADMIN_KEY.sched-ui serve --proxy http://127.0.0.1:8080 --port 8081+ браузерный CDP-стенд (~/projects/.common/scripts/browser/{start,nav,eval,screenshot}.js): рендер таблицы (shadowRoot-инспекция), клики по форме create/edit/delete, перехват window.fetch для проверки body POST/PATCH/DELETE, мок window.confirm для delete, замер геометрии (getBoundingClientRect).
Что подтверждено (контракт)
- Ceiling сериализует через тики: две due-строки одной задачи стреляют в РАЗНЫХ тиках (sibling-claim отклоняется атомарно). Параллелизм только между задачами.
- onRunFinal — на любом терминальном ране (успех тоже), не только на persistent-failure; «алерты только на фейлы» — фильтр consumer'а.
- retryCount на строке = consumed-попытки (кумулятив: после 2 фейлов = 2).
- resolveSchedulePolicy =
schedule.retry ?? task.retryцеликом; explicitpriority: 0уважается как есть. - Snapshot-семантика: правка политики не пересчитывает дедлайн пендинг-ретрая; свежая политика — со следующего диспатча.
- pause AND:
task.pausedгейтит все расписания (движок),schedule.paused— одно (due-запрос). - manual triggerTask = дефолты задачи (data, без schedule-политики), расписание не двигается.
- F1 (core 0.40.2): inner cron timezone ХОСТИТСЯ (
schedules.timezone ?? task/API tz ?? UTC), конфликт-правило удалено — задача с tz может использовать другой inner timezone (доки были правы, код врал). - F3 (core 0.40.2): PATCH /schedules/:id = partial merge (RFC 7396-стиль): меняются только поля в теле, явный
nullочищает, опущенное сохраняется — dedupKey не осиротевает при правке одного правила.
Находки №5 (UI, ждут разбора)
- U1: форма sched-schedules кладёт значение tz-поля ВНУТРЬ schedule-entry как
timezone(валидно только для cron), а не как body-leveltz→ interval/once с tz нельзя ни создать, ни отредактировать (400 «timezone is only valid on cron schedules»); edit любой interval-строки с body-tz сломан (форма предзаполняет tz из строки). - U2: таблица sched-schedules переполняет контейнер на ~58px (1076 vs 1018 при длинных JSON в rule/data) — actions/delete за правым краем карточки. Общий стиль
table{width:100%}+ auto-layout безtable-layout:fixed/word-breakна td;overflow:hiddenна table не спасает.sched-tasks(7 колонок) — ровно 1018px.
Как продолжить (закрытие раунда)
- Бамп версий в package.json стенда →
npm install --registry=...(после каждого фикса). - Новые проверки — отдельный
.mjsпо паттерну существующих (check()+ SUMMARY), изолированные DB на сценарий; UI — браузерный CDP-стенд (см. выше). - Отчёт — письмо в
sched/.agents/inbox/с фронтматтеромfrom: admin, формат «делал → ожидал → получил → раздел доки». Не чинить, не пушить, их доску не трогать. - №1–№4 ПРИНЯТЫ (52/52 после фиксов), №5 репорт ушёл (13/13 + U1/U2) — ждём разбор → закрытие раунда (процедура fnf-testing-procedure пополнится результатами).