Repository navigation
dev-lead fix-bot-comment edits a verbatim org-standard stub on a standards-sync PR when a bot suggests it — the PR drifts from the template it syncs #2185
Description
Problem
On a standards-sync PR, a dev-lead fix-bot-comment pass will edit a verbatim org-standard caller stub when a review bot suggests it. The PR then no longer matches the template it exists to sync, and with auto-merge on it can land that way.
Nothing in dev-lead stops this:
prompts/dev-lead/fix-bot-comment.mdhas one stub guardrail (line 44, "never forward an undeclared input across a channel pin"). It says nothing about a stub whose header readsSOURCE OF TRUTH: petry-projects/.github/standards/workflows/<name>.yml, or about a PR labeledstandards-sync.- The harness (
scripts/dev-lead-fix-reviews.sh) has no check that a pass on astandards-syncPR left the synced files unchanged. - The stub's own header tells agents not to change the trigger events. The pass ignored it.
The bot's suggestion was plausible on its face, so the model's judgement alone is not a reliable guard.
Evidence
petry-projects/incubator PR #164 (chore: sync 3 org-standard workflow stub(s) from petry-projects/.github), 2026-10-10:
- CodeAnt opened a
Majorthread on the new.github/workflows/persona-mention.yml: "pull_requestreview_requestedis not subscribed, so reviewer assignments never reach the reusable". - Run 38043757605 (
fix-bot-comment, statusapplied) pushedbadfc374"fix(bot): address bot feedback". It added apull_request: [review_requested]trigger and deleted the five-line NOTE that explains why the template omits that trigger (the router has no path for reviewer assignment; finding 10 in Persona framework — pre-rollout review findings .github#755). - dev-lead replied "Fixed", CodeAnt replied "verified this suggestion was addressed", and the thread was resolved. Auto-merge was on for that head.
- A maintainer review and a
fix-reviewsdispatch were needed to restore the file (5dc549d7, tree identical to the pre-change commit111bb767).
That run used dev-lead/v1-stable at 4fd4eacd. The prompt and harness on main (0fe8e4c4) carry no rule that would have prevented it, so this is not fixed by the re-pin to dev-lead/v139-stable.
Why it matters now
The fleet sweep on 2026-10-12 opens sync PRs that add persona-mention.yml to more repos. CodeAnt is likely to raise the same suggestion on each one. A drifted stub that merges is flagged as drift by the next sweep, which opens another sync PR, and the cycle can repeat.
Options
- Prompt: in the dev-lead review prompts (
fix-bot-comment,fix-reviews,review-changes,on-mention), a file whose header names aSOURCE OF TRUTHunderpetry-projects/.github/standards/is read-only in a consumer repo. A bot suggestion to change it gets a "declined, change the template instead" reply and no code change. - Harness: on a PR labeled
standards-sync, refuse to push a pass that modifies a file the sync commit wrote, the same way the test-tamper guard refuses a test removal. A maintainer finding could still override it explicitly.
Option 2 is the deterministic guard. Option 1 covers stubs edited outside a sync PR.
Scope decision (maintainer, 2026-10-10)
Answering the triage question in the comments: do both. The harness check (option 2) is the primary guard, because it is deterministic. The prompt rule (option 1) is the backstop. A maintainer (non-bot) review may override the harness check to restore a synced stub to the template, as the second acceptance criterion says; a bot suggestion never can.
Acceptance criteria
- A
fix-bot-commentpass on astandards-syncPR that would change a synced stub pushes nothing, and answers the bot thread as declined with a pointer to the template inpetry-projects/.github. - A maintainer (non-bot) review thread that asks for a synced stub to be restored to the template is still applied.
- A sync PR's own files outside
standards/scope, and non-sync PRs, are unaffected. - Covered by a test in the harness and/or prompt-contract suites.
Activity
github-actions commentedon Oct 10, 2026
Thanks for the thorough report and the detailed evidence from incubator PR #164, which makes the failure easy to follow. To help scope the fix, which guard do you prefer as the primary one: the deterministic harness check in
scripts/dev-lead-fix-reviews.sh(option 2), with the prompt rule (option 1) as a backstop, or both together? Also say whether a non-bot maintainer review should be able to override the harness check, as your acceptance criteria imply.don-petry commentedon Oct 10, 2026
Dev-Lead Implementation Plan
Issue: #2185 — dev-lead fix-bot-comment edits a verbatim org-standard stub on a standards-sync PR when a bot suggests it
Scope
Add a deterministic harness guard that refuses to push a bot-driven pass (
fix-bot-comment,fix-reviews) on astandards-syncPR when it changes a synced org-standard stub (headerSOURCE OF TRUTH: petry-projects/.github/standards/…), unless the change restores the stub to the content the sync commit wrote; plus a prompt rule in the four review prompts that makes such stubs read-only and answers the bot as declined with a pointer to the template.Implementation Checklist
scripts/lib/sync-stub-guard.sh(new): pure helpers (ssg_template_path,ssg_has_sync_label) + impuressg_scan_pass <pre-pass> <head> <merge-base>→clean/drift(+path<TAB>template) /unknown(fail closed). A changed stub is allowed only when its post-pass blob equals the blob the PR's first commit touching it wrote (the sync commit) — that is the maintainer "restore to template" path.scripts/dev-lead-fix-reviews.sh: source the lib; incommit_and_push, forfix-bot-comment|fix-reviewsonly, run the scan when the pass touches a stub, read the PR's labels/base, and ondrift/unknownrefuse the push (rc 4, same path as the test-tamper guard) via a newflag_sync_stub_driftthat posts one deduped "declined — change the template in petry-projects/.github" comment naming each template, holds the PR and disables auto-merge. Maintainer-driven intents (review-changes/human-pr,on-mention,human) are not guarded.prompts/dev-lead/{fix-bot-comment,fix-reviews,review-changes,on-mention}.md: "Guardrail — a synced org-standard stub is read-only" — decline the bot suggestion (no code change, no addressed-marker) with a pointer topetry-projects/.github/standards/…; restoring the stub to its template is allowed.Tests to Write
tests/dev-lead/unit/test_sync_stub_guard.bats: header detection; label detection; scan on a temp git repo — bot drift on a synced stub →driftrc1 naming the template; restore to the synced content →clean; non-stub files and.github-privateSOURCE OF TRUTH files →clean; missing merge base / pre-pass head →unknownrc2; deleting the stub →drift; harness wiring (guard sourced, intents scoped, rc 4).tests/dev-lead/unit/test_sync_stub_readonly_guardrail.bats: prompt-contract — the guardrail is present in all four prompts, namesSOURCE OF TRUTH,standards-sync, the declined reply and the template pointer.Test Command
bats tests/dev-lead/unit/test_sync_stub_guard.bats tests/dev-lead/unit/test_sync_stub_readonly_guardrail.bats(plus the fulltests/dev-lead/unitsuite) andbash .dev-lead/scripts/dev-lead-lint.shdon-petry commentedon Oct 10, 2026
Dev-Lead: Implementation Complete — PR #2191
The implementation for issue #2185 is durable: commits are pushed and a pull request is open. This record is backed by verifiable artifacts you can confirm in one click.
fe4b81c6bebb2c130831c063263fa09f05cf67b4main: 8 file(s), +643/-4 linesReview happens on the PR. Acceptance criteria and test results are evidenced by the PR's diff and CI checks — not asserted here. If a later stage fails, this claim is retracted in place.
feat: implement issue #2185 — dev-lead fix-bot-comment edits a verbat…
feat: implement issue #2212 — Sync-stub guard does not cover fix-ci o…