Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
d325942
preferences, ardia, gia: only work PRs the user opened or is assigned to
claude Sep 1, 2026
835b39b
memories: move the PR-scope rule to reviewing-prs.md, its designated …
claude Sep 1, 2026
3342a7f
ardia, gia, reviewing-prs: resolve the invoking user; fetch assignees…
claude Sep 1, 2026
86037f1
reviewing-prs, ardia, gia: workflow-opened PRs are in scope
claude Sep 1, 2026
c38a918
reviewing-prs, ardi, ardia, pr-sweep: address self-review findings
claude Sep 1, 2026
70a493f
reviewing-prs, gia, derive-dont-enumerate: carry the named-in-request…
claude Sep 1, 2026
5b35a5a
ardia, derive-dont-enumerate: semantic breaks on two long lines
claude Sep 1, 2026
722be6c
reviewing-prs, ardia, pr-overlap: third self-review round
claude Sep 1, 2026
27dcc5f
reviewing-prs: semantic break on the WORKFLOW_TOKEN sentence
claude Sep 1, 2026
2f0bcf2
reviewing-prs, ardia: fourth self-review round
claude Sep 1, 2026
a048423
reviewing-prs, ardia, ardiaei, derive-dont-enumerate: fifth self-revi…
claude Sep 1, 2026
ec1f57f
reviewing-prs, mma: sixth self-review round
claude Sep 1, 2026
d86a5bd
reviewing-prs: order the Dependabot clause so its pronoun binds
claude Sep 1, 2026
1414c3e
wrap-up, post-merge, sync-with-main, reviewing-prs, ardia: seventh se…
claude Sep 1, 2026
29d421c
cascade, mma, post-merge, wrap-up, ardia, tool-mappings, reviewing-pr…
claude Sep 1, 2026
52f2960
codex-skills: regenerate the tool-mappings wrapper
claude Sep 1, 2026
4796b3d
tool-mappings: register WHO_AM_I in the registry source
claude Sep 1, 2026
89c76ac
ardi, ardia, wrap-up: Copilot round two
claude Sep 1, 2026
cd248c7
Copilot round three: a mention is not a request; fail-closed identity…
claude Sep 1, 2026
f583dea
ardia, cascade, mma, reviewing-prs: finish the Copilot round-three edits
claude Sep 1, 2026
109ecea
Copilot round four: excluded PRs stay untouched; normalise author fields
claude Sep 1, 2026
fc37e37
AGENTS.md, reviewing-prs: Copilot round five
claude Sep 1, 2026
ff64e7e
Copilot round six: one contract for the Actions-app arm; no comments …
claude Sep 1, 2026
45ec685
preferences, reviewing-prs: Copilot round seven
claude Sep 1, 2026
cbe7644
Merge origin/main into claude/pr-authorship-scope
claude Sep 2, 2026
0fcf764
Copilot round eight: fail-closed fallback in AGENTS.md; keep headRefN…
claude Sep 2, 2026
fb82837
Self-review round: blank line at the merge splice, link #284 in ardia…
claude Sep 2, 2026
97101c6
Copilot round nine: gate commenting, reviewing, and merging; scope th…
claude Sep 2, 2026
a567167
Copilot round ten: aliases on the assignee arm; MCP assignees are log…
claude Sep 2, 2026
5e4b5f7
Copilot round eleven: chores arm in AGENTS.md; scope before preparing…
claude Sep 2, 2026
9f14daa
Copilot round twelve: date the MCP assignee measurements in Pacific time
claude Sep 2, 2026
2199b1a
Copilot round thirteen: scope test in check-history, batch-merge, and…
claude Sep 2, 2026
523b232
batch-merge-and-resolve: the Do bullet keys on the scope test too
claude Sep 2, 2026
90a5358
Copilot round fourteen: name the Actions app by slug; qualify the mem…
claude Sep 2, 2026
f0ba24c
Copilot round fifteen: scope the GII cleanup sweep, the post-merge re…
claude Sep 2, 2026
271ff39
CLAUDE.md: the batch-merge summary bullet keys on the scope test too
claude Sep 2, 2026
6512046
Copilot round sixteen: scope gi's takeover step; author and assignees…
claude Sep 2, 2026
ec54fc4
Copilot round seventeen and the automated review's note: park a child…
claude Sep 2, 2026
1c029f9
Copilot round eighteen: scope the chores predicate, mwc's peer-PR pat…
claude Sep 2, 2026
7178958
Copilot round nineteen: exact bot logins, alias set, bot-author arm k…
claude Sep 2, 2026
037a353
Copilot round twenty: name the Actions app in the canonical memory's …
claude Sep 2, 2026
1321fae
Copilot round twenty-one: reconcile the don't-touch-branches rule wit…
claude Sep 2, 2026
34d7a32
Copilot round twenty-two: executable alias expansion in chores; drop …
claude Sep 2, 2026
e900102
Copilot round twenty-three: request arm in chores; author arm in the …
claude Sep 2, 2026
15f9f17
Copilot round twenty-four: match only the documented bot login forms …
claude Sep 2, 2026
15e408c
chores: say how the two scope inputs are set, with examples beside th…
claude Sep 2, 2026
39d53cb
Copilot round twenty-five: make the chores identity fallback observable
claude Sep 2, 2026
96d79ca
chores: an empty identity yields an empty identity set, not [""]
claude Sep 2, 2026
48e6226
Copilot round twenty-six: parallel scope arms; explicit-request wordi…
claude Sep 2, 2026
bf0075e
Copilot round twenty-seven: qualify the out-of-scope examples by test…
claude Sep 2, 2026
cc48c7a
Copilot round twenty-eight: chores clears the aliases on identity fai…
claude Sep 2, 2026
b0800ba
Round twenty-nine and the automated review: keep the full list for is…
claude Sep 2, 2026
97cfd16
Copilot round thirty: gate the feedback and handoff comments on the s…
claude Sep 2, 2026
447fae7
Copilot round thirty-one: reapply the scope test before each write, n…
claude Sep 2, 2026
28c20e5
Copilot round thirty-two: an explicit exclusion veto in the chores pr…
claude Sep 2, 2026
988b545
chores: reapply the scope test before step 2's close as well
claude Sep 2, 2026
3b32086
scope test: an explicit exclusion vetoes every positive arm, everywhere
claude Sep 2, 2026
ab89045
scope recheck: cover GII step 3 and every chores predicate input
claude Sep 2, 2026
2ce74f9
check-history: scope authorizes a PR, a claim check says whether it i…
claude Sep 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,33 @@ This grants no merge authority: the strict merge policy below still applies.
(`gh issue reopen <issue-number>`) per
[`revert-merge.md`](shared/workflow/revert-merge.md).

## Only work PRs opened by the user, assigned to the user, explicitly requested by the user, or authored by the Actions app

Before pushing to, editing, commenting on, reviewing, resolving threads on,
dispatching a paid review of, or merging any PR, resolve the invoking user
and read the PR's author and assignees.
Proceed only when the author or one of the assignees is that user (or an
alias `memories/reviewing-prs.md` lists for that same user), the user
explicitly asked for work on that PR by name (or, through an explicit
`chores` call, on the Dependabot/Renovate population), or the author is the
GitHub Actions app (`github-actions`).
Comment thread
d-morrison marked this conversation as resolved.
A mention such as "do not touch" followed by a PR number is not a request, a
claim comment confers no scope, and a sweep skill's "every open PR" means
every PR that passes this test.
Comment thread
d-morrison marked this conversation as resolved.
An explicit exclusion ("do not touch" followed by a PR number) is a veto: it
removes that PR before any positive arm is evaluated, the user's own PRs and
the Actions app's included, and every sweep carries the exclusion list into
each recheck and each delegated scan.
A review-only run that CI or a skill invocation dispatched naming the target
PR (an `@claude review`, a `claude-code-review.yml` run) is that explicit
request, whoever authored the PR; it reviews and stops there.
An out-of-scope PR is reported to the user and left untouched.
Comment thread
d-morrison marked this conversation as resolved.
When no identity operation is available, fail closed the way `ardia` does:
leave the author and assignee arms unevaluated, act only on PRs the user
explicitly asked for or the Actions app authored, and say so in the report.
`memories/reviewing-prs.md` carries the full rule and its provenance;
`skills/ardia/SKILL.md` step 1 is the reference implementation.

## Always arm a persistent PR loop

This applies in any repo, not only Morrison-Lab ones.
Expand Down
6 changes: 5 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,8 @@ One to three sentences is enough.
The trailing marker is required, per the section above: this comment paraphrases the user in the user's own voice under the user's own login, which is the shape most easily read as their own writing.
Don't quote verbatim — paraphrase so it reads naturally in the PR thread.
Skip trivial acknowledgments or conversational exchanges with nothing to act on.
Post it only on a PR that passes `memories/reviewing-prs.md`'s scope test.
Feedback about an out-of-scope PR, such as a request not to touch it, stays in chat and the session notebook rather than on that PR.

This makes context visible to future @claude sessions, other reviewers, and contributors who only see the PR thread.

Expand Down Expand Up @@ -930,7 +932,7 @@ The key points, restated here because a bare pointer is invisible to a consumer
Attribution is a second axis, and it runs before the claim: intersect the merge's own deleted and renamed paths (`git diff --name-status -M "$merge^1" "$merge" | grep -E '^(D|R)'`) with each conflict, and report conflicts caused alongside conflicts found.
`git show --name-status <merge>` cannot supply that set for a **true** (two-parent) merge --- it prints no file list at all there, and grepping its header for `^[ADMR]` returns three phantom paths.
It does diff a squash merge normally, so whether it works depends on how the repo merges rather than on the commit in front of you.
A conflict you caused on a branch you do not own is an explanatory comment, not a push.
A conflict you caused on a PR that fails `memories/reviewing-prs.md`'s scope test is a report to the user, not a comment or a push.
- **Independent per-PR checking cannot see pair collisions.**
Every PR can be clean against `main` while two of them conflict with each other.
Only a pairwise `git merge-tree` between PR heads finds that.
Expand Down Expand Up @@ -1817,6 +1819,8 @@ recurred immediately in a `jq` filter reading a PR review body.)
A peer may have further commits planned, so merging one that just went clean can destroy work it was about to push --- and that is exactly the case where the peer's PR unblocks yours and the temptation is strongest.
Start the clock at the clean verdict on the current head, which a push resets, rather than at the PR's `updatedAt`, which any comment bumps.
The threshold is an inference, so confirm it: message the owning session directly when `ListAgents` reaches it, and otherwise post a comment saying you intend to merge and wait a further five minutes for a hold-off.
The path applies only to a peer PR that passes `memories/reviewing-prs.md`'s scope test (a peer session under your own login satisfies the author arm).
Another lab member's PR that fails the test gets neither the comment nor the merge.
[`mwc`](skills/mwc/SKILL.md)'s "Another session's PR" section carries the derivation and the pattern/anti-pattern pair (ai-config#2460).

**One standing exception: PRs targeting `Morrison-Lab/ai-config` carry a standing `mwc` grant**, with no per-session re-issue and no `enable-mwc` step --- `hooks/no-unauthorized-merge.py` reads the merge's target repo off the command.
Expand Down
2 changes: 1 addition & 1 deletion codex-skills/ardia/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: "ardia"
description: "Drive all open PRs to clean."
description: "Drive every in-scope open PR to clean."
---

