Backlog scorer: rank open issues into lanes (read-only) - #173
Merged
juemerson-at-purestorage merged 18 commits intoSep 25, 2026
Merged
juemerson-at-purestorage merged 18 commits into
juemerson-at-purestorage merged 18 commits into
Conversation
…GitHubRead.ps1 Adds Invoke-PfbGitHubPagedList: follows rel=next links, flattens both -FollowRelLink output shapes, and throws when the last page still links to a next one. -UserAgent is mandatory on every call. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… the brief gate No behaviour change: an anonymous read-only run against dmann000/fb-powershell before and after the extraction produced identical output. The gate keeps its own User-Agent. New-PfbDriftIssue.ps1's pointer now names the lib. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Drops pull requests, maps state_reason to the gh shape ConvertFrom-PfbDriftIssue reads (StrictMode-safe), and parses each issue's block alone so a malformed trusted block is reported instead of stopping the run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Errors (unplaceable) send an issue to labelErrors; warnings leave it in its lane. The paired legacy source:drift exception is never warned on. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A single named table drives the in-band sort and the proposed priority; an unknown category or dead-key severity throws. The dmann000#163-dmann000#172 hand triage is a fixture test and reproduces 10/10 with LF and CRLF bodies. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Priority, readiness, impact, size, live findings, number -- no weights. Each row names the first key that differs from the row above it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Every open issue lands in exactly one of seven lanes; ranked lanes carry rank and decidedBy, triage carries proposals, labelErrors carries its problems. A trusted issue with no live finding is noted. LF and CRLF bodies give the same result. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e and strict render GFM strips a title such as 'Add <name> support', or a label problem that echoes an HTML comment, as raw HTML. Format-PfbBacklogCell now backslash-escapes < as well as |; the JSON keeps the text unescaped. Also pins three render paths: a triage row with no proposal, a note on a row hidden by -First, and the whole Markdown under Set-StrictMode Latest. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Fetches open issues (paged, anonymous unless a token is given), reads the two committed drift reports and writes PfbBacklog.json/.md to -OutputPath, or the Markdown to the console. Nothing is committed and no label is written. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… variables The drift fixture's analysedVersions is now 2.27, so the specVersion 2.28 assertion can only pass if the value comes from the dead-key report. The anonymous-mode hint names GH_TOKEN (the first fallback) as well as GITHUB_TOKEN. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
workflow_dispatch plus workflow_run on Drift Issues (any conclusion); issues: read only; latest run wins. Markdown to the job summary, JSON as a 90-day artifact. -First is passed only when the input is non-empty. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…mary source Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
PfbGitHubRead.Tests.ps1 18, PfbBacklogTools.Tests.ps1 147, Build-PfbBacklog.Tests.ps1 16 -- new files, gated wholesale on 5.1 because the code under test is PowerShell 7 only. Measured, not inferred. Header note recomputed from the map: 22 entries, 503. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…alify rate-limit wording Co-Authored-By: Claude Opus 5.5 (1M context) <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.
Summary
Adds
tools/Build-PfbBacklog.ps1, a read-only backlog scorer. It sorts every open issue into exactly one lane and ranks the lanes that are ready to work, so a script rather than a person picks the next unit of work.Lanes:
agent-ready,design-approved) and design (needs-design).blocked,human-only), confirmClose (resolved-upstream).docs/TRIAGE-ROLES.md.Output is
PfbBacklog.json(schema v1) andPfbBacklog.md. The newBacklogworkflow publishes the Markdown to the job summary and uploads the JSON as a 90-day artifact. Nothing is committed andReports/is untouched.What it adds
tools/lib/PfbGitHubRead.ps1: shared read-only GitHub REST helpers (Invoke-PfbGitHubApi,Invoke-PfbGitHubList, and a newInvoke-PfbGitHubPagedList).-FollowRelLink, flattening both page shapes.tools/lib/PfbBacklogTools.ps1: the pure rules.source:driftissues contribute findings.decidedBy.tools/Build-PfbBacklog.ps1: reads open issues through the paged helper and joins them to the committed drift and dead-key reports.-Repo,-Token(thenGH_TOKEN, thenGITHUB_TOKEN),-OutputPath,-Lane,-First..github/workflows/backlog.yml: runs onworkflow_dispatchand after everyDrift Issuesrun.contents: readandissues: readonly.backlogwith cancel-in-progress.run:blocks only throughenv:.Tests/PfbGitHubRead.Tests.ps1,Tests/PfbBacklogTools.Tests.ps1andTests/Build-PfbBacklog.Tests.ps1.tools/README.md: a new section documenting the scorer.Refactor
scripts/Assert-PfbAgentReadyBrief.ps1now dot-sourcestools/lib/PfbGitHubRead.ps1instead of defining its own REST helpers. Its messages, guards and User-Agent are unchanged. The script has no tests, so I checked it with an anonymous live run before and after the extraction: the output was identical (Compare-Objectprinted nothing).tools/New-PfbDriftIssue.ps1:158's comment pointer now points at the lib.Design decisions
Priority first. The human
priority:label is the primary sort key; the score only orders issues within a band.Tiered keys, no weights. Issues sort by priority, readiness, impact class, size, live finding count (descending), then issue number.
decidedBynames the first key that differs from the row above.Proposals only. No labels are written. Triage issues get a proposed priority and size, with a
differsflag when these disagree with the current labels.Impact classes. The proposal comes from the issue's live drift findings. It reproduces the hand triage of Drift: dead or unreachable request keys in the 'arrays' family #163-Drift: dead or unreachable request keys in the 'support' family #172 10/10, pinned as a fixture test.
Size is S for 10 or fewer live findings and M above that; L is never proposed. An unknown category or severity throws.
Nothing committed. Output goes to the job summary and a run artifact.
Output shaping only.
-Laneand-Firstshape the Markdown only; the JSON always carries every lane.notesfield. Each row carries anotesarray. For example, a trusted issue with 0 live findings is flagged as possibly resolved.Markdown escaping. Cells escape
|and<, so titles and label problems that contain<name>or HTML comments are not dropped by GFM.Verification
Scoped Pester, touched areas (8 files):
Tests/coverage-baseline.psd1pins thewinps51ExpectedSkips at 18 / 147 / 16. The source is#Requires -Version 7.0, so every Describe skips on 5.1. The header was recomputed as 22 entries summing to 503, across 213 test files.labelErrorswas empty.git statuswas clean afterwards.Test-PfbWireExemption.ps1gives VERDICT: EXEMPT. The diff leaves the module source and the manifest entirely untouched, so nothing here can alter a request the module sends or a response it parses.No version bump or CHANGELOG edit.
After merge
workflow_runfires only from the workflow file on the default branch. TheDrift Issues→Backlogchain starts working once this is merged; until then onlyworkflow_dispatchcan run it.🤖 Generated with Claude Code