Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ All notable changes to this portable workflow pack are documented here.

#### Added

- **Add `skills/pr-batch/bin/stale-assignment-sweep`, a dry-run-first warn-then-release sweep that decays inactive human assignments (nudge → 4-day grace → release) using anti-squatting and inactivity clocks renewed only by the assignee's own comments, reviews, and issue-referencing commits or linked-PR events, pausing on exempt labels, skipping `agent-claimed` items, re-checking live state before every comment or release, and never touching automation-set assignees (failing closed when the automation set or its own posting identity is unresolved).** [issue 209](https://github.com/shakacode/agent-workflows/issues/209).
- **Make batch selection and triage assignee-aware: a human assignee reserves an issue or PR (owned means skip), reserved items are listed with their assignee names instead of silently dropped, and items with no assignee or only an automation identity stay eligible.**
- **Add a bounded exact-head PR merge helper that safely selects direct merge or merge-queue submission, reconciles ambiguous outcomes, and preserves unknown provenance.**
- **Add Codex picker metadata (`agents/openai.yaml`) for `continue`, `status`, `tdd`, `run-ci`, `verify-pr-fix`, and `untrusted-contributor-intake`, and document `qa-stress` as the deliberate picker-metadata exclusion.**
Expand Down
1 change: 1 addition & 0 deletions bin/validate
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ ruby skills/pr-batch/bin/pr-merge-submit-test.rb
ruby skills/pr-batch/bin/stage-dependency-gate-test.rb
ruby skills/pr-batch/bin/agent-coord-bounded-test.rb
ruby skills/pr-batch/bin/pr-security-preflight-test.rb
ruby skills/pr-batch/bin/stale-assignment-sweep-test.rb
ruby skills/task-observer/bin/task-observer-test.rb
ruby skills/untrusted-contributor-intake/bin/untrusted-contributor-intake-contract-test.rb
ruby skills/update-changelog/bin/changelog-merged-prs-test.rb
Expand Down
44 changes: 44 additions & 0 deletions docs/pr-batch-skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,50 @@ The `agents/openai.yaml` file under a skill is optional Codex UI metadata for sk

Beyond permissions, selection itself is assignee-aware: a human assignee — any assignee outside the repo's resolved automation set — marks an issue or PR as reserved: owned means skip. The automation set is resolved from the trust config's `trusted_bots` plus `[bot]`-suffixed logins via the `pr-security-preflight` chain (`trusted_users` are human actors and stay reservable), failing closed to skip when unresolved. `$plan-pr-batch`, `$triage`, and `$plan-issue-triage` classify assignees after fetching the full scoped set (`no:assignee` alone omits automation-only-assigned eligible items), exclude reserved items from actionable batches, and list them with their assignee names; items with no assignee, or only an automation identity, stay eligible.

## Stale-Assignment Sweep

Because owned means skip, an assignment left with no follow-through would block
that work forever. `skills/pr-batch/bin/stale-assignment-sweep` treats assignment
as a lease, not a deed: it nudges, then (only after an unanswered grace) releases
inactive human assignments back to the batch pool. It is the human-timescale
analog of the coordination backend's agent heartbeat leases.

- **Default is dry-run.** With no `--apply`, it makes zero GitHub mutations and
only prints a digest of would-nudge / would-release items, each with its clock,
days inactive, and assignee. Run it report-only for ~2 weeks to tune TTLs
before enabling writes. `--apply` posts the nudge/audit comments and removes
assignees.
- **Clocks (config-driven).** `time-to-first-activity` (default 7 days): assigned
but zero activity by the assignee since assignment — the primary anti-squatting
clock. `inactivity-after-start` (default 14 days for issues, 7 for PRs): no
assignee activity for the TTL. Activity that renews a lease is the assignee's
own comments, reviews, and issue-referencing commits or linked-PR events — not
raw timeline commits, which carry no GitHub login and so cannot be attributed
(a commit renews only when it surfaces as a `referenced`/`cross-referenced`
timeline event). Other people's activity does not renew it. The report-only
rollout is how you validate this activity coverage before enabling writes.
- **Flow: nudge → grace → release.** At threshold it posts a nudge comment; four
days (`--grace-days`) after an *unanswered* nudge it removes the assignee and
posts an audit comment. It never releases without a prior unanswered nudge. Any
assignee reply resets the clock; exempt labels (`--exempt-label`, default
`blocked`, `on-hold`) pause it.
- **Automation is never swept.** An assignee is automation when its login carries
the `[bot]` suffix *and* its base name is in the trust-config `trusted_bots` set
(resolved via the `pr-security-preflight` chain), mirroring
`pr-security-preflight`'s own bot check — a bare login is human even if it
matches a bot's base name, and `trusted_users` are humans and remain
reservable/sweepable. Items carrying the `agent-claimed` label are skipped
entirely (agent-claim staleness is owned by backend heartbeats). When the trust
config cannot be resolved it fails closed: human assignments are left untouched.
Every skip is reported, so nothing is silently dropped.
- **Config & determinism.** `--repo` (repeatable or comma-separated; defaults to
`gh repo view`), `--first-activity-ttl-days`, `--issue-inactivity-ttl-days`,
`--pr-inactivity-ttl-days`, `--grace-days`, `--exempt-label`,
`--comment-identity`, `--trust-config`. Inject the reference clock with `--now`
or `STALE_ASSIGNMENT_SWEEP_NOW`; bound gh with
`STALE_ASSIGNMENT_SWEEP_GH_TIMEOUT_SECONDS`. Run it on a schedule (Actions cron
or the coordination daemon).

## Whole-Surface Triage Flow

Use `$triage` when the coordinator wants the generated equivalent of a manual
Expand Down
Loading
Loading