Skip to content

pr-pipeline: inputs from the 2,000-PRs effort, and the local-lane work waiting on deployed lanes #6202

Open

Description

@kyle-sexton

Problem

The 2,000-PRs effort (integration branch feat/poteto-2500-prs-digest) planned merge authority, a post-PR
stage and a post-merge stage before #6139 added the PR pipeline convention (docs/conventions/pr-pipeline/,
ADRs 0049-0051). The pipeline now governs those stages. The effort's merge work is redesigned as the local
babysit lane that docs/conventions/pr-pipeline/README.md:204 allows ("A repository has one merge
authority: either the local babysit lane (loop-lane) or pr-merge"). That lane reads the same rung and
work-class config as pr-merge; no second merge rubric is built.

The effort builds none of this local-lane work until the pipeline's verify, merge and post-merge lanes are
deployed. Until then the local lane has no review verdict to read, and nothing lowers the merge rung after
a bad merge. This issue does two things. It hands the pipeline effort the items that belong in its lanes
or schema, and it records the deferred work and its design, so that work can be re-planned once the lanes
exist. Slice numbers below are the effort's own work-unit numbers, given so its pull request can cross-refer.

Inputs for the pipeline effort

  1. Say which merge authority a repository uses. README:204 states the one-authority rule, but the
    schema has no field for it. Proposal: merge.authority with values pr-merge and local-babysit.
    Until such a field exists, the local lane treats any configured pr-merge lane as "not mine". Lanes
    and slots are enabled by default in the schema.
  2. Name the rung-lowering repository variable and the kill switch (README:100, README:198-200), so a
    local lane can honour both. Proposal: a 404 from a readable variables endpoint means "not lowered",
    and any other failure means rung off.
  3. Tie verdict check runs to the lanes App. Any workflow with checks: write can post a check run
    named <lane> / <activity>. Name the App's identity in a lane-power file, so readers accept only check
    runs that App posted.
  4. Add to the reader-forced denied paths: AGENTS.md, CLAUDE.md and .claude/** at any depth;
    every docs/conventions/*.yaml lane-power or policy file (for example execution-target.yaml, which
    chooses where unattended stages run); docs/conventions/workspace-environment.md (a repository's entry file), whose setup,
    up, info and down commands lanes run unattended in every worktree; and the merge wrapper's
    scripts. Until the pipeline adopts them,
    the local lane keeps its own forced set as a superset of the pipeline's.
  5. Read team config at the base SHA. README:98-99 covers the lane's own config. A skill a lane calls
    should also read docs/conventions/*.yaml and instruction files at base-sha, not the PR head, or a PR
    can change the rules it is judged by. The effort's shared reader (lib/parse-concern-value.sh) gains a
    validated --ref for this.
  6. Record a relocated <root> where a local reader can find it. README:37-38 lets a repository move
    <root>; plugin readers use the fixed docs/conventions.
  7. Post-merge smoke check and canary. Where a consumer deploys, post-merge-verify should run the
    consumer's declared smoke check against that environment, and a silent-revert canary alert should file
    a raw issue linking the PR. Candidate activity: a non-interactive verification:confirm post-merge mode.
  8. C4 (structural work) under the local lane. Proposal: the local lane refuses C4 at any rung, because
    ADR 0050 requires three independent checkers including a Codex judge, which only CI lanes provide. C4
    autonomy stays with pr-merge.
  9. When a respond lane counts as active. Proposal: enabled in config, and its workflow file present on
    the default branch. babysit-prs stands down for that duty only then. A consumer who copies the example
    config, which enables every lane, must not lose babysit's feedback, CI-fix and base-update work while
    the lanes do not exist.
  10. Refine and verify slots. code-metrics:audit-suppressions as a pr-run-checks gate (its
    non-interactive findings output ships in the effort), and code-tidying:dissolve-comments report --added-since as a pr-refine slot, in place of a local comment pass at PR prep.
  11. Skills the example lanes call ask questions nobody answers under dontAsk.
    source-control:pull-request asks for approval (SKILL.md:229,236) when called as fix-ci and
    address-feedback. verification:confirm asks for the goal (SKILL.md:115) when called as
    check-intent. batch-simplify is called without its unattended flag. review:fanout is a review
    fan-out, not a late-comment sweeper. None of the called skills writes detector-findings or a record
    bundle.
  12. Plan comment as a check-intent input. With plan_store: tracker (planning's userConfig, or
    the plan_store key in docs/conventions/planning.yaml, which wins), /planning:plan posts the
    approved plan to the claimed work item through /work-items:track publish-plan as one comment whose
    first line is <!-- planning:plan v1 -->; a re-publish edits that comment in place. check-intent
    may read it through the issue input, taking only a comment whose first line is that marker and
    whose author is a trusted actor (the newest when there are several), and treats the plan text as
    data.
  13. Plugins for CI lanes. The cloud bootstrap's plugin list covers local-lane stages only. CI lanes
    need the plugins that own their activities' skills.
  14. Model and effort per lane. The schema sets no model or effort per lane or activity. ADR 0045 makes
    the multi-agent plugin the routing owner.
  15. The review of record. pr-review runs review:code-review, which reads only CLAUDE.md and
    REVIEW.md. The effort's paved-path and file-size rules reach that review only through REVIEW.md.
    feat(source-control): call review:explain-change from the pull-request ready flow #6107 adds an explain call at ready, beside the pr-explain lane.
  16. Upstream producer naming and trust. The standards vocabulary has no upstream function words for
    the effort's monthly upstream-drift workflow. The issues it files as github-actions[bot] carry text
    from upstream repositories into intake, so that bot should not count as a trusted actor.

Deferred local-lane work

Each item waits for the deployed verify, merge and post-merge lanes, then is re-planned against them. The
design that was planned before deferral is in each collapsed section.

Constraints for that re-plan:

  • No local merge authority without a deployed post-merge-verify.
  • The local lane never writes work-class: labels: a label the operator's own identity sets cannot be told
    apart from a human's (README:141-143).
  • A config parse error resolves the whole file to rung off, never one key from a partly parsed file.
  • The canonical example config is a reader test fixture.
22: babysit reads merge authority from the pipeline config

babysit's merge gate reads merge.rung, merge.diff-check and lanes from the target repository's
docs/conventions/pr-pipeline.yaml, fetched through the contents API from its default branch, as it
fetches .claude/source-control.md today. The text goes to the shared reader on stdin. The lane rung key
babysit_loop_merge retires, with a retirement record so the new reader warns when the key is still
present. The rung is capped by the rung-lowering variable (input 2). A missing file, extends: or a parse
error resolves off.

23 and 30: review verdict and the non-author verify stage

Planned before the pipeline: a non-author verify session before ready, which wrote a
review: independent pass label with a head, base and patch-id marker. Redesign proposal: the local lane
accepts only the pipeline's verify verdicts. That means a passing, App-posted check run (input 3) for each
verify-stage gate activity the config declares, on the final commit or one with the same patch id
(README:138, 201-202), plus ci-status green.

24: the merge wrapper's gates

Gates: the effective work class (the strictest work-class: label on same-repository closing issues,
re-checked against the diff) against the rung; the effective denied paths (renames included) and the line
cap; the verdict above; holds; ci-status. C4 is refused locally (input 8) and C5 always. A person's
"merge these" grant keeps every base gate. An authority refusal exits 11.

On a merge-queue base, gh pr merge enqueues with or without --auto (commit af63181), and it arms
auto-merge instead when required checks are pending. The design re-reads that every required check passed
on the pinned head (--match-head-commit) just before the call, and disables an armed auto-merge. A later
read-back files needs-human when the merged head differs from the gated head. GitHub's merge-queue docs
do not say what a push to a queued PR's head does, so the design does not rely on one.

25: loop-lane "Autonomy ladder (merge authority)" text

Posted on #6140, which rewrites the same section. Both merge authorities read merge.rung. The per-run
raise autopilot --merge c3-this-run and its pre-escalation dispatch retire, because a rung rises only
through a merged config change (README:198).

26: unattended local lanes launched in auto mode

Scheduled local runs launch headless with --permission-mode auto. A denied action that needs a person
posts an escalation marker. The new AGENTS.md sentence sits beside the CI-lane dontAsk clause and names
local lanes only.

27 and 122: turning local merge on, and the probe

Turning local merge on is the merged config change README:191-192 describes. The probe runs a local
--bg auto-mode babysit lane on the scratch repository kyle-sexton/autonomy-demo-scratch, plus a
control run. Its config declares a verify activity whose check run is App-posted. It uses no
merge.authority key until the schema has one. The record names the levers a consumer would need if the
auto-mode classifier denies the merge ("Merge Without Review").

28: a cloud session merging through the wrapper

The probe tests whether a Claude Code cloud session can prove readiness and merge through the wrapper. The
cloud proxy serves only pinned GraphQL operations. It matters only if a repository runs its local lane on
a cloud host.

29, 45 and 130: stage hand-offs

/work-items:work ends with /source-control:pull-request ready (the pipeline's entry, README:50),
instead of monitoring the PR itself. babysit-prs stands down for each respond duty whose lane is active
(input 9) and keeps it otherwise. The draft-elevation setting babysit_loop_draft_elevation (which
decides when babysit treats a draft as still being built) applies to non-pipeline PRs only. The work-items
stage notes map onto the pipeline's stage keys (intake, pre-ready) instead of a second stage list.

37, 38 and 39: post-merge

Planned before the pipeline: a verification:confirm post-merge mode, called by every local merge path;
and a push-to-main workflow labelling post-merge: check pending on merges neither path made.
Superseded in design by post-merge-verify (README:79). Input 7 carries the smoke check and canary.

43: "Merged in window" in the morning brief

The morning brief shows recently merged PRs when the pipeline config's rung is above off.

125: work-loop dispatches an item's build to its class execution target

Deferred until Claude Code offers a cloud launch that starts without a terminal. A scratch-repository
probe showed claude --cloud refuses to start without a TTY, and under a pseudo-terminal it stops at the
folder-trust dialog, which an unattended lane must never answer. Merging it as a path that always falls
back to local was declined: no caller could use it. Re-plan against whatever non-interactive launch
exists then, keeping the execution-target guard (an untrusted-input stage never reaches a cloud host
that has not passed the probe).

Done when

  • The pipeline effort has accepted, declined or scheduled each of the 16 inputs, and recorded its answer
    here.
  • Inputs 1-3 and 7 are settled, and the verify, merge and post-merge lanes are deployed. The deferred work
    is then re-planned, citing this issue, and the issue closes.

Amendment (auto-merge-safe-prs)

Decisions from the auto-merge-safe-prs plan, accepted by the user on 2026-10-12. Where this section and the
text above disagree, this section wins. Phase numbers refer to that plan.

What changes

  • Merges are no longer human-only. The babysit lane may merge, without a human, a same-repository C2
    pull request that the new diff risk scorer rates LOW, on review evidence bound to the pinned head SHA.
    Everything else stays human-merged.
  • The wrapper is the one merge authority. babysit_merge.py (--unattended) makes every unattended
    merge decision, on every host. No GitHub Actions merge workflow is built, and pr-merge is not deployed
    in this repository.
  • The deferral ends early for this repository. The deferred local-lane work no longer waits for the
    pipeline's verify, merge and post-merge lanes. The constraint "No local merge authority without a deployed
    post-merge-verify" is met by the wrapper's own post-merge check (phase 10) instead.
  • V1 merges nothing until two things are live: the post-merge check (phase 10), and the agent identity,
    a GitHub App installed on this repository only (filed in melodic-software/github-iac). Until both exist,
    the unattended path refuses. It is turned on by one human-merged config change (phase 15).
  • C2 only at launch. C3 joins only by a merged config change once its promotion evidence holds. C4 stays
    human-gated and C5 human-merged; no C4 rung is added.

Answers to the inputs and deferred items

  • Input 1: accepted as merge.authority (local-babysit | pr-merge), plus merge.agent-identity,
    which is required when the authority is local-babysit (phase 5).
  • Input 2: accepted. The rung-lowering variable is CLAUDE_LANES_MERGE_RUNG_CAP (off/C2/C3),
    human-set and lower-only; the wrapper never writes it. A 404 after a proven-readable listing means no cap;
    any other failure means off. Kill switches: CLAUDE_LANES_DISABLED (org) and
    CLAUDE_LANES_REPO_DISABLED (repository) must each read exactly false; a read error or a
    repository-level CLAUDE_LANES_DISABLED shadow refuses. A post-merge failure is recorded as a marker issue
    that only a human can clear by closing it.
  • Input 3: superseded by run-bound evidence. Per lane, the newest run of the lane's caller workflow on
    the pinned SHA must conclude success and carry a completion annotation and marker for that SHA (phase 9).
    This depends on the review lanes failing when no review completed (fix(review): AI review lanes report success without posting a review on large PRs #7257, phase 3). The App-posted check
    run design in items 23 and 30 is replaced by this.
  • Input 4: accepted as the HIGH path floor, fixed in code and unioned with merge.diff-check.denied-paths.
    A HIGH path is never auto-merged.
  • Input 5: accepted. Config is read at the base SHA.
  • Input 7: accepted as four post-merge signals: the scheduled full pr-require-checks run, a full run
    dispatched per auto-merged SHA, the silent-revert canary, and a read-back that the merged headRefOid
    equals the pinned SHA. A red full run gets one re-run of its failed jobs first: red again counts as a
    failure, green records a flake. A failure files the demotion marker issue, which holds the rung at off
    until a human closes it directly. Only one unattended merge is in flight at a time. No auto-revert in V1. No deploy-target smoke
    check, but owner decision 16 (2026-10-14) requires a per-PR live smoke of changed skills before the first unattended merge of any PR touching plugins/*/skills/** or plugins/*/agents/**; until it exists those PRs are excluded from auto-merge.
  • Input 8: accepted. C4 is refused locally.
  • Item 22: adopted, except that babysit_loop_merge does not retire. It stays as a second cap, lowered
    to c2-mechanical (phase 2). The effective rung is the minimum of merge.rung, babysit_loop_merge, the
    cap variable and any open demotion.
  • Item 24: adopted. Merges go through the merge queue with --match-head-commit, never --auto, and
    only when every required check is green; an armed auto-merge is a refusal that the wrapper disarms.
  • Item 25: the proposal stands. The paired raise c3-this-run can no longer widen an unattended merge.

New external effects

  • Merge-group backstop job (phase 11). A new job in pr-require-checks.yml, needed by ci-status,
    with issues: read. For every queue entry a non-human enqueued, it re-checks from the base SHA the rung,
    the kill switches and the fixed rules (HIGH paths, size, label provenance, demotion issue, holds, one merge
    in flight, ALLGREEN grouping), and fails the group on any miss. It can eject queue entries.
  • Post-merge alert workflow (phase 12). A new workflow_run workflow with issues: write only. When a
    scheduled or dispatched full run, or the canary, fails on main, it files the demotion issue as
    github-actions[bot], so detection does not wait for a lane cycle.

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 4, 2026
  2. github-actions commented on Oct 4, 2026

    @github-actions
    Contributor

    Thanks for the report. Automated triage handed this issue to a maintainer.

    Automated triage. A maintainer reviews it.

  3. added
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 4, 2026
  4. kyle-sexton commented on Oct 12, 2026

    @kyle-sexton
    MemberAuthor

    Parked work from #7009: slice 125, the per-item cloud launch. It was not merged.

    • Branch: slice/125-class-execution-target at 302ee81cb (3 commits, 10 files). It dispatches an item's build to its class execution_target and lets autonomy and harness-ops choose each stage's host.
    • Why it is parked: a live probe could not start a cloud session. claude --cloud refuses without a TTY, and under a pseudo-terminal it stops at the folder-trust dialog, which an unattended lane must never answer. As built, the per-item cloud launch cannot run, so merging it would ship dormant code.
    • What would unblock it: a non-interactive cloud launch path, which is this issue's lane-deployment design to settle. When that path exists, rebase the branch onto it or rebuild it, then re-run the probe. Its security-surface review is in the feat: adopt the 2,000-PRs talk decisions across the marketplace #7009 record: no path from an untrusted stage to a cloud host, and ET_TRUSTED_STAGES is empty.
  5. removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 12, 2026
  6. added theissue type on Oct 12, 2026
  7. kyle-sexton commented on Oct 13, 2026

    @kyle-sexton
    MemberAuthor

    For Q99 and Q128: the "Instructed, not enforced" gap is closed by #7050 (merged 2026-10-12, Refs: #7008). The promotion-evidence helper now reads the four promotion_evidence_* values itself from managed and user settings only; values set through --settings, server-managed settings or MDM read as unset, so the helper fails closed on them. #7008 closes as completed with this note. The Phase 3 security review of that enforcement is tracked on #4588.

    This was generated by AI.

  8. kyle-sexton commented on Oct 13, 2026

    @kyle-sexton
    MemberAuthor

    For the Q99 and Q128 owners: the channel-F gap from #7008 is closed. #7050 makes the promotion-evidence helper read its options only from operator settings, and #7364 tests that a lane-chosen checker or binding (argv, the CLAUDE_PLUGIN_OPTION_* mirror, checkout settings, .claude/source-control.md) never yields promoted.

    The remaining promotion-evidence work is tracked in #4588. Shipped there: the per-host deployment requirements (#7357), operator credential roots for the checker (#7362), the resolver's lane-writability refusal (#7370), the end-to-end test (#7364), eval cases (#7367) and an evidence publisher in report mode (#7361). Still open: the resolver's freshness check on the publisher's output and its deployment, which wait on the one-merge-authority decision. Unattended merge stays off; nothing here widens merge authority.

  9. kyle-sexton commented on Oct 15, 2026

    @kyle-sexton
    MemberAuthor

    D0 recorded (owner decisions 57, 57a, 72-73, 2026-10-14): the single merge authority is the Automation Lanes script-only CI pr-merge lane (reads babysit_merge_policy.py, #7467), not a local babysit_merge.py lane; Phase 15 of the local plan is superseded and #7334 is closed. pr-merge stays report-only until it judges a real lane-authored PR. Promotion evidence is computed inline (#7516, #7526); remaining wiring is #4588. Decision 16 is tracked in #7529; post-V1 retro in #7531.

  10. kyle-sexton commented on Oct 18, 2026

    @kyle-sexton
    MemberAuthor

    Decision recorded.

    Question: The issue holds 16 pipeline inputs and some deferred local merge-lane designs. A 2026-10-14 comment made the CI pr-merge lane the only merge authority, which retires the local lane. Options: (a) close as superseded; (b) file the still-live inputs as separate issues, then close; (c) keep it open as the record.

    Owner's answer: (b) but narrower. The issue's 2026-10-12 amendment already answers inputs 1-5, 7 and 8. Check only inputs 6 and 9-16 against pr-merge. The local-lane sections are moot. Basis: #6202 body and D0 comment.

    The owner accepted this recommendation as item D12 of a 32-decision batch in an attended backlog-shaping session on 2026-10-18. The batch question: "Accept all 32 recommendations, including the four flagged above (D2 close the relearn, D26 cross-repo sync without per-repo confirm, D10 narrow hook, D23 delete guard only)?" The owner answered: "Accept all 32 (Recommended)".

    Posted by AI from the owner's answer in that session.

  11. added
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.

    Type

    Fields

    No fields configured for Task.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions