- .admin claim-guard pushed + verified: claim-gate run over real .admin board skips all 4 claimable .admin tasks with reason=needs-human (zero slip-through). - Always-on bring-up started (docker mongo+reconciler) then torn down per user "don't start pollers without permission". Host task-runner never started — no claim/spawn occurred. .env/secrets.env/guard left in place, ready. - Worker config decided: this workstation; AGENT_RUNTIME=claude-opus; AGENT_CAPABILITIES=needs-internet; headless claude login suffices. - Caught a stale-claimable task (MoreThenCms cms-maljarka-https-mode-bug-fix was ⚪ ready though the bug was fixed today) — closed it. Lesson recorded: sweep boards for stale-claimable before enabling always-on. - GATE: starting pollers awaits explicit user grant. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
71 lines
5.9 KiB
Markdown
71 lines
5.9 KiB
Markdown
# agents-task-runner-vds-deploy
|
||
|
||
> Slug legacy-named `-vds-deploy`; scope corrected 2026-06-08 — VDS-as-worker DROPPED.
|
||
> Per-machine federation: each WORKER runs its own `agents-task-runner`, claims from the
|
||
> SHARED Gitea board, runs the agent LOCALLY, commits/pushes. VDS hosts the Gitea board
|
||
> ONLY (already up) — not a worker, nothing deploys on it.
|
||
|
||
## Goal
|
||
Поднять `agents-task-runner` (the poller) на первой worker-машине, нацелив на shared
|
||
Gitea-board. Машина клеймит только то, что умеет (capability-filter), `.admin` исключён
|
||
из автономного клейма до governance L2/L3. Сначала DRY_RUN на prod-board, затем один
|
||
живой цикл на реальной non-`.admin` таске: spawn → commit → push, verified.
|
||
|
||
## Key files
|
||
- `~/projects/.common/lib/agents-task-runner/` — runtime (plain JS, `type:module`, v0.16.2)
|
||
- `server.js` — reconcile loop entry (`npm start`)
|
||
- `task-runner/server.js` — task-runner entry (`npm run task-runner`)
|
||
- `lib/cross-project-poller.js` — claim loop, requirements-filter, confirm-gate
|
||
- `lib/consult-backend/` — execution-policy governance (consult_policy + needs-human gate)
|
||
- `docker-compose.yml` / `docker-compose.host.yml` / `Dockerfile`
|
||
- `secrets.env.example` — секреты-шаблон (ANTHROPIC_API_KEY / Gitea token / projects-meta)
|
||
- `config/` — node-config overlays
|
||
- `~/projects/.common/lib/projects-meta-mcp/dist/` — уже собран (build-prereq для НЕГО, не для раннера)
|
||
|
||
## Decisions log
|
||
- 2026-06-08: Взята в работу из ⚪ ready. **Build-prereq в Next action неточен** — раннер
|
||
это чистый JS (нет tsconfig / `npm run build`, запускается `node server.js`), собирать
|
||
нечего; `npm run build` релевантен только `projects-meta-mcp`, а его `dist/` уже есть.
|
||
Источник заблуждения — общий BUILD-prereq из consult-execution-policy-governance review,
|
||
где TS-only касался projects-meta-mcp.
|
||
- 2026-06-08: Re-scoped (из STATUS-блока): VDS = board-host only, VDS-as-worker dropped.
|
||
Poller живёт на worker-машинах (workstation / factory Linux).
|
||
- 2026-06-08: guard `.admin/.tasks/policy.toml` (default_weight=needs-human) **запушен**
|
||
(`94972472`) + **верифицирован**: прогон dist-модулей claim-gate на реальном `.admin` board
|
||
→ все 4 claimable `.admin`-таски скипаются `reason=needs-human`, ноль проскочивших.
|
||
- 2026-06-08: always-on bring-up НАЧАТ (`.env` RECONCILER_ENABLED=true, secrets.env, docker
|
||
build + `mongo`+`reconciler` up через host-override) — затем **ОСТАНОВЛЕН и снесён** (`compose
|
||
down`) по запрету user'а "не запускай поллеров без разрешения". host task-runner так и НЕ
|
||
стартовал → ни одного claim/spawn не было. Конфиг (.env/secrets.env) остался на диске, готов.
|
||
- 2026-06-08: **находка, валидирующая gating** — DRY_RUN-кандидат
|
||
`OpeItcLoc03/MoreThenCms/cms-maljarka-https-mode-bug-fix` был ⚪ ready, хотя баг починен сегодня
|
||
(cross-board stale: фикс жил в `.admin`, таска — на MoreThenCms board, никто не закрыл). Без
|
||
паузы always-on заспавнил бы агента «чинить» уже починенное. Таска закрыта user-confirmed
|
||
(MoreThenCms `890eae27`). Урок: до always-on нужен sweep board'ов на stale-claimable.
|
||
|
||
## Open questions
|
||
- [ ] **GATE: запуск поллеров требует явного разрешения user'а** (2026-06-08 — "не запускай
|
||
поллеров без моего разрешения"). До гранта — НЕ стартовать host task-runner и НЕ поднимать
|
||
reconciler с RECONCILER_ENABLED=true.
|
||
- [x] Первая worker-машина → **эта workstation** (user-решение 2026-06-08).
|
||
- [x] Headless-auth → `claude login` достаточно (spawn наследует env хост-процесса; API-key не нужен).
|
||
- [x] Capability-filter → `AGENT_CAPABILITIES=needs-internet` (минимально), `AGENT_RUNTIME=claude-opus`.
|
||
|
||
## Completed steps
|
||
- [x] 2026-06-08: orientation — раннер локализован (`~/projects/.common/lib/agents-task-runner`,
|
||
v0.16.2, JS), build-prereq разобран (фантом для раннера), common pull актуален (`e7b1143`).
|
||
- [x] 2026-06-08: prereq-чек на workstation зелёный — node v22.22, docker 29.3.1 up,
|
||
`projects-meta-mcp/dist/tasks-cli.js` собран, runner `node_modules` есть, `auth.toml` есть.
|
||
- [x] 2026-06-08: **DRY_RUN-смок прошёл end-to-end.** Хост-процесс `task-runner` (PORT 3000,
|
||
`DRY_RUN=1 AGENT_RUNTIME=claude-opus AGENT_CAPABILITIES=needs-internet SPAWN_MODE=local`),
|
||
один тик через `POST /tasks/crossProjectAgentPoller` + `GET /runs/:id` (curl `--noproxy "*"`).
|
||
Результат: `{dryRun:true, claimed:false, candidate:{project:"OpeItcLoc03/MoreThenCms",
|
||
slug:"cms-maljarka-https-mode-bug-fix"}}`. Полный cross-boundary путь
|
||
(reconciler→runner→CLI→реальный shared-board read) работает; claim-token НЕ записан, spawn НЕ
|
||
вызван. Capability-фильтр (`needs-internet`) отработал — кандидат non-`.admin`. Процесс заглушён.
|
||
|
||
## Notes
|
||
- HARD: `.admin` исключён из автономного клейма до governance L2/L3 (см. STATUS-блок § blocker).
|
||
- anti-self-review: distinct machine-id на каждый worker.
|
||
- Секреты per-machine: 600 root, не в git.
|