Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions docs/decisions/2026-08-07-realtime-hub-visibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Работа коллеги видна в общем поиске почти сразу

## Контекст

Командный хаб отдавал историю с задержкой в часы. Два разных лага складывались:

1. **Клиент отправлял транскрипты только на `SessionStart`.** Пока человек не
закроет текущую сессию и не откроет следующую, ничего из его работы на хаб не
уезжало вообще. Для долгой сессии это полдня.
2. **Сервер индексировал загруженное раз в 10 минут** (`OnUnitActiveSec=10min`).

Требование, из-за которого это стало проблемой: вечерний дайджест работы команды
собирается из хаба, а «видеть, что делает команда» хочется в момент работы, а не
на следующий день. Формулировка задачи — «написал сообщение, оно видно; агент
ответил, ответ виден».

## Решение

- Плагин пушит после каждого хода: хуки `UserPromptSubmit` и `Stop` дополнительно
к существующему `SessionStart`. Оба вызывают `session-recall hub push` в фоне.
- Серверный таймер индексации — раз в минуту вместо десяти.

Итоговая задержка: секунды на отправку плюс до минуты на индексацию.

## Почему

**Почему push после каждого хода, а не по таймеру на клиенте.** Ход — это ровно
то событие, после которого появились новые байты. Таймер либо будит машину
впустую, либо просыпается не тогда.

**Почему это дёшево.** Отправка инкрементальная — уезжает только хвост файла.
Замер на реальной сессии: 2.4 секунды на 87 KB, и это в фоне (`&`), сессия его не
ждёт. `pgrep` не даёт запуститься второму пушу поверх идущего.

**Почему хук молчит у тех, кто не в команде.** Первой строкой — проверка
`hub.json`; нет файла, значит машина не подключена к хабу, и хук выходит с нулём.
Плагин ставят и вне нашей команды, у них не должно появляться ни ошибок, ни
лишних запусков.

**Почему минута, а не 10 секунд.** Прогон индексации — это эмбеддинги новых
чанков; десятисекундный цикл начал бы наслаиваться сам на себя без выигрыша,
который человек способен заметить.

## Что протестировали

- `session-recall hub push` на живой сессии: 2 файла, 89 161 байт, 2.4 с.
- `/v1/recent` за день с ключом участника: сессии приходят с полем владельца —
видно, чья работа, без ручной сверки.
- Прогон индексации на сервере при 10 накопленных файлах: 34 с CPU. За минуту
накапливается заметно меньше, в цикл укладывается.

## Отвергли

- **Индексация по событию из `/v1/ingest`** — честный realtime, но это очередь и
разделяемое состояние между сервисом и индексатором; минутный таймер даёт почти
тот же результат без нового кода.
- **Пуш на `PostToolUse`** — срабатывает по десятку раз за ход, а новых байтов
добавляет столько же, сколько один пуш в конце.
- **Ускорить только серверный таймер** — не помогло бы: главный лаг был на
клиенте, где данные лежали до следующего запуска сессии.

---
07.08.2026 · PR: hooks + docs + timer на сервере (`claude-recall-index.timer`)
17 changes: 12 additions & 5 deletions docs/team-hub.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,13 @@ session-recall hub push
session-recall hub status
```

Дальше ничего делать не нужно: при старте каждой сессии агента новые
транскрипты уходят на сервер сами.
Дальше ничего делать не нужно: транскрипты уходят на сервер сами — при старте
сессии, а потом после каждого хода (твоё сообщение, ответ агента). Отправка
инкрементальная, это доли секунды в фоне и она не задерживает сессию.

Сервер переиндексирует загруженное раз в минуту, так что работа коллеги видна
в общем поиске примерно через минуту после того, как она произошла, — не нужно
ждать, пока он закроет сессию.

### Как этим пользоваться

Expand Down Expand Up @@ -163,9 +168,11 @@ session-recall hub secrets status # сколько секретов маск
session-recall hub index
```

Запускается по таймеру. Идёт тем же кодом, что и локальная индексация, — по
одному проходу на владельца. Один сбойный транскрипт не останавливает
остальных.
Запускается таймером `claude-recall-index.timer` раз в минуту — это то, что
делает общий поиск почти realtime. Идёт тем же кодом, что и локальная
индексация, — по одному проходу на владельца. Один сбойный транскрипт не
останавливает остальных. Прогон занимает секунды: за минуту накапливается
несколько файлов, а не сотни.

---

Expand Down
24 changes: 23 additions & 1 deletion hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"description": "Keep the session-recall index freshincremental re-index in the background at session start.",
"description": "Keep the index fresh: a full incremental re-index at session start, plus a lightweight hub push after every turn so teammates see the session as it happens.",
"hooks": {
"SessionStart": [
{
Expand All @@ -11,6 +11,28 @@
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"timeout": 5,
"command": "[ -f \"$HOME/.local/share/session-recall/hub.json\" ] || exit 0; export PATH=\"$HOME/.local/bin:$HOME/bin:$PATH\"; sr=session-recall; command -v \"$sr\" >/dev/null 2>&1 || exit 0; pgrep -f \"$sr hub push\" >/dev/null 2>&1 || (\"$sr\" hub push >>/tmp/session-recall-push.log 2>&1 &)"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"timeout": 5,
"command": "[ -f \"$HOME/.local/share/session-recall/hub.json\" ] || exit 0; export PATH=\"$HOME/.local/bin:$HOME/bin:$PATH\"; sr=session-recall; command -v \"$sr\" >/dev/null 2>&1 || exit 0; pgrep -f \"$sr hub push\" >/dev/null 2>&1 || (\"$sr\" hub push >>/tmp/session-recall-push.log 2>&1 &)"
}
]
}
]
}
}
Loading