[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6XCBAEPZQTAS5FZYCPDEGAG":3,"skill-same:01M6XCBAEPZQTAS5FZYCPDEGAG":67},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":6,"ownerHtmlUrl":49,"ownerBlogUrl":50,"ownerDescription":51,"updatedAt":52,"install":53,"resources":66},"01M6XCBAEPZQTAS5FZYCPDEGAG","pipeline-monitor",null,"Monitor the workbuddy agent pipeline, detect stuck issues, zombie processes, and missed redispatches. Works for both the 3-unit bundle (supervisor + coordinator + worker) and single-process `serve`. Use when the user says 'monitor the pipeline', 'check workbuddy status', '监工', '看看跑完了没', or asks to watch issue progress.","Lincyaw\u002Fworkbuddy","Lincyaw","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F53161583?v=4","01M6XC87YTNETZ3AARKMHXJYJR","Aoyang Fang","01M6XC882ZSY5XBX2W6S88AGNH",2,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FLincyaw\u002Fworkbuddy\u002Fblob\u002Fmain\u002Fplugins\u002Fworkbuddy\u002Fskills\u002Fpipeline-monitor\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"monitor","pipeline monitor","pipeline","progress","status","when","single","for","agent pipeline","coordinator","unit","detect","issues","watch","worker","missed","issue","use","check","supervisor","2026-11-10 10:12:30",false,"---\nname: pipeline-monitor\ndescription: \"Monitor the workbuddy agent pipeline, detect stuck issues, zombie processes, and missed redispatches. Works for both the 3-unit bundle (supervisor + coordinator + worker) and single-process `serve`. Use when the user says 'monitor the pipeline', 'check workbuddy status', '监工', '看看跑完了没', or asks to watch issue progress.\"\n---\n\n# Pipeline Monitor\n\nInteractive skill that watches the workbuddy pipeline, diagnoses common\nfailure modes, and applies safe fixes. Works for both the v0.5+ default\n**bundle** topology (`supervisor` + `coordinator` + `worker` units) and\nthe legacy single-process **serve** mode.\n\n## When to use\n\n- User asks to monitor \u002F watch \u002F check the pipeline\n- User suspects issues are stuck or agents are failing\n- User wants a post-mortem on a completed batch\n- Background monitoring notified you that an agent completed or failed\n\n## Step 0: Detect deployment topology\n\n```bash\nps -eo pid,cmd | grep -E \"workbuddy (supervisor|coordinator|worker|serve)\" | grep -v grep\n```\n\n- **Bundle** (default since v0.5): three processes — `workbuddy supervisor`\n  + `workbuddy coordinator` + `workbuddy worker`. The supervisor owns the\n  agent subprocesses behind a unix socket, so the worker can be killed and\n  restarted without losing in-flight Claude\u002FCodex runs.\n- **Serve**: a single `workbuddy serve` process. Killing it kills agents.\n\nFor systemd installs, also run:\n\n```bash\nsystemctl --user status workbuddy-supervisor workbuddy-coordinator workbuddy-worker 2>\u002Fdev\u002Fnull \\\n  || systemctl --user status workbuddy\n```\n\nThe CLI surface is identical across both topologies — only the failure\nrecovery details differ (see \"Bundle vs serve recovery\" below).\n\n## What to check (every pass)\n\n1. **Issue state via CLI** — what workbuddy thinks is happening\n   ```bash\n   workbuddy status --repo Owner\u002FRepo\n   workbuddy status --stuck                 # issues idle >1h, or cycle counts > 0\n   workbuddy status --tasks --status running\n   workbuddy status --events --since 10m    # audit trail\n   ```\n\n2. **Automated diagnosis** — surfaces common patterns with suggested fixes\n   ```bash\n   workbuddy diagnose                      # scan\n   workbuddy diagnose --fix                # apply only safe fixes (cache invalidation etc.)\n   workbuddy diagnose --repo Owner\u002FRepo --format json   # for piping\n   ```\n\n3. **GitHub labels** — the ground truth, in case the local DB is stale\n   ```bash\n   gh issue view N -R Owner\u002FRepo --json labels,state,comments \\\n     --jq '{labels: [.labels[].name], state: .state, comments: (.comments | length)}'\n   ```\n\n4. **Agent processes** — what's actually running on the host\n   ```bash\n   ps -eo pid,etime,pcpu,cmd | grep -E \"codex.*exec|claude.*exec\" | grep -v grep\n   ```\n\n5. **Hooks** — operator-owned event hooks (cap-hit alerts, Slack pings, etc.)\n   ```bash\n   workbuddy hooks list\n   workbuddy hooks status --coordinator http:\u002F\u002F127.0.0.1:8081 \\\n     --token-file \u002Fhome\u002F$USER\u002F.config\u002Fworkbuddy\u002Fauth-token\n   ```\n\n6. **Operator incident inbox** — coordinator drops files here when something\n   needs human\u002FClaude attention (cap-hit, lost worker, dispatch refusal)\n   ```bash\n   ls -lt ~\u002F.workbuddy\u002Foperator\u002Finbox\u002F 2>\u002Fdev\u002Fnull\n   # operator-watch tails this and spawns Claude per incident\n   ```\n\n## Block until something happens\n\nPrefer `status --watch` over hand-rolled `until` loops:\n\n```bash\nworkbuddy status --watch --repo Owner\u002FRepo --issue N --timeout 30m\n```\n\nFor a free-form wait on labels:\n\n```bash\nuntil gh issue view N -R Owner\u002FRepo --json labels --jq '[.labels[].name]' \\\n      | grep -q \"status:done\"; do sleep 30; done\necho \"ISSUE_COMPLETED\"\n```\n\n## Direct DB peeks (when CLI isn't enough)\n\nUseful columns added since v0.4: `claim_token`, `acked_at`,\n`heartbeat_at`, `rollout_index`, `rollouts_total`, `rollout_group_id`.\n\n```bash\nsqlite3 .workbuddy\u002Fworkbuddy.db \u003C\u003C'SQL'\nSELECT agent_name, status, worker_id, heartbeat_at, lease_expires_at, created_at\n  FROM task_queue\n WHERE repo='Owner\u002FRepo'\n ORDER BY created_at DESC LIMIT 10;\nSQL\n```\n\nUseful event types: `state_entry`, `dispatch`, `completed`,\n`worker_registered`, `dispatch_blocked_by_dependency`, `claim_expired`,\n`poll_cycle_done`, `token_usage`.\n\nSince v0.6.24 the audit trail also carries the **self-healing** signals\ndescribed below: `dispatch_skipped_inflight` (with `source` of\n`statemachine`, `router`, or `resync`), `dispatch_skipped_agent_not_found`,\n`transition_skipped`, `task_reaped`, `periodic_recovery_tick`,\n`issue_resynced`, and `worker_tunnel_down` findings from `diagnose`.\n\n## Self-healing signals (since v0.6.24)\n\nThe coordinator runs three background loops that recover the pipeline\nwithout operator intervention. Recognising their event signatures saves\nchasing ghosts.\n\n- **5-minute snapshot resync** (`internal\u002Fpoller`): for every cached\n  open issue carrying a workflow trigger label, the poller re-emits an\n  `EventIssueResynced` state-entry. The state machine consults\n  `IsInflight` + `HasAnyActiveTask`; if either gates, you see\n  `dispatch_skipped_inflight` with `source=\"resync\"` and `trigger=\"issue_resynced\"`.\n  An `issue_resynced` audit row appears **only** when both guards pass\n  and the issue actually gets re-dispatched.\n  Healthy steady-state: many `dispatch_skipped_inflight` (one per\n  labeled issue per 5min), zero `issue_resynced`.\n- **60-second `task_queue` reaper** (`internal\u002Fapp\u002Ftask_reaper`): any\n  row with `status='running'` and a heartbeat older than 5 minutes (or\n  `NULL` heartbeat older than 5 min from `created_at`) is flipped to\n  `failed`, `exit_code=-2`, and a `task_reaped` event with\n  `{task_id, repo, issue_num, agent, worker_id, last_heartbeat_at, reason:\"no_heartbeat\"}`\n  is emitted. Watch this when a worker host dies or OOM-killer reaps\n  a supervisor.\n- **60-second periodic recovery sweep** (`PollerManager.recoverAllPeriodically`):\n  walks every active repo, calls `recoverOrphanedActiveStates`, and\n  emits `periodic_recovery_tick` with `{repos_swept, issues_redispatched}`.\n  After the reaper unblocks `HasAnyActiveTask`, this re-issues\n  `EventIssueCreated` so the issue gets re-dispatched.\n\nThese three together close the silent-stall pattern from issue #345\n(coordinator restart with cache already in sync → no events → nothing\ndispatches). If you see an issue stuck `developing` with the worker\nalive, **first check whether the recovery loop is firing** — a\nzero-count `periodic_recovery_tick` every 60 seconds confirms the\nloop is healthy and the issue truly is in-flight, not silently dropped.\n\n## Common failure modes & fixes\n\n### A. Issue not dispatched — missing `workbuddy` label\nSymptom: issue has `status:developing` but no task in queue.\n```bash\ngh issue edit N -R Owner\u002FRepo --add-label workbuddy\n```\n\n### B. Task stuck `running` with expired lease and no agent process\nSymptom: `task_queue.status=running`, `lease_expires_at` in the past,\nno codex\u002Fclaude process for it.\n\nSince v0.6.24 the `task_queue` reaper handles this automatically —\nwithin ~60s of the heartbeat aging past 5min, the row flips to\n`failed\u002Fexit_code=-2` and a `task_reaped` event fires. The next\n`periodic_recovery_tick` (also ~60s) re-issues `EventIssueCreated`\nand the state machine re-dispatches. Verify via:\n\n```bash\nworkbuddy status --events --since 5m --type task_reaped\nworkbuddy status --events --since 5m --type periodic_recovery_tick\n```\n\nIn **bundle** mode this is otherwise rare — the supervisor reconciles\nsurviving agents back to the worker on reattach. If the reaper hasn't\nfired yet and you don't want to wait, force it manually:\n\n```bash\nworkbuddy issue restart --repo Owner\u002FRepo --issue N \\\n  --coordinator http:\u002F\u002F127.0.0.1:8081 \\\n  --token-file \u002Fhome\u002F$USER\u002F.config\u002Fworkbuddy\u002Fauth-token\nworkbuddy cache invalidate --repo Owner\u002FRepo --issue N\n```\n\nIn **serve** mode (no supervisor), the reaper still runs as part of the\ncoordinator loop. Use `workbuddy recover --kill-zombies --prune-worktrees`\nonly when you need to clean up host-side worktrees \u002F pids;\nhand-editing `task_queue` rows remains discouraged (claim tokens \u002F\nheartbeats interact in non-obvious ways).\n\n### C. Worker not picking up a `pending` task\nSymptom: a `pending` task exists, but the worker is idle. Often an older\n`running` row with a stale lease blocks the claim query.\n```bash\nworkbuddy diagnose --fix          # reaps stale claims, invalidates cache\n# If still stuck after the next poll cycle:\nworkbuddy issue restart --repo Owner\u002FRepo --issue N\n```\n\n### D. Dev-agent self-blocks — missing Acceptance Criteria\nSymptom: dev-agent completes in ~1 min and sets `status:blocked`. Edit\nthe issue body to add a `## Acceptance Criteria` section, then:\n```bash\ngh issue edit N -R Owner\u002FRepo --remove-label 'status:blocked' --add-label 'status:developing'\nworkbuddy cache invalidate --repo Owner\u002FRepo --issue N\n```\n\n### E. Agent completes but doesn't change labels\nSymptom: task `completed`, agent process gone, but labels unchanged. The\nLLM didn't run the routing `gh issue edit`. The coordinator self-heals\nthis on the next poll, but you can shortcut:\n```bash\ngh issue edit N -R Owner\u002FRepo --remove-label 'status:developing' --add-label 'status:reviewing'\n```\n\n### F. Review sends issue back to developing (normal retry)\nLabel flips `reviewing → developing`. Do not intervene. The 3-cycle cap\n(REQ-055) auto-stops dispatch and posts a needs-human comment.\n\n### G. Coordinator not detecting label changes\nSymptom: labels changed on GitHub but no `state_entry` event.\n```bash\nworkbuddy cache invalidate --repo Owner\u002FRepo --issue N\n```\n\n### H. Codex stuck in API inference (most common runtime failure)\nSymptom: codex process alive at ~0% CPU, no children, no JSONL writes\nfor 10+ min. Often after the agent has already changed labels.\n```bash\n# Find the live session log\nls -lt .workbuddy\u002Fsessions\u002F | head\n# Confirm staleness\nfor f in .workbuddy\u002Fsessions\u002F*\u002Fcodex-exec.jsonl; do\n  age=$(( $(date +%s) - $(stat -c '%Y' \"$f\") ))\n  [ $age -gt 600 ] && echo \"STALE ($age s): $f\"\ndone\n# Confirm no child processes\npstree -p \u003Ccodex-pid>\n```\nFix: kill the codex pid. In **bundle** mode the worker reattaches and\nrecords a clean exit; in **serve** mode you may need\n`workbuddy recover --kill-zombies` to clean up. Then check labels — if\nthey already advanced, just `cache invalidate` and let the next poll\nmove on; otherwise `workbuddy issue restart`.\n\n### I. Issue claim stuck after coordinator crash (REQ-057\u002F059)\nSymptom: no dispatch even after `cache invalidate`; `diagnose` shows a\nclaim still held by a dead coordinator\u002Fworker.\n- Self-heal: claims have a TTL — wait for expiry, the next poll emits\n  `claim_expired` and overwrites.\n- Self-heal (v0.6.24+): the periodic-recovery sweep + reaper combo\n  picks up stale running rows within ~2 minutes total. Watch for\n  `task_reaped` followed by `periodic_recovery_tick` with\n  `issues_redispatched >= 1` and a fresh `dispatch` event for the issue.\n- Force: `workbuddy recover` clears local runtime state; for a remote\n  coordinator's in-memory inflight tracker, use\n  `workbuddy issue restart --coordinator \u003Curl>`.\n\n### N. Coordinator restart with cache already in sync (silent-stall, REQ-150\u002F151\u002F152, fixes #345)\nSymptom: coordinator was restarted; eligible issues sit at their\nexisting `status:reviewing` \u002F `status:developing` labels with no\n`task_enqueued`, no `dispatch`, no error — only `poll_cycle_done`\nevents appear.\n\nThis is the pre-v0.6.24 silent-stall. The poller diffs labels against\nits cache; when the cache is already in sync after restart, no event\nfires and the state machine is never invoked.\n\nSelf-heal (no manual action needed since v0.6.24):\n- Within 60s the periodic-recovery sweep enumerates cached open issues\n  carrying a workflow trigger label and re-emits `EventIssueCreated`\n  via `recoverOrphanedActiveStates`.\n- Within 5min the snapshot resync emits `EventIssueResynced` on every\n  poll cycle, redundant defense in case the recovery sweep is gated by\n  a stale `running` task row (which the reaper handles, see fix B).\n- Confirm by watching:\n  ```bash\n  workbuddy status --events --since 10m \\\n    --type periodic_recovery_tick \\\n    --type issue_resynced \\\n    --type dispatch_skipped_inflight\n  ```\n  Healthy cadence: 10 `periodic_recovery_tick` events + 2\n  `dispatch_skipped_inflight` (source=resync) per labeled issue in\n  10 minutes. Zero `issue_resynced` rows is **also healthy** — that\n  audit fires only when a resync actually re-dispatches.\n\n### J. Consecutive-failure cap reached (REQ-055)\nSymptom: `diagnose` reports \"dev-agent has failed 3 times in a row\",\ndispatch stops, issue gets a needs-human comment.\n- Read the latest comments: **\"Infra Error\"** header → launcher\u002Fruntime\n  crash (REQ-056), doesn't burn the budget; fix infra, then restart. A\n  plain **\"Failure\"** header → agent disagrees with the AC; tighten AC\n  or intervene.\n- Reset: fix the root cause, flip label back to `status:developing`,\n  `workbuddy cache invalidate --repo Owner\u002FRepo --issue N`.\n\n### K. Worktree setup failed — worker refuses to fall back to CWD (REQ-058)\nSymptom: issue comment \"worktree setup failed\"; task marked failed.\n```bash\nworkbuddy recover --prune-worktrees --dry-run    # preview\nworkbuddy recover --prune-worktrees              # apply\nworkbuddy issue restart --repo Owner\u002FRepo --issue N\n```\n\n### M. Issue not dispatching because a dependency is blocking it\nSymptom: issue is `status:developing` with the `workbuddy` label, no\nagent process, no `dispatch` event in `workbuddy status --events`. The\nissue may also carry a ? reaction added by workbuddy.\n\nThe Coordinator gates dispatch on `workbuddy.depends_on` declared in the\nissue body (YAML block under `## Dependencies`). When verdict is\n`blocked` or `needs_human`, dispatch is refused and a\n`dispatch_blocked_by_dependency` event is logged.\n\nDiagnose:\n```bash\nworkbuddy status --repo Owner\u002FRepo            # CYCLES + DEPENDENCY columns\nworkbuddy status --events --type dispatch_blocked_by_dependency --since 1h\nworkbuddy diagnose --repo Owner\u002FRepo          # surfaces malformed\u002Fcyclic deps\ngh issue view N -R Owner\u002FRepo --json body --jq .body | grep -A5 'workbuddy:'\n```\n\nFix by intent:\n- **Blocker really not done yet** → wait, or work the upstream issue.\n- **Blocker actually done, declaration stale** → edit the issue body to\n  drop the satisfied `depends_on` ref, then\n  `workbuddy cache invalidate --repo Owner\u002FRepo --issue N`.\n- **Need to override a real dependency for one run** → add the\n  `override:force-unblock` label (verdict flips to `override`). Don't\n  hand-toggle `status:blocked` — the Coordinator owns that label.\n- **Malformed `depends_on` ref** → `diagnose` points at the offending\n  line; fix the YAML, `cache invalidate`.\n- **Cross-repo ref** (`owner\u002Fother#N`) — accepted-but-unsupported in\n  v0.1; verdict goes to `needs_human` until the upstream lands or the\n  ref is removed.\n\n### L. Worker restart didn't kill agents — that's by design (bundle only)\nBundle mode preserves agent runs across worker restarts via the\nsupervisor socket. If you `systemctl --user restart workbuddy-worker`\nand `ps` still shows codex\u002Fclaude — that's correct, not a leak. The new\nworker reattaches and resumes the JSONL stream.\n\n## Bundle vs serve recovery cheat sheet\n\n| Symptom | Bundle (default) | Serve |\n|---|---|---|\n| Worker crashed mid-task | Supervisor keeps the agent; worker reattaches on restart | Agent dies with the process; use `recover --kill-zombies` |\n| Need to upgrade workbuddy without dropping runs | `workbuddy deploy upgrade --name workbuddy-worker` | Drain or accept downtime |\n| Local runtime cleanup | `workbuddy recover --prune-worktrees` (don't `--kill-zombies` lightly — supervisor is managing them) | `workbuddy recover --kill-zombies --prune-worktrees` |\n\n## Decision tree\n\n```\nDetect topology (bundle vs serve)\n│\n├─ workbuddy diagnose --repo … (start here, every time)\n│\n├─ Check GitHub labels for target issues\n│  ├─ All status:done → Report. Stop.\n│  ├─ status:developing\u002Freviewing + active agent process → Normal. Monitor.\n│  └─ Label unchanged for >10 min with no agent process → see fixes B\u002FE\u002FH\n│\n├─ workbuddy status --tasks --status running \u002F --stuck\n│  ├─ running + agent alive → Normal. Wait or `status --watch`.\n│  ├─ running + no agent → fix B\n│  ├─ pending + worker alive → fix C\n│  └─ no pending + labels unchanged → fix A or G\n│\n└─ Logs \u002F journal\n   ├─ journalctl --user -u workbuddy-coordinator -n 100   # bundle\n   ├─ journalctl --user -u workbuddy-worker      -n 100   # bundle\n   └─ journalctl --user -u workbuddy             -n 100   # legacy serve\n```\n\n## Reporting template\n\n```markdown\n## Pipeline Status Report\n\n| Issue | Repo | State | Cycles | Agent | Notes |\n|-------|------|-------|--------|-------|-------|\n| #37 | AegisLab | reviewing | 2\u002F3 | review-agent | In progress |\n| #88 | workbuddy | developing | 0\u002F3 | dev-agent | Started |\n\n**Topology:** bundle (supervisor + coordinator@127.0.0.1:8081 + 1 worker)\n**Repos:** Lincyaw\u002Fworkbuddy, OperationsPAI\u002FAegisLab\n**Live agents:** 1 codex\n**Interventions:** `issue restart` for #37 after stale claim\n```\n\n## Arguments\n\nOptional: `\u003Cowner\u002Frepo> \u003Cissue-numbers...>`\nExample: `\u002Fpipeline-monitor OperationsPAI\u002FAegisLab 37 42`\nIf omitted, monitor all repos and all open workbuddy-labeled issues.\n","# Pipeline Monitor\n\nInteractive skill that watches the workbuddy pipeline, diagnoses common\nfailure modes, and applies safe fixes. Works for both the v0.5+ default\n**bundle** topology (`supervisor` + `coordinator` + `worker` units) and\nthe legacy single-process **serve** mode.\n\n## When to use\n\n- User asks to monitor \u002F watch \u002F check the pipeline\n- User suspects issues are stuck or agents are failing\n- User wants a post-mortem on a completed batch\n- Background monitoring notified you that an agent completed or failed\n\n## Step 0: Detect deployment topology\n\n```bash\nps -eo pid,cmd | grep -E \"workbuddy (supervisor|coordinator|worker|serve)\" | grep -v grep\n```\n\n- **Bundle** (default since v0.5): three processes — `workbuddy supervisor`\n  + `workbuddy coordinator` + `workbuddy worker`. The supervisor owns the\n  agent subprocesses behind a unix socket, so the worker can be killed and\n  restarted without losing in-flight Claude\u002FCodex runs.\n- **Serve**: a single `workbuddy serve` process. Killing it kills agents.\n\nFor systemd installs, also run:\n\n```bash\nsystemctl --user status workbuddy-supervisor workbuddy-coordinator workbuddy-worker 2>\u002Fdev\u002Fnull \\\n  || systemctl --user status workbuddy\n```\n\nThe CLI surface is identical across both topologies — only the failure\nrecovery details differ (see \"Bundle vs serve recovery\" below).\n\n## What to check (every pass)\n\n1. **Issue state via CLI** — what workbuddy thinks is happening\n   ```bash\n   workbuddy status --repo Owner\u002FRepo\n   workbuddy status --stuck                 # issues idle >1h, or cycle counts > 0\n   workbuddy status --tasks --status running\n   workbuddy status --events --since 10m    # audit trail\n   ```\n\n2. **Automated diagnosis** — surfaces common patterns with suggested fixes\n   ```bash\n   workbuddy diagnose                      # scan\n   workbuddy diagnose --fix                # apply only safe fixes (cache invalidation etc.)\n   workbuddy diagnose --repo Owner\u002FRepo --format json   # for piping\n   ```\n\n3. **GitHub labels** — the ground truth, in case the local DB is stale\n   ```bash\n   gh issue view N -R Owner\u002FRepo --json labels,state,comments \\\n     --jq '{labels: [.labels[].name], state: .state, comments: (.comments | length)}'\n   ```\n\n4. **Agent processes** — what's actually running on the host\n   ```bash\n   ps -eo pid,etime,pcpu,cmd | grep -E \"codex.*exec|claude.*exec\" | grep -v grep\n   ```\n\n5. **Hooks** — operator-owned event hooks (cap-hit alerts, Slack pings, etc.)\n   ```bash\n   workbuddy hooks list\n   workbuddy hooks status --coordinator http:\u002F\u002F127.0.0.1:8081 \\\n     --token-file \u002Fhome\u002F$USER\u002F.config\u002Fworkbuddy\u002Fauth-token\n   ```\n\n6. **Operator incident inbox** — coordinator drops files here when something\n   needs human\u002FClaude attention (cap-hit, lost worker, dispatch refusal)\n   ```bash\n   ls -lt ~\u002F.workbuddy\u002Foperator\u002Finbox\u002F 2>\u002Fdev\u002Fnull\n   # operator-watch tails this and spawns Claude per incident\n   ```\n\n## Block until something happens\n\nPrefer `status --watch` over hand-rolled `until` loops:\n\n```bash\nworkbuddy status --watch --repo Owner\u002FRepo --issue N --timeout 30m\n```\n\nFor a free-form wait on labels:\n\n```bash\nuntil gh issue view N -R Owner\u002FRepo --json labels --jq '[.labels[].name]' \\\n      | grep -q \"status:done\"; do sleep 30; done\necho \"ISSUE_COMPLETED\"\n```\n\n## Direct DB peeks (when CLI isn't enough)\n\nUseful columns added since v0.4: `claim_token`, `acked_at`,\n`heartbeat_at`, `rollout_index`, `rollouts_total`, `rollout_group_id`.\n\n```bash\nsqlite3 .workbuddy\u002Fworkbuddy.db \u003C\u003C'SQL'\nSELECT agent_name, status, worker_id, heartbeat_at, lease_expires_at, created_at\n  FROM task_queue\n WHERE repo='Owner\u002FRepo'\n ORDER BY created_at DESC LIMIT 10;\nSQL\n```\n\nUseful event types: `state_entry`, `dispatch`, `completed`,\n`worker_registered`, `dispatch_blocked_by_dependency`, `claim_expired`,\n`poll_cycle_done`, `token_usage`.\n\nSince v0.6.24 the audit trail also carries the **self-healing** signals\ndescribed below: `dispatch_skipped_inflight` (with `source` of\n`statemachine`, `router`, or `resync`), `dispatch_skipped_agent_not_found`,\n`transition_skipped`, `task_reaped`, `periodic_recovery_tick`,\n`issue_resynced`, and `worker_tunnel_down` findings from `diagnose`.\n\n## Self-healing signals (since v0.6.24)\n\nThe coordinator runs three background loops that recover the pipeline\nwithout operator intervention. Recognising their event signatures saves\nchasing ghosts.\n\n- **5-minute snapshot resync** (`internal\u002Fpoller`): for every cached\n  open issue carrying a workflow trigger label, the poller re-emits an\n  `EventIssueResynced` state-entry. The state machine consults\n  `IsInflight` + `HasAnyActiveTask`; if either gates, you see\n  `dispatch_skipped_inflight` with `source=\"resync\"` and `trigger=\"issue_resynced\"`.\n  An `issue_resynced` audit row appears **only** when both guards pass\n  and the issue actually gets re-dispatched.\n  Healthy steady-state: many `dispatch_skipped_inflight` (one per\n  labeled issue per 5min), zero `issue_resynced`.\n- **60-second `task_queue` reaper** (`internal\u002Fapp\u002Ftask_reaper`): any\n  row with `status='running'` and a heartbeat older than 5 minutes (or\n  `NULL` heartbeat older than 5 min from `created_at`) is flipped to\n  `failed`, `exit_code=-2`, and a `task_reaped` event with\n  `{task_id, repo, issue_num, agent, worker_id, last_heartbeat_at, reason:\"no_heartbeat\"}`\n  is emitted. Watch this when a worker host dies or OOM-killer reaps\n  a supervisor.\n- **60-second periodic recovery sweep** (`PollerManager.recoverAllPeriodically`):\n  walks every active repo, calls `recoverOrphanedActiveStates`, and\n  emits `periodic_recovery_tick` with `{repos_swept, issues_redispatched}`.\n  After the reaper unblocks `HasAnyActiveTask`, this re-issues\n  `EventIssueCreated` so the issue gets re-dispatched.\n\nThese three together close the silent-stall pattern from issue #345\n(coordinator restart with cache already in sync → no events → nothing\ndispatches). If you see an issue stuck `developing` with the worker\nalive, **first check whether the recovery loop is firing** — a\nzero-count `periodic_recovery_tick` every 60 seconds confirms the\nloop is healthy and the issue truly is in-flight, not silently dropped.\n\n## Common failure modes & fixes\n\n### A. Issue not dispatched — missing `workbuddy` label\nSymptom: issue has `status:developing` but no task in queue.\n```bash\ngh issue edit N -R Owner\u002FRepo --add-label workbuddy\n```\n\n### B. Task stuck `running` with expired lease and no agent process\nSymptom: `task_queue.status=running`, `lease_expires_at` in the past,\nno codex\u002Fclaude process for it.\n\nSince v0.6.24 the `task_queue` reaper handles this automatically —\nwithin ~60s of the heartbeat aging past 5min, the row flips to\n`failed\u002Fexit_code=-2` and a `task_reaped` event fires. The next\n`periodic_recovery_tick` (also ~60s) re-issues `EventIssueCreated`\nand the state machine re-dispatches. Verify via:\n\n```bash\nworkbuddy status --events --since 5m --type task_reaped\nworkbuddy status --events --since 5m --type periodic_recovery_tick\n```\n\nIn **bundle** mode this is otherwise rare — the supervisor reconciles\nsurviving agents back to the worker on reattach. If the reaper hasn't\nfired yet and you don't want to wait, force it manually:\n\n```bash\nworkbuddy issue restart --repo Owner\u002FRepo --issue N \\\n  --coordinator http:\u002F\u002F127.0.0.1:8081 \\\n  --token-file \u002Fhome\u002F$USER\u002F.config\u002Fworkbuddy\u002Fauth-token\nworkbuddy cache invalidate --repo Owner\u002FRepo --issue N\n```\n\nIn **serve** mode (no supervisor), the reaper still runs as part of the\ncoordinator loop. Use `workbuddy recover --kill-zombies --prune-worktrees`\nonly when you need to clean up host-side worktrees \u002F pids;\nhand-editing `task_queue` rows remains discouraged (claim tokens \u002F\nheartbeats interact in non-obvious ways).\n\n### C. Worker not picking up a `pending` task\nSymptom: a `pending` task exists, but the worker is idle. Often an older\n`running` row with a stale lease blocks the claim query.\n```bash\nworkbuddy diagnose --fix          # reaps stale claims, invalidates cache\n# If still stuck after the next poll cycle:\nworkbuddy issue restart --repo Owner\u002FRepo --issue N\n```\n\n### D. Dev-agent self-blocks — missing Acceptance Criteria\nSymptom: dev-agent completes in ~1 min and sets `status:blocked`. Edit\nthe issue body to add a `## Acceptance Criteria` section, then:\n```bash\ngh issue edit N -R Owner\u002FRepo --remove-label 'status:blocked' --add-label 'status:developing'\nworkbuddy cache invalidate --repo Owner\u002FRepo --issue N\n```\n\n### E. Agent completes but doesn't change labels\nSymptom: task `completed`, agent process gone, but labels unchanged. The\nLLM didn't run the routing `gh issue edit`. The coordinator self-heals\nthis on the next poll, but you can shortcut:\n```bash\ngh issue edit N -R Owner\u002FRepo --remove-label 'status:developing' --add-label 'status:reviewing'\n```\n\n### F. Review sends issue back to developing (normal retry)\nLabel flips `reviewing → developing`. Do not intervene. The 3-cycle cap\n(REQ-055) auto-stops dispatch and posts a needs-human comment.\n\n### G. Coordinator not detecting label changes\nSymptom: labels changed on GitHub but no `state_entry` event.\n```bash\nworkbuddy cache invalidate --repo Owner\u002FRepo --issue N\n```\n\n### H. Codex stuck in API inference (most common runtime failure)\nSymptom: codex process alive at ~0% CPU, no children, no JSONL writes\nfor 10+ min. Often after the agent has already changed labels.\n```bash\n# Find the live session log\nls -lt .workbuddy\u002Fsessions\u002F | head\n# Confirm staleness\nfor f in .workbuddy\u002Fsessions\u002F*\u002Fcodex-exec.jsonl; do\n  age=$(( $(date +%s) - $(stat -c '%Y' \"$f\") ))\n  [ $age -gt 600 ] && echo \"STALE ($age s): $f\"\ndone\n# Confirm no child processes\npstree -p \u003Ccodex-pid>\n```\nFix: kill the codex pid. In **bundle** mode the worker reattaches and\nrecords a clean exit; in **serve** mode you may need\n`workbuddy recover --kill-zombies` to clean up. Then check labels — if\nthey already advanced, just `cache invalidate` and let the next poll\nmove on; otherwise `workbuddy issue restart`.\n\n### I. Issue claim stuck after coordinator crash (REQ-057\u002F059)\nSymptom: no dispatch even after `cache invalidate`; `diagnose` shows a\nclaim still held by a dead coordinator\u002Fworker.\n- Self-heal: claims have a TTL — wait for expiry, the next poll emits\n  `claim_expired` and overwrites.\n- Self-heal (v0.6.24+): the periodic-recovery sweep + reaper combo\n  picks up stale running rows within ~2 minutes total. Watch for\n  `task_reaped` followed by `periodic_recovery_tick` with\n  `issues_redispatched >= 1` and a fresh `dispatch` event for the issue.\n- Force: `workbuddy recover` clears local runtime state; for a remote\n  coordinator's in-memory inflight tracker, use\n  `workbuddy issue restart --coordinator \u003Curl>`.\n\n### N. Coordinator restart with cache already in sync (silent-stall, REQ-150\u002F151\u002F152, fixes #345)\nSymptom: coordinator was restarted; eligible issues sit at their\nexisting `status:reviewing` \u002F `status:developing` labels with no\n`task_enqueued`, no `dispatch`, no error — only `poll_cycle_done`\nevents appear.\n\nThis is the pre-v0.6.24 silent-stall. The poller diffs labels against\nits cache; when the cache is already in sync after restart, no event\nfires and the state machine is never invoked.\n\nSelf-heal (no manual action needed since v0.6.24):\n- Within 60s the periodic-recovery sweep enumerates cached open issues\n  carrying a workflow trigger label and re-emits `EventIssueCreated`\n  via `recoverOrphanedActiveStates`.\n- Within 5min the snapshot resync emits `EventIssueResynced` on every\n  poll cycle, redundant defense in case the recovery sweep is gated by\n  a stale `running` task row (which the reaper handles, see fix B).\n- Confirm by watching:\n  ```bash\n  workbuddy status --events --since 10m \\\n    --type periodic_recovery_tick \\\n    --type issue_resynced \\\n    --type dispatch_skipped_inflight\n  ```\n  Healthy cadence: 10 `periodic_recovery_tick` events + 2\n  `dispatch_skipped_inflight` (source=resync) per labeled issue in\n  10 minutes. Zero `issue_resynced` rows is **also healthy** — that\n  audit fires only when a resync actually re-dispatches.\n\n### J. Consecutive-failure cap reached (REQ-055)\nSymptom: `diagnose` reports \"dev-agent has failed 3 times in a row\",\ndispatch stops, issue gets a needs-human comment.\n- Read the latest comments: **\"Infra Error\"** header → launcher\u002Fruntime\n  crash (REQ-056), doesn't burn the budget; fix infra, then restart. A\n  plain **\"Failure\"** header → agent disagrees with the AC; tighten AC\n  or intervene.\n- Reset: fix the root cause, flip label back to `status:developing`,\n  `workbuddy cache invalidate --repo Owner\u002FRepo --issue N`.\n\n### K. Worktree setup failed — worker refuses to fall back to CWD (REQ-058)\nSymptom: issue comment \"worktree setup failed\"; task marked failed.\n```bash\nworkbuddy recover --prune-worktrees --dry-run    # preview\nworkbuddy recover --prune-worktrees              # apply\nworkbuddy issue restart --repo Owner\u002FRepo --issue N\n```\n\n### M. Issue not dispatching because a dependency is blocking it\nSymptom: issue is `status:developing` with the `workbuddy` label, no\nagent process, no `dispatch` event in `workbuddy status --events`. The\nissue may also carry a ? reaction added by workbuddy.\n\nThe Coordinator gates dispatch on `workbuddy.depends_on` declared in the\nissue body (YAML block under `## Dependencies`). When verdict is\n`blocked` or `needs_human`, dispatch is refused and a\n`dispatch_blocked_by_dependency` event is logged.\n\nDiagnose:\n```bash\nworkbuddy status --repo Owner\u002FRepo            # CYCLES + DEPENDENCY columns\nworkbuddy status --events --type dispatch_blocked_by_dependency --since 1h\nworkbuddy diagnose --repo Owner\u002FRepo          # surfaces malformed\u002Fcyclic deps\ngh issue view N -R Owner\u002FRepo --json body --jq .body | grep -A5 'workbuddy:'\n```\n\nFix by intent:\n- **Blocker really not done yet** → wait, or work the upstream issue.\n- **Blocker actually done, declaration stale** → edit the issue body to\n  drop the satisfied `depends_on` ref, then\n  `workbuddy cache invalidate --repo Owner\u002FRepo --issue N`.\n- **Need to override a real dependency for one run** → add the\n  `override:force-unblock` label (verdict flips to `override`). Don't\n  hand-toggle `status:blocked` — the Coordinator owns that label.\n- **Malformed `depends_on` ref** → `diagnose` points at the offending\n  line; fix the YAML, `cache invalidate`.\n- **Cross-repo ref** (`owner\u002Fother#N`) — accepted-but-unsupported in\n  v0.1; verdict goes to `needs_human` until the upstream lands or the\n  ref is removed.\n\n### L. Worker restart didn't kill agents — that's by design (bundle only)\nBundle mode preserves agent runs across worker restarts via the\nsupervisor socket. If you `systemctl --user restart workbuddy-worker`\nand `ps` still shows codex\u002Fclaude — that's correct, not a leak. The new\nworker reattaches and resumes the JSONL stream.\n\n## Bundle vs serve recovery cheat sheet\n\n| Symptom | Bundle (default) | Serve |\n|---|---|---|\n| Worker crashed mid-task | Supervisor keeps the agent; worker reattaches on restart | Agent dies with the process; use `recover --kill-zombies` |\n| Need to upgrade workbuddy without dropping runs | `workbuddy deploy upgrade --name workbuddy-worker` | Drain or accept downtime |\n| Local runtime cleanup | `workbuddy recover --prune-worktrees` (don't `--kill-zombies` lightly — supervisor is managing them) | `workbuddy recover --kill-zombies --prune-worktrees` |\n\n## Decision tree\n\n```\nDetect topology (bundle vs serve)\n│\n├─ workbuddy diagnose --repo … (start here, every time)\n│\n├─ Check GitHub labels for target issues\n│  ├─ All status:done → Report. Stop.\n│  ├─ status:developing\u002Freviewing + active agent process → Normal. Monitor.\n│  └─ Label unchanged for >10 min with no agent process → see fixes B\u002FE\u002FH\n│\n├─ workbuddy status --tasks --status running \u002F --stuck\n│  ├─ running + agent alive → Normal. Wait or `status --watch`.\n│  ├─ running + no agent → fix B\n│  ├─ pending + worker alive → fix C\n│  └─ no pending + labels unchanged → fix A or G\n│\n└─ Logs \u002F journal\n   ├─ journalctl --user -u workbuddy-coordinator -n 100   # bundle\n   ├─ journalctl --user -u workbuddy-worker      -n 100   # bundle\n   └─ journalctl --user -u workbuddy             -n 100   # legacy serve\n```\n\n## Reporting template\n\n```markdown\n## Pipeline Status Report\n\n| Issue | Repo | State | Cycles | Agent | Notes |\n|-------|------|-------|--------|-------|-------|\n| #37 | AegisLab | reviewing | 2\u002F3 | review-agent | In progress |\n| #88 | workbuddy | developing | 0\u002F3 | dev-agent | Started |\n\n**Topology:** bundle (supervisor + coordinator@127.0.0.1:8081 + 1 worker)\n**Repos:** Lincyaw\u002Fworkbuddy, OperationsPAI\u002FAegisLab\n**Live agents:** 1 codex\n**Interventions:** `issue restart` for #37 after stale claim\n```\n\n## Arguments\n\nOptional: `\u003Cowner\u002Frepo> \u003Cissue-numbers...>`\nExample: `\u002Fpipeline-monitor OperationsPAI\u002FAegisLab 37 42`\nIf omitted, monitor all repos and all open workbuddy-labeled issues.\n",{"name":5,"description":7},"main","b9778c800f442939b879c9a556dfb8d6f4a40971","plugins\u002Fworkbuddy\u002Fskills\u002Fpipeline-monitor",1,"https:\u002F\u002Fgithub.com\u002FLincyaw\u002Fworkbuddy","https:\u002F\u002Fgithub.com\u002FLincyaw","http:\u002F\u002Fprofile.aoyangfang.top\u002F","Student in The Chinese University of Hong Kong, Shenzhen","2026-06-08 13:33:51",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add Lincyaw\u002Fworkbuddy --skill pipeline-monitor",{"tool":59,"command":60},"bunx","bunx skills add Lincyaw\u002Fworkbuddy --skill pipeline-monitor",{"tool":62,"command":63},"pnpm","pnpm dlx skills add Lincyaw\u002Fworkbuddy --skill pipeline-monitor","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FLincyaw\u002Fworkbuddy\u002Fblob\u002Fmain\u002Fplugins\u002Fworkbuddy\u002Fskills\u002Fpipeline-monitor\u002FSKILL.md",true,[],[68,92,129,154,180,201],{"skillNo":69,"name":70,"nameZh":6,"description":71,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":74,"publishedAt":39},"01M6XCBSW1MMEAWEF38VX9NH3E","workbuddy-guide","Explain and operate workbuddy: what it is, which command to reach for, and where to find deeper references. **Trigger whenever the user mentions 'workbuddy' in any context** — including operational requests (register\u002Fonboard a repo, add\u002Fbind a worker, 注册仓库, 加仓库, 接入新仓库, onboard repo, set up worker), explanatory questions (how to use workbuddy, workbuddy guide, teach me workbuddy, 怎么用workbuddy, 使用指南), deployment\u002Frunning\u002Foperating\u002Fdebugging workbuddy, and questions about how issues\u002Ftasks are scheduled or how dependencies between issues work (depends_on, blocked, dependency gate, 依赖, 调度, 排队, '为什么没派发'), and questions about parallel-development workflows (rollouts:N fan-out, synthesize\u002Fsynthesis reduce step, cherry-pick, '并行开发', '多个方案', 'rollout'). Invoke this skill before running workbuddy CLI commands so the documented onboarding flow (coordinator register + worker repos add) and the dependency\u002Fscheduling model aren't re-derived from scratch.","https:\u002F\u002Fgithub.com\u002FLincyaw\u002Fworkbuddy\u002Fblob\u002Fmain\u002Fplugins\u002Fworkbuddy\u002Fskills\u002Fworkbuddy-guide\u002FSKILL.md",[],[75,76,77,31,78,79,80,81,82,83,33,84,85,86,28,87,88,89,90,91],"guide","workbuddy guide","debugging","SET","model","pick","up","rollouts","deeper","bind","how to","operating","re","operate","which","scheduled","invoke",{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":111,"publishedAt":39},"01M6XCBM7B95PB3Q6PHZ3TCM7F","web-debug","Validate the workbuddy webui (SPA + auth + JSON API) end-to-end on the same machine workbuddy runs on, using browser-use's headless harness. Use when the user says 'verify the frontend', 'test the SPA', 'check dashboard loads', '前端验证', '验下 webui', or after merging changes that touch internal\u002Fwebui, web\u002F, or the auth\u002Fcookie path.","https:\u002F\u002Fgithub.com\u002FLincyaw\u002Fworkbuddy\u002Fblob\u002Fmain\u002Fplugins\u002Fworkbuddy\u002Fskills\u002Fweb-debug\u002FSKILL.md",[98,103,106],{"categoryNo":99,"categoryName":100,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":104,"categoryName":105,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":107,"categoryName":108,"taxonomyType":109,"taxonomyTypeDesc":110},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[112,113,114,115,116,117,118,119,37,36,120,121,122,123,124,125,126,127,128,24],"web","debug","web debug","frontend","auth","browser","harness","api","webui","spa","end","machine","touch","loads","headless","browser-use","using browser",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":133,"categories":134,"keywords":138,"publishedAt":39},"01M6XCBFR925WJSWEYVHGSTT56","setup-repo","Configure a GitHub repository for workbuddy orchestration — creates labels, the two canonical agent configs (dev + review), workflow definitions, issue templates, and config.yaml. Use when the user says 'set up repo', 'configure repo for workbuddy', 'initialize workbuddy', '配置仓库', '初始化workbuddy', or wants to onboard a new repo.","https:\u002F\u002Fgithub.com\u002FLincyaw\u002Fworkbuddy\u002Fblob\u002Fmain\u002Fplugins\u002Fworkbuddy\u002Fskills\u002Fsetup-repo\u002FSKILL.md",[135],{"categoryNo":136,"categoryName":137,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000023","Skill与智能体开发",[139,140,141,142,143,144,145,146,147,78,148,149,81,35,150,151,152,26,153,24],"setup","setup repo","repo","review","orchestration","workflow","config","dev","repository","configure","initialize","new repo","初始化","canonical","labels",{"skillNo":155,"name":156,"nameZh":6,"description":157,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":158,"categories":159,"keywords":163,"publishedAt":39},"01M6XCB5RTYNH7QK9RQ5Z4B6NK","merge-flow","Merge a batch of approved workbuddy PRs into main: order them, resolve conflicts against design intent, validate post-merge health, and report. Use when the user asks to 'merge the batch', 'merge approved PRs', 'integrate finished issues', '批量合并', '处理冲突'; or when the merge-agent is invoked.","https:\u002F\u002Fgithub.com\u002FLincyaw\u002Fworkbuddy\u002Fblob\u002Fmain\u002Fplugins\u002Fworkbuddy\u002Fskills\u002Fmerge-flow\u002FSKILL.md",[160],{"categoryNo":161,"categoryName":162,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000015","视觉设计",[164,165,166,167,168,169,31,170,171,172,36,173,174,175,176,44,177,178,179,24],"merge","flow","merge flow","design","validate","report","batch","health","user","integrate","resolve conflicts","conflicts","intent","post","design intent","prs",{"skillNo":181,"name":182,"nameZh":6,"description":183,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":184,"categories":185,"keywords":189,"publishedAt":39},"01M6XCB29F96RJ02Z3BXTAVYSB","deploy","Workbuddy deployment topology guide — explains the 3-unit bundle (supervisor + coordinator + worker), the rolling-restart property, and the cutover from the legacy single-process `serve` install. Use when the user says 'how should I deploy workbuddy', 'install workbuddy as a service', 'switch to bundle', 'rolling restart', '部署 workbuddy', '升级到 bundle'.","https:\u002F\u002Fgithub.com\u002FLincyaw\u002Fworkbuddy\u002Fblob\u002Fmain\u002Fplugins\u002Fworkbuddy\u002Fskills\u002Fdeploy\u002FSKILL.md",[186],{"categoryNo":187,"categoryName":188,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000011","运维与部署",[182,190,191,192,38,193,194,75,36,195,196,33,197,198,199,200,29,28,25,24],"deployment","topology","how","process","install","Legacy","switch","service","as","bundle","serve",{"skillNo":202,"name":203,"nameZh":6,"description":204,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":205,"categories":206,"keywords":207,"publishedAt":39},"01M6XCB0SEG4W4RTFHFGXS7D51","example-skill","This description is intentionally long enough to satisfy the validator reliably.","https:\u002F\u002Fgithub.com\u002FLincyaw\u002Fworkbuddy\u002Fblob\u002Fmain\u002Finternal\u002Fvalidatedocs\u002Ftestdata\u002Fl4-pass\u002F.codex\u002Fskills\u002Fexample-skill\u002FSKILL.md",[],[208,209,210,211],"example skill","example","long","validator"]