Files
microdao-daarion/docs/HUMANIZED_STEPAN_v2.7_CHANGELOG.md
Apple 67225a39fa docs(platform): add policy configs, runbooks, ops scripts and platform documentation
Config policies (16 files): alert_routing, architecture_pressure, backlog,
cost_weights, data_governance, incident_escalation, incident_intelligence,
network_allowlist, nodes_registry, observability_sources, rbac_tools_matrix,
release_gate, risk_attribution, risk_policy, slo_policy, tool_limits, tools_rollout

Ops (22 files): Caddyfile, calendar compose, grafana voice dashboard,
deployments/incidents logs, runbooks for alerts/audit/backlog/incidents/sofiia/voice,
cron jobs, scripts (alert_triage, audit_cleanup, migrate_*, governance, schedule),
task_registry, voice alerts/ha/latency/policy

Docs (30+ files): HUMANIZED_STEPAN v2.7-v3 changelogs and runbooks,
NODA1/NODA2 status and setup, audit index and traces, backlog, incident,
supervisor, tools, voice, opencode, release, risk, aistalk, spacebot

Made-with: Cursor
2026-03-03 07:14:53 -08:00

7.8 KiB
Raw Blame History

Humanized Stepan — CHANGELOG v2.7

Version: v2.7
Date: 2026-02-25
Базується на: v2.6 (Jaccard guard, tone_constraints, 3-рівневі привітання, seeded RNG)


Summary

  • Додано memory horizon: recent_topics (до 5 записів) замість єдиного last_topic.
  • Додано human topic labels (last_topic_label) — Степан оперує "план на завтра поле 12", а не "plan_day".
  • Додано summarize_topic_label() — rule-based витяг 68 слів з тексту без дієслів-тригерів і стоп-слів.
  • Light follow-up (≤6 слів + last_topic) не додає шум до recent_topics (depth="light"push не відбувається).
  • Contextual greeting (interaction_count ≥ 8) тепер: з ймовірністю 20% (seeded rng) підхоплює recent_topics[-2] — Степан "пам'ятає" більше однієї теми без подвійного згадування.
  • ZZR safety disclaimer: якщо погодний тригер + обприскування/гербіцид/ЗЗР — автоматично додається "Дозування та вікна застосування — за етикеткою препарату та регламентом.".
  • Додано tests/test_stepan_invariants.py — 25 тестів-інваріантів проти "повзучої ботячості".

Key features (деталі)

Memory horizon — recent_topics

"recent_topics": [
  {"label": "план на завтра поле 12", "intent": "plan_day", "ts": "2026-02-25T..."},
  {"label": "датчики вологості поле 7", "intent": "iot_sensors", "ts": "2026-02-25T..."}
]
  • Максимум 5 записів; старіші витісняються.
  • last_topic і last_topic_label — backward-compat aliases на recent_topics[-1].
  • Dedup: якщо той самий intent + label підряд — не дублюється.

summarize_topic_label

Вхід Вихід
"зроби план на завтра по полю 12" "План на завтра по полю 12"
"перевір датчики вологості поле 7" "Датчики вологості поле 7"
"сплануй тижневий збір по полях" "Тижневий збір по полях"

Правила: прибирається leading action verb (зроби/перевір/порахуй/…), стоп-слова, обрізка до 8 слів. Числа, поля, культури, дати зберігаються.

ZZR disclaimer

Regex _ZZR_RE спрацьовує на: обробк|обприскування|гербіцид|фунгіцид|ЗЗР|пестицид|інсектицид|протруювач.
Застереження додається лише коли є і погодний тригер і ZZR-тригер в одному повідомленні.

Invariant tests (anti-regression)

Інваріант Обмеження
INV-1: Greeting ≤ 80 символів
INV-2: Thanks/Ack ≤ 40 символів
INV-3: Заборонені фрази "чим можу допомогти", "оберіть", "я як агент", "я бот"
INV-4: Технічні слова container, uvicorn, trace_id, STEPAN_IMPORTS_OK
INV-5: ZZR disclaimer при ZZR+погода → "за етикеткою" або "за регламентом"
INV-6: Horizon len(recent_topics) ≤ 5 після 7+ push
INV-7: Міграція lazy, idempotent, backward-compat

Backward compatibility

Аспект Деталі
_version 3 → 4 (нові поля recent_topics, last_topic_label)
Міграція Lazy при load_user_profile() — виконується автоматично при першому зверненні
last_topic Залишається як alias, завжди синхронізований з recent_topics[-1].intent
last_topic_label Новий alias на recent_topics[-1].label; якщо нема — встановлюється під час міграції
tone_constraints Вже в v2.6; міграція додає якщо відсутній
update_profile_if_needed Новий параметр depth="deep" (default) — backward-compat, старі виклики не ламаються
recent_topics відсутній Якщо профіль v3 без recent_topicsmigrate_profile_topics() створює 1 елемент з last_topic

Міграція migrate_profile_topics()idempotent: повторний виклик не змінює вже мігрований профіль.


Non-goals / not included

  • Немає LLM у light mode або reflection.
  • Немає змін в інфраструктурі (Dockerfile, compose, env).
  • Немає змін у Gateway/http_api.py.
  • Немає нових API ендпоінтів.
  • Немає змін у поведінці deep mode orchestration.
  • Немає змін у системному промпті (тільки хедер-версія).

Tests

Результат: 101/101 зелених (без регресій з v2.6)

Файл Тестів Опис
tests/test_stepan_invariants.py 25 Нові інваріанти anti-regression
tests/test_stepan_acceptance.py 28 Acceptance + v2.7 сесійні сценарії
tests/test_stepan_light_reply.py ~26 Light reply юніт-тести
tests/test_stepan_memory_followup.py ~22 Memory + follow-up класифікація
# Тільки інваріанти
python3 -m pytest tests/test_stepan_invariants.py -v

# Acceptance
python3 -m pytest tests/test_stepan_acceptance.py -v

# Всі Stepan тести
python3 -m pytest tests/test_stepan_invariants.py tests/test_stepan_acceptance.py \
  tests/test_stepan_light_reply.py tests/test_stepan_memory_followup.py -v

Known limitations

Timezone і daily seed

date.today() використовує локаль контейнера. Контейнер має бути в Europe/Kyiv (TZ=Europe/Kyiv), інакше "новий день" Степана настане о 22:00 або 23:00 за Київським часом. Перевірка:

docker exec dagi-gateway-node1 date

Memory-service downtime

При недоступності — деградація до локального in-memory кешу (TTL 30 хв). Кеш не переживає рестарт контейнера. Профілі не зберігаються між сесіями якщо memory-service down > 30 хв.

ZZR regex — можливий overreach

Слово "обробка" без агрохімічного контексту (напр. "обробка ґрунту") може спрацювати. Якщо в проді виявиться шум — звузити regex: вимагати ще одне слово з [препарат|норма|л/га|кг/га|концентрат].


Rollback

# Відкатити зміни у конкретних файлах
git checkout HEAD~1 -- crews/agromatrix_crew/memory_manager.py
git checkout HEAD~1 -- crews/agromatrix_crew/light_reply.py
git checkout HEAD~1 -- crews/agromatrix_crew/run.py

# Rebuild gateway (без секретів)
cd /opt/microdao-daarion
docker compose -f docker-compose.node1.yml up -d --build dagi-gateway-node1

# Перевірка
docker logs dagi-gateway-node1 --since 5m 2>&1 | grep -E "Stepan mode|STEPAN_IMPORTS_OK|error|Error" | tail -30