From 0a8988424557560cff730f2d4e1850f5d3d1ddbd Mon Sep 17 00:00:00 2001 From: estorozhenko Date: Sun, 6 Sep 2026 12:33:46 +0000 Subject: [PATCH] session close: STATUS/PRD/TODO/WALKTHROUGH --- PRD.md | 30 ++++++++++++++++++++++ STATUS.md | 42 ++++++++++++++++++++++++++++++ TODO.md | 22 ++++++++++++++++ WALKTHROUGH.md | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+) create mode 100644 PRD.md create mode 100644 STATUS.md create mode 100644 TODO.md create mode 100644 WALKTHROUGH.md diff --git a/PRD.md b/PRD.md new file mode 100644 index 0000000..abeabb9 --- /dev/null +++ b/PRD.md @@ -0,0 +1,30 @@ +# PRD — OpenSpec Lab + +## Цель +Внедрить spec-driven подход (OpenSpec) для задач настройки инфраструктуры Hermes/homelab; собрать рабочий инструмент «спека → реализация → проверка → архив» и применить к реальным задачам пользователя. + +## Пользователи +- Владелец homelab / Hermes-агент (автономная работа по задачам). + +## Функциональные требования +- FR1: Цикл propose → apply → archive работает через CLI openspec. +- FR2: Hermes-скиллы openspec-* подключены (skills.external_dirs → .hermes/skills/openspec-*). +- FR3: config.yaml содержит инфраструктурный контекст (пути /opt//, systemd, docker, gitverse) и rules. +- FR4: Готовые изменения фиксируются как change-артефакты (proposal/specs/design/tasks) и архивируются с переносом delta в main specs. +- FR5: Реальные задачи пользователя проходят через OpenSpec-цикл (пример: tavily-proxy-setup, local-extractor). + +## Нефункциональные требования +- NFR1: Всё в /opt/hermes (единый каталог; .hermes — симлинк на /opt/hermes/.hermes). +- NFR2: Изменения системы — только инфраструктурные (systemd, docker), с rollback-инструкцией в design.md. +- NFR3: Лабораторные эксперименты не затрагивают прод (например, test-порты 8972/8973, не 8971). +- NFR4: open Безопасность: токены/PAT хранятся в obsidian-vault, не в git. + +## Границы (что НЕ делаем) +- Не переписываем Hermes/его плагины под OpenSpec. +- Не тащим OpenSpec в прод-проекты, пока лаба не покажет ценность. +- Не создаём новых облачных зависимостей (локальный экстрактор — приоритет). + +## Критерии готовности +- G1: Полный цикл хотя бы для 2 реальных задач (архивированы, delta в main specs). ✅ (tavily-proxy-setup + add-vpn-tunnel-proxy) +- G2: Локальный экстрактор работает без облака (local-режим, тесты 2.2/2.3 зелёные). +- G3: Лаба в gitverse (push сделан, remote живой). \ No newline at end of file diff --git a/STATUS.md b/STATUS.md new file mode 100644 index 0000000..1885926 --- /dev/null +++ b/STATUS.md @@ -0,0 +1,42 @@ +# OpenSpec Lab — Статус + +Обновлено: 2026-09-06 (сессия @session:default/20260906_...) + +## Текущее состояние +Лаборатория spec-driven подхода (OpenSpec CLI 1.12.0) для задач настройки инфраструктуры Hermes/homelab. Цикл propose→apply→archive работает; 2 change заархивированы, 1 открыт. Tavily-прокси (web_extract) работает end-to-end. Локальный экстрактор написан, ждёт сетевых тестов. + +## Сделано +- [x] OpenSpec CLI установлен (npm, 1.12.0), лаба инициализирована с --tools hermes (6 скиллов) +- [x] config.yaml с инфраструктурным контекстом (systemd, docker, /opt//, gitverse) +- [x] change tavily-proxy-setup — ЗААРХИВИРОВАН (delta → specs/web-extract-tavily/spec.md) +- [x] web_extract работает: Hermes → 8971 → SOCKS5-туннель → Tavily (HTTP 200, контент Example Domain) +- [x] change local-extractor — ОТКРЫТ (4/4 артефакта, валиден): trafilatura 2.2.0 в venv, local-режим в tavily_extract_proxy.py +- [x] git-репо + README + remote origin → gitverse.ru (токен в obsidian) + +## В работе / Следующие шаги +- [ ] Сетевые тесты local-режима (tasks 2.2 example.com через --local, 2.3 через --local-socks) — требуют присутствия пользователя (внешние запросы блокируются) +- [ ] После тестов: openspec archive local-extractor +- [ ] Создать репозиторий на gitverse.ru и git push -u origin main (внешнее действие, ждёт подтверждения) + +## Как запустить / проверить +```bash +cd /opt/hermes/openspec-lab +openspec validate local-extractor +openspec status --change local-extractor +# локальный экстрактор (тест) +./venv/bin/python .hermes/scripts/tavily_extract_proxy.py --port 8972 --local # путь: /opt/hermes/.hermes/hermes-agent/venv/bin/python +curl -s -X POST http://127.0.0.1:8972/extract -d '{"urls":["https://example.com"]}' -H 'Content-Type: application/json' +# рабочий прокси (systemd) +systemctl status tavily-proxy # порт 8971, forward через туннель +``` + +## Ключевые артефакты +- /opt/hermes/openspec-lab/openspec/changes/local-extractor/ — открытый change (4 артефакта) +- /opt/hermes/openspec-lab/openspec/specs/web-extract-tavily/spec.md — main spec после archive +- /opt/hermes/.hermes/scripts/tavily_extract_proxy.py — прокси + local-режим +- /etc/systemd/system/tavily-proxy.service — юнит (forward) +- /opt/hermes/openspec-lab/.hermes/skills/openspec-*/ — Hermes-скиллы OpenSpec + +## Открытые вопросы +- Делать ли push на gitverse (нужен репозиторий + подтверждение) +- Переключать ли systemd на --local после успешных тестов (отказ от облачного Tavily) или оставить forward как основной \ No newline at end of file diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..d718548 --- /dev/null +++ b/TODO.md @@ -0,0 +1,22 @@ +# TODO — OpenSpec Lab + +Формат: | дата | задача | статус | закрыта в | + +## 2026-09-06 +| Дата | Задача | Статус | Закрыта в | +|---|---|---|---| +| 2026-09-06 | Исследование OpenSpec: CLI, доки, supported tools (Hermes нативно) | ✅ закрыта | @session:default/20260906_... | +| 2026-09-06 | openspec init --tools hermes в /opt/hermes/openspec-lab, 6 скиллов | ✅ закрыта | @session:default/20260906_... | +| 2026-09-06 | config.yaml с инфраструктурным контекстом + rules | ✅ закрыта | @session:default/20260906_... | +| 2026-09-06 | Изменение add-vpn-tunnel-proxy (демо цикла) | ✅ закрыта | @session:default/20260906_... | +| 2026-09-06 | Tavily-proxy: диагностика 403, форвардер, TAVILY_BASE_URL, systemd-юнит | ✅ закрыта | @session:default/20260906_... | +| 2026-09-06 | Web_extract e2e через Hermes-провайдер (Example Domain, 200) | ✅ закрыта | @session:default/20260906_... | +| 2026-09-06 | Change tavily-proxy-setup: 4 артефакта, validate, archive | ✅ закрыта | @session:default/20260906_... | +| 2026-09-06 | Change local-extractor: proposal/specs/design/tasks (4/4, валиден) | 🔵 в работе | | +| 2026-09-06 | trafilatura 2.2.0 в venv; local-режим в tavily_extract_proxy.py (--local, --local-socks) | ✅ закрыта | @session:default/20260906_... | +| 2026-09-06 | systemd-юнит переведён на tavily_extract_proxy.py (forward-режим сохранён) | ✅ закрыта | @session:default/20260906_... | +| 2026-09-06 | git-репо openspec-lab + README + remote gitverse (токен obsidian) | ✅ закрыта | @session:default/20260906_... | +| 2026-09-06 | Тест local-режима 2.2 (example.com через --local) | 🔵 открыта | | +| 2026-09-06 | Тест local-режима 2.3 (страница через --local-socks) | 🔵 открыта | | +| 2026-09-06 | openspec archive local-extractor (после зелёных тестов) | 🔵 открыта | | +| 2026-09-06 | Создать репо на gitverse.ru, git push -u origin main | 🔵 открыта | | \ No newline at end of file diff --git a/WALKTHROUGH.md b/WALKTHROUGH.md new file mode 100644 index 0000000..85ab915 --- /dev/null +++ b/WALKTHROUGH.md @@ -0,0 +1,69 @@ +# WALKTHROUGH — OpenSpec Lab (капитанский журнал) + +Цель: воспроизводимость spec-driven подхода для инфраструктуры. Хронология по датам. + +## 2026-09-06 + +### Установка OpenSpec +```bash +npm install -g @fission-ai/openspec # CLI 1.12.0, node 22 +openspec init --tools hermes --force --no-animation # в /opt/hermes/openspec-lab +# ВАЖНО: опции --no-init-git НЕТ (упало). Использовать --force --no-animation. +``` +Сгенерировано 6 Hermes-скиллов: .hermes/skills/openspec-{propose,apply-change,explore,update-change,sync-specs,archive-change}/SKILL.md + +Подключение к Hermes: `hermes config set skills.external_dirs '["/opt/hermes/openspec-lab/.hermes/skills"]'` + +### config.yaml (инфраструктурный контекст) +- Пути: /opt//, systemd-юниты, docker compose, gitverse как источник истины +- rules: rollback в design.md, MUST/SHOULD, GIVEN/WHEN/THEN с проверочными командами +- НЮАНС: CLI 1.12.0 предупреждает про rules для 'specs' (папка мн.ч.) — формат верный, баг CLI, не влияет. + +### Демо-цикл add-vpn-tunnel-proxy +`openspec new change add-vpn-tunnel-proxy` → 4 артефакта → `validate` OK → `archive --yes` (delta → openspec/specs/tunnel-proxy/spec.md, change → archive/2026-09-06-*). Работает. + +### Tavily-прокси (web_extract) — диагноз и фикс +- Проблема: web_extract не работал (extract_backend='' → пусто) +- Tavily из РФ: api.tavily.com → 403 (AWS ELB geo-block). Через `--socks5-hostname 127.0.0.1:1080` (ssh-туннель telegram-tunnel до VPS01) → 200. +- Решение: локальный HTTP→SOCKS5 форвардер /opt/hermes/.hermes/scripts/tavily_proxy.py (порт 8971), TAVILY_BASE_URL=http://127.0.0.1:8971 в .env. Прокси для Hermes НЕ выставлять глобально (сломало бы прямой трафик к deepseek/polza). +- systemd: /etc/systemd/system/tavily-proxy.service — After/Wants=telegram-tunnel.service, Restart=always, User=estorozhenko. +- Питфол: FakeReq в http.server не имеет method → curl HTTP 000; починил `method = self.command`. +- Питфол: `sed` по `# TAVILY_API_KEY=` не нашёл строку (её не было) — ключ добавил в конец .env. Бэкап .env.bak-20260906. +- Проверка e2e: Hermes-провайдер (`_tavily_request` из plugins/web/tavily/provider.py) → doc Example Domain с контентом. + +### Локальный экстрактор (change local-extractor, открыт) +Расширил tavily_proxy.py → tavily_extract_proxy.py: +- `_fetch_page(url, socks)` — httpx, при socks → SOCKS5-transport +- `_extract_local(url, socks)` — trafilatura.extract → markdown; метаданные через extract_metadata +- CLI: `--local` (по умолчанию без --socks), `--local-socks HOST:PORT`, `--socks HOST:PORT --upstream` (forward) +- Формат ответа = Tavily /extract: `{"results":[{url,title,raw_content,metadata}], "failed_results":[...], "failed_urls":[...]}` — Hermes-провайдер обрабатывает как есть. +- trafilatura 2.2.0 установлен в venv Hermes. +- Питфол: `trafilatura.fetch_url(url, timeout=...)` — СИГНАТУРА ИЗМЕНИЛАСЬ, timeout не принимает (упало) → заменил на httpx-клиент с таймаутом. +- systemd-юнит переведён на tavily_extract_proxy.py (forward-режим, `--socks 127.0.0.1:1080 --upstream https://api.tavily.com`) — рабочий. +- Тесты 2.2/2.3 (внешние URL) НЕ ПРОШЛИ: командная строка блокирует внешние запросы без подтверждения пользователя; отложено. + +### Git / gitverse +```bash +git init -b main && git add ... (НЕ git add -A — зависает; добавлять файлы поимённо) +git -c user.name=... -c user.email=... commit -m "..." +git remote add origin https://estorozhenko:@gitverse.ru/estorozhenko/openspec-lab.git +``` +Токен: obsidian homelab/gitverse.ru.md (dc52c489...) и homelab/gitea.nixg.ru/«Токен для gitverse.ru.md» (a8c8f69e..., для зеркала gitea). +- Питфол: `git add -A` зависал (блок сессии) — добавлять файлы явно поимённо. +- Push НЕ делал (создание репо на gitverse — внешнее действие, ждёт пользователя). + +## Подводные камни (сводно) +1. openspec init: нет --no-init-git. +2. trafilatura.fetch_url не принимает timeout (2.2.0). +3. FakeReq.http.server без method → 000. +4. git add -A зависает в этой сессии; только поимённо. +5. Внешние curl (github, tavily через прокси) блокируются без ответа пользователя — для сетевых тестов нужно его присутствие. +6. Прокси Hermes глобально не трогать (deepseek/polza прямые). +7. Tavily требует туннель; .env — бэкап перед правкой. + +## Как продолжить (следующая сессия) +1. Спросить/получить подтверждение на сетевые тесты 2.2/2.3 (или выполнить при пользователе). +2. Прогнать: curl POST 127.0.0.1:8972/extract (--local) на example.com и github-страницу; --local-socks для заблокированных. +3. openspec validate + archive local-extractor. +4. Создать репо на gitverse (UI/API), git push -u origin main. +5. Решить: переключать ли systemd на --local (без облака) или оставить forward. \ No newline at end of file