--- name: pr-to-green description: Bring a pull request to green by syncing with main, resolving conflicts safely, and fixing failing checks with CausalPy conventions. --- # PR to Green This skill provides a deterministic maintainer workflow for taking an in-flight PR branch to green. ## When to use - A PR is behind `main` and needs sync/rebase - There are merge conflicts to resolve intelligently - Remote checks are failing (tests, docs, lint, or packaging) - You need a concise update for the PR describing what was fixed and what remains ## Preconditions - Confirm branch and remotes before making git changes - Preserve user/unrelated local modifications; never discard unknown work - Use CausalPy environment commands (uv is the default; see `.agents/skills/python-environment/SKILL.md` for the conda fallback): - `uv run ` (default), e.g. `uv run pytest`, `uv run make test-patch-cov` - `$CONDA_EXE run -n CausalPy ` (conda fallback, only when `uv` is unavailable) - For PyMC/PyTensor/matplotlib imports and test commands, request full permissions as needed ## PR number entrypoint (manual invocation) If the user provides a PR number (for example `PR #724`), do this first: 1. Resolve PR metadata from GitHub - `gh pr view ` to get title, state, head branch, base branch, mergeability, and check summary. - `gh pr checks ` to get per-check pass/fail/pending status. 2. Move local repo to the PR branch - `gh pr checkout ` (preferred) so local branch tracks the PR head. 3. Verify branch context before edits - Confirm current branch, tracking status, and whether local uncommitted work exists. 4. Continue with the main workflow below using the PR base branch from GitHub metadata (not assumptions about `main`). ## Workflow 1. Triage and early exit - Assess PR state from entrypoint metadata: branch divergence, mergeability, and check results. - If the PR is up-to-date with its base branch, has no conflicts, and all remote checks pass: - Report "PR is green — no action needed" and stop. - Otherwise, classify what needs fixing: behind-base, conflicts, failing checks, or a combination. 2. Sync branch with base - Prefer `git fetch upstream` then `git rebase upstream/` (or maintainer-preferred merge strategy). - If the PR cannot be checked out, report the blocker and ask for maintainer guidance. - Resolve conflicts file-by-file with intent preservation. - Re-run targeted checks after conflict resolution to detect semantic drift. 3. Fix failing checks with smallest valid change - Lint/type: apply minimal code changes, avoid broad refactors. - Tests: patch root cause and add/adjust tests under `causalpy/tests/` if behavior changes. - Docs/doctest: follow docs placement and glossary/citation conventions. - Packaging/release checks: verify version and install/import expectations. 4. Re-run checks in escalating scope - Fast local signal first (targeted tests/lint). - Then full gate commands required by project norms. - Always run `prek run --all-files` before final handoff. - If fixes introduced new failures, loop back to step 3 with the new failure set. Do not push until a full local pass is achieved or blockers are identified. 5. Push and verify remote - Push fixes to the PR branch (`git push`). - Monitor remote checks via `gh pr checks ` until they complete or a timeout is reached. - If remote checks fail on issues not reproducible locally, note the discrepancy explicitly. 6. Prepare maintainer-ready status update - What was failing. - What changed to fix it. - Which checks now pass (local and remote). - Remaining blockers (if any) and exact next steps. ## Subagent delegation Use subagents (via the Task tool) when work is noisy, broad, or high-risk. Each subagent runs in its own context window and returns a condensed result. ### `ci-failure-investigator` Trigger when CI logs are long/noisy, failures span multiple jobs, or failure family is unclear. Handoff (include in Task prompt): - PR number and branch name - Failed job names and relevant log snippets or `gh run view` output - Ask for: root cause ranking, fix-first order, and minimal patch plan ### `merge-conflict-analyst` Trigger when rebase/merge produces non-trivial conflicts, intent differs across branches, or conflict count is high. Handoff (include in Task prompt): - Target branch and merge/rebase direction - Full conflict list (`git diff --name-only --diff-filter=U`) and key conflict markers/snippets - Ask for: conflict risk map, lowest-risk resolution order, and explicit escalations ### Maintainer escalation clause (required) Do not auto-resolve and continue silently when conflicts are highly complex. Instead, stop and request maintainer input with a brief report. Escalate by default when: - `.ipynb` conflicts are messy (overlapping cell content plus metadata/output churn) - conflict resolution would drop one branch's meaningful behavior - conflicts touch core contracts and intent is ambiguous (experiments/models/tests/docs all changed around same behavior) Escalation report must include: - conflicted file list and risk class - resolution options (1-2) with trade-offs - recommended next step and what decision is needed from maintainer ### Scope drift / upstream compatibility escalation (required) Do not keep patching silently when greening a PR turns into broader compatibility work outside the PR's feature surface. Stop after root-cause identification and ask the maintainer whether to continue in the PR or split the work into a separate branch/PR from `main`. Escalate by default when: - the failing checks are caused by third-party API or version drift in shared/core code - the fix would benefit multiple open PRs or the default branch, not just the current PR - the next fix would modify shared integrations beyond the feature the PR is introducing - successive CI reruns keep exposing new failure families outside the original PR scope Scope-drift report must include: - the original PR goal and the newly discovered broader issue - which files are feature-specific versus shared/core compatibility files - options: patch in the PR, split a separate compatibility PR, or pause for maintainer direction - the recommended next step and why ## CausalPy guardrails - Never use destructive git commands unless explicitly requested - Do not create ad hoc test scripts; use `pytest` tests in `causalpy/tests/` - Keep PyMC-heavy tests runtime-controlled via `sample_kwargs` - Keep docs/notebooks in correct locations and formats - If checks cannot be run, report exactly what was skipped and why