Commit graph build-cran-binaries/local/patches/README.md
Author SHA1 Message Date
6ed17f3fb1
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
2026-07-15 07:34:07 +00:00
af481f5129 ci(crow): add weekly patch-proposal + feedback-loop pipeline (#118)
All checks were successful
ci/crow/cron/process-updates/3 Pipeline was successful
ci/crow/cron/process-updates/4 Pipeline was successful
ci/crow/cron/process-updates/10 Pipeline was successful
Adds the scheduled pipeline for the failure-triage proposer/tracker landed in #117 (issue #115, steps 3 + 4).

## `.crow/weekly-patch-proposals.yaml`

A single (non-matrix) job -- the classifier groups over all of `single_builds`, so unlike the per-platform `weekly-audit-missing` it runs once globally. Weekly it:

1. `propose-patches.R --open-issue` -- posts/updates a Forgejo tracking issue with the auto-proposable registry entries (human reviews, trial-builds, opens the PR; nothing merges).
2. `proposal-tracking.R` -- logs the feedback-loop metrics (signature hit rate, proposed-vs-merged, retirement candidates).

Low blast radius: clones read-only (`REPO_RO_TOKEN`); the only write is the tracking issue via `FORGEJO_TOKEN`. It builds nothing (no B2 keys, no bincraft).

Triggers: `cron: weekly-patch-proposals` (register the cron in the crow UI) or manual with `task=weekly-patch-proposals`, matching the `archive-missed-packages` convention. Documented under "Scheduled run" in `local/patches/README.md`.

`yamllint` and the other pre-commit hooks pass.

Reviewed-on: #118
2026-07-14 15:17:16 +00:00
1c297c01bf feat(local): auto-propose registry patches and track the feedback loop (#117)
Implements steps 3 + 4 of #115, building on the classifier merged in #116. Now that bincraft **v4.4.3** applies registry `patch`/`makevars`/`configure_args` to the *target* package build (previously deps-only), a trial patched build is a meaningful acceptance gate, so the "propose" half is viable.

## Step 3 — propose, do not apply

- **`local/propose-patches.R`** — for each classified, safe fix affecting a package with no current registry entry, emits a pre-filled `registry.json` entry and validates the candidate set against a *temporary* merged registry (the real one is never touched unless asked).
  - default: print candidates + validation, **take no action**
  - `--write`: append entries to `registry.json` + the proposals ledger (you commit + open the PR)
  - `--open-issue`: post/update a Forgejo tracking issue (reuses the weekly-audit `httr2` + `FORGEJO_TOKEN` pattern)
- **`local/trial-build-patch.R`** — isolated bincraft build of one package with the registry applied (no upload/archive/metadata; `patchhash` keeps it out of the real cache). Exit 0/1, so it gates a CI step or manual pre-merge check.

The human gate stays: nothing merges. Acceptance = `validate-patches.R` passes (checked automatically) **and** the trial build succeeds. Novel source diffs and unknown signatures are never proposed (they carry `auto = FALSE`).

## Step 4 — feedback loop

- **`local/proposal-tracking.R`** (read-only) — signature hit rate (builds/pkgs/addressed/open per signature), proposed-vs-merged (a proposal counts merged once its package is in the registry), and retirement candidates (registry entries whose package no longer fails, i.e. likely fixed upstream).
- **`local/proposal-tracking-lib.R`** — the pure metric/ledger helpers.

## Supporting changes

- Refactored the classify helpers to expose a pure `build_triage_report()` + a list-returning entry builder; `failing-builds-report.R` now renders from the shared function (no behaviour change).
- `validate-patches.R` gains optional `PATCH_DIR`/`REGISTRY_FILE` overrides (backward-compatible) so a candidate registry can be validated in isolation.
- Documented the propose/trial-build/tracking workflow in `local/patches/README.md`.

## Verification

- 71 unit tests pass (incl. new `test-proposal-tracking-lib.R`) under the Dockerized R 4.5.3 build env.
- All pre-commit hooks pass (`air-format`, `validate-patches`, prettier, etc.).
- Smoke-tested all three entrypoints end-to-end with a stubbed DB: dry-run, `--write` (produces a registry that passes the canonical validator + a valid ledger, then reverted), and the tracker.

Closes #115

Reviewed-on: #117
2026-07-14 15:03:24 +00:00
f11ba7172f feat(local): classify failing binary builds and pre-fill registry suggestions (#116)
All checks were successful
ci/crow/cron/process-updates/9 Pipeline was successful
Implements steps 1 + 2 of #115: turn recorded build failures into triaged patch suggestions instead of hand-scraping Crow logs.

## What this adds

A **read-only** reporting pipeline over the `single_builds` metadata table. It never writes to the DB or the registry.

- `local/failing-builds-classify.R` — pure, DB-free helpers:
  - `normalise_error()` strips temp paths, version numbers, hex addresses, and the package name so the same root cause collapses to one fingerprint.
  - `fingerprint_error()` extracts the salient error line and normalises it.
  - `classify_error()` matches against a seed signature set; unmatched errors are never guessed at.
  - `propose_registry_entry()` renders a schema-valid `registry.json` entry.
- `local/failing-builds-report.R` — entrypoint: queries `single_builds WHERE error_occurred = TRUE AND removed = FALSE`, groups by root cause (signature when classified, fingerprint otherwise), classifies each group, and prints a triaged report. Flags: `--platform`, `--arch`, `--min`, `--json`; `PLATFORM`/`ARCH` env fallbacks.
- `local/tests/test-failing-builds-classify.R` — unit tests for the helpers.
- `local/patches/README.md` — documents the workflow.

## Seed signatures

Each rule carries a fix tier, confidence, and an auto/human-only flag:

| Signature | Fix | Disposition |
| --- | --- | --- |
| `tbb/tbb_stddef.h: No such file` | makevars `-DTBB_INTERFACE_NEW` | auto-proposable |
| RcppParallel bundled TBB (musl / new g++) | curated `disable-tbb.patch` | auto-proposable |
| system `libuv.so` link leak | force vendored/static lib | **human triage** (novel source diff) |
| unmatched | none | **human triage** |

## Guardrails honored

- No autonomous novel source diffs: only known env/makevars levers and already-curated package patches are auto-proposable; anything needing a brand-new diff, and any unknown signature, is routed to human triage.
- No DB or registry writes; no change to the public `src/contrib` index.
- Reuses `single_builds.error_text`; no new failure-capture pipeline.

## Verification

- All helper unit tests pass under the Dockerized R 4.5.3 build env.
- Pre-commit hooks pass (`air-format`, `validate-patches`, prettier, etc.).
- Smoke-tested the full report path with a stubbed DB; generated proposals pass the real `local/validate-patches.R`.

Steps 3 (auto-open PRs) and 4 (feedback loop) are intentionally deferred, per the issue's suggestion to validate the signature set first.

Closes #115

Reviewed-on: #116
2026-07-14 14:45:25 +00:00
55a18fd87d feat: patch registry + wiring for per-package patching (#103)
Some checks failed
ci/crow/cron/process-updates/15 Pipeline failed
ci/crow/cron/process-updates/14 Pipeline failed
ci/crow/cron/process-updates/16 Pipeline failed
ci/crow/cron/process-updates/18 Pipeline failed
ci/crow/cron/process-updates/11 Pipeline failed
ci/crow/cron/process-updates/12 Pipeline failed
ci/crow/cron/process-updates/17 Pipeline failed
ci/crow/cron/process-updates/6 Pipeline failed
ci/crow/cron/process-updates/5 Pipeline failed
## Summary

Adds the curated **patch registry** and wiring that drives bincraft's new package-patching mechanism (see bincraft PR `feat/package-patching`).
Lets specific packages be patched (env/configure/Makevars overrides or source diffs) before pak installs them — including as transitive dependencies — so compiler-/OS-specific failures like RcppParallel's bundled TBB stop cascading.

## What's included

- `local/patches/registry.json` — initial entry: RcppParallel with `RCPP_PARALLEL_USE_TBB=0` for alpine / ubuntu-2604, plus `local/patches/README.md` schema docs.
- `local/validate-patches.R` — validates schema, referenced patch files, and ambiguous overlaps; clean failure + exit 1 (no stacktrace).
- `.pre-commit-config.yaml` — a `validate-patches` hook (re-runs when the registry or the validator changes).
- `local/build-one.R` / `local/build-all.R` — pass `patches = "local/patches"` to `bincraft::build_binary_package()`.
- `specs/2026-06-30-package-patching-design.md` and `plans/2026-06-30-package-patching-implementation.md`.

## ⚠️ Merge ordering (blocker)

This PR adds a `patches = ...` argument to `build_binary_package()` calls.
The `.crow/*.yaml` workflows currently pin bincraft **v4.2.3**, which does not accept that argument — CI will error with `unused argument (patches=...)` until:

1. bincraft **v4.3.0** is released (PR `feat/package-patching`), and
2. the pin is bumped in `.crow/build-all-versions-install-deps.yaml`, `.crow/build-all-versions.yaml`, and `.crow/process-updates.yaml`.

The `.crow` pin bump will be added to this PR once bincraft v4.3.0 is tagged. Do not merge before then.

Reviewed-on: #103
2026-06-30 08:50:19 +00:00