8.0 KiB
agent-sync
Назначение
Транспорт и протокол обмена задачами/статусами/артефактами между агентами инфраструктуры servaki через Nextcloud (WebDAV, n.servaki.online, папка /_agents/). Не замена git (Gitea git1.servaki.online — канон кода/спек), а второй слой для крупного/оперативного: сборки, дампы, статусы-хартбиты, файловая очередь inbox/processing/done между агентами (laptop-agent, lilia/les, claude-agent).
Ядро — один переносимый POSIX-скрипт ncx.sh (git-bash на ПК + Linux-ВМ), работающий поверх curl + WebDAV. Секреты (app-password) хранятся вне git в ~/.servaki-secrets/nextcloud.env.
- Основной язык: POSIX shell (sh)
- Суммарный LOC по коду: ~197 (весь код —
ncx.sh, 197 строк; остальное — Markdown-доки и.env.example)
Архитектура
Каталогов src/* нет — плоский репо. Модули = функции внутри ncx.sh (диспетчер main → подкоманды → WebDAV-примитивы → утилиты).
graph TD
ENV["nextcloud.env<br/>(секреты, вне git)"] --> NCX
subgraph ncx.sh
MAIN["main() — диспетчер CLI"]
MAIN --> INIT[cmd_init]
MAIN --> LS[cmd_ls]
MAIN --> PUT[cmd_put]
MAIN --> GET[cmd_get]
MAIN --> MKDIR[cmd_mkdir]
MAIN --> SEND[cmd_send_task]
MAIN --> CLAIM[cmd_claim]
MAIN --> DONE[cmd_done]
MAIN --> STATUS[cmd_status]
MAIN --> SELF[cmd_selftest]
NEED["_need_creds()<br/>DAV/ROOT URL"]
CURL["_curl() — curl -K - (stdin auth)"]
SHA["_sha256()"]
MKCOL["_mkcol / _mkdirp (MKCOL)"]
EXISTS["_exists (PROPFIND)"]
MOVE["_move_noover (MOVE Overwrite:F)"]
INIT --> NEED --> CURL
SEND --> PUT
PUT --> SHA
PUT --> MKCOL
GET --> EXISTS
GET --> SHA
CLAIM --> LS
CLAIM --> MOVE
CLAIM --> PUT
DONE --> PUT
STATUS --> PUT
end
NCX[ncx.sh] -->|WebDAV/HTTPS| NC["Nextcloud n.servaki.online<br/>/_agents/"]
Entry-points / маршруты
HTTP-сервера/роутов нет — это WebDAV-клиент (исходящие вызовы к Nextcloud). Публичный интерфейс — CLI-подкоманды. Все ходят через _curl (curl --fail-with-body -K -) к NC_BASE/remote.php/dav/files/<user>/_agents/....
| Команда | Функция | WebDAV-метод(ы) | Назначение |
|---|---|---|---|
ncx init |
cmd_init | MKCOL | создать структуру _agents/ под своего агента |
ncx ls <path> |
cmd_ls | PROPFIND Depth:1 | листинг каталога |
ncx put <local> <remote> |
cmd_put | PUT (+GET верификация) | залить файл + sha256-сайдкар, сверить целостность |
ncx get <remote> <local> |
cmd_get | GET, PROPFIND | скачать + сверить sha256 |
ncx mkdir <path> |
cmd_mkdir | MKCOL | создать каталог рекурсивно |
ncx send-task <to> <local.md> |
cmd_send_task | PUT | положить задачу в tasks/<to>/inbox |
ncx claim [agent] |
cmd_claim | MOVE Overwrite:F | атомарно забрать 1 задачу inbox→processing |
ncx done <task> [result] |
cmd_done | PUT, DELETE | processing→done + результат + аудит |
ncx status <local.md> |
cmd_status | PUT | опубликовать хартбит status/<agent>-status.md |
ncx selftest |
cmd_selftest | — (оффлайн) | проверка окружения без сети |
Ключевые цепочки вызовов
- Публикация файла (
put):cmd_put→_sha256(локальная сумма) →_mkdirp(MKCOL) →_curl -T(PUT тела) → PUT сайдкара.sha256→ скачать назад в tmp → сверить sha256 →_dieпри расхождении. Гарантия целостности больших бинарей. - Отправка задачи (
send-task):cmd_send_task→_mkdirp tasks/<to>/inbox→cmd_put(тело задачи с YAML-шапкой в inbox агента-получателя). - Атомарный захват (
claim):cmd_claim→cmd_ls inbox→ фильтр.md→ цикл_move_noover(MOVE inbox→processing,Overwrite: F); код201=захвачено (exactly-once),412=уже занято → аудит-маркер вaudit/<agent>/→ GET тела в./_ncx-work/. Первый забравший выигрывает, гонок нет. - Завершение (
done):cmd_done→ дописатьresult/done_by/done_atв локальный файл →cmd_putвdone/→DELETEизprocessing/→ аудит-маркер. - Хартбит (
status):cmd_status→cmd_putвstatus/<agent>-status.md(single-writer на файл → без конфликтов синка).
Тех-долг
Ниже — предположения по эвристике (греп/чтение одного файла). Точность — через codebase-memory-mcp.
- Dead-code кандидаты: явных не найдено — все
_*-примитивы иcmd_*достижимы изmain();_existsиспользуется вcmd_get,_move_noover— вcmd_claim. (предположение) - Дубли/расхождение доков: структура
/_agents/описана дважды и по-разному:README.md/ncx.sh=inbox|processing|done+audit/, аAGENT-SYNC-NEXTCLOUD.md= толькоinbox|done+shared-memory/. Второй документ помечен как «предложение схемы» и частично устарел относительно кода. (предположение) - Хрупкая логика аудита в
cmd_claim: fallback между/tmp/ncx-audit.$$и./.ncx-audit.$$через двойную проверку-f— легко рассинхронизировать; кандидат на упрощение. (предположение) cmd_claimв pipe-подоболочке (... | while read):return 0выходит из подоболочки, не из функции — семантика «одна задача за вызов» может вести себя неожиданно при нескольких задачах. (предположение)shared-memory/упомянут в доке, ноcmd_initего не создаёт — рассинхрон спеки и кода. (предположение)
TODO для Лилии (codebase-memory-mcp)
- Построить точный call-graph
ncx.sh(функция→функция, включая косвенные вызовы черезmaincase). - Подтвердить/опровергнуть dead-code (реальная достижимость
_exists, аудит-fallback, поведениеreturnв subshellcmd_claim). - Cross-service links — зафиксировать связи:
n.servaki.online(85.208.87.14, Nextcloud 33.0.5),git1.servaki.online(Gitea, репоgerman/agent-sync), домены*.servaki.online; агенты-контрагентыlaptop-agent/lilia(les) /claude-agent; упоминание репоcascade(git-канон). Проверить реальные обращения из других наших репо кncx/_agents/. - Снять снапшот graph.db.zst и связать с этим MAP.md.
- Сверить расхождение схемы
/_agents/междуREADME.mdиAGENT-SYNC-NEXTCLOUD.md, пометить актуальную.