@codedrifters/configulator 0.0.410 → 0.0.411

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -21446,6 +21446,573 @@ var pnpmBundle = {
21446
21446
  ]
21447
21447
  };
21448
21448
 
21449
+ // src/agent/bundles/pr-babysitting.ts
21450
+ var BABYSIT_R1_RETIRING_ISSUE = 916;
21451
+ var BABYSIT_STALL_WINDOW_FLOOR_MINUTES = 30;
21452
+ function renderCiVerificationLines(policy) {
21453
+ const workflows = policy.ciVerification.requiredWorkflows;
21454
+ const gate = workflows.length === 0 ? [
21455
+ " This project configures **no** explicit required-workflow list,",
21456
+ " so treat **every** workflow run observed for the head SHA as",
21457
+ " required \u2014 the conservative zero-config default."
21458
+ ] : [
21459
+ " This project gates on the following required workflows; a",
21460
+ " listed workflow with no run for the head SHA counts as",
21461
+ " pending, never green:",
21462
+ "",
21463
+ ...workflows.map((name) => ` - \`${name}\``)
21464
+ ];
21465
+ return [
21466
+ "- **CI status.** Read it exactly the way the `pr-reviewer` does \u2014",
21467
+ " never invent a second contract. The primary read is the check-runs",
21468
+ " rollup (`gh pr checks <n>`). When the token is a **fine-grained**",
21469
+ " PAT that read returns",
21470
+ " `HTTP 403: Resource not accessible by personal access token`;",
21471
+ " fall back to the Actions runs API, which a fine-grained PAT with",
21472
+ " `Actions: Read-only` can read:",
21473
+ "",
21474
+ " ```bash",
21475
+ ' gh api "repos/{{repository.owner}}/{{repository.name}}/actions/runs?head_sha=<SHA>&per_page=100" \\',
21476
+ " --jq '.workflow_runs[] | {name, status, conclusion}'",
21477
+ " ```",
21478
+ "",
21479
+ ...gate,
21480
+ "",
21481
+ " A 403 is a **visibility failure, not a green signal**. Never treat",
21482
+ " an unreadable rollup as passing."
21483
+ ];
21484
+ }
21485
+ function buildBabysitPrsSkill(policy) {
21486
+ return {
21487
+ name: "babysit-prs",
21488
+ description: "Operator sweep over the open-PR queue: confirm the autonomous pipeline is merging the clean majority and intervene only on the states it cannot self-heal",
21489
+ disableModelInvocation: true,
21490
+ userInvocable: true,
21491
+ platforms: { cursor: { exclude: true } },
21492
+ instructions: [
21493
+ "# Babysit Open Pull Requests",
21494
+ "",
21495
+ "One **operator cycle** over the open-PR queue in",
21496
+ "**{{repository.owner}}/{{repository.name}}**. This skill is the",
21497
+ "operator layer that sits *above* the autonomous PR pipeline \u2014 it",
21498
+ "confirms the pipeline is keeping up and intervenes only on the",
21499
+ "small set of states the pipeline **cannot self-heal**.",
21500
+ "",
21501
+ "It is **not** a second reviewer and **not** a second orchestrator.",
21502
+ "Review and arming belong to `pr-reviewer`; issue-queue scanning and",
21503
+ "dispatch belong to `orchestrator`. See **Composability** below for",
21504
+ "the exact boundaries.",
21505
+ "",
21506
+ "## Usage",
21507
+ "",
21508
+ "```",
21509
+ "/babysit-prs [--interval <minutes>] [--once] [--dry-run]",
21510
+ "```",
21511
+ "",
21512
+ "### Flags",
21513
+ "",
21514
+ "- **`--interval <minutes>`** \u2014 pin the cycle cadence instead of",
21515
+ " self-pacing. Also sets the stall window (see **Cadence**).",
21516
+ "- **`--once`** \u2014 run a single cycle and stop without emitting a",
21517
+ " next-check recommendation. The default already runs exactly one",
21518
+ " cycle per invocation; `--once` additionally suppresses the",
21519
+ " `NEXT_CHECK_IN` line for callers that drive their own schedule.",
21520
+ "- **`--dry-run`** \u2014 classify every open PR and report the action",
21521
+ " each class *would* take, without running any of them. Nothing is",
21522
+ " pushed, armed, labelled, or commented. Use it to inspect the",
21523
+ " queue before letting the skill act.",
21524
+ "",
21525
+ "One invocation is **one cycle**. To babysit continuously, drive the",
21526
+ "skill from a loop or a scheduled task at the cadence it recommends.",
21527
+ "",
21528
+ "## Core principle \u2014 don't do redundant work",
21529
+ "",
21530
+ "The pipeline reliably reviews, arms `--auto --squash`, and merges",
21531
+ "clean PRs on its own. **Do not** re-review, re-arm, rebase, or",
21532
+ "otherwise drive a PR that is already progressing \u2014 you only race",
21533
+ "the pipeline, restart CI, and burn tokens. In the reference session",
21534
+ "this skill was distilled from, roughly **4 of every 5 cycles needed",
21535
+ "no intervention at all**.",
21536
+ "",
21537
+ "Your job is the stuck classes in **Handlers** below. For everything",
21538
+ "else: confirm it is defect-free, let the pipeline merge it, and",
21539
+ "re-check next cycle. A cycle whose entire output is",
21540
+ "`no action needed` is a **successful** cycle, not a wasted one.",
21541
+ "",
21542
+ "Two corollaries that decide most judgement calls:",
21543
+ "",
21544
+ "1. **Every act-on branch is gated on a stall window.** No PR is",
21545
+ " touched on the first cycle a signal appears. A signal must have",
21546
+ " held for at least the stall window before it counts as stuck.",
21547
+ "2. **When in doubt, report and re-check.** Reporting a PR you did",
21548
+ " not understand costs one line of output. Acting on a PR the",
21549
+ " pipeline was already handling costs a restarted CI run, a",
21550
+ " contended lease, or a lost commit.",
21551
+ "",
21552
+ "## Prerequisites & environment",
21553
+ "",
21554
+ "- **`gh` must be on `PATH`.** Some non-interactive sessions start",
21555
+ " with a minimal `PATH` that omits the package-manager prefix.",
21556
+ " Resolve it **once** per session with `command -v gh`; if that",
21557
+ " fails, prepend the platform's package prefix (for example",
21558
+ ' `export PATH="/opt/homebrew/bin:$PATH"` on Homebrew macOS,',
21559
+ " `/usr/local/bin` or `/home/linuxbrew/.linuxbrew/bin` elsewhere)",
21560
+ " and re-check. Abort the cycle with a clear diagnostic if `gh` is",
21561
+ " still unresolvable \u2014 never fall back to raw `curl`.",
21562
+ "- **Resolve the default branch from the repo, never hard-code it:**",
21563
+ "",
21564
+ " ```bash",
21565
+ " default_branch=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')",
21566
+ " ```",
21567
+ "",
21568
+ ...renderCiVerificationLines(policy),
21569
+ "- **Foreground git only.** Run every git command as a discrete",
21570
+ " foreground invocation. Do not background them and do not build",
21571
+ " sleep-loops inside a cycle \u2014 the cadence between cycles is the",
21572
+ " only waiting this skill does.",
21573
+ "- **Isolated worktree for all git surgery.** Never touch the user's",
21574
+ " working checkout. Create one detached worktree per session, reuse",
21575
+ " it across handlers, and remove it before the cycle ends:",
21576
+ "",
21577
+ " ```bash",
21578
+ ' wt="${TMPDIR:-/tmp}/babysit-prs-wt"',
21579
+ ' git worktree add --detach "$wt" "origin/$default_branch"',
21580
+ ' # \u2026reuse: git -C "$wt" <cmd> \u2026',
21581
+ ' git worktree remove --force "$wt" # always, even on abort',
21582
+ " ```",
21583
+ "",
21584
+ "- **Never force-push.** Not `--force`, not `--force-with-lease`, on",
21585
+ " any branch, for any reason. Every recipe in this skill produces a",
21586
+ " fast-forward-pushable merge commit precisely so a plain",
21587
+ " `git push` suffices.",
21588
+ "- **Scope of edits.** Only ever modify paths that the PR's **own",
21589
+ " diff already touches**. Never introduce a file the PR did not",
21590
+ " already carry, and never edit a lockfile (`pnpm-lock.yaml`,",
21591
+ " `yarn.lock`, `package-lock.json`, `**/*.lock`), anything under",
21592
+ " `**/.projen/**`, or any file whose first five lines carry a",
21593
+ " `~~ Generated by projen` / `// Generated by` marker. Those are",
21594
+ " regenerated by synth, not merged by hand.",
21595
+ "- **Merge model.** Squash. Where the default branch is protected",
21596
+ " **strict** (require-up-to-date), armed PRs legitimately sit at",
21597
+ " `BEHIND` until refreshed \u2014 that is the protection working, not a",
21598
+ " defect. An armed `--auto --squash` survives a branch refresh.",
21599
+ "",
21600
+ "## Per-cycle procedure",
21601
+ "",
21602
+ "### Step 1 \u2014 Sweep",
21603
+ "",
21604
+ "```bash",
21605
+ "gh pr list --state open --limit 100 \\",
21606
+ " --json number,title,isDraft,mergeable,mergeStateStatus,autoMergeRequest,labels,headRefName,updatedAt \\",
21607
+ " --jq '.[] | {n: .number, draft: .isDraft, mergeable, merge_state: .mergeStateStatus, armed: (.autoMergeRequest != null), labels: [.labels[].name], branch: .headRefName, updated: .updatedAt}'",
21608
+ "```",
21609
+ "",
21610
+ "One JSON object per line, all filtering done **jq-side**. Do not",
21611
+ "reformat the sweep into tab- or space-separated records and parse",
21612
+ "them in the shell: a record whose fields can be empty (labels, most",
21613
+ "commonly) collapses under the shell's default word-splitting and",
21614
+ "silently shifts every later field. Keep the data in JSON from the",
21615
+ "`gh` call to the classification decision.",
21616
+ "",
21617
+ "If the queue is empty, report `no open PRs`, emit the next-check",
21618
+ "recommendation, and stop.",
21619
+ "",
21620
+ "### Step 2 \u2014 Compute the stall window",
21621
+ "",
21622
+ `The stall window is **2 \xD7 the cycle interval**, floored at **${BABYSIT_STALL_WINDOW_FLOOR_MINUTES} minutes**.`,
21623
+ "A signal counts as *stalled* only when the PR's `updatedAt` is older",
21624
+ "than the window. `updatedAt` is deliberately conservative \u2014 any",
21625
+ "activity at all (a commit, a label, a comment, a reviewer pass)",
21626
+ "resets it, which biases the skill toward waiting rather than acting.",
21627
+ "That is the intended bias.",
21628
+ "",
21629
+ "### Step 3 \u2014 Classify each PR",
21630
+ "",
21631
+ "Assign **exactly one** class per PR, taking the first match walking",
21632
+ "the table top to bottom:",
21633
+ "",
21634
+ "| # | Class | Signal | Action |",
21635
+ "|---|-------|--------|--------|",
21636
+ "| 1 | `DRAFT` | `isDraft` is true | none \u2014 the author has not asked for review |",
21637
+ "| 2 | `IN-FLIGHT-DELEGATION` | `review:fixing` **and** `review:needs-worker` | none \u2014 a worker pull is queued (**D2**) |",
21638
+ "| 3 | `CONFIRM-PENDING` | `review:fixing` without `review:needs-worker` | none unless stalled (**D2**) |",
21639
+ "| 4 | `NEEDS-WORKER` | `review:needs-worker` without `review:fixing` | none unless stalled (**D2**) |",
21640
+ "| 5 | `LABEL-ANOMALY` | `review:awaiting-human` **and** (`review:fixing` or `review:needs-worker`) | re-invoke the reviewer (**D2**) |",
21641
+ "| 6 | `AWAITING-HUMAN` | `review:awaiting-human` alone | report, and check **R1** eligibility |",
21642
+ "| 7 | `CI-RED` | required CI concluded `failure` / `timed_out` / `cancelled` | report only (**D4**) |",
21643
+ "| 8 | `CONFLICT-SHARED-INDEX` | `mergeable` is `CONFLICTING` **and** every conflict is a shared-index row-insert race | **R1** surgery |",
21644
+ "| 9 | `CONFLICT-OTHER` | `mergeable` is `CONFLICTING`, anything else | report only (**D4**) |",
21645
+ "| 10 | `BEHIND-STALLED` | armed **and** `merge_state` is `BEHIND` **and** stalled | chase the branch (**D3**) |",
21646
+ "| 11 | `UNREVIEWED-STALLED` | not armed, no `review:*` label, no reviewer-notes comment, **and** stalled | hand to `pr-reviewer` (**D1**) |",
21647
+ "| 12 | `PROGRESSING` | anything else | none \u2014 the pipeline has it |",
21648
+ "",
21649
+ "Rows 2\u20134 are the pipeline's own legitimate intermediate states. They",
21650
+ "are listed **above** the conflict and BEHIND rows on purpose: a PR",
21651
+ "with a delegation in flight is being worked on right now, whatever",
21652
+ "else its merge state says, and touching it contends the lease.",
21653
+ "",
21654
+ "### Step 4 \u2014 Act",
21655
+ "",
21656
+ "Run the handler named in the Action column. Under `--dry-run`,",
21657
+ "print the handler that would run and move on without executing it.",
21658
+ "",
21659
+ "### Step 5 \u2014 Report and recommend a cadence",
21660
+ "",
21661
+ "Emit the report described in **Output**, then the next-check",
21662
+ "recommendation from **Cadence** (unless `--once` was passed).",
21663
+ "",
21664
+ "## Handlers",
21665
+ "",
21666
+ "Four **durable** handlers (D1\u2013D4) and one **residual** handler (R1).",
21667
+ "The durable handlers reflect permanent properties of the pipeline",
21668
+ "and branch protection; they do not go away. The residual handler is",
21669
+ "isolated behind its own heading and annotated with the issue that",
21670
+ "retires it, so deleting it is a mechanical edit.",
21671
+ "",
21672
+ "### D1 \u2014 Unreviewed and stalled \u2192 hand to `pr-reviewer` *(durable)*",
21673
+ "",
21674
+ "A PR that is not armed, carries no `review:*` label, has no sticky",
21675
+ "`## Reviewer notes` comment, and has been idle past the stall window",
21676
+ "was never picked up by a reviewer pass. Hand it to the reviewer \u2014",
21677
+ "**do not** review or arm it yourself:",
21678
+ "",
21679
+ "```",
21680
+ "/review-pr <n>",
21681
+ "```",
21682
+ "",
21683
+ "The reviewer applies the project's PR-review policy, decides",
21684
+ "`auto-merge` vs `human-required`, and arms only when the policy",
21685
+ "allows. Operator-arming an **unreviewed** PR bypasses that policy",
21686
+ "entirely and is an anti-pattern (see **Anti-patterns**).",
21687
+ "",
21688
+ "Most PRs *do* get picked up on their own. Only hand over one that",
21689
+ "has genuinely stalled.",
21690
+ "",
21691
+ "### D2 \u2014 Review-label states: classify and route, never hand-clear *(durable)*",
21692
+ "",
21693
+ "The delegation loop spans three passes and is coordinated entirely",
21694
+ "by two labels: the `review:fixing` lease and the",
21695
+ "`review:needs-worker` marker. Every combination below is a **valid**",
21696
+ "position in that loop, not a deadlock:",
21697
+ "",
21698
+ "| Labels present | Meaning | Operator action |",
21699
+ "|----------------|---------|-----------------|",
21700
+ "| `review:fixing` + `review:needs-worker` | delegation in flight; a top-level `issue-worker` pass will pull it | **none** |",
21701
+ "| `review:fixing` alone | worker finished and cleared its marker; a reviewer confirm pass owns the PR | none; if stalled, re-invoke `/review-pr <n>` |",
21702
+ "| `review:needs-worker` alone | a fix-list is queued and unconsumed | none; if stalled, **report** \u2014 the worker's own scan pulls it |",
21703
+ "| `review:awaiting-human` + either delegation label | **invariant violation** \u2014 a PR is either in the delegation loop or handed to a human, never both | re-invoke `/review-pr <n>` |",
21704
+ "",
21705
+ "**The operator never runs `gh pr edit --remove-label review:*`.**",
21706
+ "This is the single most important rule in this handler, and it is a",
21707
+ "deliberate reversal of how a human operator used to clear these.",
21708
+ "",
21709
+ "Hand-clearing was correct when a reviewer pass could hold the lease",
21710
+ "with no mechanism to ever release it. That is no longer the shape of",
21711
+ "the system. Three owners now reconcile these labels, and each one",
21712
+ "clears exactly the label it owns:",
21713
+ "",
21714
+ "- The **reviewer's confirm pass** releases `review:fixing` after the",
21715
+ " worker's report lands.",
21716
+ "- The **`issue-worker`** clears `review:needs-worker` as the",
21717
+ " mandatory, atomic completion of its hand-off \u2014 including when",
21718
+ " every fix-list item failed.",
21719
+ "- The **maintenance sweep** reconciles both stuck states without a",
21720
+ " human: it re-arms `review:needs-worker` on an orphaned lease, and",
21721
+ " removes `review:needs-worker` on a consumed-but-uncleared wedge,",
21722
+ " posting an audit-trail comment either way.",
21723
+ "",
21724
+ "An operator who strips a label out from under those owners destroys",
21725
+ "the state they key on: clearing `review:needs-worker` by hand makes",
21726
+ "an unconsumed fix-list look consumed, so the confirm pass merges a",
21727
+ "PR whose fixes were never applied; clearing `review:fixing` by hand",
21728
+ "invites a second delegation on top of a live one. Re-invoking the",
21729
+ "reviewer is strictly better in every case \u2014 its **Phase 2.8 label",
21730
+ "reconciliation** step resolves genuine invariant violations",
21731
+ "canonically, logs each correction on a `**Label reconciliation:**`",
21732
+ "line in the sticky notes comment, and only ever *removes* a",
21733
+ "contradicting label.",
21734
+ "",
21735
+ "So the durable operator capability here is **classification and",
21736
+ "routing**, not clearing. If a label state persists across several",
21737
+ "cycles even after a reviewer re-invocation, that is a pipeline bug \u2014",
21738
+ "report it and file an issue rather than papering over it by hand.",
21739
+ "",
21740
+ "### D3 \u2014 Armed but `BEHIND` past the stall window \u2192 chase *(durable)*",
21741
+ "",
21742
+ "Inherent to strict branch protection, not a bug: an armed PR must be",
21743
+ "up to date with the default branch before it can merge, and a busy",
21744
+ "default branch can outrun it. Give every freshly-armed or `BEHIND`",
21745
+ "PR **one** convergence window first \u2014 they usually self-merge.",
21746
+ "",
21747
+ "Past the stall window, refresh the branch. Prefer the API, which",
21748
+ "produces a merge commit server-side and needs no worktree:",
21749
+ "",
21750
+ "```bash",
21751
+ "gh pr update-branch <n>",
21752
+ "```",
21753
+ "",
21754
+ "If that is unavailable, do the same thing locally in the worktree",
21755
+ "and push **without** force:",
21756
+ "",
21757
+ "```bash",
21758
+ 'git -C "$wt" fetch origin',
21759
+ 'git -C "$wt" checkout -B "<branch>" "origin/<branch>"',
21760
+ 'git -C "$wt" merge --no-edit "origin/$default_branch"',
21761
+ 'git -C "$wt" push origin "<branch>"',
21762
+ "```",
21763
+ "",
21764
+ "**Merge, never rebase.** The PR branch is already published and",
21765
+ "diverged, so a rebase rewrites history that others have fetched and",
21766
+ "forces a `--force-with-lease` push this skill forbids. A merge",
21767
+ "commit is fast-forward-pushable with a plain `git push`. Squash-merge",
21768
+ "collapses the merge commit at merge time anyway, so it costs nothing",
21769
+ "in the final history.",
21770
+ "",
21771
+ "If the merge conflicts, **abort it** (`git merge --abort`) and",
21772
+ "re-classify the PR as a conflict class \u2014 do not resolve conflicts in",
21773
+ "this handler.",
21774
+ "",
21775
+ "### D4 \u2014 Report-only classes *(durable)*",
21776
+ "",
21777
+ "Some classes are genuinely not operator work. Report them with one",
21778
+ "line each and take no action:",
21779
+ "",
21780
+ "- **`CI-RED`** \u2014 a required workflow concluded red. A permanent",
21781
+ " failure is the author's or the reviewer's to fix, and the reviewer",
21782
+ " already flags it with `status:needs-attention`. Never rerun CI to",
21783
+ " see if it goes away, and never refresh the branch to restart it.",
21784
+ "- **`CONFLICT-OTHER`** \u2014 a conflict outside the shared-index class.",
21785
+ " The reviewer's typed generic recipe delegates these to",
21786
+ " `issue-worker`; hand-merging one here duplicates that path and",
21787
+ " risks resolving it differently than the pipeline would.",
21788
+ "- **`AWAITING-HUMAN`** \u2014 the reviewer finished and handed the merge",
21789
+ " decision to a human. Surface it so the human sees it. (Check **R1**",
21790
+ " eligibility first \u2014 a hand-off caused by a *failed* shared-index",
21791
+ " fix is the one case where the pipeline explicitly asked for this",
21792
+ " kind of help.)",
21793
+ "- **`DRAFT`** \u2014 the author has not asked for review yet.",
21794
+ "",
21795
+ `### R1 \u2014 Shared-index merge conflict *(residual \u2014 retires with #${BABYSIT_R1_RETIRING_ISSUE})*`,
21796
+ "",
21797
+ `> **Deleting this handler.** When #${BABYSIT_R1_RETIRING_ISSUE} lands, delete this`,
21798
+ "> entire `### R1` section, drop row 8 (`CONFLICT-SHARED-INDEX`) from",
21799
+ "> the classification table, and delete the matching eval. Nothing",
21800
+ "> else in this skill references it.",
21801
+ "",
21802
+ "Two PRs raced to insert a row into the same shared registry, index,",
21803
+ "or feature-matrix page and the loser is `CONFLICTING`. The pipeline",
21804
+ "handles the common case on its own: the reviewer classifies the",
21805
+ "conflict, emits a `synthetic:rebase-shared-index` fix-list item, and",
21806
+ "an `issue-worker` applies the typed re-insert recipe. **This handler",
21807
+ "exists only for the cases where that delegation could not run.**",
21808
+ "",
21809
+ "#### Eligibility \u2014 all four must hold",
21810
+ "",
21811
+ "1. **Every** conflicting path matches one of the shared-index globs:",
21812
+ "",
21813
+ ...DEFAULT_SHARED_INDEX_PATHS.map((p) => ` - \`${p}\``),
21814
+ "",
21815
+ "2. **Every** conflict hunk touches data rows only. Inspect each",
21816
+ " `<<<<<<<` / `=======` / `>>>>>>>` hunk: every conflicting line",
21817
+ " must start with `| ` and be neither the table header row nor the",
21818
+ " `|---|---|` separator. If any hunk touches the frontmatter block,",
21819
+ " the page H1, surrounding prose, the header row, or the separator",
21820
+ " row, this is **not** a row-insert race \u2014 re-classify as",
21821
+ " `CONFLICT-OTHER` and report.",
21822
+ "3. No conflicting path is a lockfile, lives under `**/.projen/**`, or",
21823
+ " carries a generated-file marker in its first five lines.",
21824
+ "4. The PR does **not** carry `review:human-required`, and one of:",
21825
+ " - it carries `review:awaiting-human` **and** its most recent",
21826
+ " worker-report comment records a",
21827
+ " `synthetic:rebase-shared-index` item as `failed` \u2014 the pipeline",
21828
+ " tried, could not finish, and explicitly asked for a human; **or**",
21829
+ " - it has been `CONFLICTING` past the stall window with **neither**",
21830
+ " `review:fixing` nor `review:needs-worker` \u2014 no delegation is in",
21831
+ " flight and none fired.",
21832
+ "",
21833
+ "If any check fails, report the PR and move on. In particular a",
21834
+ "`review:human-required` PR is never resolved here: pushing",
21835
+ "operator-merged content into it expands the diff the human is",
21836
+ "reviewing without their consent.",
21837
+ "",
21838
+ "#### Recipe",
21839
+ "",
21840
+ "Deliberately **identical** to the worker's typed",
21841
+ "`synthetic:rebase-shared-index` recipe, so an operator resolution and",
21842
+ "a pipeline resolution can never produce different content.",
21843
+ "",
21844
+ "```bash",
21845
+ 'git -C "$wt" fetch origin',
21846
+ 'git -C "$wt" checkout -B "<branch>" "origin/<branch>"',
21847
+ 'git -C "$wt" merge --no-edit "origin/$default_branch"',
21848
+ "```",
21849
+ "",
21850
+ "For each conflicting file, resolve by **union**: the `<<<<<<< HEAD`",
21851
+ "side carries this PR's row and the other side carries the row that",
21852
+ "already merged. Keep **both**, re-inserted in the file's declared",
21853
+ "sort order (alphabetical on the first column unless the page",
21854
+ "documents otherwise), remove the conflict markers, and stage it:",
21855
+ "",
21856
+ "```bash",
21857
+ 'git -C "$wt" add "<path>"',
21858
+ "```",
21859
+ "",
21860
+ "Then verify each re-inserted row appears **exactly once** in the",
21861
+ "staged content \u2014 zero means the row was dropped, more than one means",
21862
+ "the merge duplicated it:",
21863
+ "",
21864
+ "```bash",
21865
+ 'count=$(git -C "$wt" show ":<path>" | grep -Fc "<row-unique-marker>")',
21866
+ '[ "$count" = "1" ] || { echo "BLOCKED verification failed for <path>"; exit 1; }',
21867
+ "```",
21868
+ "",
21869
+ "On any `BLOCKED` result, run `git merge --abort`, report the PR as",
21870
+ "`BLOCKED <reason>`, and leave it for a human. Otherwise complete the",
21871
+ "merge and push \u2014 plain push, never force:",
21872
+ "",
21873
+ "```bash",
21874
+ 'git -C "$wt" commit --no-edit',
21875
+ 'git -C "$wt" push origin "<branch>"',
21876
+ "```",
21877
+ "",
21878
+ "Do **not** arm the PR afterwards. Resolving the conflict returns it",
21879
+ "to a state the pipeline can act on; the next reviewer pass decides",
21880
+ "whether it merges. If the PR carried `review:awaiting-human`, leave",
21881
+ "that label alone (**D2**) and note the resolution in the report so",
21882
+ "the human can act on a now-mergeable PR.",
21883
+ "",
21884
+ "A PR in this class may need re-resolving after each sibling merges",
21885
+ "into the same page. That is expected; it converges.",
21886
+ "",
21887
+ "## Anti-patterns",
21888
+ "",
21889
+ "- **Don't refresh or rebase an armed PR that is merely `BLOCKED` on a",
21890
+ " queued CI run.** You will restart CI and push the merge further",
21891
+ " away. Diagnose the merge state before touching the branch.",
21892
+ "- **Don't operator-arm an unreviewed PR.** Arming is the reviewer's",
21893
+ " decision, made under the project's PR-review policy. Hand it to",
21894
+ " `/review-pr` instead (**D1**).",
21895
+ "- **Don't hand-clear `review:*` labels** (**D2**). Route to the owner",
21896
+ " that clears each one.",
21897
+ "- **Don't force-push.** Ever, on any branch.",
21898
+ "- **Don't hand-merge a non-shared-index conflict.** The pipeline has",
21899
+ " a typed recipe for those; duplicating it here invites divergence.",
21900
+ "- **Don't edit a path the PR's own diff does not already touch**, and",
21901
+ " never a lockfile or generated file.",
21902
+ "- **Don't act on the first sighting of a signal.** Every act-on",
21903
+ " branch is stall-window gated for a reason.",
21904
+ "- **Don't scan the issue queue and don't dispatch `issue-worker` on",
21905
+ " an issue.** That is the orchestrator's job, not this skill's.",
21906
+ "",
21907
+ "## Composability",
21908
+ "",
21909
+ "This skill composes with the pipeline; it never reimplements it.",
21910
+ "",
21911
+ "- **`pr-reviewer` owns review and arming.** Every path in this skill",
21912
+ " that needs a PR reviewed, re-confirmed, or armed invokes",
21913
+ " `/review-pr <n>` and lets the reviewer apply the policy. This skill",
21914
+ " contains no acceptance-criteria checking, no policy evaluation, and",
21915
+ " no `gh pr merge --auto` call.",
21916
+ "- **`orchestrator` owns the issue queue.** This skill never runs the",
21917
+ " queue scan, never claims or labels an issue, never creates a",
21918
+ " branch for an issue, and never dispatches `issue-worker` on one. It",
21919
+ " reads **open PRs** only.",
21920
+ "- **`issue-worker` owns fix-list application.** This skill never",
21921
+ " posts a fix-list, never applies one, and never writes a",
21922
+ " worker-report comment.",
21923
+ "- **The maintenance sweep owns stale-lease reconcile.** This skill",
21924
+ " observes lease states; it does not reconcile them.",
21925
+ "",
21926
+ "The only writes this skill makes are: `gh pr update-branch` (**D3**),",
21927
+ "a non-force `git push` of a conflict resolution (**R1**), and its own",
21928
+ "report. Everything else is a read or a delegation.",
21929
+ "",
21930
+ "Origin labels are **not** an eligibility gate here. Sweep and",
21931
+ `auto-merge eligibility have never been origin-gated, and ${DELEGATION_ELIGIBLE_ORIGIN_LIST}`,
21932
+ "both mark a PR bot-authored for fix-delegation purposes. Classify",
21933
+ "every open PR regardless of origin label \u2014 including PRs carrying",
21934
+ "none. Origin labels matter only where this skill quotes the",
21935
+ "reviewer's delegation guard, which admits",
21936
+ `${DELEGATION_ELIGIBLE_ORIGIN_PHRASE}.`,
21937
+ "",
21938
+ "## Output",
21939
+ "",
21940
+ "One line per PR, then a summary, then the cadence recommendation:",
21941
+ "",
21942
+ "```",
21943
+ "Cycle <ISO-8601 UTC> (stall window: <n>m)",
21944
+ " PR #<n> <CLASS> <action taken, or 'no action'>",
21945
+ " PR #<n> <CLASS> <action taken, or 'no action'>",
21946
+ "Summary: <total> open, <acted> acted on, <left> left to the pipeline",
21947
+ "NEXT_CHECK_IN <minutes>",
21948
+ "```",
21949
+ "",
21950
+ "Under `--dry-run`, the action column reads `would: <handler>` and the",
21951
+ "summary reports `0 acted on`.",
21952
+ "",
21953
+ "## Cadence",
21954
+ "",
21955
+ "The workload is **bursty** \u2014 quiet stretches punctuated by batches of",
21956
+ "related PRs \u2014 and mostly idle. A fixed 15-minute cadence was measured",
21957
+ "as too frequent for it: it multiplies no-op cycles without landing",
21958
+ "stuck PRs meaningfully sooner.",
21959
+ "",
21960
+ "**Preferred \u2014 dynamic self-pacing.** End each cycle by choosing the",
21961
+ "next delay from what the sweep actually saw:",
21962
+ "",
21963
+ "| Observation | `NEXT_CHECK_IN` |",
21964
+ "|-------------|-----------------|",
21965
+ "| Any conflict class, label anomaly, or a batch actively landing | 15 minutes |",
21966
+ "| All open PRs clean, armed, or converging | 25\u201330 minutes |",
21967
+ "| Queue empty | 45\u201360 minutes |",
21968
+ "",
21969
+ "**Simple \u2014 fixed interval.** Pass `--interval 30`. Thirty minutes",
21970
+ "halves the idle-cycle overhead versus fifteen and still catches stuck",
21971
+ "PRs well inside a tolerable window, because the default branch keeps",
21972
+ "advancing around a stuck PR regardless.",
21973
+ "",
21974
+ "Drop to 15 minutes only when you specifically want stuck PRs cleared",
21975
+ "as fast as possible during a heavy burst and accept the idle",
21976
+ "overhead."
21977
+ ].join("\n"),
21978
+ referenceFiles: [
21979
+ {
21980
+ path: "evals/evals.json",
21981
+ content: JSON.stringify(
21982
+ {
21983
+ skill_name: "babysit-prs",
21984
+ evals: [
21985
+ {
21986
+ id: 1,
21987
+ prompt: "/babysit-prs \u2014 there are three open PRs. #101 is armed for squash auto-merge and reports mergeStateStatus BEHIND, last updated four minutes ago. #102 carries review:fixing and review:needs-worker. #103 is MERGEABLE, armed, and CI is green.",
21988
+ expected_output: "The skill takes no action on any of the three and says so explicitly. #101 classifies as PROGRESSING, not BEHIND-STALLED: it was updated four minutes ago, well inside the stall window (2 x the interval, floored at 30 minutes), so it gets its convergence window and is left alone \u2014 no `gh pr update-branch`, no worktree, no push. #102 classifies as IN-FLIGHT-DELEGATION and is left untouched; the skill does not clear `review:fixing` or `review:needs-worker`, does not post a fix-list, and does not invoke the reviewer. #103 classifies as PROGRESSING and is left for the pipeline to merge. The report lists one line per PR with `no action`, a summary reading 3 open / 0 acted on / 3 left to the pipeline, and a NEXT_CHECK_IN recommendation of 25-30 minutes because everything is clean or converging. The skill never scans the issue queue and never calls `gh pr merge --auto`.",
21989
+ files: [],
21990
+ product_context_refs: []
21991
+ },
21992
+ {
21993
+ id: 2,
21994
+ prompt: "/babysit-prs \u2014 PR #204 is CONFLICTING. The only conflicting file is docs/src/content/docs/profiles/companies/index.md and the conflict is a single pair of table rows that two PRs inserted at the same position. The PR has carried review:awaiting-human for two hours with no review:fixing or review:needs-worker, and its latest worker-report comment records the synthetic:rebase-shared-index item as failed.",
21995
+ expected_output: "The skill classifies #204 as CONFLICT-SHARED-INDEX and runs the R1 handler, having confirmed all four eligibility checks: the path matches the shared-index glob set, every conflict hunk touches only `| ` data rows (not the frontmatter, H1, table header, or separator row), no conflicting path is a lockfile or projen-generated file, and the PR lacks `review:human-required` while carrying `review:awaiting-human` alongside a failed `synthetic:rebase-shared-index` worker report. It creates or reuses a detached worktree outside the user's checkout, checks out the PR branch there, merges the default branch in (merge, never rebase), resolves the conflict by union \u2014 keeping both rows, re-inserted in the file's declared sort order \u2014 stages the file, and verifies with `git show :<path> | grep -Fc` that each re-inserted row appears exactly once. On success it completes the merge commit and pushes with a plain non-force `git push`. It does NOT arm the PR, does NOT remove the `review:awaiting-human` label, and does NOT force-push. It removes the worktree before finishing and reports the resolution so the human sees a now-mergeable PR. Had any verification returned a count other than 1, the expected behaviour is `git merge --abort` plus a `BLOCKED` report line rather than a push.",
21996
+ files: [],
21997
+ product_context_refs: []
21998
+ },
21999
+ {
22000
+ id: 3,
22001
+ prompt: "/babysit-prs --interval 30 \u2014 PR #305 has been armed for squash auto-merge and stuck at mergeStateStatus BEHIND for the last three hours with no other activity. PR #306 carries both review:awaiting-human and review:needs-worker.",
22002
+ expected_output: "#305 classifies as BEHIND-STALLED: it is armed, BEHIND, and its updatedAt is older than the 60-minute stall window (2 x the 30-minute interval). The skill chases it by refreshing the branch, preferring `gh pr update-branch 305`; if that is unavailable it falls back to a worktree checkout plus `git merge --no-edit origin/<default-branch>` and a plain `git push`. It never rebases and never force-pushes, and if the local merge conflicts it aborts the merge and re-classifies rather than resolving. #306 classifies as LABEL-ANOMALY \u2014 `review:awaiting-human` together with a fix-delegation label is a mutually-exclusive invariant violation \u2014 and the skill re-invokes `/review-pr 306` so the reviewer's Phase 2.8 label reconciliation resolves it canonically and logs the correction. The skill explicitly does NOT run `gh pr edit --remove-label` on either `review:awaiting-human` or `review:needs-worker`, because the reviewer confirm pass, the issue-worker, and the maintenance sweep each own clearing their own label. The cadence line reports the pinned 30-minute interval.",
22003
+ files: [],
22004
+ product_context_refs: []
22005
+ }
22006
+ ]
22007
+ },
22008
+ null,
22009
+ 2
22010
+ )
22011
+ }
22012
+ ]
22013
+ };
22014
+ }
22015
+
21449
22016
  // src/agent/bundles/pr-review-policy.ts
