feat(local): report unclassified and dependency-blocked failures for discovery

The proposer issue only lists auto-proposable fixes (currently the TBB
signatures), so every failure without a signature -- and every group blocked on
a dependency build -- was invisible unless someone read the run log. That hid
the classifier's blind spots and, with them, which new signatures are worth
adding next.

Extend the tracker to surface those blind spots and give them the same
visibility as the proposals:

- add pure `unclassified_summary()` (unknown-signature groups ranked by build
  count, capped with an explicit dropped count) and `blocked_summary()` helpers
- print both sections in proposal-tracking.R and add a `--open-issue` mode that
  posts/updates a "Unclassified build failures (needs signatures)" Forgejo issue
- run the tracker with --open-issue in the weekly crow pipeline (second issue)
- cover the new helpers with tests and document the flow in the patches README
This commit is contained in:
Patrick Schratz 2026-07-15 07:34:07 +00:00
commit 6ed17f3fb1
No known key found for this signature in database
GPG key ID: 62050D5BC68AB6DC

View file

@ -119,6 +119,49 @@ test_that("proposed_vs_merged marks a package merged once it is registered", {
expect_identical(stan$status, "merged")
})
test_that("unclassified_summary ranks unknown groups and caps output", {
failures <- data.frame(
name = c("a", "b", "c", "d", "solo"),
platform = "ubuntu-2604",
arch = "amd64",
error_text = c(
# 4 builds share one unknown fingerprint; 1 build a different unknown.
rep("mystery linker meltdown at stage 3", 4L),
"a totally different unknown boom"
),
stringsAsFactors = FALSE
)
report <- build_triage_report(failures, registered_pkgs = character(0L))
s <- unclassified_summary(report, max_groups = 30L, max_pkgs = 2L)
expect_identical(s$total_groups, 2L)
expect_identical(s$total_builds, 5L)
# Largest group first, and its example packages are capped at max_pkgs.
expect_identical(s$groups[[1L]]$build_count, 4L)
expect_length(s$groups[[1L]]$packages, 2L)
expect_true(s$groups[[1L]]$packages_truncated)
# max_groups cap is reported, not silently dropped.
capped <- unclassified_summary(report, max_groups = 1L)
expect_length(capped$groups, 1L)
expect_identical(capped$dropped_groups, 1L)
})
test_that("blocked_summary lists each dependency and its dependent count", {
failures <- data.frame(
name = c("ACEsimFit", "AovBay", "AdaptGauss"),
platform = "ubuntu-2604",
arch = "amd64",
error_text = "Error: USE_TBB=Linux is not supported on this toolchain",
stringsAsFactors = FALSE
)
report <- build_triage_report(failures, registered_pkgs = character(0L))
b <- blocked_summary(report, max_pkgs = 2L)
expect_length(b, 1L)
expect_identical(b[[1L]]$blocked_on, "RcppParallel")
expect_identical(b[[1L]]$n_packages, 3L)
expect_true(b[[1L]]$packages_truncated)
})
test_that("retirement_candidates flags entries whose package no longer fails", {
entries <- list(
list(package = "RcppParallel"),