watch-pr
Watch an Elixir/Phoenix PR with an Amp Orb keep-alive lease until required non-deployment CI is green and review threads are resolved. Use after opening or updating a PR.
Install
npx skills add https://github.com/oliver-kriska/claude-elixir-phoenix/tree/main/scripts/port_lib/amp_overlay/watch-pr
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install oliver-kriska-claude-elixir-phoenix@llmmart
git clone https://github.com/oliver-kriska/claude-elixir-phoenix.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole oliver-kriska/claude-elixir-phoenix collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Watch PR — Amp-Native Lifecycle
Use the elixir_phoenix_watch_pr plugin tool. Do not launch gh pr checks --watch, gh run watch, a foreground sleep loop, or the copied Claude watcher
script: none of those owns an Amp Orb keep-alive lease.
Iron Laws
- Acquire one bounded keep-alive lease — start the plugin lifecycle once, then let its durable state and dedupe handle polling and plugin reloads.
- Deployment is never readiness — deployment, release, preview,
production, and prod checks are reported under
excludedChecks; they are never counted as passing or failing required CI. - Never merge or deploy — watching and
--fixauthorize neither action. --fixuses the same worker thread — the plugin serializes one concise event turn at a time and directs that turn to the installedphx-pr-reviewworkflow for actionable review feedback or failed required CI. Validate the cause before editing.- Every watch is bounded — timeout and every other terminal path release the lease. A timeout is incomplete, never success.
Start
Parse the PR number/URL and flags, then call:
elixir_phoenix_watch_pr {
"action": "start",
"pr": "<number-or-url>",
"checksOnly": false,
"fix": false
}
Map --checks-only and --fix to booleans. Map --max-hours,
--quiet-minutes, and --poll-seconds to maxDurationHours,
quietPeriodMinutes, and pollIntervalSeconds. Defaults are 2 hours maximum,
15 minutes quiet, and 60 seconds polling. Report the tool's initial snapshot
and then stop taking turns; the plugin wakes this thread only for actionable
failures or feedback and terminal outcomes.
Event Handling
- Unchanged snapshots do not wake the model.
- A changed head SHA resets readiness but does not itself wake the model.
- Failed or cancelled required non-deployment CI wakes the model once per distinct actionable snapshot. Pending and passing progress keeps polling inference-silent.
- Excluded deployment-like checks appear separately in explicit status and terminal summaries. Their transitions do not reset readiness or wake the model.
- Any unresolved review thread keeps the lease active.
- A head push, required-check transition, review, or comment resets the quiet clock. This includes a review with no unresolved thread or dedicated check, but routine non-actionable activity does not wake the model.
- With
--fix, unresolved feedback explicitly loadsphx-pr-review; required CI failures include check names and links. Re-fetch threads or inspect logs, fix only valid branch-owned causes, verify, push the authorized PR branch update, reply, and resolve where appropriate. Do not blindly rerun shared CI. - Required CI must remain green with zero unresolved threads and no relevant activity for the full quiet period before success releases the lease. Never accept an early green snapshot as immediate readiness.
Status and Stop
Use the same tool with "action": "status" or "action": "stop". Stop is
idempotent and releases the lease; it does not delete durable history.
Post-Completion Boundary
The plugin registers an optional durable Amp webhook and stores its bearer URL in the owner-only credential file reported by the tool. If a repository administrator configures GitHub to send PR review/check events to that URL, a later event can wake the paused Orb and probe the authoritative PR state. Webhook events must identify the exact watched PR number or current watched head SHA; empty or unrelated repository events are ignored.
The plugin never changes GitHub webhook settings. Without that external setup, polling ends after the quiet period and a later human comment cannot wake a paused Orb. Say this explicitly; do not imply polling continues after lease release.
Reference
references/watcher-mechanics.md— lease, durability, filtering, webhook, and billing behavior
Files (claude-elixir-phoenix)
-
references
-
watcher-mechanics.md 6.1 KB
# Amp Watcher Mechanics ## Lifecycle The generated plugin owns the lifecycle rather than a shell process: ```text start → validate PR → acquire keep-alive → persist snapshot → poll quietly ├─ required CI/reviews pending ───────────────────────────────┐ ├─ actionable failure/feedback → deduplicated event/fix turn ──┤ ├─ routine progress/activity → reset quiet, no model turn ─────┤ ├─ ready → 15-minute activity quiet window → release → success│ ├─ timeout/API error/closed/manual stop → release → incomplete│ └─ plugin reload → release old lease → recover state/lease ───┘ ``` Amp's normal inactivity pause is about five minutes. The default 15-minute quiet period covers delayed check-backed and account-level reviews while the lease—not an active model turn—keeps the Orb awake. A 60-second poll is responsive without paying for model inference on unchanged state. The 2-hour cap covers normal CI/review latency while limiting one HIGH worker to two Orb-hours; raise it only when a known slow pipeline justifies the added cost. All three values are configurable per watch within bounded ranges: | Setting | Default | Range | Tradeoff | | --- | ---: | ---: | --- | | Poll interval | 60 seconds | 30–300 seconds | Faster response versus more GitHub API traffic | | Quiet period | 15 minutes | 5–60 minutes | Catch delayed reviews versus extra Orb runtime after readiness | | Active duration | 2 hours | 0.5–24 hours | Slow-pipeline reliability versus a hard billing ceiling | ## Durable and Idempotent Processing Workspace Amp configuration stores watch identity, bound thread ID, options, deadline, latest head SHA, normalized check/thread snapshot hashes, pending fix event hash, and recent webhook IDs. Reload recovery reacquires a lease only for an active, unexpired watch. Amp dispose releases all process-owned leases; process exit also ends them server-side. Snapshot and fix markers are written into appended user messages. Before an append, the plugin scans recent full-thread messages for the marker. This makes the append idempotent across a crash between the thread side effect and the configuration update. `--fix` has one in-memory turn runner per PR, while its pending and in-flight hashes remain durable. Failed or cancelled required CI and unresolved threads share one actionable hash, so unchanged failures do not queue duplicate turns and new evidence waits for the current turn to finish. ## Readiness Contract `gh pr checks --required --json` is the source of required checks. Older GitHub CLI versions fall back to its non-interactive tabular output. Buckets `pass` and `skipping` are green; `pending`, `fail`, and `cancel` are not. Names and workflows matching deployment, deployments, deploy, release, preview, production, or prod are removed from readiness and retained in a separate excluded list. Optional non-deployment checks are not promoted to required checks. A draft PR is not ready. Every unresolved GitHub review thread—including outdated but unresolved threads—is actionable until the `phx-pr-review` turn validates and resolves or rejects it. Do not treat the first green snapshot as ready. For example, Enaia starts `Static checks`, `Design-system lifecycle`, `check_gettext`, `migration_check`, `check_dialyzer`, `test`, `Integration tests`, `Playwright E2E tests`, `Codex PR Review`, and aggregate `All checks`, while an account-level Codex review may arrive later without its own check. Each current head SHA change, required-check transition, review-thread change, top-level PR comment, and submitted review resets the 15-minute quiet clock. Jobs such as `deploy_branch`, `deploy_staging`, `draft_release`, and `tag_version` remain excluded and do not reset it. Polling and stabilization do not imply a model turn. Pending/passing required check transitions, head pushes, submitted reviews without an unresolved thread, and top-level comments reset the quiet clock but remain inference-silent. Deployment-like transitions are even quieter: they are persisted and reported by explicit status and terminal summaries, but neither reset the clock nor append a message. Only failed/cancelled required checks, unresolved threads, and terminal outcomes wake the model. With `--fix`, actionable evidence is appended to the same serialized worker thread with check names/links and unresolved-thread details. The turn may inspect logs, fix branch-owned causes, verify, and push the authorized branch; it must not blindly rerun shared CI, merge, or deploy. Without `--fix`, the same evidence is reported once for inspection rather than repaired. Review-thread GraphQL pagination is bounded at 1,000 threads. Exceeding that bound or receiving malformed/incomplete API data is a polling error, never a false green result. Five consecutive polling errors terminate incomplete and release the lease. ## Durable Webhook Reactivation `amp.createWebhook` registers a stable capability URL for the Orb thread and plugin. The URL is a bearer secret: it is written under `~/.config/amp/phx-watch-pr/` with owner-only permissions, never logged or put in a normal thread message. Payloads only select a repository plus an exact watched PR number or current watched head SHA; events that identify neither and unrelated status/check events are ignored. All evidence is re-fetched through authenticated `gh` calls and payload text is never used as agent instructions. Webhook delivery is at least once, so Amp event IDs are retained and snapshot markers deduplicate effects. A successful dormant watch reacts only to GitHub check/status/PR/review events. It acquires a lease and probes for two minutes to allow GitHub eventual consistency. No relevant change returns immediately to dormant success; changed CI, head, or review state starts a fresh bounded active window. Creating the GitHub repository webhook requires shared administration permission, so the plugin never does it automatically. Without external configuration, the 15-minute quiet window is the final opportunity to catch a comment before the Orb becomes eligible to pause.
-
-
SKILL.md 4.2 KB
--- name: watch-pr description: Watch an Elixir/Phoenix PR with an Amp Orb keep-alive lease until required non-deployment CI is green and review threads are resolved. Use after opening or updating a PR. effort: medium argument-hint: <PR number or URL> [--checks-only] [--fix] [--max-hours N] [--quiet-minutes N] --- # Watch PR — Amp-Native Lifecycle Use the `elixir_phoenix_watch_pr` plugin tool. Do not launch `gh pr checks --watch`, `gh run watch`, a foreground sleep loop, or the copied Claude watcher script: none of those owns an Amp Orb keep-alive lease. ## Iron Laws 1. **Acquire one bounded keep-alive lease** — start the plugin lifecycle once, then let its durable state and dedupe handle polling and plugin reloads. 2. **Deployment is never readiness** — deployment, release, preview, production, and prod checks are reported under `excludedChecks`; they are never counted as passing or failing required CI. 3. **Never merge or deploy** — watching and `--fix` authorize neither action. 4. **`--fix` uses the same worker thread** — the plugin serializes one concise event turn at a time and directs that turn to the installed `phx-pr-review` workflow for actionable review feedback or failed required CI. Validate the cause before editing. 5. **Every watch is bounded** — timeout and every other terminal path release the lease. A timeout is incomplete, never success. ## Start Parse the PR number/URL and flags, then call: ```text elixir_phoenix_watch_pr { "action": "start", "pr": "<number-or-url>", "checksOnly": false, "fix": false } ``` Map `--checks-only` and `--fix` to booleans. Map `--max-hours`, `--quiet-minutes`, and `--poll-seconds` to `maxDurationHours`, `quietPeriodMinutes`, and `pollIntervalSeconds`. Defaults are 2 hours maximum, 15 minutes quiet, and 60 seconds polling. Report the tool's initial snapshot and then stop taking turns; the plugin wakes this thread only for actionable failures or feedback and terminal outcomes. ## Event Handling - Unchanged snapshots do not wake the model. - A changed head SHA resets readiness but does not itself wake the model. - Failed or cancelled required non-deployment CI wakes the model once per distinct actionable snapshot. Pending and passing progress keeps polling inference-silent. - Excluded deployment-like checks appear separately in explicit status and terminal summaries. Their transitions do not reset readiness or wake the model. - Any unresolved review thread keeps the lease active. - A head push, required-check transition, review, or comment resets the quiet clock. This includes a review with no unresolved thread or dedicated check, but routine non-actionable activity does not wake the model. - With `--fix`, unresolved feedback explicitly loads `phx-pr-review`; required CI failures include check names and links. Re-fetch threads or inspect logs, fix only valid branch-owned causes, verify, push the authorized PR branch update, reply, and resolve where appropriate. Do not blindly rerun shared CI. - Required CI must remain green with zero unresolved threads and no relevant activity for the full quiet period before success releases the lease. Never accept an early green snapshot as immediate readiness. ## Status and Stop Use the same tool with `"action": "status"` or `"action": "stop"`. Stop is idempotent and releases the lease; it does not delete durable history. ## Post-Completion Boundary The plugin registers an optional durable Amp webhook and stores its bearer URL in the owner-only credential file reported by the tool. If a repository administrator configures GitHub to send PR review/check events to that URL, a later event can wake the paused Orb and probe the authoritative PR state. Webhook events must identify the exact watched PR number or current watched head SHA; empty or unrelated repository events are ignored. The plugin never changes GitHub webhook settings. Without that external setup, polling ends after the quiet period and a later human comment cannot wake a paused Orb. Say this explicitly; do not imply polling continues after lease release. ## Reference - `references/watcher-mechanics.md` — lease, durability, filtering, webhook, and billing behavior
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.