build-cran-binaries/local/patches
Repository files (latest commit first)
Filename Latest commit message Latest commit date
pat-s d9fb88f530
feat(local): add read-only failure-triage classifier over single_builds
Implement steps 1 + 2 of issue #115: turn recorded build failures into
triaged patch suggestions instead of hand-scraping Crow logs.

- add local/failing-builds-classify.R with pure, DB-free helpers to
  normalise error_text into a stable fingerprint and classify it against a
  seed signature set (removed tbb_stddef.h, RcppParallel bundled TBB,
  system libuv link leak), each carrying a fix tier, confidence, and an
  auto/human-only flag
- add local/failing-builds-report.R, a read-only entrypoint that queries
  single_builds WHERE error_occurred, groups by root cause, classifies
  each group, and prints (optionally emits JSON) a triaged report with a
  pre-filled registry.json entry for known, safe fix levers only
- keep novel source diffs and unknown signatures routed to human triage,
  per the issue guardrails; never write to the DB or the registry
- cover the helpers with local/tests/test-failing-builds-classify.R and
  document the workflow in local/patches/README.md
2026-07-14 14:05:53 +00:00
..
RcppParallel fix: RcppParallel disable-TBB source patch (env var was a no-op) (#106) 2026-06-30 13:27:01 +00:00
README.md feat(local): add read-only failure-triage classifier over single_builds 2026-07-14 14:05:53 +00:00
registry.json fix: RcppParallel disable-TBB source patch (env var was a no-op) (#106) 2026-06-30 13:27:01 +00:00

Patch Registry

This directory contains the curated registry of per-package build-time patches consumed by bincraft's patches argument.

Schema

The registry is defined in registry.json as an array of patch entries. Each entry specifies lightweight build-time overrides (environment variables, configure arguments, Makevars) and optionally a source diff to apply before building.

Field semantics

Field Type Required Description
package string yes CRAN package name.
versions string yes "*" for any, a constraint such as ">=5.1.0", or an exact version "5.1.11-2". Env-tier fixes are typically "*"; source diffs are normally exact or lower-bounded because a diff is pinned to the source it was generated against.
platforms array of strings yes Matched against the running build's platform tokens — distro family (alpine, ubuntu, redhat), codename (ubuntu-2604, alpine-324), and arch (amd64, arm64). An entry matches if any listed token matches any build token. ["*"] matches all platforms.
env object no Environment variables exported only for this package's isolated build.
configure_args array no Arguments passed as --configure-args to the isolated build.
makevars object no Key/value pairs written into a package-local Makevars for the isolated build.
patch string or null no Path (relative to local/patches/) to a unified diff applied to the unpacked CRAN source before building.
reason string yes Human explanation, surfaced in logs and metadata.

Adding an entry

To add a new patch entry:

  1. Add an object to the array in registry.json with the fields documented above. Start with lightweight overrides (environment variables, configure arguments, Makevars) before resorting to source diffs.

  2. If a source diff is needed, place it in local/patches/<package>/<file>.patch and reference its path in the patch field. For example, a diff for RcppParallel would go in local/patches/RcppParallel/fix.patch and be referenced as "patch": "RcppParallel/fix.patch".

  3. The reason field should clearly explain why the patch is needed and what problem it solves.

Validation

The registry is validated and applied by bincraft during the build process. For manual validation, run the validator from the repo root:

Rscript local/validate-patches.R

This validates the schema, referenced patch-file existence, and checks for duplicate entries across platforms and versions.

Triaging failures into entries

local/failing-builds-report.R turns recorded build failures into triaged patch suggestions instead of hand-scraping Crow logs (issue #115, steps 1 + 2). It is read-only: it queries single_builds WHERE error_occurred, groups failures by a normalised error fingerprint, classifies each group against the known signature set in local/failing-builds-classify.R, and prints a report.

# All platforms/arches; needs the DB password.
PGPASS=... Rscript local/failing-builds-report.R
# Restrict scope and also emit a machine-readable report.
PGPASS=... Rscript local/failing-builds-report.R --platform alpine-321 --arch amd64 --json report.json

Each group is tagged AUTO-PROPOSABLE (a known env/makevars lever, or an already-curated package patch, safe to pre-fill as a registry.json entry) or HUMAN TRIAGE (unknown signature, or a fix that needs a novel source diff). For auto-proposable groups it prints a ready-to-review registry entry; still run validate-patches.R and an isolated trial build before merging. Novel source diffs and unknown signatures stay human-reviewed by design.

Add a new signature by appending a rule to build_signatures() in local/failing-builds-classify.R; the pure helpers are covered by local/tests/test-failing-builds-classify.R.