feat(local): auto-propose registry patches and track the feedback loop

Implement steps 3 + 4 of issue #115 on top of the failure classifier, now
that bincraft v4.4.3 applies registry patches/makevars/configure_args to the
target build (not just dependencies), so a trial patched build is meaningful.

- refactor the classify helpers to expose a pure build_triage_report() and a
  list-returning entry builder; failing-builds-report.R now renders from it
- add local/propose-patches.R (step 3, "propose, do not apply"): emit a
  pre-filled registry.json entry for each classified, safe, unregistered
  failure, validate the candidate set against a temporary merged registry,
  and (only on request) --write it plus a proposals ledger, or --open-issue a
  Forgejo tracking issue; the human gate and validator/trial-build acceptance
  stay, and novel source diffs / unknown signatures are never proposed
- add local/trial-build-patch.R: isolated bincraft build of one package with
  the registry applied (no upload/archive/metadata) as the pre-merge gate
- add local/proposal-tracking.R + local/proposal-tracking-lib.R (step 4):
  signature hit rate, proposed-vs-merged, and retirement candidates, with the
  pure helpers covered by tests
- teach validate-patches.R optional PATCH_DIR/REGISTRY_FILE overrides so a
  candidate registry can be validated without touching the real one
- document the propose/trial-build/tracking workflow in local/patches/README.md
This commit is contained in:
Patrick Schratz 2026-07-14 15:01:55 +00:00
commit 8afa584da3
No known key found for this signature in database
GPG key ID: 62050D5BC68AB6DC

View file

@ -59,3 +59,37 @@ For auto-proposable groups it prints a ready-to-review registry entry; still run
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`.
### Proposing entries (step 3: propose, do not apply)
`local/propose-patches.R` takes the auto-proposable candidates one step further: for each classified, safe fix affecting a package with no current entry, it emits a pre-filled `registry.json` entry and validates the candidate set against a temporary merged registry (the real registry is never touched unless you ask).
The human gate stays: it never merges.
```bash
# Default: print candidates + validation, take no action.
PGPASS=... Rscript local/propose-patches.R
# Append the candidates to registry.json + the proposals ledger (you commit + open the PR).
PGPASS=... Rscript local/propose-patches.R --write
# Or post/update a Forgejo tracking issue instead (needs FORGEJO_TOKEN).
PGPASS=... FORGEJO_TOKEN=... Rscript local/propose-patches.R --open-issue
```
The acceptance criteria before merging a proposal are: `validate-patches.R` passes (checked automatically), and an isolated trial build succeeds.
Run the trial build inside the failing platform's build-env image; it uploads/archives nothing and writes no metadata:
```bash
Rscript local/trial-build-patch.R <package>
```
`--write` and `--open-issue` also append to `local/patches/proposals-log.json`, a ledger of what was proposed.
### Feedback loop (step 4)
`local/proposal-tracking.R` reports the signature hit rate, proposed-vs-merged status (a proposal counts as merged once its package appears in the registry), and retirement candidates (registry entries whose package no longer appears in any current failure, so the upstream cause was likely fixed).
It is read-only.
```bash
PGPASS=... Rscript local/proposal-tracking.R --json metrics.json
```
The pure metric/ledger helpers live in `local/proposal-tracking-lib.R` and are covered by `local/tests/test-proposal-tracking-lib.R`.