P-CLAW-AGENT-CORE этап 1: агентный цикл оператора (loop + verification) - #34
Draft
EpicStarAi wants to merge 3 commits into
Draft
P-CLAW-AGENT-CORE этап 1: агентный цикл оператора (loop + verification)#34EpicStarAi wants to merge 3 commits into
EpicStarAi wants to merge 3 commits into
Conversation
Base branch backup/operator-ui-account-fetch (7659db4) regressed the guard to a null-stub resolveBoundAccountId and dropped resolveBoundAccount, while 7 routes still import it — the tree does not typecheck. Restore the deny-by-default, binding-backed guard verbatim from origin/backup/auth-session-bootstrap (the BoundResolution ok/none/mismatch resolver). Identical to the guard the parallel auth-guard session uses, so this is a prerequisite, not a competing change. Prereq for P-CLAW-AGENT-CORE stage 1 (agent loop). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…routes P-CLAW-AGENT-CORE stage 1 (§1 + §3): turn the operator from one call into an agentic loop. Engine (lib/agent, pure + unit-testable via Node type-stripping): - types.ts: AgentRun / AgentStep / AgentStepResult, ports (ToolRegistry, Planner, RunStore, Clock). maxSteps=12, run timeout, REPEAT_LIMIT. - runLoop.ts: plan -> pick -> (mutation => approval gate, pause) -> call -> verify -> record -> re-evaluate. Hard maxSteps AND wall-clock timeout, repeated-step detection, per-step persist BEFORE + AFTER, tool errors never silently kill the run, cancel checked between steps and mid-call (already-run external effects recorded, not rolled back). - verify.ts: deriveStepStatus — success ONLY with a passing verification; ok without a check => unverified; contradicted => failed; mutation may never be unverified. Reusable verifiers (message-id, nonempty, count). - planner.ts: deterministic HeuristicPlanner that decomposes the goal and RE-EVALUATES on real results (empty/failed reads change the next move); an LLM planner can drop in behind the same port later. - tools.ts: real registry — read/draft via backend /ai/route (never sends); publish maps to a mutation guard the loop never executes. Persistence (mirrors telegramBindings): agentRunsDb.ts (pg, CREATE TABLE IF NOT EXISTS, additive) + agentRunsStore.ts (fs fallback, works with no DATABASE_URL); migrations/003_agent_runs.sql. Routes (authenticated, security not weakened): - POST /api/operator/run — getPrincipal 401; slot resolved server-side via resolveBoundAccount; body accountId ignored; launches loop, returns run id. - GET /api/operator/run/[id] — auth + owner-scoped; account id masked. - POST /api/operator/run/[id]/cancel — auth + owner-scoped; sets cancel flag. Tests: 12 new (loop completion, cancel-between-steps, loop detection, maxSteps, timeout, honest tool-error, verification discipline, broken-tool => not-green, unverified, mutation-never-executed). Full suite 17/17 green; tsc --noEmit clean. tsconfig: allowImportingTsExtensions (permissive) so the engine's .ts imports load in both next build and node --test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ncel Adds an isolated "Агентный цикл" panel to the Operator Office that drives the authenticated loop routes: POST /api/operator/run, poll GET /run/[id], and a Stop button -> POST /run/[id]/cancel. Each step shows its plain-language intent, risk chip and status badge; partial / unverified / awaiting_approval render DISTINCTLY from a green success (an unverified step is never a check-mark), with the verification method + evidence shown per step. Self-contained component + one dashboard zone; no change to the existing chat flow (keeps this isolated from parallel sessions). .gitignore: local .agent-runs.json fs store. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
P-CLAW-AGENT-CORE — этап 1: оператор из «одного вызова» в агентный цикл
Draft. Базовая ветка PR:
backup/operator-ui-account-fetch(7659db4) — это линия прод-релиза, несущая фундамент гейта (getPrincipal, resolveBoundAccount, telegramMutationsEnabled, approval-гейт prepare→confirm→execute, operator-роуты). Вmainэтого фундамента нет. Тегаqclaw-release-20260717-1130в репозитории не существует; ближайшая соответствующая проду ветка — эта.Что построено (§1 + §3 спеки)
Движок цикла (
apps/web/lib/agent/, чистый, юнит-тестируемый):types.ts—AgentRun/AgentStep/AgentStepResult, порты (ToolRegistry,Planner,RunStore,Clock).maxSteps=12, таймаут рана,REPEAT_LIMIT.runLoop.ts— план → выбрать шаг → (risk=mutation ⇒ пауза на approval-гейт) → вызвать инструмент → верифицировать → записать → переоценить. ЖёсткийmaxStepsИ wall-clock таймаут, детект повторяющегося шага, запись шага ДО и ПОСЛЕ выполнения, ошибка инструмента не убивает run молча, отмена проверяется между шагами и сразу после вызова (уже выполненное внешнее действие фиксируется, не откатывается).verify.ts—deriveStepStatus:successтолько при пройденной верификации; ok без проверки ⇒unverified; проверка опровергла ⇒failed; мутация не может бытьunverified.planner.ts— детерминированныйHeuristicPlanner, который раскладывает цель на этапы и переоценивает по реальным результатам (пустой/упавший read меняет следующий ход). LLM-планировщик встаёт за тот же порт позже.tools.ts— реальный реестр: read/draft через backend/ai/route(никогда не шлёт); publish — mutation-заглушка, которую цикл не исполняет.Персистентность (по образцу telegramBindings):
agentRunsDb.ts(pg,CREATE TABLE IF NOT EXISTS, аддитивно) +agentRunsStore.ts(fs-фолбэк, работает безDATABASE_URL);migrations/003_agent_runs.sql.Роуты (аутентифицированы, безопасность не ослаблена):
POST /api/operator/run—getPrincipal401; слот резолвится на сервере черезresolveBoundAccount;accountIdиз тела игнорируется; запускает цикл, возвращает id рана.GET /api/operator/run/[id]— auth + owner-scoped; account id маскируется.POST /api/operator/run/[id]/cancel— auth + owner-scoped; ставит флаг отмены.UI: изолированная панель «Агентный цикл» в Operator Office — цель, план, шаги с intent + risk + бейджем статуса (
partial/unverified/awaiting_approvalпоказаны иначе, чемsuccess), кнопка Стоп.Дисциплина проверки (§3)
Шаг не может быть
successтолько потому, что вызов не бросил исключение. Для каждого шага отдельно хранитсяverified {method, passed, evidence}. Искусственно сломанный инструмент (ok без эффекта) даётfailed; непроверяемый —unverified; ни то ни другое не зелёная галочка. Мутация никогда не исполняется в цикле — паузаwaiting_approvalпод существующий гейт.Безопасность (не ослаблена)
getPrincipal(в обработчике — middleware/api/operator/*тут не покрывает; параллельная сессия закрывает это отдельно, я не конфликтую).resolveBoundAccountна сервере; клиентскийaccountIdигнорируется.prepare→confirm→execute, уважаютtelegramMutationsEnabled(); никакого обхода, никакого захардкоженногоoperatorApproved.ЗАПРЕЩЁННОЕ — не делалось
Нет mock/demo/fake-success; нет деплоя; нет реальных отправок в Telegram;
TELEGRAM_MUTATIONне менялся; TDLib-сессии и привязки не тронуты.Проверки — всё зелёное
npm run build✓ (Compiled successfully; роуты/api/operator/run*зарегистрированы),tsc --noEmit✓,npm run lint✓ (только пре-существующий baseline warnings).npm test— 17/17 (12 новых: полный цикл, отмена между шагами, детект зацикливания, maxSteps, таймаут, честная ошибка инструмента, дисциплина верификации, сломанный инструмент ⇒ не-зелёный, unverified, мутация не исполняется).POST/GET/cancel→ 401; cross-user GET чужого рана → 403. Аутентифицированный рансобери→проанализируй→подготовь: шаг Bootstrap Core v1 infrastructure and AI Operator docs #1get_last_messages→ success (verified.passed=true); шаг Reconcile production P3.5-P3.8 hotfixes into GitHub #2summarize_chat→ failed (LLM отключён в среде — честная ошибка бэкенда, не фейковый успех); планировщик переоценил, повторил один раз, затем честно остановился (failed: stage_failed:summarize_chat). Зелёный многошаговый финал требует включённого LLM (env), сам цикл детерминированно доказан тестами.🤖 Generated with Claude Code