21450
22017
  var DEFAULT_PATHS_EXEMPT_FROM_SIZE = [
21451
22018
  "docs/**"
@@ -23486,7 +24053,11 @@ function buildPrReviewBundle(policy = resolvePrReviewPolicy()) {
23486
24053
  // `agentConfig.additionalRulePaths`.
23487
24054
  filePatterns: [
23488
24055
  ".claude/agents/pr-reviewer.md",
23489
- ".claude/skills/review-pr/**"
24056
+ ".claude/skills/review-pr/**",
24057
+ // The operator skill quotes the policy's CI-verification
24058
+ // contract verbatim; loading the policy when it is edited
24059
+ // keeps the two from drifting.
24060
+ ".claude/skills/babysit-prs/**"
23490
24061
  ],
23491
24062
  content: [
23492
24063
  "# PR Review Policy",
@@ -23790,7 +24361,10 @@ function buildPrReviewBundle(policy = resolvePrReviewPolicy()) {
23790
24361
  // `agentConfig.additionalRulePaths`.
23791
24362
  filePatterns: [
23792
24363
  ".claude/agents/pr-reviewer.md",
23793
- ".claude/agents/issue-worker.md"
24364
+ ".claude/agents/issue-worker.md",
24365
+ // The operator skill's D2 handler routes on the label states
24366
+ // this protocol defines; it must load alongside them.
24367
+ ".claude/skills/babysit-prs/**"
23794
24368
  ],
23795
24369
  content: [
23796
24370
  "# PR Review Feedback Protocol",
@@ -24137,7 +24711,12 @@ function buildPrReviewBundle(policy = resolvePrReviewPolicy()) {
24137
24711
  tags: ["workflow"]
24138
24712
  }
24139
24713
  ],
24140
- skills: [reviewPrSkill, reviewPrsSkill],
24714
+ // `babysit-prs` is built from the resolved policy here rather than
24715
+ // declared as a module-level const, so the consumer's
24716
+ // `ci-verification.required-workflows` is baked into the rendered
24717
+ // skill at bundle-build time. Nothing rewrites skill content after
24718
+ // the bundle is assembled.
24719
+ skills: [reviewPrSkill, reviewPrsSkill, buildBabysitPrsSkill(policy)],
24141
24720
  subAgents: [prReviewerSubAgent],
24142
24721
  labels: [
24143
24722
  {