maps: fix — репо-папки как обычные файлы (было submodule/gitlink), 45 MAP.md теперь в репо

This commit is contained in:
german
2026-07-12 20:21:49 +03:00
parent 7faebe0a06
commit 4bfad7475f
90 changed files with 2217 additions and 45 deletions
Submodule agent-sync deleted from 0279a432b2
+89
View File
@@ -0,0 +1,89 @@
# 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-примитивы → утилиты).
```mermaid
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 | — (оффлайн) | проверка окружения без сети |
## Ключевые цепочки вызовов
1. **Публикация файла (`put`)**: `cmd_put` → `_sha256` (локальная сумма) → `_mkdirp`(MKCOL) → `_curl -T` (PUT тела) → PUT сайдкара `.sha256` → скачать назад в tmp → сверить sha256 → `_die` при расхождении. Гарантия целостности больших бинарей.
2. **Отправка задачи (`send-task`)**: `cmd_send_task` → `_mkdirp tasks/<to>/inbox` → `cmd_put` (тело задачи с YAML-шапкой в inbox агента-получателя).
3. **Атомарный захват (`claim`)**: `cmd_claim` → `cmd_ls inbox` → фильтр `.md` → цикл `_move_noover` (MOVE inbox→processing, `Overwrite: F`); код `201`=захвачено (exactly-once), `412`=уже занято → аудит-маркер в `audit/<agent>/` → GET тела в `./_ncx-work/`. Первый забравший выигрывает, гонок нет.
4. **Завершение (`done`)**: `cmd_done` → дописать `result/done_by/done_at` в локальный файл → `cmd_put` в `done/` → `DELETE` из `processing/` → аудит-маркер.
5. **Хартбит (`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` (функция→функция, включая косвенные вызовы через `main` case).
- Подтвердить/опровергнуть **dead-code** (реальная достижимость `_exists`, аудит-fallback, поведение `return` в subshell `cmd_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`, пометить актуальную.