skills(running-tend): move outage recovery upstream into tend - #3742
Conversation
|
this whole section seems like it should be in tend rather than worktrunk? if so, put a small PR into tend and remove from worktrunk |
|
Agreed — nothing in it was worktrunk-specific. Opened max-sixty/tend#851, which adds the section to tend's bundled This PR now just deletes the section — the three-line correction it originally carried is folded into the upstream text. One sequencing note: merging here before #851 lands leaves a gap with no drain guidance in either place, costing at most one daily sweep (the outage issue accumulates rather than losing rows), so holding this until upstream merges is the safer order if you'd rather not have the window. |
## Problem Gap 2 of #816: a `tend-outage` row names the trigger a dead session stranded, but nothing re-runs it. `tend-review` fires only on `pull_request_target`, so a PR whose one review attempt died stays unreviewed until someone happens to push again — and the outage issue that recorded it stays open, folding the next incident into a stale one. The recovery shape has been running in worktrunk's `running-tend` overlay since the incident that filed #816, across two outages of both flavours (a 5-hour session-limit exhaustion and a weekly-limit exhaustion). It is generic — every consumer running `tend-review` on `pull_request_target` loses reviews the same way — so worktrunk's maintainer asked for it upstream rather than kept per-repo ([max-sixty/worktrunk#3742](max-sixty/worktrunk#3742 (comment))). The companion PR removes it from worktrunk's overlay once this lands. ## Solution One section in the bundled `review-runs` skill, at the end of Step 1 where failed runs are already being classified. Four rules, each a recipe: - **Find** the open `tend-outage` issue and extract its run/trigger rows. Empty on most days, so the check is a cheap no-op. - **Diagnose before re-running.** The issue body says only "The bot failed to process a request". The annotation is the cheapest next look — and #818, if it lands, makes it name the cause on the most common path — but when it doesn't, the session log carries the `<synthetic>` message. Both subscription limits are listed, because they reset on different clocks: assuming the session window's reset understates a weekly exhaustion, which can strand most of a day. - **Re-run only what won't recover on its own.** Scheduled workflows come back on their next cron tick; only event-triggered runs (`review`, `mention`, `triage`, `ci-fix`) strand. Confirm the work is still missing first — a later push often re-triggers the workflow by itself. - **Order the re-run after a clean run**, not after an assumed clock. Re-running into a still-exhausted quota just refills the outage issue with fresh rows. Closing the drained issue is part of the recipe: `report-failure.sh` auto-closes only duplicates from the create-create race, never the surviving issue. ## Testing Documentation only — no generator or action code paths change, so there is nothing for `wt test` to exercise. The commands in the section are the ones worktrunk's sweep has been running: the `grep -oE 'runs/[0-9]+|\| #[0-9]+'` extraction matches the row format `report-failure.sh` emits (`| ${TIMESTAMP} | [workflow run](${RUN_URL}) | ${REF} |`), and the workflow-trigger split is read off the generator templates — `review.yaml.j2` is `pull_request_target`, `ci-fix.yaml.j2` is `workflow_run`, `mention.yaml.j2` is `issue_comment` plus the relayed dispatch, `triage` is `issues`, and `scheduled.yaml.j2`/`notifications.yaml.j2` are `schedule`. ## Scope Skill guidance only, and deliberately not the automated recovery pass #816 sketched — that carries the design tradeoffs #818 flagged (which workflows, the quota-window ordering, confirming the work is still missing). Those are exactly the judgements a skill can make per-case and a script cannot, so the agent-driven half is worth having whether or not a deterministic pass ever lands. Textually disjoint from the other open outage-path changes: #818 is in `claude/action.yaml`, #823 and #836 and #809 are in `shared/steps/report-failure.sh`. Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
Removes the Outage Recovery section from the overlay; the guidance now lives in tend's bundled
review-runsskill, proposed in max-sixty/tend#851.Why upstream. Nothing in the section was worktrunk-specific: the
tend-outageissue shape, thepull_request_target-only trigger that makes a deadtend-reviewunrecoverable, the session-log message that names the quota limit, and the scheduled-vs-event-triggered split are all properties of tend itself. Every consumer runningtend-reviewloses reviews the same way. That was already the disposition in max-sixty/tend#816 (Gap 2), which the upstream PR closes out.What changed from the original PR. This branch first carried a three-line correction naming the second subscription limit. That correction is folded into the upstream section instead, so the net diff here is the removal.
Sequencing. Merging this before #851 lands leaves a window with no drain guidance in either place. The window costs one daily sweep at most, and the outage issue accumulates rather than losing data, so it's a maintainer call whether to hold this until upstream merges.