build-cran-binaries/.superpowers/handoff/task-B2-report.md

3.1 KiB

Task B2 Report: Registry Validator Script

Status

DONE — commit e3e219e: feat(patches): add registry validator script

File created

local/validate-patches.R — written verbatim from the brief.

Step 2: Success case

$ Rscript local/validate-patches.R; echo "exit=$?"
Patch registry OK (1 entrie(s)).
exit=0

Matches expected output exactly.

Step 3: Failure case

$ cp local/patches/registry.json /tmp/reg.bak
$ Rscript -e 'writeLines("[{\"package\":\"X\"}]", "local/patches/registry.json")'
$ Rscript local/validate-patches.R; echo "exit=$?"
Error in vapply(reg, function(e) { : values must be length 1,
 but FUN(X[[1]]) result is length 0
Execution halted
exit=1
$ cp /tmp/reg.bak local/patches/registry.json

Exit code is 1 as required. Note: the broken entry (missing versions) causes the vapply call to crash with an R runtime error before reaching the validation FAILED print path. The error message is different from the brief's expected text, but the exit code contract (exit=1) is met. This is a behaviour of the verbatim script from the brief — not a deviation.

Registry restore verification

After cp /tmp/reg.bak local/patches/registry.json, git status shows no diff on local/patches/registry.json — it is byte-identical to the original.

Git status before commit

Only local/validate-patches.R was staged; .superpowers/ remained untracked and was not committed.

Concerns

The vapply call in the ambiguous-overlap check will crash (rather than report a clean validation error) when an entry is missing its versions field. The missing-field loop catches the schema error and populates errs, but the script reaches the vapply before printing those errors. Downstream tasks (B3/B4) may want to guard the vapply with a length/NULL check so the FAILED message is always printed cleanly. This was not changed here — the task required verbatim implementation of the brief.


Fix: Null-safe key construction (commit 7e382c7)

What changed

In local/validate-patches.R, the keys <- vapply(...) block now uses %||% (base R 4.5.3) to substitute "?" for any NULL e$package or e$versions:

keys <- vapply(reg, function(e) {
  sprintf(
    "%s|%s|%s",
    e$package %||% "?",
    paste(sort(as.character(unlist(e$platforms))), collapse = ","),
    e$versions %||% "?"
  )
}, character(1L))

No other code changed (validation loop, error-print block, exit codes, messages all unchanged).

Verify: good registry (exit 0)

$ Rscript local/validate-patches.R; echo "exit=$?"
Patch registry OK (1 entrie(s)).
exit=0

Verify: malformed registry (exit 1, no stacktrace)

$ cp local/patches/registry.json /tmp/reg.bak
$ Rscript -e 'writeLines("[{\"package\":\"X\"}]", "local/patches/registry.json")'
$ Rscript local/validate-patches.R; echo "exit=$?"
Patch registry validation FAILED:
  - entry 1 (X): missing versions, platforms, reason
exit=1
$ cp /tmp/reg.bak local/patches/registry.json
registry restored

No R Error in ... / Execution halted stacktrace. Clean validation FAILED message with all collected errors printed before exit.