Compare commits

..
2 Commits
Author SHA1 Message Date
n1kt4r 97f03a9dd5 DESIGN v2: refocus to autonomous content producer with grounding
Смена целенаправленности: не реклама/аналитика метрик, а производство
контента (текст, изображение, подкаст, видео) + анализ его метрик + SEO.

- Новый центральный объект content_items (kind, status-конвейер
  brief→generated→optimized→published→measured, site, deal_id)
- areas: text, image, podcast, video, seo_onpage, seo_semantics, publish
- metric_kind: reach, engagement, position, traffic, conversion, revenue, speed, quality
- источники метрик: Метрика API, GSC, Yandex Webmaster, Wordstat (+platform/manual/client)
- skills привязаны к реальному стеку: editor-pro, ComfyUI, Silero TTS,
  video-pipeline, Wordstat, Astro (retrieval по bge-m3)
- автономия по заслугам: тир на область, +1 за 3 успеха, -1 за провал
- конвейер производства добавлен как сквозной процесс
- TODO переписан: 8 шагов (0-7) с критериями приёмки
2026-09-23 14:42:15 +05:00
n1kt4r 436dd5fa31 DESIGN: grounded loop + merit-based autonomy; reprioritize TODO (7 steps)
- DESIGN.md: три контура (сделки / заземление / методы), модель данных,
  правила нормализации метрик, тиры автономии по заслугам, энергия от результата
- Судья = метрики разного типа: охват, позиции, вовлечённость, конверсии,
  продажи, деньги, стоимость, скорость, качество (ручной вердикт)
- Автономия по областям (seo/ads_budget/content_publish/client_comms/...),
  +1 тир за 3 успеха, -1 за провал, затухание 90 дней, границы persona непреодолимы
- P7 сужен до тонкого Channel (console/telegram/file); harness-реестр отложен
- TODO.md переписан под 7 шагов с критериями приёмки
2026-09-23 14:37:17 +05:00
3 changed files with 365 additions and 57 deletions

No files matched your search