# ardia (Codex wrapper)
Expand Down
2 changes: 1 addition & 1 deletion memories/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ index in that directory.
| File | Title | Covers |
|------|-------|--------|
| [`preferences.md`](preferences.md) | User preferences (cross-workspace) | Standing working rules: never-assume/always-verify, record learnings as you go, cite sources for tool-behavior claims, issue-first, and the ARDI / fully-clean definitions. |
| [`reviewing-prs.md`](reviewing-prs.md) | Reviewing someone else's PR | Leftover-artifact findings follow what the PR is landing, owner scope vs the author's mechanical box, review-only is not ARDI, and post every finding already in hand, split from `preferences.md` at the 1200-line gate (UCD-SERG/shigella#31). |
| [`reviewing-prs.md`](reviewing-prs.md) | Reviewing someone else's PR | Leftover-artifact findings follow what the PR is landing, owner scope vs the author's mechanical box, review-only is not ARDI, post every finding already in hand, and only work PRs opened by the user, assigned to the user, explicitly requested by name, or authored by the Actions app (a sweep's "every open PR" is not a scope grant; UCD-SERG/serodynamics 2026-09-01), split from `preferences.md` at the 1200-line gate (UCD-SERG/shigella#31). |
| [`github.md`](github.md) | GitHub PR/issue queue management | Operational write-action checklist, stale remotes, the GII startup sweep, stacked-PR pitfalls, consumer enumeration (`gh search code`), secondary rate limits, and `gh pr edit`. The `gh` CLI itself, GitLab, remote-session bash access, and consumer-CI content now live in their own split files (linked at the top). |
| [`gh-cli.md`](gh-cli.md) | GitHub CLI (`gh`) | The `gh` CLI behavior, rate limits, pagination, handling `GH_PAGER`, GraphQL vs REST pools, and fallback strategies. Split out of `github.md`. |
| [`github-remote-sessions.md`](github-remote-sessions.md) | GitHub access from bash in remote/web sessions | What a remote or web session can reach on GitHub from bash when `gh`/`glab` are absent: session-scope 403s, the MCP-then-`add_repo`-then-`git ls-remote` ladder, the proxy's push-but-not-delete rule, and GitHub Pages policy denials. Split out of `github.md` (ai-config#694 pattern) at the 1200-line gate. |
Expand Down
12 changes: 10 additions & 2 deletions memories/github.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,16 @@ Moved to [`gh-cli.md`](gh-cli.md).

When starting a GII loop, do a cleanup pass before diving into ARDI:

1. **List all open PRs** with `mcp__github__list_pull_requests`. Look for
stale bot-opened PRs that target the same issues as the queue.
1. **List all open PRs** with `mcp__github__list_pull_requests` (fields
`number,title,user,assignees`).
Keep the full list for step 3's issue-coverage detection, which only reads
it, and apply `reviewing-prs.md`'s scope test (opened by or assigned to the
invoking user, explicitly requested, or authored by the GitHub Actions app)
immediately before every mutation in steps 2 through 4 (the close in step
2, the close and the note in step 3, the merge in step 4): an out-of-scope
PR is reported to the user rather than closed, commented on, or merged
into, and an issue it already covers is left to it rather than grabbed.
Look for stale bot-opened PRs that target the same issues as the queue.
2. **Close empty PRs** — bot-opened branches with no commits (e.g. a `@claude`
task run that posted a comment but never pushed code). Check `get_commits`
on each PR before closing.
Expand Down
17 changes: 11 additions & 6 deletions memories/preferences.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@
Merge the most-isolated PR (disjoint files) FIRST --- it rides through without a re-resync; sequence foundational/big same-file PRs LAST so lighter PRs rebase onto simpler `main`.
An agent watching a PR must POLL its own `mergeable`/`mergeStateStatus` on EVERY watch tick (a newly-appearing conflict from someone else's merge is NOT a CI event, so a CI-completion monitor never fires on it), and on catching one immediately `git fetch origin main && git merge origin/main`, resolve, re-run checks, push --- staying in the watch loop until the PR is merged or closed (clean regresses to CONFLICTING when main moves).
The coordinator's nudge is only a backstop for a genuinely-dead agent. (Learned on sparta 2026-07-01 merging the movement cluster.)
Beyond same-file collisions: after ANY merge that advances the base (`main`), proactively re-sync EVERY trailing open PR branch and resolve conflicts --- don't wait for a branch to show DIRTY or for the next review trigger.
Beyond same-file collisions: after ANY merge that advances the base (`main`), proactively re-sync EVERY trailing open PR branch that passes `memories/reviewing-prs.md`'s scope test and resolve conflicts (an out-of-scope branch is reported to the user and left untouched) --- don't wait for a branch to show DIRTY or for the next review trigger.
In R packages the recurring conflicts are DESCRIPTION `Version:` (bump above main) and NEWS.md (union-merge, keeping both sides' bullets and one subsection per heading); the `@claude` bot auto-syncs non-conflicting branches but does NOT resolve these real DESCRIPTION/NEWS conflicts.
Sequential merges cascade version-check reds and NEWS/DESCRIPTION conflicts down the whole stack of trailing PRs, so keeping them all synced after each merge keeps the queue mergeable; parallelize with worktree-isolated workers, capped at ~3 concurrent to respect shared CI runners. (Learned on ucdavis/bcs.)
**The DESCRIPTION half of this cascade is obsolete once a repo adopts `Morrison-Lab/gha`'s new `bump-dev-version`/`version-check` capabilities (gha#390, tracking gha#388)** --- PRs stop touching `Version:` at all, so there's no version-bump conflict left to cascade down the stack.
Expand Down Expand Up @@ -397,8 +397,10 @@
The existing instruction already covered this; the gap was execution discipline in a fast multi-merge loop, not missing guidance --- re-read this bullet at the top of every "pick the next backlog item" cycle.
In a multi-AGENT pipeline, UMS runs at BOTH levels: each subagent runs UMS once ITS PR merges (it stops after reporting CLEAN, so the coordinator resumes it post-merge with a "your PR merged, run UMS" nudge --- or the agent-launch spec bakes in a final UMS step), and the coordinator runs its own UMS for the cross-PR orchestration learnings no single subagent can see (merge-order sequencing, conflict-cascade handling, pipeline mechanics).
Each agent writes its OWN memory file plus one MEMORY.md index line to keep the conflict surface small; avoid rewriting shared memory bodies concurrently. (Learned on sparta 2026-07-01.)
- After ANY PR merges to main (under mwc, post-merge, or manual merge), IMMEDIATELY and autonomously sweep all open PRs in the repository for merge conflicts (`gh pr list --state open --json number,title,headRefName,mergeable,mergeStateStatus`).
For any PR reporting `CONFLICTING` or `UNKNOWN`, fetch main, test the merge, resolve the conflict in an isolated worktree, and push the sync commit proactively without waiting for the user to point it out or ask for it. (Learned on ai-config, 2026-08-24: "cai: you should have checked PR conflicts on your own".)
- After ANY PR merges to main (under mwc, post-merge, or manual merge), IMMEDIATELY and autonomously sweep all open PRs in the repository for merge conflicts (`gh pr list --state open --json number,title,headRefName,author,assignees,mergeable,mergeStateStatus`).
Filter that list by `memories/reviewing-prs.md`'s scope test first (opened by or assigned to the invoking user, explicitly requested by name, or authored by the GitHub Actions app);
an out-of-scope conflicting PR is reported to the user and left untouched.
For any in-scope PR reporting `CONFLICTING` or `UNKNOWN`, fetch main, test the merge, resolve the conflict in an isolated worktree, and push the sync commit proactively without waiting for the user to point it out or ask for it. (Learned on ai-config, 2026-08-24: "cai: you should have checked PR conflicts on your own".)
Comment thread
d-morrison marked this conversation as resolved.
- Keep it simple.
Don't over-explain or ask permission for straightforward fixes --- just do them.
- Don't re-ask a decision that's already settled and built.
Expand Down Expand Up @@ -531,9 +533,12 @@
Both additions were already on `main` in fuller form, and the diff had also rewritten three *correct* relative links into broken ones --- the `check-links.py` failure being blamed on that session all along.)

- **Don't touch anyone else's branch.**
**Do:** only push to or modify branches I created in my own worktree.
**Don't:** push commits, force-push, checkout, or edit branches belonging to another session or user --- even if the content looks worth keeping or the branch looks abandoned.
If a branch needs work that isn't mine, flag it and let the owner handle it. (User directive, 2026-08-19.)
**Do:** only push to or modify branches I created in my own worktree, or a PR branch that passes `memories/reviewing-prs.md`'s scope test (opened by me, assigned to me, explicitly requested, or the Actions app's) and carries no live claim from another session.
**Don't:** push commits, force-push, checkout, or edit branches belonging to another session or user that fail that test --- even if the content looks worth keeping or the branch looks abandoned.
If a branch needs work that isn't mine, flag it and let the owner handle it.
A live claim on an in-scope branch still means waiting for it to expire, per `claim-pr`.
(User directive, 2026-08-19.
The scope-test carve-out follows the 2026-09-01 directives in `reviewing-prs.md`.)
- **A delegated subagent runs in the parent session's working tree, so the "Use ONE worktree per branch/PR" rule above governs your own agents, not only other sessions.**
The remedy is already written down: [`gip`](../skills/gip/SKILL.md) says to
give every subagent `isolation: "worktree"`, and
Expand Down
Loading
Loading