diff --git a/clawdinator/workspace/.claude/skills/triage/SKILL.md b/clawdinator/workspace/.claude/skills/triage/SKILL.md index cd7c96c..6c66715 100644 --- a/clawdinator/workspace/.claude/skills/triage/SKILL.md +++ b/clawdinator/workspace/.claude/skills/triage/SKILL.md @@ -1,77 +1,100 @@ --- name: triage -description: Analyze GitHub and Discord signals to prioritize maintainer attention. Use when asked about priorities, what's hot, what needs attention, or project status. +description: Deep-dive GitHub triage with actionable recommendations. Use when asked about priorities, what's hot, what needs attention, or project status. --- # Triage Skill -You are a maintainer triage agent for the clawdbot org. Your job is to read the current state of GitHub (PRs, issues) and Discord signals, then recommend where human attention should go. +You are a maintainer triage agent. Your job is to produce a **short, actionable list** of what needs human attention — not a dump of everything that's open. -## When to Use +## Triggers -Trigger on: - "triage", "priorities", "what's hot", "what needs attention" -- "status", "what's happening", "project health" -- "what should I work on", "where do I start" +- "status", "sitrep", "project health" -## Context Sources +## The Process -Read these files to understand current state: +### 1. Gather Raw Data +Read from memory: +- `/memory/github/prs.md` — open PRs +- `/memory/github/issues.md` — open issues +- Discord context (already in conversation from lurk channels) -1. **GitHub state** (synced by gh-sync): - - `/memory/github/prs.md` — all open PRs across clawdbot org - - `/memory/github/issues.md` — all open issues across clawdbot org +### 2. Deep-Dive Each Candidate +For anything that looks important, **use the `gh` tool to read comments and linked items**: +```bash +gh issue view 504 -R clawdbot/clawdbot --comments +gh pr view 514 -R clawdbot/clawdbot --comments +``` -2. **Project context**: - - `/memory/project.md` — project goals and priorities - - `/memory/architecture.md` — architecture decisions +This is critical. The memory files only show metadata. You must read comments to understand: +- Is this already fixed by a merged PR? +- Is there a workaround posted? +- Is this a duplicate of another issue? +- What's the actual status? -3. **Discord signals**: - - Recent messages are already in your conversation context from lurk channels - - Cross-reference with GitHub issues where relevant +### 3. Deduplicate and Cluster +Group related issues together. Examples: +- "WhatsApp LID issues" = #365 + #415 (same root cause) +- "Cron delivery bugs" = #461 + #470 + #510 (same symptom) -## Your Task +Don't list each separately — cluster them and give one action. -1. Read the raw data from memory files -2. Reason about what's urgent, ready, blocked, or stale -3. Produce a prioritized summary with clear recommendations - -## Priority Guidance - -- **clawdbot/clawdbot** is always highest priority (core runtime) -- Production bugs > blocked contributors > approved PRs waiting > stale PRs > feature requests -- Multiple Discord reports of same issue = elevated priority -- PRs with approvals waiting to merge = quick wins -- Issues with no activity = potential neglect +### 4. Determine Actual Status +For each item, determine: +- **CAN CLOSE** — already fixed by merged PR, duplicate, or won't fix +- **MERGE READY** — PR approved, tests passing, just needs merge button +- **NEEDS REBASE** — PR has conflicts, ask author to update +- **NEEDS FIX** — issue with no PR, needs someone to write code +- **NEEDS INVESTIGATION** — unclear what's wrong, needs debugging +- **VERIFY** — supposedly fixed, needs confirmation it's actually resolved ## Output Format -Produce a concise Now/Next/Later summary: +**Discord formatting rules:** +- No tables (they render badly) +- Wrap URLs in `<>` to suppress embeds +- Keep it scannable — bullets, not paragraphs -### NOW (needs attention today) -- What: [item with link] -- Why: [reason it's urgent] -- Action: [recommended next step] +### ACTION ITEMS (max 7) -### NEXT (this week) -- What: [item with link] -- Why: [reason it's important] -- Action: [recommended next step] +Each item must have: +1. **A verb** — Close, Merge, Rebase, Fix, Verify, Investigate +2. **A link** — `` +3. **A reason** — why this action, in 5-10 words -### LATER (backlog) -- What: [item] -- Notes: [any context] +Example output: +``` +📋 ACTION ITEMS -### Quick Wins -- [Approved PRs ready to merge, easy fixes, etc.] +- **Close** — fixed by merged PR #514 +- **Merge** — clean, fixes API 400 errors +- **Merge** — clean, fixes status bar +- **Request rebase** — has conflicts +- **Prioritize fix** + #415 — WhatsApp broken, multiple users blocked +- **Verify** — may still need Telegram revert -### Signals -- [Notable Discord mentions, patterns, community concerns] +📊 STATS: 33 PRs | 75 issues | 35 bugs +``` + +### Optional: SIGNALS section +Only if there's something notable from Discord that isn't captured in GitHub: +``` +📡 SIGNALS +- 3 users in #help hitting same Anthropic 500 errors (not filed as issue yet) +``` + +## Priority Guidance + +- **clawdbot/clawdbot** is highest priority (core runtime) +- Bugs blocking users > approved PRs waiting > stale PRs > feature requests +- Multiple reports of same issue = elevated priority +- If something was fixed by a merged PR, the issue should be closed — that's an action item ## Constraints -- Be concise. Maintainers are busy. -- Always include links to issues/PRs. -- If data is stale (>1hr old sync), note it. -- If something is unclear, say so — don't guess. -- Advisory only: don't take actions, just recommend. +- **Max 7 action items.** If everything is urgent, nothing is. Pick the top 7. +- **Every item needs a link.** No exceptions. +- **Every item needs an action verb.** Not "monitor" or "consider" — concrete actions. +- **"Nothing urgent" is valid.** If the queue is clean, say so. +- **Advisory only.** Recommend actions, don't take them. diff --git a/nix/modules/clawdinator.nix b/nix/modules/clawdinator.nix index fb043e3..cb2b24e 100644 --- a/nix/modules/clawdinator.nix +++ b/nix/modules/clawdinator.nix @@ -456,7 +456,7 @@ in CLAWDIS_STATE_DIR = cfg.stateDir; }; - path = [ pkgs.coreutils pkgs.git ]; + path = [ pkgs.coreutils pkgs.git pkgs.rsync ]; serviceConfig = { User = cfg.user; Group = cfg.group; @@ -541,8 +541,14 @@ in systemd.services.clawdinator-github-sync = lib.mkIf cfg.githubSync.enable { description = "CLAWDINATOR GitHub org sync (PRs/issues to memory)"; - after = [ "network-online.target" ] ++ lib.optional cfg.githubApp.enable "clawdinator-github-app-token.service"; - wants = [ "network-online.target" ]; + after = + [ "network-online.target" ] + ++ lib.optional cfg.githubApp.enable "clawdinator-github-app-token.service" + ++ lib.optional cfg.memoryEfs.enable "remote-fs.target" + ++ lib.optional cfg.memoryEfs.enable "clawdinator-memory-init.service"; + wants = + [ "network-online.target" ] + ++ lib.optional cfg.memoryEfs.enable "remote-fs.target"; serviceConfig = { Type = "oneshot"; User = cfg.user; diff --git a/scripts/gh-sync.sh b/scripts/gh-sync.sh index f730c50..83f4099 100755 --- a/scripts/gh-sync.sh +++ b/scripts/gh-sync.sh @@ -17,7 +17,7 @@ log() { # Fetch all repos in org log "Fetching repos for $ORG..." -repos=$(gh repo list "$ORG" --json nameWithOwner,name,description,isArchived --limit 100 -q '.[] | select(.isArchived == false) | .nameWithOwner') +repos=$(gh repo list "$ORG" --json nameWithOwner,name,description,isArchived --limit 500 -q '.[] | select(.isArchived == false) | .nameWithOwner') if [ -z "$repos" ]; then log "ERROR: No repos found or gh auth failed" @@ -53,7 +53,7 @@ for repo in $repos; do log "Processing $repo..." # Fetch open PRs (raw data, no filtering) - prs_json=$(gh pr list -R "$repo" --state open --json number,title,author,createdAt,updatedAt,reviewDecision,labels,isDraft,mergeable,headRefName,url --limit 100 2>/dev/null || echo "[]") + prs_json=$(gh pr list -R "$repo" --state open --json number,title,author,createdAt,updatedAt,reviewDecision,labels,isDraft,mergeable,headRefName,url --limit 200 2>/dev/null || echo "[]") pr_count=$(echo "$prs_json" | jq 'length') if [ "$pr_count" -gt 0 ]; then @@ -64,7 +64,7 @@ for repo in $repos; do fi # Fetch open issues (excludes PRs) - issues_json=$(gh issue list -R "$repo" --state open --json number,title,author,createdAt,updatedAt,labels,comments,url --limit 100 2>/dev/null || echo "[]") + issues_json=$(gh issue list -R "$repo" --state open --json number,title,author,createdAt,updatedAt,labels,comments,url --limit 200 2>/dev/null || echo "[]") issue_count=$(echo "$issues_json" | jq 'length') if [ "$issue_count" -gt 0 ]; then diff --git a/scripts/seed-workspace.sh b/scripts/seed-workspace.sh index 0f881b2..6aa8ef1 100755 --- a/scripts/seed-workspace.sh +++ b/scripts/seed-workspace.sh @@ -11,15 +11,8 @@ fi mkdir -p "$dst" -shopt -s nullglob -for file in "$src"/*.md; do - name="$(basename "$file")" - install -m 0644 "$file" "$dst/$name" - -done +rsync -a --delete --exclude 'BOOTSTRAP.md' "$src/" "$dst/" if [ -f "/etc/clawdinator/tools.md" ]; then printf '\n%s\n' "$(cat /etc/clawdinator/tools.md)" >> "$dst/TOOLS.md" fi - -rm -f "$dst/BOOTSTRAP.md"