Phase 3 (Q14): distinct sweeper-PR naming + reap-exempt own-PR exclusion#6
Merged
Merged
Conversation
petemoore
added a commit
that referenced
this pull request
Jun 15, 2026
… plan Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cost-safety (idempotency is the only thing bounding agentic spend): the tool must never re-ingest its own replacement PR as a fresh dependabot PR. The author filter is the primary gate, but on the test bed the fix-PR author is also an accepted author, so an own-PR could re-enter the expensive agentic step. - SweeperPRTitle derives the replacement title from the dependabot title with the conventional-commit type swapped to `fix` (build(deps): … → fix(deps): …), or prepends `fix(deps): ` when there's no parseable prefix. Replaces the verbatim copy of the dependabot title that made the two indistinguishable (T12). - New reap-exempt `created_prs` table (created PR → origin dependabot PR), with Writer.RecordCreatedPR and Reader.CreatedPRs on both stores. Store.Reap only prunes pr_progress, so these records are permanent (review C1) — a branch-name heuristic is rejected (branch names are attacker-spoofable; the DB record is not). - The orchestrator records every replacement it opens (new and pre-existing branches) and excludes recorded PRs from the scan set each cycle. The reverse link (created→origin) also enables the dashboard pairing (Phase 4). Tests: TestSweeperPRTitle; created_prs survives Reap on BOTH stores (C1); RecordCreatedPR/CreatedPRs roundtrip; excludeOwnPRs (+ nil/empty pass-through). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
359ac25 to
190238d
Compare
petemoore
added a commit
that referenced
this pull request
Jun 15, 2026
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 3 sub-item Q14 (
docs/WORKPLAN.md; resolves T12). Cost-safety-critical. Independent of the analyser-removal rework.Why
Idempotency is the only thing bounding agentic spend, so the tool must never re-ingest its own replacement PR as a fresh dependabot PR. The author filter is the primary in-scope gate, but on the test bed (
--accept-author petemoore, which is also the fix-PR author) an own-PR could be re-ingested and re-enter the expensive agentic step.What
SweeperPRTitle— replacement title = dependabot title with the conventional-commit type swapped tofix(build(deps): …→fix(deps): …), orfix(deps):prepended when there's no parseable prefix. Replaces the verbatim copy ofpr.Titlethat made dependabot and sweeper PRs indistinguishable.created_prstable (created PR → origin dependabot PR), withWriter.RecordCreatedPR/Reader.CreatedPRson both stores.Store.Reaponly prunespr_progress, so these records are permanent (review C1). A branch-name heuristic is explicitly rejected — branch names are attacker-spoofable; a DB record of what we created is not.Tests
TestSweeperPRTitle— type-swap, prepend-when-bare, group titles, idempotence.TestCreatedPRsSurviveReapon both stores (sqlite + in-memory) — the C1 regression: the record persists across aReapthat prunespr_progress.TestRecordCreatedPRRoundtrip,TestExcludeOwnPRs(+ nil/empty pass-through).Schema note:
created_prsis added viaCREATE TABLE IF NOT EXISTS— no migration needed (the test DB is disposable; flagged in WORKPLAN for when production traffic lands).Local:
go build/vet/test ./...,gofmt,staticcheckall clean.🤖 Generated with Claude Code