Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add a scheduled tech debt burndown skill - #14095

Merged
williammartin merged 11 commits into
trunkfrom
tech-debt/staticcheck-alias-import
Aug 7, 2026
Merged

Add a scheduled tech debt burndown skill#14095
williammartin merged 11 commits into
trunkfrom
tech-debt/staticcheck-alias-import

Conversation

@williammartin

@williammartin williammartin commented Aug 7, 2026

Copy link
Copy Markdown
Member

N/A - no related issue.

Description

.golangci.yml disables errcheck, staticcheck, and gosec with the comment "To enable later due to too many issues". The backlog behind that comment is roughly 1900 findings. Nobody is going to clear it in one sitting, and a sweeping cleanup PR would be unreviewable, so it just sits there.

This adds a tech-debt-burndown skill designed to run unattended on a schedule. Each run picks one target, fixes it, validates it, and opens a ready-to-review pull request. The binding constraint is that the resulting PR must be reviewable in about two minutes - throughput is explicitly not the goal, because the bottleneck is human review attention, not an agent's ability to generate diffs.

Three properties do most of the work:

  • One open burndown PR at a time. A run stops immediately if a tech-debt/* PR is already open. This is the backpressure: the loop cannot outrun the reviewer, and a stalled PR halts production rather than piling more behind it.
  • Three attempts, one landing. An unattended run that gives up at its first difficulty wastes the whole tick, so a run may attempt up to three targets, reverting fully between them. The first that validates becomes the PR; the others' failure reasons ride along in the memory file, so the loop learns from bad luck instead of repeating it.
  • Allow-list of .go files only. A run cannot edit the workflows that schedule it, this skill file, go.mod, or CODEOWNERS, because none of them are Go source. Self-modification is blocked by construction rather than by a deny-list somebody has to keep complete.

.experiments/tech-debt-burndown/memory.md is the steering channel. It has a human-owned Current focus section that runs read and must never edit, plus agent-appendable sections for rejected targets and failed attempts, under a 150-line budget covering the entries only, so the fixed instructions at the top cannot crowd out learning.

The first run of the skill is included so reviewers can judge the output rather than only the instructions: it takes pkg/cmd/alias/imports from 5 staticcheck findings to zero.

How did you test this change?

The sensor command, before the change:

$ golangci-lint run --no-config --default=none --enable=staticcheck \
    --max-issues-per-linter=0 --max-same-issues=0 ./pkg/cmd/alias/imports/...
pkg/cmd/alias/imports/import.go:132:5: QF1012: Use fmt.Fprintf(...) instead of WriteString(fmt.Sprintf(...))
pkg/cmd/alias/imports/import.go:142:5: QF1012: Use fmt.Fprintf(...) instead of WriteString(fmt.Sprintf(...))
pkg/cmd/alias/imports/import.go:155:4: QF1012: Use fmt.Fprintf(...) instead of WriteString(fmt.Sprintf(...))
pkg/cmd/alias/imports/import.go:167:4: QF1012: Use fmt.Fprintf(...) instead of WriteString(fmt.Sprintf(...))
pkg/cmd/alias/imports/import.go:174:4: QF1012: Use fmt.Fprintf(...) instead of WriteString(fmt.Sprintf(...))
5 issues:
* staticcheck: 5

And after:

$ golangci-lint run --no-config --default=none --enable=staticcheck \
    --max-issues-per-linter=0 --max-same-issues=0 ./pkg/cmd/alias/imports/...
0 issues.

gh alias import output is unchanged, and the existing tests are what prove it. import_test.go asserts exact wantStderr strings covering all five rewritten messages - the two "Could not import alias" refusals, the expansion refusal, "Changed alias", and "Added alias". They pass untouched:

$ go test ./pkg/cmd/alias/...
ok  	github.com/cli/cli/v2/pkg/cmd/alias/delete	0.326s
ok  	github.com/cli/cli/v2/pkg/cmd/alias/imports	0.625s
ok  	github.com/cli/cli/v2/pkg/cmd/alias/list	0.699s
ok  	github.com/cli/cli/v2/pkg/cmd/alias/set	0.939s
ok  	github.com/cli/cli/v2/pkg/cmd/alias/shared	(cached)

go test ./... and make lint were also run. Both report failures, and stashing the change and re-running confirms both are pre-existing on a clean tree, unrelated to this PR: 3 govet issues in toolchain source, and the git package tests failing due to a local safe.bareRepository git config.

That experience is why the skill now computes a validation baseline on clean trunk at the start of each run and compares failure sets afterwards, instead of demanding a green build. An earlier revision of this branch recorded those two specific failures in the memory file, which was a mistake: they are properties of one machine's git config and toolchain, so a run in Actions would have been misled by them. Computing the baseline per run makes the skill portable across environments.

Key points

  • No new test for the code change, deliberately. The skill requires a test for new behavior. This change has none - it is a mechanical WriteString(fmt.Sprintf(x)) to Fprintf(&msg, x) rewrite, and the existing exact-output assertions fail if a single byte moves. The skill now spells out this exception and requires the PR to name the covering test so the claim can be checked rather than trusted.
  • The skill does not respond to review comments. An earlier design had a second skill that would read Copilot's review, apply what was right, argue with what was wrong, and mark the PR ready. It was dropped: the whole premise is that these diffs are small enough that review comments should be rare, and an agent that pushes follow-up commits in response to a reviewer is a much larger capability than the problem needs. If a comment does arrive, a human handles it, and the one-PR-at-a-time cap means the loop pauses until they do.
  • A run that lands nothing is silent. No issue, no comment. With an hourly loop, any per-tick notification becomes noise fast, and the absence of PRs is a sufficient signal. The tradeoff is that "working through a hard area" and "broken since Tuesday" look identical from outside.
  • The sensor commands carry --max-issues-per-linter=0 --max-same-issues=0, and that is load-bearing rather than tidiness. golangci-lint truncates to 50 per linter and 3 of the same text by default, which inverts the oracle: you fix the three findings you were shown, re-run, and the tool displays three that were previously hidden, so a correct fix reads as a failed one and gets reverted. pkg/cmd/auth/status reports 3 findings without the flags and 16 with them. Caught in review by @babakks.
  • --no-config on the sensor command is deliberate but sharp: it bypasses this repo's gosec exclusions and test-file rules, so a gosec run under it reports findings .golangci.yml already excludes on purpose. The skill says to cross-check.
  • Repo-wide, staticcheck reports no SA findings at all - it is entirely style and quickfix categories. Useful for calibrating how much of this backlog is correctness risk versus cosmetics, and recorded in the memory file.
  • .experiments/ is a new top-level directory, chosen to mark the whole thing as provisional and to give each experimental skill its own space.

Notes for reviewers

Start with pkg/cmd/alias/imports/import.go. It is 15 lines added, 25 removed, and it shows what a run actually produces. If that diff is not obviously correct at a glance, the skill has failed at its one job and the rest is not worth reading.

Then read SKILL.md, particularly "Assume nobody is watching", "Check the preconditions", "What you may change", and "Three attempts". Those four sections carry the unattended design; the rest is the target menu and mechanics.

What I would most like scrutiny on:

  • Is the backpressure right? One open PR at a time means merging one a day gives you one a day regardless of tick frequency. That is intentional, but it also means a single contested PR halts the loop completely.
  • Is the .go-only allow-list the right boundary? It blocks self-modification cleanly, but it also means the skill can never fix debt in workflows, Makefiles, or docs.
  • Is the memory file a good idea at all? It is committed, human-editable state that an agent also appends to. It could rot, or grow into a diary nobody reads. The 150-line entry budget and the human-owned Current focus section are attempts to bound that, but they are conventions rather than mechanisms.
  • The authorship answers are now standing choices baked into the skill, since an unattended run cannot pause to ask as the template instructs. Worth confirming that is an acceptable way to satisfy that requirement.

Authorship and follow-up

Who wrote this:

  • A human wrote it.
  • An agent wrote it under close human direction.
  • An agent wrote it independently, and no human has guided the implementation beyond the initial prompt.

Who answers review comments:

  • @williammartin will read and reply directly.
  • An agent will draft replies and @username will read them before they are posted.
  • Nobody has explicitly committed to replying.

williammartin and others added 4 commits August 6, 2026 21:54
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 7db06537-cb57-48b9-b09c-e0ea393c3734
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 7db06537-cb57-48b9-b09c-e0ea393c3734
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 6dba8ad8-2a85-4cda-a057-cf91b58a158e
Also record what this run learned: the staticcheck backlog is entirely
stylistic with no SA findings, and which test and lint failures are
pre-existing on a clean tree so future runs don't chase them.

Co-authored-by: Copilot <[email protected]>
Copilot-Session: 6dba8ad8-2a85-4cda-a057-cf91b58a158e
Copilot AI lite review requested due to automatic review settings August 7, 2026 08:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a new tech-debt-burndown agent skill to enable incremental, reviewable tech-debt cleanup runs in the GitHub CLI repo, and includes an example “first run” cleanup that resolves staticcheck findings in gh alias import.

Changes:

  • Add a new .github/skills/tech-debt-burndown/SKILL.md describing the one-thing-per-run workflow, target selection tiers, validation, and stopping rules.
  • Add a persistent, repo-committed memory file at .experiments/tech-debt-burndown/memory.md to carry binding corrections across independent runs.
  • Remove staticcheck QF1012 findings in pkg/cmd/alias/imports/import.go by switching from WriteString(fmt.Sprintf(...)) to fmt.Fprintf(...).
Show a summary per file
File Description
pkg/cmd/alias/imports/import.go Mechanical output-building change to eliminate staticcheck QF1012 findings without changing user-facing output.
AGENTS.md Adds a discoverability pointer to the new tech-debt burndown skill.
.github/skills/tech-debt-burndown/SKILL.md New skill definition and runbook for small, verifiable tech-debt fixes.
.experiments/tech-debt-burndown/memory.md New binding “standing corrections” file to reduce repeated mistakes and re-proposed targets across runs.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

williammartin and others added 2 commits August 7, 2026 13:11
The precedence rule justified itself with a false premise: every entry
so far was written by an agent run, not a human. Justify precedence by
specificity instead, and tell runs to re-verify factual claims rather
than trusting them wholesale.

Co-authored-by: Copilot <[email protected]>
Copilot-Session: 6dba8ad8-2a85-4cda-a057-cf91b58a158e
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 6dba8ad8-2a85-4cda-a057-cf91b58a158e

@babakks babakks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of bite-sized changes! Also, I'd love to see how the memory file evolve over time.

Comment thread .github/skills/tech-debt-burndown/SKILL.md
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 6dba8ad8-2a85-4cda-a057-cf91b58a158e
@williammartin williammartin changed the title Add tech debt burndown skill Add a scheduled tech debt burndown skill Aug 7, 2026
williammartin and others added 3 commits August 7, 2026 14:30
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 6dba8ad8-2a85-4cda-a057-cf91b58a158e
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 6dba8ad8-2a85-4cda-a057-cf91b58a158e
Without --max-issues-per-linter=0 --max-same-issues=0 the output is
truncated to 3 findings of the same text, so fixing them reveals three
previously hidden ones and a correct fix reads as a failed one.

Co-authored-by: Copilot <[email protected]>
Copilot-Session: 6dba8ad8-2a85-4cda-a057-cf91b58a158e
@williammartin
williammartin marked this pull request as ready for review August 7, 2026 12:41
@williammartin
williammartin requested a review from a team as a code owner August 7, 2026 12:41
@williammartin
williammartin requested review from sergiou87 and a balanced review from Copilot August 7, 2026 12:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Suppressed comments (2)

.github/skills/tech-debt-burndown/SKILL.md:184

  • 🛑 Requirement: An exclusion cannot ratchet a clean package

This repository uses linters.default: none, and these linters are absent from the enable list. A rule under linters.exclusions suppresses matching findings, so adding one for a cleaned package either does nothing while the linter is disabled or hides future regressions once it is enabled - the opposite of holding the package clean. Use an enable/inclusion strategy that actually checks cleaned paths, and remove the corresponding carve-out at lines 257-258.

When a package goes clean, you may add a scoped exclusion to `.golangci.yml` that
holds it clean, in the same pull request. That is a ratchet: without it the
package silently regresses and the work is lost. Adding an exclusion is the only
edit to that file you may make. Never disable a linter, widen an existing
exclusion, or add a blanket rule.

.github/skills/tech-debt-burndown/SKILL.md:358

  • 💭 Commentary: Restore the checkout on no-PR exits

After the switch at line 103, this path stops without restoring the original branch; lines 106-109 only instruct restoration after a pull request is opened. A manual run that exhausts all attempts therefore leaves the operator on a throwaway branch. Capture the original branch before switching and restore it on every exit that does not open a pull request.

If all three fail, stop. Do not open a pull request, do not open an issue, do not
comment anywhere. The run is simply silent, and the absence of a pull request is
the signal. Anything noisier turns a bad hour into a notification storm.
  • Files reviewed: 4/4 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread .github/skills/tech-debt-burndown/SKILL.md Outdated
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
@williammartin
williammartin merged commit 4c5f76f into trunk Aug 7, 2026
11 checks passed
@williammartin
williammartin deleted the tech-debt/staticcheck-alias-import branch August 7, 2026 13:07

@streetercurtis290-cloud streetercurtis290-cloud left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Aug 21, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [cli/cli](https://github.com/cli/cli) | minor | `v2.97.0` → `v2.98.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>cli/cli (cli/cli)</summary>

### [`v2.98.0`](https://github.com/cli/cli/releases/tag/v2.98.0): GitHub CLI 2.98.0

[Compare Source](cli/cli@v2.97.0...v2.98.0)

#### Security

A security vulnerability has been identified, and fixed, that binds the local forwarded port to all available network interfaces by default.

Users of `gh codespace ports forward` are advised to update `gh` to version `v2.98.0` as soon as possible.

For more information see: <GHSA-vfhh-p7hm-pxfh>

#### Support worktrees in `pr checkout`

Users can now checkout a pull request into a git worktree by using the new `--worktree PATH` flag in `gh pr checkout`:

```shell
gh pr checkout 12 --worktree ../wt-feature
```

#### Add semantic search to `search issues`

The `gh search issues` command now supports semantic search for issues. Users can select the search type by passing the `--search-type` flag:

```shell
gh search issues --search-type semantic ...

gh search issues --search-type hybrid ...
```

For more information about semantic search see: ["Improved Search for github issues is now generally available"](https://github.blog/changelog/2026-04-02-improved-search-for-github-issues-is-now-generally-available/).

#### What's Changed

##### ✨ Features

- Add --worktree flag to gh pr checkout by [@&#8203;tidy-dev](https://github.com/tidy-dev) in [#&#8203;13946](cli/cli#13946)
- Set GH\_EXTENSION=1 when gh invokes an extension by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14072](cli/cli#14072)
- Add --search-type flag for semantic and hybrid issue search by [@&#8203;michaeljacholke](https://github.com/michaeljacholke) in [#&#8203;14006](cli/cli#14006)

##### 🐛 Fixes

- Fix `RESTWithNext` error type, repairing `gh status` and attestation retries by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13988](cli/cli#13988)
- Trim spaces when parsing X-Oauth-Scopes in `gh release create` by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14065](cli/cli#14065)
- Fix project item-add output for non-TTY by [@&#8203;zwick](https://github.com/zwick) in [#&#8203;14056](cli/cli#14056)

##### 📚 Docs & Chores

- Slim down dependabot triage comments by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14019](cli/cli#14019)
- Require explicit MR review ownership by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14028](cli/cli#14028)
- Collapse spam triage into the agentic issue-triage workflow by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14027](cli/cli#14027)
- Run Dependabot triage every hour by [@&#8203;sergiou87](https://github.com/sergiou87) in [#&#8203;14030](cli/cli#14030)
- Route deploy key requests through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13989](cli/cli#13989)
- Route ssh key requests through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13994](cli/cli#13994)
- Route gpg key requests through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13997](cli/cli#13997)
- Route autolink requests through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14013](cli/cli#14013)
- Route extension requests through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14059](cli/cli#14059)
- Route release creation through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14062](cli/cli#14062)
- Tell agents to use the MR template in AGENTS.md by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14074](cli/cli#14074)
- Make Dependabot triage cheaper and more decisive by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14079](cli/cli#14079)
- Route release deletions through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14077](cli/cli#14077)
- Give Dependabot triage a real reachability check by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14087](cli/cli#14087)
- Restore automatic spam issue closure by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14088](cli/cli#14088)
- Add a scheduled tech debt burndown skill by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14095](cli/cli#14095)
- Use reflect.Pointer instead of deprecated reflect.Ptr by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14098](cli/cli#14098)
- Clarify what belongs in the MR template's testing section by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14103](cli/cli#14103)
- Rename cli-code-reviewer skill to code-review by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;14116](cli/cli#14116)
- Add aw-actions group to dependabot configuration by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;14123](cli/cli#14123)
- Isolate tests from local machine's auth and git configuration by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;14128](cli/cli#14128)
- Don't ask for feature detection cleanup comments when not needed by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;14139](cli/cli#14139)
- Accept pre-release tags in deployment validation by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;14193](cli/cli#14193)
- ci: add temporary step to verify Linux repo signing keys by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;14202](cli/cli#14202)
- Revert "ci: add temporary step to verify Linux repo signing keys" by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;14203](cli/cli#14203)
- Fix issue triage action compatibility \[skip changelog] by [@&#8203;tidy-dev](https://github.com/tidy-dev) in [#&#8203;14207](cli/cli#14207)

##### :dependabot: Dependencies

- chore(deps): bump github.com/sigstore/sigstore-go from 1.2.2 to 1.3.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14047](cli/cli#14047)
- chore(deps): bump the codeql-actions group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14049](cli/cli#14049)
- chore(deps): bump google.golang.org/grpc from 1.82.1 to 1.83.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14048](cli/cli#14048)
- chore(deps): bump github.com/google/go-containerregistry from 0.21.7 to 0.21.8 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14066](cli/cli#14066)
- chore(deps): bump actions/attest from 4.2.1 to 4.2.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14100](cli/cli#14100)
- chore(deps): bump azure/login from 3.0.0 to 3.0.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14101](cli/cli#14101)
- chore(deps): bump the codeql-actions group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14091](cli/cli#14091)
- chore(deps): bump github/gh-aw-actions/setup-cli from 0.83.4 to 0.85.4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14068](cli/cli#14068)
- chore(deps): bump github.com/google/go-containerregistry from 0.21.8 to 0.21.9 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14119](cli/cli#14119)
- chore(deps): bump github.com/klauspost/compress from 1.19.1 to 1.19.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14120](cli/cli#14120)
- chore(deps): bump the aw-actions group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14147](cli/cli#14147)
- chore: sign APT repository with both keys by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;13271](cli/cli#13271)
- chore(deps): bump github.com/yuin/goldmark from 1.8.4 to 1.8.5 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14029](cli/cli#14029)
- chore(deps): bump actions/attest from 4.2.0 to 4.2.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14050](cli/cli#14050)
- Bump golangci-lint in CI to v2.12.2 by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14102](cli/cli#14102)
- chore(deps): bump the aw-actions group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14124](cli/cli#14124)
- chore(deps): bump google.golang.org/protobuf from 1.36.11 to 1.36.12 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14140](cli/cli#14140)
- Upgrade gh-aw workflows to v0.85.4 by [@&#8203;tidy-dev](https://github.com/tidy-dev) in [#&#8203;14141](cli/cli#14141)
- Bump Go to 1.26.6 by [@&#8203;github-actions](https://github.com/github-actions)\[bot] in [#&#8203;14143](cli/cli#14143)
- chore: bump go to 1.26.7 by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;14205](cli/cli#14205)
- chore(deps): bump github.com/stretchr/testify from 1.11.1 to 1.12.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14204](cli/cli#14204)
- chore(deps): bump the codeql-actions group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14169](cli/cli#14169)
- chore(deps): bump golang.org/x/crypto from 0.54.0 to 0.55.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14164](cli/cli#14164)
- chore(deps): bump charm.land/lipgloss/v2 from 2.0.5 to 2.0.6 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14166](cli/cli#14166)
- Bump gh-aw-actions to v0.87.1 and recompile agentic workflows by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;14210](cli/cli#14210)

#### New Contributors

- [@&#8203;sergiou87](https://github.com/sergiou87) made their first contribution in [#&#8203;14030](cli/cli#14030)
- [@&#8203;michaeljacholke](https://github.com/michaeljacholke) made their first contribution in [#&#8203;14006](cli/cli#14006)

**Full Changelog**: <cli/cli@v2.97.0...v2.98.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODguMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4OC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWlub3IiXX0=-->
claude Bot added a commit to bugabinga/mothergod that referenced this pull request Aug 23, 2026
…180)

**Symptom.** The operator's review body reached the BDFL only if that
specific wake survived the debounce and the agent followed
`TRIGGER_URL`. No sweep read it.

**Evidence.** The sweep read `issues/comments` (conversation) and
`pulls/comments` (inline). A review body is in neither; it lives in
`pulls/{n}/reviews`, which nothing in this repository fetched (#147).
This very PR's wake was a `pull_request_review` with an empty body, and
running the new tool over this run's own window recovers it, plus a
second operator review on #142 from 13:48 that no digest ever mentions.

## What changed

`.github/scripts/operator-sweep` prints every operator input since the
previous successful run as one chronological timeline:

| channel | source |
|---|---|
| conversation comments | `issues/comments?since=` |
| inline review comments | `pulls/comments?since=` |
| **review bodies** | `pulls/{n}/reviews` over the PRs touched since the
anchor |
| threads opened | `issues?since=`, authored by the operator |
| state changes | `issues/events`: reopened, closed, labeled |
| wakes that died queued | cancelled `agent-bdfl` runs |

Steps 1 and 2 of the run economy become step 1, one command. The
displaced-run sweep is **deleted, not corrected**: everything it
recovered lossily by display title is now recovered as content, on any
wake, displaced or not.

## The premise, verified rather than assumed

The review channel needs a candidate list because GitHub exposes no
repo-wide reviews endpoint. Candidates are the PRs whose `updated_at` is
at or after the anchor. That is complete only if submitting a review
bumps `updated_at`, which is the kind of claim this sweep exists to stop
believing:

`cli/cli#14095` closed `2026-08-07T13:07:02Z` with zero conversation
comments and no inline comment after `12:53:18Z`. It took a `COMMENTED`
review at `2026-08-19T23:11:40Z`. Its `updated_at` reads
`2026-08-19T23:11:41Z`. Nothing else touched it in those twelve days.

## Noise, cut mechanically rather than by training the reader to skim

- Labels applied while opening a thread are dropped; the `opened` entry
already carries them.
- The `closed` that rides a `merged` is dropped; a merge is an outcome,
not input.
- What cannot be cut is documented in place: `GH_ADMIN_TOKEN` writes are
operator-attributed (#50), so a BDFL merge made with it reads here as
operator action.

## Liveness (#147 item 4)

The last line always prints per-channel counts, the operator login swept
for, and the anchor. A sweep that returns nothing forever is now
distinguishable from a quiet week, and a wrong login is visible on the
run it is wrong. Every walk GitHub gives no `since` for reports
`INCOMPLETE:` rather than truncating silently.

## Scope note for the reviewer

This edits `.github/workflows/agent-bdfl.yml`, so it is mine to merge
(GOVERNANCE, workflow-file carve-out). It does not touch
`agent-review.yml`, so your review applies normally. The prompt diff is
the two sweeps collapsing into one step plus renumbering; the substance
is in the script.

Run it on any window: `.github/scripts/operator-sweep --since
2026-08-23T13:00:00Z`.

---
_Generated by [Claude Code](https://claude.ai/code)_

Co-authored-by: Oliver Jan Krylow <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants