You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Generated PR ownership is split across overlapping controllers. Maint 71 filters only sync/workflows- heads today (.github/workflows/maint-71-merge-sync-prs.yml:284), while Maint 82 and .github/scripts/sync_dependency_campaign.js:493-530 separately decide which exceptions are claimable by Codex. Dev-tool-sync PRs therefore follow a different merge path, and unchanged exception state can continue to produce automation work.
This is a current efficiency defect: repeated observation of the same blocker consumes agent runs without changing repository state. One repository-owned reconciliation contract should decide merge/close disposition, and agent handoff should occur only when the exception fingerprint changes.
Scope
Make Maint 71 the sole generated-PR merge/close reconciler for both sync and dev-tool-sync lanes. Make Maint 82 the durable state and exception classifier. Publish a stable handoff record that opener/closer and sync-dependency automation can consume without duplicating policy.
Non-goals
Do not move business logic into local automation configuration.
Do not auto-merge PRs with unresolved active review debt, real test failures, or source-template conflicts.
Do not wake a coding agent merely because a scheduled poll observed unchanged state.
Do not count a workflow scaffold as complete until fixtures prove deduplication across multiple scheduled runs.
Implementation tasks
Extend .github/workflows/maint-71-merge-sync-prs.yml to reconcile both sync/workflows- and deps/sync-dev-versions- PRs through the same contract.
Centralize classification in .github/scripts/sync_pr_merge_contract.js: current, awaiting-checks, review-blocked, repo-local-failure, shared-source-failure, superseded, expired, and owner-decision.
Have Maint 71 emit a normalized result record containing PR identity, head SHA, delivery generation, check/review state, disposition, blocker owner, and exact next command.
Make .github/workflows/maint-82-sync-dependency-auto-pilot.yml consume those records and own durable campaign state rather than recomputing merge disposition independently.
Extend the existing fingerprint in .github/scripts/sync_dependency_campaign.js to include only state that should trigger new work; preserve updated_at, claim generation, and lease history.
Apply campaign:needs-local-codex only for new or materially changed actionable exception fingerprints, and remove it after terminal disposition or successful claim completion.
Document the remote handoff schema and local-consumer migration in docs/ops/SYNC_DEPENDENCY_CAMPAIGN.md; mark local watcher changes as an operator follow-up, not repository implementation.
Add observability showing new, unchanged, resolved, and re-opened exception counts per run.
Acceptance criteria
.github/scripts/__tests__/sync_dependency_campaign.test.js proves the same exception observed on three consecutive runs creates one claim generation and one agent handoff.
.github/scripts/__tests__/sync_pr_merge_contract.test.js applies identical merge/review/check rules to sync and dev-tool-sync fixtures.
Workflow tests prove Maint 71 is the only path that merges or closes generated PRs and Maint 82 only persists state and requests bounded exception work.
A changed head SHA, review-thread set, check-failure cluster, or delivery generation creates a new fingerprint; a timestamp-only change does not.
Durable state records the exact blocker owner and next command, allowing an opener/closer run to resume without rediscovery.
Deliberate-break test: remove fingerprint persistence or vary only updated_at, verify the campaign test detects duplicate handoffs, then revert and verify it passes.
Run python scripts/dev_check.py --action test and workflow validation successfully.
Delivery notes
The repository contract should be sufficient for local automations to become thin pollers. A separate operator change may update those local pollers after this issue merges, but that external mutation is not part of this issue's completion claim.
Why
Generated PR ownership is split across overlapping controllers. Maint 71 filters only
sync/workflows-heads today (.github/workflows/maint-71-merge-sync-prs.yml:284), while Maint 82 and.github/scripts/sync_dependency_campaign.js:493-530separately decide which exceptions are claimable by Codex. Dev-tool-sync PRs therefore follow a different merge path, and unchanged exception state can continue to produce automation work.This is a current efficiency defect: repeated observation of the same blocker consumes agent runs without changing repository state. One repository-owned reconciliation contract should decide merge/close disposition, and agent handoff should occur only when the exception fingerprint changes.
Scope
Make Maint 71 the sole generated-PR merge/close reconciler for both sync and dev-tool-sync lanes. Make Maint 82 the durable state and exception classifier. Publish a stable handoff record that opener/closer and sync-dependency automation can consume without duplicating policy.
Non-goals
Implementation tasks
.github/workflows/maint-71-merge-sync-prs.ymlto reconcile bothsync/workflows-anddeps/sync-dev-versions-PRs through the same contract..github/scripts/sync_pr_merge_contract.js: current, awaiting-checks, review-blocked, repo-local-failure, shared-source-failure, superseded, expired, and owner-decision..github/workflows/maint-82-sync-dependency-auto-pilot.ymlconsume those records and own durable campaign state rather than recomputing merge disposition independently..github/scripts/sync_dependency_campaign.jsto include only state that should trigger new work; preserveupdated_at, claim generation, and lease history.campaign:needs-local-codexonly for new or materially changed actionable exception fingerprints, and remove it after terminal disposition or successful claim completion.docs/ops/SYNC_DEPENDENCY_CAMPAIGN.md; mark local watcher changes as an operator follow-up, not repository implementation.Acceptance criteria
.github/scripts/__tests__/sync_dependency_campaign.test.jsproves the same exception observed on three consecutive runs creates one claim generation and one agent handoff..github/scripts/__tests__/sync_pr_merge_contract.test.jsapplies identical merge/review/check rules to sync and dev-tool-sync fixtures.updated_at, verify the campaign test detects duplicate handoffs, then revert and verify it passes.python scripts/dev_check.py --action testand workflow validation successfully.Delivery notes
The repository contract should be sufficient for local automations to become thin pollers. A separate operator change may update those local pollers after this issue merges, but that external mutation is not part of this issue's completion claim.