📦 2026-08-27 canonical handoff
Historical record — 2026-08-27
Preserved as observed. This remains the current canonical handoff: Clusters 1, 2, 4 and 5 applied in that order, with the ordering enforced by six digest-linked shared files. Current truth: Program Masterplan.
Scope: WRDP bench, 2026-08-27. This page is the delivery vehicle for four clusters of bench work that were each verified in place but had no path into the canonical repository. It changes no plugin behaviour. Everything it packages remains releaseEligible: false; the release owner applies source through the locked pipeline in BUILDING.md.
What is being handed over
| cluster | date | files | net lines | evidence |
|---|---|---|---|---|
| 1 | 2026-08-26 | 5 | +50 / −8 | play surface repair |
| 2 | 2026-08-26 | 3 | +27 / −11 | playable quiz repair |
| 4 | 2026-08-27 | 14 | +210 / −72 | performance remediation |
| 5 | 2026-08-27 | 2 | +61 / −8 | not-found and token scope |
18 distinct files. Cluster 3 was an audit and changed nothing, which is why the series skips from 2 to 4.
Net lines count changed diff lines, and the blank-line convention is not uniform across the series because each row reports the figure its own evidence page published. Cluster 4’s +210 / −72 excludes 9 added and 3 removed blank lines, so that patch’s raw diff is +219 / −75. Clusters 2 and 5 change no blank line, so their figures are the same either way. Cluster 1’s +50 / −8 includes 3 added blank lines, and is +47 / −8 without them.
Ordering is enforced, not asserted
Four files are touched by more than one cluster, and they produce six ordering links, because includes/Frontend/QuizEmbed.php and includes/Frontend/QuizQueryViewer.php each appear in two of them. For each link, the later cluster’s preimage digest equals the nearest earlier cluster’s postimage digest, so applying the series out of order fails a preimage check instead of silently producing a wrong tree:
| link | file |
|---|---|
| 1 → 2 | includes/Frontend/QuizEmbed.php |
| 1 → 2 | includes/Frontend/QuizQueryViewer.php |
| 1 → 5 | assets/css/qwizz-tokens.css |
| 2 → 4 | includes/Admin/DashboardPresenter.php |
| 2 → 4 | includes/Frontend/QuizEmbed.php |
| 2 → 5 | includes/Frontend/QuizQueryViewer.php |
All six links were verified programmatically against the eight manifests this session, comparing only against the nearest earlier cluster that touched each file rather than every earlier cluster.
How to apply it
q5vault/audits/qwizz/2026-08-27-apply-clusters.sh --target <plugin-root> --check-only
q5vault/audits/qwizz/2026-08-27-apply-clusters.sh --target <plugin-root>
<plugin-root> is the directory holding quizwizz.php, includes/ and assets/. The script:
- refuses a target without
quizwizz.php - snapshots every already-present file any cluster touches, and records every touched path the series will create, before touching anything; on any failure it restores each snapshotted file, deletes each file the run itself created, and exits non-zero, so a failed run leaves the tree as it found it — including the absence of the file the series adds
- verifies each cluster’s preimage manifest, dry-runs the patch, applies it, then verifies the postimage manifest, per cluster in order
- treats a
(did-not-exist)preimage entry as must be absent, which is how the one new file is handled - builds, versions and signs nothing
--check-only verifies cluster 1 only. That is a deliberate limitation stated in the script rather than papered over: clusters 2, 4 and 5 have preimages that are the preceding cluster’s postimages, so they cannot be checked against an unpatched tree. A full run verifies them in sequence.
Proof that the series reproduces the bench
Not a claim that the patches “look right” — an executed reconstruction:
- Copied the live plugin tree.
- Reverse-applied all four patches, newest first, returning it to the pre-Cluster-1 state, and deleted the one file Cluster 4 creates so the tree genuinely lacked it.
- Ran
--check-only: cluster 1’s five preimage digests matched. - Ran the full script: all four clusters applied, and every postimage digest matched at every step, including
assets/css/qwizz-empty.cssreported as(absent, will be created). - Compared all 18 files against the live bench: 18/18 byte-identical, zero mismatches.
Three defects this packaging exposed
The first two were found by executing the handoff rather than by reading it. The third was found by re-auditing this page against the script it documents, and is a defect in the guarantee stated above rather than in any patch. All three are fixed above.
The Cluster 4 patch could not have been applied by the release owner. assets/css/qwizz-empty.css is a new file, but the patch had been generated against an empty placeholder on the a/ side instead of an absent path. Applied to a tree where the file genuinely does not exist — the state of any canonical checkout — it failed:
checking file assets/css/qwizz-empty.css
Hunk #1 FAILED at 317.
1 out of 1 hunk FAILED
Regenerated with the file absent on the a/ side so GNU diff -N emits the epoch-timestamp creation marker that patch understands. The patch digest therefore changed, and the Cluster 4 evidence page was corrected to match:
| sha256 | |
|---|---|
| superseded | 65605c06a4fa31a809d1416ad5d7ebd993a5d242365a5a1369c47fc2da6fb91e |
| current | 0b60aa9f5bf469afd20ba03df77f010582a56e6b916b8fd6f20b63fdb6513e18 |
The line counts are unchanged at +210 / −72, and the round-trip to the postimage tree still reproduces byte-for-byte. Had this series been handed over without executing it, the release owner would have hit a failed hunk on the one genuinely new file.
Two latent bash bugs in the apply script itself, both caught by running it:
local name=$1 date=$2 manifest="$HERE/$date-…"— bash expands every word of alocalcommand before the builtin assigns any of them, so$datewas unbound underset -u. Split into two statements.printf '-- preimage\n'—printfread the leading--as an end-of-options marker and rejected the call. Rewritten asprintf '%s\n' '-- preimage'.
The second failure is also the script’s rollback proof: it aborted mid-cluster-1 and restored every file it had snapshotted, which is exactly the transactional behaviour it promises. No file count is stated for that run: the tree in that episode did not yet contain assets/css/qwizz-empty.css, so the snapshot could have covered at most the 17 files that existed, and no per-run total from the aborted run is on record here.
The rollback guarantee on this page was overstated for created files. It promised that a failed run leaves the tree exactly as it found it, which held only for files that already existed: as first cut the script snapshotted a path only when it was present, and its restore loop only copied, never deleted, so a rollback after Cluster 4 had created assets/css/qwizz-empty.css would have left that file behind in a tree that never had it. The script was corrected in the same pass as this page. It now records every touched path that is absent at snapshot time (2026-08-27-apply-clusters.sh:172-179) and deletes those paths during rollback (:71-77) alongside restoring the snapshotted files (:65-70), so the bullet above describes behaviour rather than an aspiration.
Artifacts
In q5vault/audits/qwizz/:
2026-08-27-apply-clusters.sh— the ordered, transactional applier2026-08-26-cluster1-source.patch+-preimage.sha256+-postimage.sha2562026-08-26-cluster2-source.patch+-preimage.sha256+-postimage.sha2562026-08-27-cluster4-source.patch+-preimage.sha256+-postimage.sha2562026-08-27-cluster5-source.patch+-preimage.sha256+-postimage.sha256
Release boundary
releaseEligible: false, unchanged by this packaging. Nothing under vendor/, build/, provenance, release ZIPs or QUIZWIZZ_VERSION is touched by any patch in the series. SCHEMA_VERSION moves 1.6.7 → 1.6.8 in Cluster 4; that is the migration mechanism, not a release version, and the migration is applied by the plugin’s own Installer::maybe_upgrade().
What this handoff does not do, stated plainly: it does not build, lint against the canonical ruleset, run the canonical test suite, regenerate the classmap, produce provenance, sign, or version. The bench has none of those inputs. It delivers a tree the release owner can trust to be exactly what was verified here, and nothing beyond that.