+280
View File
@@ -0,0 +1,280 @@
# spark-mind — DESIGN: автономный контент-продюсер с заземлением
Обновление плана от 2026-09-23 (вторая редакция: фокус смещён с рекламы/метрик
на **производство контента + анализ его метрик + SEO**).
## 1. Тезис
iLands строит общество на 80 000 агентов, чтобы получить «судью без автора».
Нам толпа не нужна: у нас есть **мир, который отвечает сам** — поисковики и
аудитория. Агент производит контент (текст, изображение, подкаст, видео),
публикует, и через заданный горизонт **замеряет, что сработало**: показы,
позиции, CTR, дочитывания, прослушивания, переходы, конверсии.
Два принципа, которых нет у iLands в рабочем виде:
1. **Заземление.** Качество контента оценивается не рассуждением агента,
а метриками, которые он не контролирует, с отложенным вердиктом.
2. **Автономия по заслугам.** Права выдаются по подтверждённому трек-рекорду:
доказал, что контент улучшает метрики — получил свободу публиковать
без спроса и выбирать темы сам. Провал — права сужаются.
Границы persona `values` непреодолимы на любом уровне.
**Что это даёт на практике:** агент не «генерирует текст вообще», а учится,
какой заголовок, структура и формат работают — на своих же сайтах
(orabota.ru, нейросети.рус, bzp02.ru и др.) и на заказах клиентов.
## 2. Три контура + конвейер
```
КОНВЕЙЕР ПРОИЗВОДСТВА brief → generated → optimized → published → measured
content_items — центральный объект, на нём замеряются метрики
A. КОНТУР ЗАКАЗОВ «для кого и за что» counterparties → deals
B. КОНТУР ЗАЗЕМЛЕНИЯ «что сработало» outcomes → capabilities → ledger
C. КОНТУР МЕТОДОВ «как производить» skills + reflection
```
Плюс сквозные: `noAction` (P5) и тонкий `Channel` (бывший P7).
## 3. Модель данных (SQLite, тот же файл БД)
### 2.1 Конвейер: content_items — центральный объект
```sql
CREATE TABLE content_items (
id TEXT PRIMARY KEY,
kind TEXT NOT NULL CHECK(kind IN ('text','image','podcast','video')),
title TEXT NOT NULL,
topic TEXT,
status TEXT NOT NULL DEFAULT 'brief'
CHECK(status IN ('brief','generated','optimized','published',
'measured','archived')),
target_url TEXT, -- где опубликован
site TEXT, -- orabota.ru | нейросети.рус | ...
deal_id TEXT REFERENCES deals(id), -- nullable: для своих сайтов
published_at INTEGER,
created_at INTEGER NOT NULL
);
```
Конвейер — это переходы `status`. Каждый переход пишется в `deal_events`-подобный
журнал, если привязан к сделке.
### A. Контур заказов
```sql
CREATE TABLE counterparties (
id TEXT PRIMARY KEY,
kind TEXT NOT NULL CHECK(kind IN ('client','platform','external')),
name TEXT NOT NULL,
notes TEXT,
trust_score REAL NOT NULL DEFAULT 0, -- derived из истории
created_at INTEGER NOT NULL
);
CREATE TABLE deals (
id TEXT PRIMARY KEY,
counterparty_id TEXT NOT NULL REFERENCES counterparties(id),
brief TEXT NOT NULL, -- что заказали (тема/формат/объём)
price REAL,
currency TEXT DEFAULT 'RUB',
status TEXT NOT NULL CHECK(status IN
('offered','accepted','delivered','paid','refused','defaulted')),
created_at INTEGER NOT NULL,
closed_at INTEGER
);
CREATE TABLE deal_events (
id TEXT PRIMARY KEY,
deal_id TEXT NOT NULL REFERENCES deals(id),
type TEXT NOT NULL,
payload_json TEXT,
created_at INTEGER NOT NULL
);
```
### B. Контур заземления
```sql
-- Один outcome = один content_item + одно измерение метрики.
CREATE TABLE outcomes (
id TEXT PRIMARY KEY,
item_id TEXT REFERENCES content_items(id), -- что мерим
deal_id TEXT REFERENCES deals(id),
area TEXT NOT NULL, -- text|image|podcast|video|seo_onpage|seo_semantics|publish
metric_kind TEXT NOT NULL CHECK(metric_kind IN
('reach','engagement','position','traffic',
'conversion','revenue','speed','quality')),
metric_name TEXT NOT NULL, -- 'impressions','ctr','avg_position','dwell_sec',
-- 'listens','completion_rate','indexing_hours','clicks'
unit TEXT, -- 'шт','%','сек','место','руб','ч'
direction TEXT NOT NULL CHECK(direction IN ('up_good','down_good')),
value_before REAL, -- null для нового контента
value_after REAL,
source TEXT NOT NULL CHECK(source IN
('metrika','gsc','webmaster','wordstat','platform','manual','client')),
horizon_days INTEGER NOT NULL,
due_at INTEGER NOT NULL,
status TEXT NOT NULL DEFAULT 'pending'
CHECK(status IN ('pending','measured','missed','unavailable')),
measured_at INTEGER,
score REAL -- нормализованный вердикт [-1..+1]
);
-- Автономия по заслугам: тир НА ОБЛАСТЬ, не общий.
CREATE TABLE capabilities (
area TEXT PRIMARY KEY,
tier INTEGER NOT NULL DEFAULT 0 CHECK(tier BETWEEN 0 AND 4),
positive_outcomes INTEGER NOT NULL DEFAULT 0,
negative_outcomes INTEGER NOT NULL DEFAULT 0,
updated_at INTEGER NOT NULL
);
CREATE TABLE ledger (
id TEXT PRIMARY KEY,
ts INTEGER NOT NULL,
delta REAL NOT NULL,
reason TEXT NOT NULL,
balance_after REAL NOT NULL
);
```
### C. Контур методов
```sql
CREATE TABLE skills (
id TEXT PRIMARY KEY,
name TEXT NOT NULL, -- 'podcast-silero','image-comfyui','seo-onpage-editor'
area TEXT NOT NULL, -- привязка к capabilities.area
method_md TEXT NOT NULL, -- как делать (промпт/алгоритм/порядок шагов)
tool TEXT, -- реальный инструмент: ace-step|silero|comfyui|editor-pro|astro|wordstat
source TEXT NOT NULL CHECK(source IN ('builtin','learned')),
validated INTEGER NOT NULL DEFAULT 0,
uses INTEGER NOT NULL DEFAULT 0,
success_rate REAL,
embedding BLOB -- bge-m3, dim=1024 — retrieval под задачу
);
```
## 4. Правила
### 4.1 Области (area) и типы метрик
| area | Что производит/делает | Типовые метрики |
|------|----------------------|-----------------|
| `text` | статьи, лонгриды, описания | показы, CTR, дочитывания, позиции |
| `image` | изображения, обложки, карточки | показы, CTR, скачивания |
| `podcast` | аудио, подкасты (Silero TTS) | прослушивания, completion rate, дослушивания |
| `video` | видео, шортсы | просмотры, watch time, удержание |
| `seo_onpage` | заголовки, структура, разметка | позиции, CTR, индексация |
| `seo_semantics` | семантика, кластеры, запросы | охват запросов, релевантность |
| `publish` | публикация, распространение | скорость публикации, индексация |
### 4.2 Нормализация метрики в score
```
raw = (value_after - value_before) / max(|value_before|, eps)
score = clamp(raw * (direction == 'up_good' ? 1 : -1), -1, 1)
```
- Нет `value_before` (новый контент) → сравнение с базлином области
(медиана последних 10 measured в этой `area`).
- `quality` — дискретно: `+1 / 0 / −1` (эксперт/клиент/человек).
- `speed` — `direction = 'down_good'` (быстрее индексация = лучше).
- `status != 'measured'` → score не участвует в трек-рекорде.
### 4.3 Автономия по заслугам
| tier | Имя | Что разрешено |
|------|-----|----------------|
| 0 | observer | только анализ и предложения, публикаций нет |
| 1 | suggest | предлагает готовый контент человеку, сам не публикует |
| 2 | ask | публикует после подтверждения |
| 3 | act+report | публикует и отчитывается; человек может откатить |
| 4 | autonomous | публикует и выбирает темы сам, в границах persona |
Переходы:
- `+1 тир` за **3 нетто-положительных** outcome в области.
- `−1 тир` за **1 нетто-отрицательный** — асимметрия: падать легче.
- Затухание: outcome старше 90 дней весит 0.5.
- Новая область стартует с tier 0.
- **Границы persona `values` непреодолимы на любом тире.**
### 4.4 Энергия
- Расход: тик, генерация (текст/фото/аудио/видео — дороже всего), публикация,
вызов саб-агента.
- Приход: **подтверждённые положительные outcomes** (особенно `revenue`),
плюс донат человека.
- Низкий баланс → интервал тиков растёт → Deep Rest.
- Отличие от iLands: энергия восполняется результатом, а не покупкой.
## 5. Триггеры heartbeat (добавляются)
| Триггер | Что делает |
|---------|------------|
| `{type:'pipeline'}` | продвинуть content_items по конвейеру (draft→generated→optimized→published) |
| `{type:'measure'}` | наступил `due_at` → тянет метрику из источника → `value_after`, `score` |
| `{type:'reflection'}` | ночной цикл: обобщает items + outcomes + thoughts → long-term и `self_observations` |
| `{type:'task'}` | cron-планировщик (нужен для measure/reflection) |
Плюс `decision.noAction: true` (P5).
Источники метрик: **Метрика API, Google Search Console, Yandex Webmaster API,
Wordstat** — у всех доступ уже настроен. Плюс `platform` (прослушивания/просмотры)
и `manual`/`client`.
## 6. Тонкий Channel (бывший P7)
```ts
interface Channel { send(text: string): Promise<void>; }
```
Реализации: `ConsoleChannel`, `TelegramChannel`, `FileChannel`.
`LLMClient` уже есть. Полный harness-реестр отложен — абстракция окупается
с ≥2 реализациями.
## 7. Методы (skills) — привязка к реальному стеку
| area | tool | Что уже есть |
|------|------|--------------|
| text | editor-pro | 7-layer markdown pipeline (типографика, SEO-слой) |
| image | comfyui | генерация изображений через diffusion-воркфлоу |
| podcast | silero | Silero TTS 24kHz, пайплайн через normalizar/tts |
| video | video-pipeline | загрузка/обработка видео |
| seo_onpage | editor-pro, astro | структура, заголовки, schema |
| seo_semantics | wordstat | Wordstat API: частотность, кластеры |
| publish | astro + deploy | сборка Astro → публикация |
Это ключевое: **скиллы агента = твой существующий производственный стек**,
а не абстрактные описания. Retrieval по bge-m3 подгружает нужный метод под задачу.
## 8. Порядок внедрения
| Шаг | Что | Критерий приёмки |
|-----|-----|------------------|
| 0 | P5 `noAction` + тонкий `Channel` | агент умеет не действовать; вывод через интерфейс |
| 1 | Планировщик (`task`/`pipeline`/`measure`) | задача с датой выполняется в срок |
| 2 | `content_items` + конвейер | item проходит brief→published, переходы в журнале |
| 3 | `outcomes` + `measure` (Метрика/GSC/Webmaster/Wordstat) | метрика замеряется через horizon, score пишется |
| 4 | `capabilities` — автономия по областям | тир растёт после 3 успехов, падает после провала |
| 5 | `skills` + retrieval + `reflection` | нужный метод подгружается по задаче; self_observations оживают |
| 6 | `deals` + `counterparties` | заказ клиента проходит offered→paid |
| 7 | `ledger` — энергия | результат пополняет энергию, дефицит замедляет тики |
Зависимости: 3 требует 1 и 2. 4 требует 3. 5 требует 2. 7 требует 3.
## 9. Что НЕ делаем
- Рекламные метрики (Директ/CPA) как основу — ушло из фокуса.
- Соцсеть/ленту/подписки внутри агента.
- Токены как валюту.
- Полный harness-реестр.
- «Суперразум из общества».
## 10. Открытые вопросы
1. **Свои сайты или клиентские заказы в первую очередь?** (влияет на приоритет
шага 2 vs 6; предлагаю сначала свои сайты — полный контроль над метриками).
2. **Кто ставит `horizon_days`** — агент предлагает, человек правит? (Мой дефолт.)
3. **Где предел «качества» текста** — только метрики или ещё экспертная оценка
Ника обязательна перед публикацией на tier<3.
+10 -7
View File
@@ -92,15 +92,18 @@ const telegram = new TelegramMessenger({
| P4 | SQLite persistence (5 таблиц, WAL) | ✅ | | P4 | SQLite persistence (5 таблиц, WAL) | ✅ |
| P5 | Telegram Channel Layer (MAX API + fallback) | ✅ | | P5 | Telegram Channel Layer (MAX API + fallback) | ✅ |
## Roadmap (P6+) ## Roadmap
Полный список незакрытых задач — в [TODO.md](./TODO.md). - **План** — [DESIGN.md](./DESIGN.md): автономный контент-продюсер с заземлением
- **Чек-лист** — [TODO.md](./TODO.md)
Кратко: Суть: агент производит контент (текст, изображение, подкаст, видео), публикует
- P6: sleep & energy, cron-планировщик, рабочие слои памяти (notepads / core self) в цикле mind, tool-runtime для под-агентов и через заданный горизонт **замеряет, что сработало** — показы, позиции, CTR,
- P7: Web UI (persona setup), конфиг/.env, retry+timeout, тесты дочитывания, прослушивания, переходы (метрики Метрики/GSC/Webmaster/Wordstat).
- Каналы: Telegram — обход SSL-проблемы bot.qw4.ru Качество оценивается не рассуждением агента, а этими метриками. Права (автономия)
- Движок: Spark X2.5-4B (unknown architecture в Ollama) выдаются по подтверждённому трек-рекорду: доказал рост метрик — получил свободу
публиковать без спроса. Скиллы агента = существующий производственный стек
(editor-pro, ComfyUI, Silero TTS, video-pipeline, Wordstat, Astro).
## License ## License
+75 -50
View File
@@ -1,63 +1,88 @@
# spark-mind — Оставшиеся TODO # spark-mind — Оставшиеся TODO
Статус: **P0–P5 завершены** (heartbeat→mind, JSON output, embeddings, sub-agents, Полный план — в [DESIGN.md](./DESIGN.md): **автономный контент-продюсер
SQLite, Telegram). Ниже — реально незакрытые пункты, проверенные по коду с заземлением на метриках и автономией по заслугам.**
(2026-09-15). Порядок — по приоритету.
## P6 — Функциональная полнота Статус: P0–P5 базовые завершены (heartbeat→mind, JSON output, bge-m3 embeddings,
sub-agents, SQLite, Telegram+fallback). Далее — программа контент-производства.
- [ ] **Sleep & energy (циркадный ритм).** Сейчас heartbeat тикает всегда Порядок обязателен: есть зависимости между шагами.
с фиксированным интервалом 5 мин. Нужно: окна активности/сна, накопление
«энергии», снижение частоты тиков в пассивные периоды.
- [ ] **Планировщик задач (cron).** Тип триггера `{ type: 'task' }` объявлен
в `heartbeat.ts`, но **ничто его не эмитит** — планировщика нет
(`scheduleNext` — это idle-таймер, не cron). Нужен движок отложенных задач.
- [ ] **Рабочая память (notepads) в цикле mind.** Таблица `notepads` и методы
`updateNotepad()`/`getNotepad()` реализованы, но **вне memory.ts не
вызываются** — слой не участвует в `handleTick`.
- [ ] **Core self (self_observations) в цикле mind.** Аналогично: `addSelfObservation()` /
`getAllSelfObservations()` реализованы, но из mind не вызываются.
Самосознательность не накапливается автоматически.
- [ ] **Реальное исполнение инструментов под-агентов.** `subagent.ts` объявляет
список tools (web_search, terminal, file_write…), но это **строки-декларации** —
исполнения нет. Нужен tool-runtime для под-агентов.
## P7 — Инфраструктура ## Шаг 0 — Основа
- [ ] P5: `decision.noAction: true` — агент может решить, что действие не нужно,
и не писать thought (сейчас heartbeat всегда «работает» → шум в памяти).
- [ ] Тонкий `Channel`: `ConsoleChannel`, `TelegramChannel`, `FileChannel`.
`sendReply` сейчас жёстко зашит на Telegram+console.
- [ ] **Web UI (persona setup).** Настройка 8 слоёв persona через интерфейс ## Шаг 1 — Планировщик (нужен для pipeline/measure/reflection)
вместо `DEFAULT_PERSONA` в коде. - [ ] Cron-задачи: триггер `{type:'task'}` объявлен, но никто не эмитит.
- [ ] **Конфиг / .env.** URL-ы Ollama (`localhost:11434`), dbPath, Telegram - [ ] Проверка due-записей в SQLite → эмит `{type:'pipeline'}` и `{type:'measure'}`.
захардкожены в `index.ts`. Вынести в конфиг/`.env`. - [ ] Ночной `{type:'reflection'}`.
- [ ] **Retry + timeout для LLM-запросов.** `fetch` в `mind.ts` и `embedding.ts` - Приёмка: задача с датой выполняется в срок.
без retry и без `AbortController` — один сетевой сбой роняет тик.
- [ ] **Тесты.** Их нет вообще. Минимум: unit на `parseSparkOutput` (nested JSON, ## Шаг 2 — Конвейер контента (центральный объект)
fences, fallback), на `Database` CRUD, на cosine-поиск. - [ ] Таблица `content_items` (kind: text|image|podcast|video; status:
brief→generated→optimized→published→measured→archived).
- [ ] Переходы статусов + журнал переходов.
- [ ] Привязка к `site` (свои сайты) и `deal_id` (клиентские заказы).
- Приёмка: item проходит brief→published, все переходы в журнале.
## Шаг 3 — Заземление: outcomes + measure
- [ ] Таблица `outcomes`: metric_kind (reach, engagement, position, traffic,
conversion, revenue, speed, quality), direction, horizon_days, due_at.
- [ ] Замер через `{type:'measure'}`: Метрика API / GSC / Yandex Webmaster / Wordstat.
- [ ] Нормализация в `score` [-1..+1]; базлайн области для нового контента.
- Приёмка: метрика замеряется через horizon, score пишется.
## Шаг 4 — Автономия по заслугам
- [ ] Таблица `capabilities` (тир на область: text, image, podcast, video,
seo_onpage, seo_semantics, publish).
- [ ] Тиры 0..4 (observer → suggest → ask → act+report → autonomous).
- [ ] +1 тир за 3 нетто-положительных; −1 за 1 отрицательный; затухание 90 дней.
- [ ] Границы persona `values` непреодолимы на любом тире.
- Приёмка: тир растёт после 3 успехов и падает после провала.
## Шаг 5 — Методы: skills + reflection
- [ ] Таблица `skills` (name, area, method_md, tool, validated, uses,
success_rate, embedding).
- [ ] Retrieval нужного метода по эмбеддингу bge-m3 (не грузить всё сразу).
- [ ] Наполнение методами из реального стека: editor-pro (text/seo_onpage),
ComfyUI (image), Silero TTS (podcast), video-pipeline (video),
Wordstat (seo_semantics), Astro (publish).
- [ ] `reflection`: ночной цикл обобщает items+outcomes+thoughts →
long-term и `self_observations` (**сейчас мёртвый слой**).
- [ ] Tool-runtime для под-агентов: tools сейчас — только строки-декларации.
## Шаг 6 — Заказы: deals + counterparties
- [ ] Таблицы `counterparties`, `deals`, `deal_events` (append-only).
- [ ] `trust_score` выводится из истории, не задаётся руками.
- [ ] Заказ клиента на контент: offered→accepted→delivered→paid|refused|defaulted.
- Приёмка: заказ проходит полный цикл.
## Шаг 7 — Энергия: ledger
- [ ] Таблица `ledger`.
- [ ] Расход: тик, генерация (текст/фото/аудио/видео), публикация, саб-агент.
- [ ] Приход: положительные outcomes + донат.
- [ ] Низкий баланс → интервал тиков растёт → Deep Rest.
- Приёмка: результат пополняет энергию, дефицит замедляет тики.
## Инфраструктура (по мере надобности)
- [ ] Конфиг / `.env`: URL-ы Ollama, dbPath, Telegram захардкожены в `index.ts`.
- [ ] Retry + timeout (AbortController) для LLM/embedding fetch.
- [ ] Тесты: `parseSparkOutput`, `Database` CRUD, cosine-поиск, нормализация score.
- [ ] Web UI (persona setup) вместо `DEFAULT_PERSONA` в коде.
## Каналы вывода ## Каналы вывода
- [ ] Telegram: обход SSL-проблемы bot.qw4.ru (`tlsv1 unrecognized name`, серверная).
- [ ] **Telegram: обход SSL-проблемы bot.qw4.ru.** Сервер отдаёт Сейчас console-only fallback.
`tlsv1 unrecognized name` (SSL alert 112) при TLS-handshake — проблема
на стороне сервера, не клиента (проверено curl-ом и Node https).
Агент сейчас работает в console-only fallback. Варианты: починить
SNI/сертификат на qw4.ru, поднять локальный MAX-релей, или другой канал
(Telegram Bot API напрямую).
## Движок ## Движок
- [ ] Spark X2.5-4B: не грузится в Ollama (`unknown architecture 'spark2_5'`).
- [ ] **Spark X2.5-4B.** Не грузится в текущей Ollama: Варианты: совместимый GGUF / llama.cpp напрямую / остаться на Ornith-1.5-9B.
`error loading model: unknown model architecture: 'spark2_5'`.
Варианты: собрать совместимый GGUF, поднять через llama.cpp напрямую
(OpenAI-сервер на :8080), или оставить Ornith-1.5-9B как основной движок.
**Важно:** локальные модели пумолкают (пустой ответ), если `subAgent` **Важно:** локальные модели пумолкают (пустой ответ), если `subAgent`
присутствует в JSON-схеме structured output — учитывать при правках промпта. в JSON-схеме structured output.
## Косметика ## Косметика
- [ ] Устаревший doc-комментарий в `mind.ts` (класс `SparkLLMClient` описан как
- [ ] Устаревший doc-комментарий в `mind.ts`: класс `SparkLLMClient` всё ещё «клиент для Spark X2.5-4B, в MVP заглушка»).
описан как «Реальный LLM-клиент для Spark X2.5-4B. В MVP — заглушка», - [ ] Дефолт модели в конструкторе `SparkLLMClient` = `'spark-x2.5-4b'`.
хотя работает с Ornith-9B и без заглушки.
- [ ] Дефолтное имя модели в конструкторе `SparkLLMClient` = `'spark-x2.5-4b'`
(index.ts переопределяет на `ornith-1.5-9b:latest`, но дефолт вводит в заблуждение).
---
Проверено `grep`-ом по коду: dead-code слои, отсутствие cron/retry/tests/.env, SSL-ошибка Telegram.