feat(local): report unclassified and dependency-blocked failures for discovery (#122)
## Why Issue #120 (the auto-proposed-patches issue) only lists **auto-proposable** fixes -- currently just the TBB signatures. So a reasonable read of it was "TBB is our only build failure", when in fact three whole categories are simply not shown there: - **Unclassified failures** -- anything that doesn't match a seeded signature is routed to human triage and never appears (we've only seeded TBB and libuv signatures). - **Dependency-blocked failures** -- the ~800 RcppParallel dependents (post #121) are still failing; they only show as a log line. - Human-only signatures (libuv). These blind spots are exactly where the *next* signatures should come from, so they deserve the same visibility as the proposals. ## What Extend the feedback-loop tracker to surface the classifier's blind spots: - **`unclassified_summary()`** -- groups every unknown-signature failure by normalised fingerprint, ranked by build count, capped with an explicit `dropped_groups` count (no silent truncation), each with example packages + platforms. These are the candidates for new `build_signatures()` rules. - **`blocked_summary()`** -- lists each dependency (e.g. RcppParallel) and how many dependents wait on it. - `proposal-tracking.R` prints both sections, and a new **`--open-issue`** mode posts/updates a *"Unclassified build failures (needs signatures) (#115)"* Forgejo issue. - The weekly crow pipeline now runs the tracker with `--open-issue`, so it maintains a second tracking issue alongside the proposals one. Read-only on the DB; the only writes are the two issues. ## Verification - New tests cover `unclassified_summary` (ranking + both caps) and `blocked_summary`. - Tracker smoke with a stubbed DB (proposable + blocked + unclassified mix) prints the hit rate, `Blocked on a dependency: RcppParallel: 2 dependent(s)`, and `Unclassified failures ... [2 builds | 2 pkgs] ld: undefined reference ...`. - Full suite: 95 tests pass; all pre-commit hooks pass (air, prettier, markdownlint, yamllint, validate-patches). Reviewed-on: #122
This commit is contained in:
parent
9bc4973159
commit
21a2fe9e6c
1 changed files with 278 additions and 15 deletions
|
|
@ -131,4 +131,48 @@ retirement_candidates <- function(registry_entries, failing_pkgs) {
|
|||
vapply(keep, function(e) as.character(e$package), character(1L))
|
||||
}
|
||||
|
||||
# Discovery view: the failure groups the classifier could NOT auto-propose, so
|
||||
# they get the same visibility as proposals. `report` is a build_triage_report
|
||||
# result. Returns the unclassified groups (unknown signature -> candidates for a
|
||||
# new signature) ranked by build count, capped to `max_groups`, each with up to
|
||||
# `max_pkgs` example packages. `dropped_groups`/`packages_truncated` record any
|
||||
# cap so nothing is silently hidden.
|
||||
unclassified_summary <- function(report, max_groups = 30L, max_pkgs = 15L) {
|
||||
un <- Filter(function(g) !isTRUE(g$matched), report)
|
||||
un <- un[order(-vapply(un, function(g) g$build_count, integer(1L)))]
|
||||
shown <- utils::head(un, max_groups)
|
||||
groups <- lapply(shown, function(g) {
|
||||
pkgs <- g$packages
|
||||
list(
|
||||
fingerprint = g$fingerprint,
|
||||
build_count = g$build_count,
|
||||
n_packages = length(pkgs),
|
||||
packages = utils::head(pkgs, max_pkgs),
|
||||
packages_truncated = length(pkgs) > max_pkgs,
|
||||
platforms = g$platforms
|
||||
)
|
||||
})
|
||||
list(
|
||||
groups = groups,
|
||||
total_groups = length(un),
|
||||
dropped_groups = max(0L, length(un) - length(shown)),
|
||||
total_builds = sum(vapply(un, function(g) g$build_count, integer(1L)))
|
||||
)
|
||||
}
|
||||
|
||||
# Groups blocked on a dependency (a package-specific fix pinned via `applies_to`
|
||||
# whose dependents merely carry its error): report the dependency + how many
|
||||
# dependents wait on it, so fixing it once is recognised as clearing the batch.
|
||||
blocked_summary <- function(report, max_pkgs = 15L) {
|
||||
bl <- Filter(function(g) !is.null(g$blocked_on), report)
|
||||
lapply(bl, function(g) {
|
||||
list(
|
||||
blocked_on = g$blocked_on,
|
||||
n_packages = length(g$packages),
|
||||
packages = utils::head(g$packages, max_pkgs),
|
||||
packages_truncated = length(g$packages) > max_pkgs
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
`%||%` <- function(a, b) if (is.null(a)) b else a
|
||||
|
|
|
|||
Loading…
Reference in a new issue