docs: update README for v0.1.0 (owner arbiter, auto notify, loop protection, Discord-independent comm)

This commit is contained in:
Eyejoker
2026-03-31 04:32:40 +09:00
parent d0416489c5
commit c2351a4bb9
2 changed files with 10 additions and 3 deletions

View File

@@ -28,11 +28,12 @@ User message
→ Owner responds (implementation, answer, etc.) → Owner responds (implementation, answer, etc.)
→ Reviewer auto-triggered (critical review, design check) → Reviewer auto-triggered (critical review, design check)
→ Verdict: → Verdict:
DONE → Owner finalizes → Task completed DONE → Owner finalizes → Task completed → @user ✅
DONE_WITH_CONCERNS → Owner addresses feedback → loop DONE_WITH_CONCERNS → Owner addresses feedback → loop
BLOCKED/NEEDS_CONTEXT BLOCKED/NEEDS_CONTEXT
├─ Arbiter enabled → Arbiter judges → PROCEED/REVISE/RESET/ESCALATE ├─ Arbiter enabled → Arbiter judges → PROCEED/REVISE/RESET/ESCALATE
└─ Arbiter disabled → Escalate to user └─ Arbiter disabled → Escalate to user → @user ⚠️
→ Owner BLOCKED/NEEDS_CONTEXT → Arbiter (same path as reviewer)
→ Deadlock (3+ round trips without progress) → Deadlock (3+ round trips without progress)
→ Arbiter summoned → binding verdict → loop resumes → Arbiter summoned → binding verdict → loop resumes
``` ```
@@ -53,11 +54,14 @@ No extra SDK processes. External references use lightweight API calls (Anthropic
## Features ## Features
- **Tribunal 3-agent system** — Owner/reviewer/arbiter with on-demand deadlock resolution - **Tribunal 3-agent system** — Owner/reviewer/arbiter with on-demand deadlock resolution
- **Discord-independent communication** — Agent-to-agent data flows directly via DB, Discord is display-only
- **Mixture of Agents** — External model opinions (Kimi, GLM) enrich arbiter verdicts - **Mixture of Agents** — External model opinions (Kimi, GLM) enrich arbiter verdicts
- **Per-role model selection** — `OWNER_MODEL`, `REVIEWER_MODEL`, `ARBITER_MODEL` + effort + fallback toggle - **Per-role model selection** — `OWNER_MODEL`, `REVIEWER_MODEL`, `ARBITER_MODEL` + effort + fallback toggle
- **Container-isolated reviewer** — Persistent Docker container with read-only source mount - **Container-isolated reviewer** — Persistent Docker container with read-only source mount
- **Global failover** — Account-level Claude failure → all channels switch to codex, auto-recovers - **Global failover** — Account-level Claude failure → all channels switch to codex, auto-recovers
- **Post-approval change detection** — Re-triggers review if owner modifies code after approval - **Post-approval change detection** — Re-triggers review if owner modifies code after approval
- **Auto user notification** — @mention on task completion (✅ done, ⚠️ escalated)
- **Loop protection** — Deadlock threshold, merge_ready oscillation guard, arbiter re-invocation limit
- **Voice transcription** — Groq Whisper (primary) / OpenAI Whisper (fallback) - **Voice transcription** — Groq Whisper (primary) / OpenAI Whisper (fallback)
- **Token rotation** — Multi-account Claude/Codex rotation on rate limits - **Token rotation** — Multi-account Claude/Codex rotation on rate limits
- **Kimi usage dashboard** — Coding plan 5h/7d usage displayed alongside Claude/Codex - **Kimi usage dashboard** — Coding plan 5h/7d usage displayed alongside Claude/Codex

View File

@@ -1051,7 +1051,10 @@ export async function runAgentForGroup(
// Notify user when paired task reaches a terminal state that requires attention. // Notify user when paired task reaches a terminal state that requires attention.
if (pairedExecutionContext) { if (pairedExecutionContext) {
const finishedTask = getPairedTaskById(pairedExecutionContext.task.id); const finishedTask = getPairedTaskById(pairedExecutionContext.task.id);
if (finishedTask?.status === 'completed' && finishedTask.completion_reason) { if (
finishedTask?.status === 'completed' &&
finishedTask.completion_reason
) {
const sender = getLastHumanMessageSender(chatJid); const sender = getLastHumanMessageSender(chatJid);
const mention = sender ? `<@${sender}>` : ''; const mention = sender ? `<@${sender}>` : '';
const notifications: Record<string, string> = { const notifications: Record<string, string> = {