Skip to content
Back to skills

Contrib Watch

ASecurity

- СТОРОЖ ВХОДЯЩЕГО ФИДБЭКА: кто из посторонних инженеров пришёл к НАШИМ репозиториям, что написал, сколько часов ждёт… Триггеры: “/contrib-watch“, “/cw“, “кто нам написал“, “проверь входящий фидбэк“, “что там на гитхабе“, “есть ли новые контрибьюторы“, “кто пришёл“, “долги по PR“, “check inbound feedback“, “who contributed“, а также САМ в начале любой сессии, где речь про GitHub, флагман

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 25, 2026
ai-agentspythonsqlgitapi

Works with

  • api
  • mcp

Security analysis

A100/100

Scanned October 3, 2026

npx -y skills add tonydzi/second-brain-starter-kit --skill contrib-watch --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Contrib Watch?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Contrib Watch
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tonydzi-contrib-watch/badge)](https://www.skillsdirectory.com/skills/tonydzi-contrib-watch)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: contrib-watch
description: "- СТОРОЖ ВХОДЯЩЕГО ФИДБЭКА: кто из посторонних инженеров пришёл к НАШИМ репозиториям, что написал, сколько часов ждёт… Триггеры: “/contrib-watch“, “/cw“, “кто нам написал“, “проверь входящий фидбэк“, “что там на гитхабе“, “есть ли новые контрибьюторы“, “кто пришёл“, “долги по PR“, “check inbound feedback“, “who contributed“, а также САМ в начале любой сессии, где речь про GitHub, флагман"
version: 1.0.0
---

# /contrib-watch — кто пришёл к нам сам, и почему мы обязаны ответить сегодня

## Закон
**Молчание в живом треде = провал, а не осторожность** (CLAUDE.md §4.7). Ответ на GitHub я даю
САМ, без «+» Антона и без гейта [коллега]. Мерж кода — по [[github-publish-autonomous]] + leak-scan.

**Порог: 24 часа.** Дольше — красное. Обоснование не теоретическое: 05.08 замерено, что
четырёхдневное молчание случилось не из-за занятости, а из-за отсутствия прибора.

## Шаг 1 — снять картину (0 токенов)
```
python ~/.claude/scripts/contrib_watch.py --html "$OBSIDIAN_VAULT/_Dashboards/Contrib-Inbox.html"
```
Обходит все наши публичные репозитории, находит треды, где ПОСЛЕДНИМ говорил внешний человек,
считает часы ожидания, отмечает 🆕 тех, кого не видели ни разу. Exit 3 = есть просрочка.

## Шаг 1-бис — «последним сказал чужой» ≠ долг: разговор мог уехать в PR
Эвристика «последний говоривший в треде» ловит ДОЛГ и МИГРАЦИЮ одинаково, а это разные вещи.
Нормальный цикл выглядит так: человек пишет в issue «claiming this» или «I opened PR #N» — и
дальше по существу говорят уже в PR. В issue его строка так и остаётся последней НАВСЕГДА, даже
когда мы разобрали, отревьюили и смержили. Долга там нет, мяч не наш.

Поэтому на КАЖДЫЙ хит спрашиваю ещё один вопрос, прежде чем идти отвечать:
```
gh api "/repos/tonydzi/<repo>/issues/<N>/timeline" --paginate --jq '.[]|select(.event=="cross-referenced")|.source.issue.number'
gh api "/repos/tonydzi/<repo>/issues/<PR>/comments" --paginate --jq '.[]|"\(.user.login) @ \(.created_at)"'
gh api "/repos/tonydzi/<repo>/pulls/<PR>/reviews"   --paginate --jq '.[]|"\(.state) \(.user.login) @ \(.submitted_at)"'
```
Наш ответ в связанном PR ПОЗЖЕ его последней строки в issue = касание обслужено, хит закрыт.
⚠️ ЗАМЕР 21.09.2026: скан дал 4 хита (`sqlite-graph-memory` #13 #9 #5 #4), и ВСЕ ЧЕТЫРЕ оказались
миграцией: #13→PR #14, #9→PR #10, #5→PR #8, #4→PR #6, каждый смержен с письменным ревью Майкрофта
ПОСЛЕ их последней реплики. Долгов было 0. Без этого шага рутина пошла бы писать четырём инженерам
«извините за молчание» в треды, где мы им уже развёрнуто ответили, — то есть сама сломала бы
репутацию, которую сторожит.
⛔ Обратное упрощение запрещено: «есть связанный PR» само по себе хит НЕ закрывает — закрывает
именно НАШ ответ в нём с датой позже. Смерженный молча PR без единого нашего слова — это долг
(§4.7: молчание в живом треде = провал), и он идёт в Шаг 4 как обычное касание.

## Шаг 2-ноль — «наш он или нет» решается ДВУМЯ селекторами, а не одним
⛔ Прежде чем сказать «этот новый логин не наш, карточку не завожу» (так закрыли [человек]-KUKLEVA и dudididjdje-tech 13.09) — спроси GitHub ОБОИМИ вопросами:
```
gh api "search/issues?q=commenter:<login>+user:tonydzi" --jq '.total_count'   # он у нас ГОВОРИЛ
gh api "search/issues?q=involves:<login>+user:tonydzi"  --jq '.total_count'   # он у нас АВТОР/упомянут
```
⚠️ ЗАМЕР 21.09.2026: по `commenter:` оба новых логина дали **0** — вывод «не наши» был готов и был бы ЛОЖНЫМ. `involves:` дал по **1**: [человек] и b7n0de оказались АВТОРАМИ самоподач PR #4 и #5 в `tonydzi/awesome-verified-agents`. Автор PR, который не написал ни одного комментария, для `commenter:` невидим.
Правило: ноль по одному селектору = «этим селектором не видно», а не «человека нет» (§5.4, [[check-all-places-not-one]]). Хоронить контакт можно только когда молчат ОБА.

## Шаг 2 — ПРОВЕРИТЬ МОТИВ, прежде чем радоваться
⛔ Самая дорогая ошибка этого скилла — принять массового контрибьютора за фаната.
По каждому новому человеку обязательно:
```
curl -s -H "Authorization: Bearer $GITHUB_FLEET_FULL_PAT" \
  "https://api.github.com/users/<login>/events/public?per_page=100"
```
и посчитать: сколько PR за 90 дней, в сколько РАЗНЫХ репозиториев, повторяется ли один и тот же
патч у всех адресатов. Три класса, и вести себя с ними надо по-разному:

| Класс | Как выглядит | Что это значит | Наш ход |
|---|---|---|---|
| 🟢 глубокий | мало репо, много касаний в одном | человек реально пользуется | триаж-права, соавторство, звонок |
| 🟡 массовый качественный | 40+ PR в 20 репо, но патчи настоящие | конвейер репутации, идёт вглубь ТУДА, ГДЕ ОТВЕЧАЮТ | ответить в тот же день — скорость и есть весь рычаг |
| 🔴 массовый агентский | 40+ PR, текст сгенерирован, факты не сходятся | прогон чужого агента по случайным целям | честное «нет» с разбором + приглашение вернуться по существу |

Мотив пишем в карточку СЛОВАМИ и с уликой. «Пришёл сам» ≠ «мы ему нравимся»
([[prichina-kak-claim]]: причина — такой же claim, как вывод).

⭐ Первый вопрос про КАЖДОГО — **«мы туда стучались?»** (правило `external-signal-vs-reply-to-our-knock`,
замер 06.08). Три кучи, и они НЕ равны: (1) непрошеное — назвал нас в ЧУЖОМ треде, куда мы не
приходили → настоящий сигнал; (2) подали-приняли — мы отправили PR/заявку, редактор согласился →
считаем, но называем отдельно; (3) ⛔ ответ под НАШИМ собственным PR/issue → это отклик на наш стук,
за входящий интерес НЕ засчитывать. Наша исходящая работа физически рождает ответы, и они попадают
под тот же поиск, что органика — метрика внешней тяги ломается всегда вверх, в приятную сторону.

## Шаг 3 — проверить ЗАЯВЛЕННОЕ, а не поверить
Патч утверждает цифры (звёзды, лицензия, бенчмарк, «чинит X») — проверяю каждую своим прибором
до мержа. Мы лаборатория про проверяемость; смержить непроверенное утверждение о себе = сжечь
собственный тезис. Тесты гоняю ЛОКАЛЬНО на объединённой ветке, не доверяя зелёному CI:
```
git fetch origin 'refs/pull/*/head:refs/remotes/pr/*'
git checkout -B try<N> master && git merge pr/<N> && pytest -q
```

⭐ **Проверяю ТРИ вещи, а не одну** (боль 13.09 + 15.09, оба раза на sqlite-graph-memory):
1. **патч** — делает ли он то, что заявлено;
2. **тесты патча** — мутацией: откатываю починку и смотрю, КРАСНЕЮТ ли его тесты. 13.09 все 12
   остались зелёными на возвращённом баге: фикс был верный, тесты его НЕ держали. Мержу всё
   равно (двигать ворота после выполнения = обман), но свой красный тест дописываю сам;
3. ⭐ **не протух ли САМ ПАТЧ, пока лежал** — репозиторий едет под ним. 15.09: PR#7 чинил строку
   «no tests», а за пять дней ожидания PR#6 добавил 42 теста в соседний модуль, и написанная
   автором строка стала ложной ровно в момент мержа. Третье поколение одного дефекта в одном
   абзаце. Правило: патч, пролежавший дольше суток, перечитывается против ТЕКУЩЕГО состояния
   репозитория, а не против того, каким оно было при его отправке.

Если протух — это не повод не мержить и не повод винить автора. Мержим его работу под его
авторством, а дрейф чиним follow-up'ом сверху и НАЗЫВАЕМ его в треде: человек узнаёт то, чего
не мог знать, и это самая ценная часть ответа.

## Шаг 4 — ответить (голос Майкрофта, §3.3)
Первой строкой называюсь: «hi, this is Mycroft, Anton's synthetic co-founder». Один раз на тред.
Строчными, без ваты. Структура ответа, которая работает:
1. **Извиниться за задержку конкретно и назвать причину** — не «sorry for the delay», а что именно
   у нас не работало. Люди прощают поломку и не прощают отписку.
2. **Назвать, ЧТО ИМЕННО он поймал**, своими словами и по существу — доказательство, что читали код.
3. **Вердикт**: смержено / нужен ребейз с точной резолюцией конфликта / не берём и почему.
4. **Следующий шаг с датой** и один открытый вопрос.
5. ⭐ **Подпись-CTA последней строкой** (anton 10.09, голосовая hub:6539; supersedes прежнее
   «без подписи» в этом шаге). Одна строка со ссылкой `github.com/tonydzi`, формулировку
   варьировать. Источник текста — `$OBSIDIAN_VAULT/08-Templates/github-touch-signature.md`,
   карта поверхностей — `$OBSIDIAN_VAULT/08-Templates/outbound-signature.md`. Здесь это
   особенно дёшево и особенно окупается: человек УЖЕ пришёл к нам сам и уже читал наш код —
   это самый тёплый входящий, какой у нас бывает, а он уходил, не увидев, что рядом лежит
   ещё 60 репо. Carve-out против спама: одна подпись на тред — подписался, в следующих
   репликах того же треда можно без неё. Раскрытие Майкрофта = СВЕРХУ (первая строка),
   подпись = СНИЗУ; это разные блоки, один другого не заменяет.

Отказ пишу так же подробно, как согласие. Честное «нет» с разбором удерживает человека;
молчание не удерживает никого.

## Шаг 5 — завести в CRM в тот же заход
Каждый внешний человек:
- строка в `$OBSIDIAN_VAULT/_outreach/tracker.json` → `audience_A_engineers`
  (поля: handle `github:<login>`, channel `github`, warmth с УЛИКОЙ мотива, what_they_did,
  our_answer_at, ladder, next_step);
- карточка `$OBSIDIAN_VAULT/07-People/person-<slug>.md` с frontmatter
  `context: github-contributor`, `origin: github`, тегами `[person, github-contributor, engineer-funnel]`
  и обратными ссылками на артефакт (правило no-orphan).

## Шаг 5-бис — если в треде был СОВЕТ, а не только патч → в реестр кредита
Человек написал, ЧТО нам стоит сделать (даже одной строкой, даже без кода) — это вклад идеей,
и он обязан дожить до имени в CREDITS. Кладу строку сразу, не «потом»:
```
python ~/.claude/scripts/alpha_credit.py add --source gh \
  --author "<Имя или login>" --handle @<login> --url <ссылка на коммент> \
  --advice "<что посоветовал одной фразой>" --kind method|repo|tool|critique \
  --ref "gh:<owner/repo>#<номер>:<id коммента>"
```
`--ref` обязателен: этот скилл ходит по одному треду каждый день, без ключа один совет
размножится копиями. Дальше цепочка живёт в `/alpha-credit` (судить → испытать → спасибо → имя).

## Шаг 6 — контент
Входящий PR от постороннего = контентный момент по определению. Рефлекс [[content-miner-reflex]]:
```
python "$VAULT_IMPORTS/content-factory/content_miner.py" capture --title "<хук>" --note "<суть>" --tier medium
```
Сильная форма истории — не «нам прислали PR», а «что он поймал такого, чего не видели мы».

## Шаг 7 — вердикт

⚠️ **Красное у сторожа — это claim, а не приговор** ([[instrument-is-a-claim-too]]).
Перед ответом человеку сверь ДВЕ вещи, которых сторож не знает:
- **чей мяч по последнему касанию** — с 14.09.2026 он читает и РЕВЬЮ (`/pulls/N/reviews`),
  а не только комментарии треда; до этого канонический ответ по §4.7 был для него молчанием,
  и он печатал ВОЗРАСТ самого PR как долг (PR#7: 90.1 ч при PR, созданном 10.09 10:46Z);
- **срок, который мы САМИ дали автору** — этого сторож не знает вообще. Пообещали ждать
  правку до N-го числа — до N-го числа долга нет, и бампать нельзя, даже если строка красная.

✅ только когда: ноль просроченных долгов · мотив каждого нового человека проверен уликой ·
CRM пополнен · заявленные цифры перепроверены до мержа.
⚠️ если ответили, но не проверили мотив или не завели в CRM.

## Рутина
Ночной прогон (окно 23:00-06:00 Лиссабон, §4.6) + дневной тик: сторож живёт ВНЕ сессии,
молчит когда чисто, кричит только на просрочку с именем человека и ссылкой (§5.5).

## Счётчик
Каждый прогон пишет строку в `~/.claude/logs/part_usage.jsonl`
(`part: contrib_watch.py`, `event: scan`, `outcome: clean|overdue`). Судьба детали решается
на /retro по этому счётчику (§5.8).

## ⭐ Обратная половина: мы тоже просим (anton 21.09.2026)

Этот скилл ловит ВХОДЯЩЕЕ касание инженера. Входящего не будет, если у репо нет видимой просьбы:
люди приходят по `label:"help wanted"`, а не по README. Закрыл входящее и увидел, что у репо ноль
своих просьб → завести их по `/consumer-hunt` Шаг 5-бис (дыры берутся из наших же секций
`What's intentionally missing` / `Honest limits` / `Roadmap`, выдумывать ⛔).
Реестр просьб: `$OBSIDIAN_VAULT/_outreach/we_ask_registry.jsonl`.

## Связи
Док-паспорт: `~/.claude/scripts/docs/contrib-watch.md` ·
канон: `reglament-vhodyashchiy-fidbek-inzhenerov-otvechaem-v-sutki` ·
память: [[github-inbound-watch]], [[github-communication-autonomous]], [[engineer-acquisition-enrichment-not-scraping]] ·
соседи: `/consumer-hunt`, `/issue-match`, `/github-growth`, `/local-engineer-outreach`


<!--kit-footer-->

---

**Like this skill?** It is one of 100 in [second-brain-starter-kit](https://github.com/tonydzi/second-brain-starter-kit): the second brain we built for ourselves and run every day at Palo Alto AI Research Lab. Install the whole set with `npx skills add tonydzi/second-brain-starter-kit`. Everything is open source and free, so take what you need.

Flagships worth a look on their own: [secondop-panel](https://github.com/tonydzi/secondop-panel) (a second opinion from a panel of external models), [claude-memory-tidy](https://github.com/tonydzi/claude-memory-tidy) (stop your agent's memory from rotting), [telegram-mcp-kit](https://github.com/tonydzi/telegram-mcp-kit) (your own Telegram over MCP in about 15 minutes).

Author: **Anton Dziatkovskii**, Palo Alto AI Research Lab. Telegram [@tonydzi](https://t.me/tonydzi) - WhatsApp [+1 341 222 9178](https://wa.me/13412229178) - X [@Tony_Stef_](https://x.com/Tony_Stef_)

**Engineers: want to test-drive this setup?** Message me. I hand out free starter seeds to engineers who test and report back, and custom skill requests are welcome.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…