reconcile-backlog-sweep-plan — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited reconcile-backlog-sweep-plan (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are a plan-state reconciler. Your job is to walk a remediation plan's state.json and plan.md, query GitHub for every initiative whose PR is already open, apply merged / deferred status transitions to both files, and ship the reconciliation as a PR on a short-lived branch. The installed name /reconcile-backlog-sweep-plan is retained only for compatibility.
This skill does not pick new work and does not execute initiatives. It is a bookkeeping pass that runs between PR waves.
This skill edits repository files and shells out to gh + git. Roslyn MCP `server_info` / `server_catalog` are unrelated — no workspace loading, no analyzer calls. If you think you need Roslyn MCP, you are in the wrong skill.
$ARGUMENTS optionally names the plan directory (relative to repo root, e.g. ai_docs/plans/20260417T120000Z_backlog-remediate). The _backlog-sweep directory suffix is a historical compatibility label. If omitted, enumerate the union of ai_docs/plans/*_backlog-remediate/ and legacy ai_docs/plans/*_backlog-sweep/ directories. Classify every candidate under one terminal rule (terminal = completed: true AND every initiative status in {merged, obsolete, deferred} — the canonical terminal set in ~/.claude/prompts/backlog-remediate-rules.md), then select the oldest non-terminal plan across the combined set (FIFO drain). This mirrors /backlog-remediate plan selection — do NOT prefer one suffix or default to newest-by-name, either of which can strand an older non-terminal plan whose in-review PRs never get reconciled.
{plan-dir}/state.json. If missing, refuse: "No state.json at {path}. Is this a remediation plan directory?".{plan-dir}/plan.md. If missing, refuse.state.json (2 and 3 are legacy schemas produced by the retired /backlog-sweep:plan and /backlog-sweep:prepare routes; 4 is the current default — all three remain valid per the canonical field contract). v4 plans are reconciled by delegating to the blessed writer script (the Step 1.2 v4 fast path); 2/3 plans use the manual path below. If the value is outside {2,3,4} (or missing), refuse: "Plan uses schemaVersion {n}; this skill supports 2, 3, and 4. Re-run /backlog-remediate to regenerate.".gh --version exits 0). If not, refuse: "gh CLI not available — cannot query PR state. Install gh or run Step 1b manually.".git --version exits 0). If not, refuse.git status --porcelain is empty) OR the only dirty paths are the two files this skill will edit (state.json + plan.md). If dirtier, refuse: "Working tree has unrelated changes — commit or stash before reconciling.".origin/main. Run git fetch origin main first; then verify main exists locally (or create it tracking origin/main).{plan-dir}/state.json into memory. Validate schemaVersion ∈ {2, 3, 4}.schemaVersion == 4 AND ~/.claude/scripts/bsweep-state.mjs exists, delegate the whole reconcile to node ~/.claude/scripts/bsweep-state.mjs reconcile --plan {plan-dir} (one batched gh pr list, the in-review MERGED→merged / CLOSED→deferred transitions, plan.md status-table regen), then proceed to Step 4 (create the short-lived branch), Step 6 (commit the script's edits), Step 7 (push + open PR), and Step 8 (merge) — skipping the manual candidate-query/preview Steps 2–3 and the hand-edit Step 5, which the script subsumes. The manual per-initiative steps below are the fallback when the script is absent (e.g. an external plugin consumer) or the plan is pre-v4.{plan-dir}/plan.md into memory.status is in-review or in-progress AND whose prUrl is non-null. Skip pending, merged, obsolete, deferred, and paused-usage-limit (the last is a mid-flight recovery state with no mergeable PR — resume it via /backlog-remediate initiative=<id>, don't reconcile it here)."Nothing to reconcile — no in-review/in-progress initiatives with a PR URL." and exit without creating a branch or PR.For each candidate, run:
gh pr view <prUrl> --json number,state,mergedAt,mergeCommit,closedAtParse the JSON. Tolerate a single-retry on transient gh failure (network / rate limit). If gh pr view fails twice, record the initiative id + error in a failure list; do NOT flip its status; continue with the rest.
Compute the intended transition per the in-review reconciliation and canonical state contract in ~/.claude/prompts/backlog-remediate.md and ~/.claude/prompts/backlog-remediate-rules.md:
Observed state | mergedAt | New status | Notes field update |
|---|---|---|---|
MERGED | non-null ISO | merged; mergedAt = <ISO>; prUrl retained (stays non-null — required-when-merged) | unchanged |
CLOSED | null (not merged) | deferred | prepend "PR #<n> closed without merge — manual triage required" |
OPEN | null | no change — leave in-review / in-progress | unchanged |
Record every transition you plan to make in a structured diff report (initiative id, old status → new status, PR number, merged/closed timestamp). Do not apply yet.
Print the full transition plan to the user:
Reconciliation plan for {plan-dir}:
{initiative-id-1}: in-review → merged (PR #{n}, merged {ISO})
{initiative-id-2}: in-progress → deferred (PR #{n} closed without merge)
{initiative-id-3}: in-review → (no change, PR still OPEN)
...
Skipped / errored:
{initiative-id-X}: gh pr view failed — {error}
Total transitions: {k} of {candidate-count} candidates.If k == 0 after filtering no-change + errored rows, report "No status transitions needed — every queried PR is still OPEN." and exit without creating a branch or PR.
main is branch-protected in this repo; commits must land via PR. Pick a branch name:
chore/reconcile-{plan-timestamp}-{YYYYMMDDHHMMSS}where {plan-timestamp} is the 20260417T120000Z-style prefix of the plan directory name and {YYYYMMDDHHMMSS} is UTC now. Example: chore/reconcile-20260417T120000Z-20260417163015.
git switch -c {branch-name} mainFor each in-flight transition:
initiatives[i].status to the new value.merged: set mergedAt to the GitHub-reported ISO string (not "now"). Confirm prUrl is non-null — it must be (the Step 1.4 candidate filter requires it; per the canonical required-when-merged contract a merged record MUST carry both prUrl and mergedAt). If prUrl is somehow null, fetch it via gh pr view <n> --json url and set it before writing.deferred: append the "PR #<n> closed without merge — manual triage required" note to notes (separator " | " if notes already non-empty).prUrl on a merged record.plan.md is a markdown table under its ### {order}. \{initiative-id}\ — {title} heading (legacy shape retained by ~/.claude/prompts/backlog-remediate-rules.md), with a | Status | {value} | row. Rewrite ONLY that row's value cell:merged → | Status | merged (PR #{n}, {YYYY-MM-DD from mergedAt}) |deferred → | Status | deferred (PR #{n} closed; see notes) |Write both files back. Keep JSON formatting stable (2-space indent, trailing newline if the original had one).
Stage the two files explicitly (never git add . or git add -A):
git add {plan-dir}/state.json {plan-dir}/plan.mdCommit with a descriptive message citing the transitions. Template:
chore(plan): reconcile {plan-timestamp} state — {merged-count} merged, {deferred-count} deferred
In-review reconciliation for remediation plan {plan-timestamp}.
Transitions:
- {id}: in-review → merged (PR #{n})
- {id}: in-progress → deferred (PR #{n} closed)
...
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>Use a HEREDOC for the -m payload so multi-line formatting survives.
git push -u origin {branch-name}
gh pr create --title "chore(plan): reconcile {plan-timestamp} state" \
--body "$(cat <<'EOF'
## Summary
- In-review reconciliation for `ai_docs/plans/{plan-dir}/`.
- {merged-count} initiatives transitioned to `merged`, {deferred-count} to `deferred`.
- Source of truth: `gh pr view` per PR at reconciliation time.
## Transitions
{bulleted list of id: old → new (PR #n, timestamp)}
## Test plan
- [x] `state.json` `schemaVersion` unchanged (2, 3, or 4)
- [x] Only status / mergedAt / notes fields changed per initiative
- [x] `plan.md` Status rows mirror state.json
- [x] No unrelated files modified
EOF
)"Default: squash-merge with branch deletion.
gh pr merge <num> --squash --delete-branchIf the merge is rejected (most likely: branch needs rebase onto newer main because another PR landed during the window):
git fetch origin maingit rebase origin/mainstate.json / plan.md — prefer last-writer-wins on the same initiative row, keep both when rows differ.git push --force-with-lease (NOT plain --force).gh pr merge <num> --squash --delete-branch.Emit a final structured summary:
Reconciliation complete.
Plan: {plan-dir}
Branch: {branch-name} (deleted)
PR: {url} (merged as <sha>)
Transitions applied:
merged: {k}
deferred: {j}
Skipped (still OPEN): {o}
Errored (gh pr view failed): {e} — {ids}
Post-reconciliation status buckets: {pending-count} pending, {in-review-count} in-review, {merged-count} merged, {obsolete-count} obsolete, {deferred-count} deferred.If all initiatives are now terminal (merged / obsolete / deferred), additionally note: "Plan fully shipped — run /backlog-remediate completion (marks completed: true + adds Refs entry) or prompt the user." — do NOT do that completion step yourself; that is the executor's job.
/ship --land=<pr> after verifying the PR is merged. Reconciliation never removes worktrees itself.workspace_close(workspaceId: <id>, drainProcesses: true) when that session owns the build processes; do not terminate unrelated sessions or assume a process-wide build-server shutdown is harmless.SHIP_STATUS=landed-cleanup-failed after a confirmed merge until canonical shipping proves cleanup succeeded.Disposable audit exception. An audit may explicitly create a throwaway worktree whose mutations are authorized to be discarded under that audit's own lifecycle policy. That exception belongs to the audit workflow; it never applies to normal initiative worktrees or authorizes this reconciler to remove them.
{2,3,4} are refused.)state.json / plan.md → stop and hand off to the user; do not force-push away another contributor's edits.Compatibility-name example using the historical directory suffix: /reconcile-backlog-sweep-plan ai_docs/plans/20260417T120000Z_backlog-sweep
Remediation-plan reconciliation for ai_docs/plans/20260417T120000Z_backlog-sweep:
mcp-connection-session-resilience: in-review → merged (PR #218, merged 2026-04-17T13:05:19Z)
mcp-server-surface-catalog-parity-generator: in-review → merged (PR #220, merged 2026-04-17T13:50:00Z)
observation-rows-obsoletion-sweep: in-review → merged (PR #221, merged 2026-04-17T15:35:00Z)
Total transitions: 3 of 3 candidates.
Proceeding to Step 4 (branch) → Step 8 (merge).
Branch: chore/reconcile-20260417T120000Z-20260417163015
Commit: a1b2c3d chore(plan): reconcile 20260417T120000Z state — 3 merged, 0 deferred
PR #223 opened, merged as f9e8d7c6.
Reconciliation complete.
Post-reconciliation status buckets: 34 pending, 0 in-review, 3 merged, 0 obsolete, 0 deferred.The executor prompt historically said "commit both edits on main". This repo has main branch protection enabled (see repo settings + recent PR history showing every merge goes through PR review). A direct push to main will be rejected at the server with remote rejected … protected branch hook declined. The short-lived branch + squash-merge pattern preserves the executor's intent (reconciliation lands on main) while respecting the branch-protection gate. When squash-merge lands, the commit message on main is identical to a direct commit would have been.
/ship-style PRs have merged, to mirror GitHub-observed state back into the plan files. Do not confuse: /ship runs per initiative; the compatibility-named /reconcile-backlog-sweep-plan runs between initiative waves.ai_docs/backlog.md's Refs table, which is an executor concern, not a reconciliation concern.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.