协作头脑风暴
brainstorming
在实现前澄清需求、探索设计选择,并形成清晰的开发方向。
manage-engagement-buffer【开发与工程】Manage an engagement buffer that ingests, prioritizes, rate-limits, deduplicates, and tracks state for incoming engagement items across platforms. Generates periodic digests and enforces cooldown periods. Composes with du-dum: du-dum sets the observation/action cadence, this skill manages the queue between beats.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Eingehende Engagement-Items ueber Plattformen hinweg aufnehmen, deduplizieren, priorisieren und ratenbegrenzen, dann einen kompakten Digest an die Aktions-Uhr uebergeben. Der Buffer sitzt zwischen rohen Plattform-Signalen und absichtlicher Aktion: er absorbiert Schuebe, fusioniert Duplikate, erzwingt Cooldowns und stellt sicher dass der Agent zuerst auf die wertvollsten Items handelt. Ohne Buffer verarbeitet ein autonomer Agent entweder Items in Ankunftsreihenfolge (verfehlt dringliche die im Rauschen vergraben sind) oder versucht alles auf einmal (trifft Rate-Limits und erscheint spammig).
Dieser Skill komponiert mit du-dum: du-dum entscheidet wann zu beobachten und zu handeln; dieser Skill entscheidet was Aktion verdient. Der Buffer ist die Queue die zwischen du-dums Schlaegen akkumuliert.
buffer_path — Pfad zur JSONL-Buffer-Dateiplatform_config — Pro-Plattform-Rate-Limits und Cooldown-Einstellungendigest_size — Anzahl Top-Items im Digest (Standard: 5)ttl_hours — Time-to-Live fuer ungehandelte Items (Standard: 48)cooldown_minutes — Per-Thread-Cooldown nach Aktion (Standard: 60)Die Engagement-Item-Struktur entwerfen. Jedes Item im Buffer ist eine einzelne JSON-Zeile mit diesen Feldern:
{
"id": "gh-notif-20260408-001",
"source": "github:pjt222/agent-almanac",
"timestamp": "2026-04-08T09:15:00Z",
"content_summary": "PR #218 review requested by contributor",
"priority": 4,
"state": "new",
"dedup_key": "github:pjt222/agent-almanac:pr-218:contributor-name",
"thread_id": "pr-218",
"ttl_hours": 48
}
Feld-Definitionen:
| Feld | Typ | Beschreibung |
|---|---|---|
id | string | Einzigartiger Identifikator (Quell-Praefix + Datum + Sequenz) |
source | string | Plattform und Kanal (github:repo, slack:channel, email:inbox) |
timestamp | ISO 8601 | Wann das Item aufgenommen wurde |
content_summary | string | Einzeilige Beschreibung des Engagement-Items |
priority | int 1-5 | Composite-Prioritaet (siehe Schritt 4) |
state | enum | new, acknowledged, acted, cooldown, merged, expired |
dedup_key | string | Composite-Schluessel: source + thread + author |
thread_id | string | Konversations-Thread-Identifikator fuer Cooldown-Tracking |
ttl_hours | int | Stunden bis Item ablaeuft wenn ungehandelt (Standard: 48) |
Als JSON-Lines-Datei speichern (ein JSON-Objekt pro Zeile). Dieses Format unterstuetzt Append-Only-Writes, Line-by-Line-Verarbeitung und einfaches Pruning durch Neuschreiben ohne die abgelaufenen Zeilen.
Erwartet: Eine JSONL-Buffer-Datei initialisiert bei buffer_path mit dem Schema dokumentiert in einem Begleitkommentar oder Header. Das Schema ist stabil genug um alle nachgelagerten Schritte zu unterstuetzen.
Bei Fehler: Wenn die Buffer-Datei nicht erstellt werden kann (Berechtigungen, Pfad-Probleme), auf eine In-Memory-Liste fuer den aktuellen Zyklus zurueckfallen und den Dateisystem-Fehler loggen. Items nicht still fallen lassen — sie irgendwo buffern, auch temporaer.
Items von Plattform-Adaptern akzeptieren und an den Buffer mit initialen Prioritaets-Zuweisungen anhaengen.
Prioritaets-Zuweisung nach Item-Typ:
| Typ | Prioritaet | Begruendung |
|---|---|---|
| Direkter Mention (@agent) | 5 | Jemand hat explizit nach Aufmerksamkeit gefragt |
| Review-Anfrage | 4 | Blockiert die Arbeit eines anderen |
| Antwort in verfolgtem Thread | 3 | Aktive Konversation an der der Agent teilnimmt |
| Notification (zugewiesen, abonniert) | 2 | Informativ, kann Aktion erfordern |
| Broadcast (Release, Ankuendigung) | 1 | Nur Bewusstsein, selten umsetzbar |
Fuer jedes eingehende Item:
state auf new setzentimestamp auf aktuelle UTC-Zeit setzendedup_key aus source + thread + author generieren# Pseudocode: ingest from GitHub adapter
for notification in github_adapter.fetch():
item = build_item(notification)
item.priority = priority_by_type(notification.reason)
item.state = "new"
append_jsonl(buffer_path, item)
log("ingested {item.id} priority={item.priority}")
Erwartet: Neue Items erscheinen in der Buffer-Datei mit korrekten Prioritaeten und state=new. Jeder Adapter produziert wohlgeformte Items unabhaengig — Adapter-Versagen blockiert keine anderen Adapter.
Bei Fehler: Wenn ein Plattform-Adapter scheitert (Auth abgelaufen, Rate-limited, Netzwerk down), das Versagen loggen und diese Quelle fuer diesen Zyklus ueberspringen. Existierende Buffer-Items nicht loeschen — veraltete Items aus einem vorigen erfolgreichen Fetch sind besser als ein leerer Buffer.
Den Buffer nach Items mit demselben dedup_key innerhalb eines konfigurierbaren Fensters scannen (Standard: 24 Stunden). Die hoechste-Prioritaet-Instanz behalten und andere als merged markieren.
dedup_key gruppierenstate=merged markierenthread_id mit unterschiedlichen Autoren innerhalb 1 Stunde indiziert einen Aktivitaets-Schub — in ein einzelnes Item mit angehaengter Teilnehmer-Anzahl an content_summary konsolidieren# Dedup logic
groups = group_by(buffer, "dedup_key", window_hours=24)
for key, items in groups:
if len(items) > 1:
keeper = max(items, key=lambda i: (i.priority, i.timestamp))
for item in items:
if item.id != keeper.id:
item.state = "merged"
# Thread burst detection
thread_groups = group_by(buffer, "thread_id", window_hours=1)
for thread_id, items in thread_groups:
active_items = [i for i in items if i.state == "new"]
if len(active_items) >= 3:
keeper = max(active_items, key=lambda i: i.priority)
keeper.content_summary += f" ({len(active_items)} participants)"
for item in active_items:
if item.id != keeper.id:
item.state = "merged"
Erwartet: Der Buffer enthaelt keine doppelten dedup_key-Eintraege innerhalb des Fensters. Thread-Schuebe sind in einzelne Items mit Teilnehmer-Anzahlen kollabiert. Die merged Items bleiben in der Datei (fuer Audit) aber sind von nachgelagerter Verarbeitung ausgeschlossen.
Bei Fehler: Wenn Deduplizierung unerwartete Merges produziert (legitime distinkte Items teilen einen Schluessel), das Dedup-Fenster verengen oder die Schluessel-Konstruktion verfeinern. Einen Content-Hash zum Dedup-Schluessel hinzuzufuegen kann Items unterscheiden die source + thread + author teilen aber genuein unterschiedlichen Inhalt haben.
Den Buffer nach Composite-Score neu sortieren der Recency-Decay und Eskalation einbezieht.
Composite-Score-Formel:
score = base_priority * recency_weight * escalation_factor
recency_weight = 0.9 ^ hours_since_ingestion
escalation_factor = 1.0 + (resubmission_count * 0.2)
# Cap effective priority at 5
effective_priority = min(5, score)
Verhalten:
3 * 1,0 * 1,0 = 3,03 * 0,43 * 1,0 = 1,29 (zerfallen unter Prioritaet-2-Items)2 * 1,0 * 1,4 = 2,8 (eskaliert nahe Prioritaet-3)Alle state=new-Items nach effective_priority absteigend sortieren. Diese sortierte Reihenfolge ist was der Digest (Schritt 6) du-dum praesentiert.
Erwartet: Der Buffer ist nach Composite-Score sortiert. Frische hoch-prioritaere Items sind oben. Alte Items sind zerfallen. Neu eingereichte Items sind eskaliert. Kein Item ueberschreitet Prioritaet 5.
Bei Fehler: Wenn die Scoring-Formel unintuitive Rangordnungen produziert (z.B. ein 1-Stunden-altes Prioritaet-2-Item rangiert ueber einem frischen Prioritaet-3-Item), die Decay-Rate anpassen. Ein Decay von 0,95 pro Stunde ist sanfter; 0,85 pro Stunde ist aggressiver. Auf Engagement-Tempo abstimmen.
Verhindern dass der Agent ueber-engagiert durch Erzwingen von Pro-Plattform-Schreib-Limits und Per-Thread-Cooldowns.
Pro-Plattform-Rate-Limits (konfigurierbar via platform_config):
| Plattform | Default-Limit | Fenster |
|---|---|---|
| GitHub-Kommentare | 1 pro 20 Sekunden | rolling |
| GitHub-Reviews | 3 pro Stunde | rolling |
| Slack-Nachrichten | 1 pro 10 Sekunden | rolling |
| E-Mail-Antworten | 5 pro Stunde | rolling |
Per-Thread-Cooldown: Nachdem der Agent auf einem Thread handelt, tritt dieser Thread fuer cooldown_minutes (Standard: 60) in Cooldown. Waehrend Cooldown werden neue Items fuer diesen Thread aufgenommen aber nicht im Digest gezeigt.
Fehler-Backoff: Beim Erhalten einer 429/Rate-Limit-Antwort von irgendeiner Plattform den Cooldown fuer diese Plattform verdoppeln. Auf Default zuruecksetzen nach erfolgreicher Aktion.
# Rate limit check before action
def can_act(platform, thread_id):
if rate_limit_exceeded(platform):
return False, "rate limited"
if thread_in_cooldown(thread_id):
return False, "thread cooldown active"
return True, "clear"
# After action
def record_action(platform, thread_id):
increment_rate_counter(platform)
set_cooldown(thread_id, cooldown_minutes)
# After rate-limit error
def handle_rate_error(platform):
current_cooldown = get_platform_cooldown(platform)
set_platform_cooldown(platform, current_cooldown * 2)
Erwartet: Der Agent ueberschreitet Plattform-Rate-Limits nie. Threads haben erzwungene Cooldown-Perioden. Rate-Limit-Fehler triggern automatischen Backoff. Der Buffer akkumuliert Items waehrend Cooldown ohne sie zu verlieren.
Bei Fehler: Wenn Rate-Limits trotz Erzwingung getroffen werden (Clock-Skew, gleichzeitige Agents), die Sicherheits-Marge erhoehen — Limits auf 80% des tatsaechlichen Plattform-Limits setzen. Wenn Cooldowns zu aggressiv sind (verfehlen zeitkritische Threads), cooldown_minutes nur fuer hoch-prioritaere Threads reduzieren.
Eine kompakte Zusammenfassung fuer du-dums Aktions-Schlag produzieren. Der Digest ist der Uebergabepunkt: du-dum liest dies, nicht den rohen Buffer.
Digest-Inhalte:
state=new-Itemsdigest_size)# Engagement Digest — 2026-04-08T12:00:00Z
## Pending: 12 items
### Top 5 by Priority
| # | Priority | Source | Summary | Age |
|---|----------|--------|---------|-----|
| 1 | 5.0 | github:pr-218 | Review requested by contributor | 2h |
| 2 | 4.2 | github:issue-99 | Maintainer question (escalated) | 6h |
| 3 | 3.0 | slack:dev | Build failure alert | 1h |
| 4 | 2.8 | github:pr-215 | CI check feedback (3 participants) | 3h |
| 5 | 2.1 | email:inbox | Collaboration inquiry | 8h |
### Expiring Soon
- github:issue-85 — 4h remaining (TTL 48h, ingested 44h ago)
### Cooldowns Active
- pr-210: 22 min remaining
- issue-92: 45 min remaining
### Buffer Health
- Total items: 47 | New: 12 | Merged: 18 | Acted: 11 | Expired: 6
Den Digest in einen bekannten Pfad schreiben (z.B. buffer_path.digest.md) den du-dums Aktions-Uhr liest.
Erwartet: Ein Digest unter 50 Zeilen den du-dum in einem Read parsen kann. Der Digest enthaelt genuegend Information um zu entscheiden worauf zu handeln, aber nicht den vollen Buffer. Wenn nichts ansteht, sagt der Digest das klar.
Bei Fehler: Wenn der Digest ueber 50 Zeilen waechst, digest_size reduzieren oder die Expiring-/Cooldown-Abschnitte aggressiver zusammenfassen. Der Digest ist eine Zusammenfassung — wenn er sich der Groesse des Buffers naehert, hat er seinen Zweck verloren.
Nachdem du-dum Items aus dem Digest verarbeitet, ihre Zustaende aktualisieren und den Audit-Trail pflegen.
State-Machine:
new → acknowledged → acted → cooldown → expired
↑ │
└───── (re-ingested) ───┘
merged → (terminal, no further transitions)
expired → (terminal, archived)
Fuer jeden State-Uebergang:
state-Feld des Items in der Buffer-Datei aktualisieren{"item_id": "...", "from": "new", "to": "acknowledged", "timestamp": "...", "reason": "du-dum digest pickup"}Retention und Pruning:
state=acted oder state=expired aelter als 7 Tage archivieren (konfigurierbar)buffer_path.archive.jsonl), nicht loeschenstate=merged-Items aelter als 24 Stunden prunen (sie haben ihren Dedup-Zweck erfuellt)# End-of-cycle maintenance
for item in buffer:
if item.state == "new" and age_hours(item) > item.ttl_hours:
transition(item, "expired", reason="TTL exceeded")
if item.state in ("acted", "expired") and age_days(item) > retention_days:
archive(item)
if item.state == "merged" and age_hours(item) > 24:
archive(item)
rewrite_buffer(buffer_path, active_items_only)
Erwartet: Jeder State-Uebergang ist mit einem Zeitstempel und Grund geloggt. Die Buffer-Datei enthaelt nur aktive Items (new, acknowledged, cooldown). Archivierte Items werden separat fuer Audit erhalten. Der Buffer waechst nicht unbegrenzt.
Bei Fehler: Wenn die Buffer-Datei waehrend Rewrite korrupt wird (partieller Write, Crash), aus dem Pre-Rewrite-Backup wiederherstellen. Immer in eine Temp-Datei schreiben und atomar umbenennen — niemals in-place neu schreiben. Wenn das Archiv zu gross wird, monatlich komprimieren oder rotieren.
du-dum — Kadenz-Muster mit dem dieser Buffer komponiert; du-dum entscheidet wann zu beobachten und zu handeln, dieser Skill entscheidet was Aktion verdientmanage-token-budget — Kosten-Buchhaltung; der Buffer respektiert Token-Budget-Beschraenkungen beim Dimensionieren von Digests und Limitieren von Aktions-Durchsatzcircuit-breaker-pattern — Versagens-Behandlung fuer Plattform-Adapter die den Buffer speisen; wenn der Adapter-Circuit oeffnet, degradiert Ingestion anmutigcoordinate-reasoning — stigmergische Signale zwischen Buffer- und Aktions-Systemen; die Buffer-Datei selbst ist ein stigmergisches Artefaktforage-resources — Entdeckung neuer Engagement-Quellen die in die Ingestion-Adapter des Buffers gespeist werden