Mirror decision sheet — 41 modified files vs 715474f
a. Purpose
The Sep-8 mirror commit is NOT PERFORMED / blocked (handover §5) because the release owner had no per-file view of what is actually dirty and why. This sheet is that view. It stages nothing, commits nothing and touches no plugin byte: a throwaway Python script (census.py, stdlib only, read-only against the tree) hashed every M row of ./scripts/qwgit.sh status --short (asserted: 41 rows, 0 ??) against four images and classified each row by a fixed ladder. Inputs: mirror GIT_DIR=.git-quizwizz, HEAD 715474f07ddf75c4dd49607aad3f82a405b0eeae; the Sep-8 baseline-manifest.json (35 archive members = exact dirty before images; 19 packet paths, 13 archive-backed and 6 mirror-backed); the sealed final-manifest.json (19-path allowlist, afterSha256 per capture, patch today-source-final.patch SHA-256 d1bc84e7…a93c). The 41 rows equal exactly archive(35) ∪ packet(19).
Class ladder (first match wins): clean-now (current = HEAD) · packet-clean-base (in packet, current = packet after, before = HEAD) · packet-on-drifted-base (in packet, current = packet after, before ≠ HEAD) · post-packet-mutation (in packet, current ≠ packet after) · inherited-catalog-artifact (not in packet, current = before, under languages/) · inherited-unpacketed (not in packet, current = before) · post-sep8-unattributed (not in packet, current ≠ before — RED).
b. Class counts
| Class | Rows |
|---|---|
packet-on-drifted-base | 13 |
packet-clean-base | 6 |
inherited-unpacketed | 5 |
inherited-catalog-artifact | 17 |
clean-now | 0 |
post-packet-mutation | 0 |
post-sep8-unattributed | 0 |
| total | 41 |
Every live byte is accounted for: the 19 packet paths still carry exactly their sealed afterSha256, and the 22 unpacketed paths still carry exactly their Sep-8 archive bytes. Nothing changed after the Sep-9 seal, and nothing is unattributed. (The Sep-14 backup-dropping cleanup removed only untracked files and left all 41 tracked rows byte-identical — receipt §5.)
c. Fresh canonical apply-check of the final packet
This had never been run: the Sep-8 receipt checked only the interim v3 patch. Today: ./scripts/qwgit.sh archive 715474f… | tar -x into a disposable directory, then inside it env -u GIT_DIR -u GIT_WORK_TREE git apply --check -p1 --whitespace=error-all today-source-final.patch (patch SHA-256 verified d1bc84e75939f5fa449b8127c58f271bb59c0e26a7bfb03443d75a4e3083a93c first). Result: exit 1, seven paths fail (patch failed: <path>:<line> / patch does not apply):
assets/css/qwizz-admin-settings-core.css:41assets/css/qwizz-admin-settings-layout.css:697assets/css/qwizz-finetune.css:159assets/js/qwizz-admin-settings.js:262assets/js/qwizz-finetune.js:22includes/Frontend/Shortcodes/CraftShortcode.php:459includes/Frontend/views/finetune-editor.php:27
These are the same seven paths the v3 assessment recorded; the final packet does not fail anywhere new. All seven are packet-on-drifted-base; the other six drifted-base paths (qwizz-admin-responsive.css, qwizz-builder.css, ExposureSettings.php, CraftService.php, builder-view.php, PresentationDocument.php) happen to apply against 715474f despite the drift, and all six packet-clean-base paths apply. git apply --check is all-or-nothing, so “expected to apply” below means the file’s hunks individually apply; the patch as a whole does not. The disposable tree was deleted afterwards; no apply without --check was run anywhere.
d. The 41 rows
Hashes are SHA-256 truncated to 8 hex; before names its source (archive = Sep-8 dirty archive member, mirror = mirror object matching the earliest pristine receipt). +N/−M is git diff --numstat 715474f -- <path>; - = binary.
| Path | Class | before | HEAD | current | packet after | +/− vs HEAD | Proposed disposition |
|---|---|---|---|---|---|---|---|
assets/css/qwizz-admin-responsive.css | packet-on-drifted-base | e3dd49aa (archive) | b1bfb5e7 | 636e08c0 | 636e08c0 | +24/−4 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
assets/css/qwizz-admin-settings-core.css | packet-on-drifted-base | 8362571a (archive) | 92d09a8e | 988fa373 | 988fa373 | +16/−85 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
assets/css/qwizz-admin-settings-layout.css | packet-on-drifted-base | b6074ed1 (archive) | dd3a99e5 | e2afa84c | e2afa84c | +0/−72 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
assets/css/qwizz-admin-settings-workspace.css | inherited-unpacketed | 48ffbe6b (archive) | 44f37cc7 | 48ffbe6b | — | +46/−155 | pre-Sep-8 modification with no packet; owner attributes the diff vs HEAD (supplied) or reverts to 715474f |
assets/css/qwizz-builder.css | packet-on-drifted-base | 462a3065 (archive) | 0b7c728d | 84e348cc | 84e348cc | +163/−62 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
assets/css/qwizz-finetune.css | packet-on-drifted-base | 9bc79c29 (archive) | dd50310b | 75c41eae | 75c41eae | +326/−122 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
assets/js/qwizz-admin-settings.js | packet-on-drifted-base | 6f5cb4ba (archive) | 352a0b06 | 70a0a621 | 70a0a621 | +55/−86 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
assets/js/qwizz-builder-controls.js | packet-clean-base | 16ccb00d (mirror) | 16ccb00d | a1ca6258 | a1ca6258 | +31/−15 | stage this file’s hunks from today-source-final.patch against 715474f; expected to apply |
assets/js/qwizz-builder-state.js | packet-clean-base | 9fad4d76 (mirror) | 9fad4d76 | 800f21e9 | 800f21e9 | +40/−4 | stage this file’s hunks from today-source-final.patch against 715474f; expected to apply |
assets/js/qwizz-builder-submit.js | packet-clean-base | 5364dcd9 (mirror) | 5364dcd9 | df41d618 | df41d618 | +9/−1 | stage this file’s hunks from today-source-final.patch against 715474f; expected to apply |
assets/js/qwizz-finetune.js | packet-on-drifted-base | debe7a3e (archive) | e8298a1a | 2c91b2ef | 2c91b2ef | +432/−245 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
config/settings-tiers.json | inherited-unpacketed | 35c27fb7 (archive) | 3bf8668e | 35c27fb7 | — | +0/−1 | pre-Sep-8 modification with no packet; owner attributes the diff vs HEAD (supplied) or reverts to 715474f |
includes/Admin/SettingsPage.php | inherited-unpacketed | 5e38f30b (archive) | 6e656038 | 5e38f30b | — | +0/−14 | pre-Sep-8 modification with no packet; owner attributes the diff vs HEAD (supplied) or reverts to 715474f |
includes/Admin/views/settings-page.php | inherited-unpacketed | d73bb702 (archive) | 2aeee39e | d73bb702 | — | +5/−18 | pre-Sep-8 modification with no packet; owner attributes the diff vs HEAD (supplied) or reverts to 715474f |
includes/ExposureSettings.php | packet-on-drifted-base | 89de47bd (archive) | 910beea0 | 63ced037 | 63ced037 | +8/−4 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
includes/Frontend/Craft/CraftService.php | packet-on-drifted-base | 09198c23 (archive) | bcb3988f | 29801c7f | 29801c7f | +3/−2 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
includes/Frontend/Shortcodes/CraftShortcode.php | packet-on-drifted-base | 2952a534 (archive) | c9610d1c | 4508e304 | 4508e304 | +24/−9 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
includes/Frontend/views/builder-view.php | packet-on-drifted-base | e5aa5684 (archive) | 0727cd04 | 92208da0 | 92208da0 | +30/−29 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
includes/Frontend/views/finetune-editor.php | packet-on-drifted-base | de5c89e1 (archive) | f3d70c91 | f2d6c9e3 | f2d6c9e3 | +78/−18 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
includes/Generation/GenerationSchemas.php | packet-clean-base | 0c51d926 (mirror) | 0c51d926 | bf8237fb | bf8237fb | +2/−9 | stage this file’s hunks from today-source-final.patch against 715474f; expected to apply |
includes/Generation/GenerationService.php | packet-clean-base | 365ab4ac (mirror) | 365ab4ac | 6ed4d076 | 6ed4d076 | +37/−25 | stage this file’s hunks from today-source-final.patch against 715474f; expected to apply |
includes/Pdf/PdfGenerator.php | packet-clean-base | c2b6b6bc (mirror) | c2b6b6bc | c2962248 | c2962248 | +6/−3 | stage this file’s hunks from today-source-final.patch against 715474f; expected to apply |
includes/PresentationDocument.php | packet-on-drifted-base | 7a49e4f0 (archive) | b83e479a | 4d546b6e | 4d546b6e | +12/−5 | owner picks base: (i) rebase the hunks onto 715474f, or (ii) accept current bytes whole-file; diff vs HEAD supplied |
includes/Settings/SettingsSchema.php | inherited-unpacketed | c2ef5599 (archive) | e8cae74a | c2ef5599 | — | +2/−3 | pre-Sep-8 modification with no packet; owner attributes the diff vs HEAD (supplied) or reverts to 715474f |
languages/quizwizz-de_DE-520b882d5a62045c160d0dc56eabc58c.json | inherited-catalog-artifact | 9490a8c9 (archive) | fac23e82 | 9490a8c9 | — | +135/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-949f8136c01f699e9f8fbc8c66d5f965.json | inherited-catalog-artifact | 06227e24 (archive) | 11ae0770 | 06227e24 | — | +25/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-cdce7c50e7a4850240f5b7a9ca845996.json | inherited-catalog-artifact | 7ad346ce (archive) | 1aada3cd | 7ad346ce | — | +312/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-quizwizz-admin-editor.json | inherited-catalog-artifact | ece11763 (archive) | 718a8e95 | ece11763 | — | +1/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-quizwizz-admin-import.json | inherited-catalog-artifact | 8aaa1eb3 (archive) | 11fcdf3e | 8aaa1eb3 | — | +1/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-quizwizz-quiz-editor-script.json | inherited-catalog-artifact | c42ef186 (archive) | 3e6eca73 | c42ef186 | — | +1/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-qwizz-admin-settings.json | inherited-catalog-artifact | 40572f3e (archive) | da1609f2 | 40572f3e | — | +1/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-qwizz-admin-shortcode-copy.json | inherited-catalog-artifact | 6d39852c (archive) | 25a9f964 | 6d39852c | — | +1/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-qwizz-admin-subjects.json | inherited-catalog-artifact | 8a5c53f4 (archive) | f1a09787 | 8a5c53f4 | — | +1/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-qwizz-block-editor-enhance.json | inherited-catalog-artifact | 63859fd2 (archive) | 8c18d16f | 63859fd2 | — | +1/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-qwizz-builder.json | inherited-catalog-artifact | 552dc559 (archive) | 5cb80776 | 552dc559 | — | +1/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-qwizz-finetune.json | inherited-catalog-artifact | c2745776 (archive) | d34654e3 | c2745776 | — | +1/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-qwizz-player.json | inherited-catalog-artifact | 000553f3 (archive) | b14925c5 | 000553f3 | — | +1/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE-qwizz-user.json | inherited-catalog-artifact | ee2eedf6 (archive) | 7c771cf5 | ee2eedf6 | — | +1/−1 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE.mo | inherited-catalog-artifact | ff5fe922 (archive) | ac4471a0 | ff5fe922 | — | +-/−- | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz-de_DE.po | inherited-catalog-artifact | bf75481d (archive) | c16dca2e | bf75481d | — | +926/−981 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
languages/quizwizz.pot | inherited-catalog-artifact | b6e20ef0 (archive) | 956c6f9b | b6e20ef0 | — | +898/−953 | regenerate from catalog commit d61d98c through the locked pipeline, or accept as build output; owner decides |
e. What the owner must decide
packet-on-drifted-base(13): the sealed packet was captured against a dirty base, so its hunks describe current − before, not current − HEAD. Options: (i) rebase the file’s hunks onto715474fby hand — the seven failing paths need this, the other six may apply as-is; (ii) accept the current live bytes whole-file as the new source (the diff vs HEAD for each is in the privatediffs/); (iii) revert to715474fand drop the Sep-8 packet for that file. The choice also settles what the pre-Sep-8 drift was, because it is folded into the whole-file diff.packet-clean-base(6): the clean case. Option (i) stage the file’s hunks fromtoday-source-final.patch(expected to apply against715474f); option (ii) revert to715474fif the Sep-8 receipt for that file is not accepted.inherited-unpacketed(5 —qwizz-admin-settings-workspace.css,settings-tiers.json,SettingsPage.php,settings-page.php,SettingsSchema.php): modified before Sep-8 with no packet and no receipt naming the change. Options: (i) attribute the diff vs HEAD (supplied privately) to a dated receipt and stage whole-file; (ii) revert to715474f. These are all Settings-surface files; the Sep-14 UI/UX round touches the first and fourth, after which their attribution is that receipt (see the refresh section when it lands).inherited-catalog-artifact(17languages/files:.po,.pot,.moand 14 script catalogs): build outputs regenerated on the bench after catalog commitd61d98c. Options: (i) regenerate through the locked pipeline from the canonical catalog source and commit the pipeline’s output; (ii) accept the bench bytes as build output; (iii) revert to715474f. Never hand-edit.
Prerequisite that no option removes: the real mirror index must be inspected for unrelated work before any qwgit.sh add, and canonical target/port stays the owner’s call (handover §5).
f. Provenance
evidence/2026-09-14-mirror-decision/(private, mode0700, not published):census.py,census.json,apply-check.txt,diffs/<path>.diff(41 files; may contain source, never copied to the vault).census.jsonSHA-256:34f2e88abfec9e580d85c222f31c7a27509577fe6e5f595d548834457a032c10.- Independent replay: 5/5 rows confirmed (first row of each of the four classes present plus a second catalog row), re-hashed by hand against the live file,
qwgit.sh show 715474f:<path>, the baseline inventory and the final capture; apply-check re-run in a fresh archive extraction. The read-onlyevidence-auditorverdict, quoted: “Independent replay confirms the census: live status is exactly 41Mrows with zero??, row_count 41 and class_counts (packet-on-drifted-base 13, inherited-catalog-artifact 17, packet-clean-base 6, inherited-unpacketed 5) sum to 41, all five audited rows reproduce their current/head/before/packet_after hashes, numstats and ladder-derived class byte-for-byte, and the fresh final-packet apply-check independently returns exit 1 with the identical seven failure paths and byte-identical stderr — zero mismatches.” - Bench model roles:
bench_edit/bench_probe/bench_auditwerenullin.omp/config.ymluntil 2026-09-14 (theevidence-auditoragent died withNo model selected); now bound toanthropic/claude-opus-5at medium/low/high. Proven in-session:omp config get modelRolesprints all three, and the replay above was produced byevidence-auditoritself.
Refresh after round F
The UX repair round changed 21 plugin files after the census above was taken, so the sheet’s 41-row view is now the pre-round-F state. Sections a through f are left exactly as they were measured; this section states what moved. The refresh artifact is evidence/2026-09-14-mirror-decision/census-refresh.json, created 2026-09-14T03:58:53Z against the same head 715474f.
Two limits on that artifact, stated because they change what it can decide:
- it recorded
row_count49 by bypassing the script’sexpected_rows41 assertion through arefreshsuffix, so the 41-row invariant that guarded the original census did not run. - it did not re-run the canonical apply-check. The exit-1 / seven-path result in section c still describes the pre-round-F packet only, and no apply-check exists for the round-F tree.
Refreshed class counts, same ladder, first match wins:
| Class | Rows before round F | Rows after round F |
|---|---|---|
post-sep8-unattributed | 0 | 13 |
post-packet-mutation | 0 | 8 |
packet-on-drifted-base | 13 | 5 |
packet-clean-base | 6 | 6 |
inherited-unpacketed | 5 | 3 |
inherited-catalog-artifact | 17 | 14 |
clean-now | 0 | 0 |
| total | 41 | 49 |
Six of the seven classes are non-empty after the round, against four before. The two that were 0 are the two RED-adjacent classes, and they hold exactly the 21 round-F files.
The 13 post-sep8-unattributed rows — not in the packet, current bytes differ from the Sep-8 before image:
assets/css/qwizz-admin-dashboard.cssassets/css/qwizz-admin-editor.cssassets/css/qwizz-admin-shell.cssincludes/Admin/DashboardPresenter.phpincludes/Admin/ListTables.phpincludes/Admin/SettingsPage.phpincludes/Admin/views/quiz-editor.phpincludes/Admin/views/settings-page.phpincludes/LanguageFlags.phpincludes/Rest/AdminController.phplanguages/quizwizz-de_DE.molanguages/quizwizz-de_DE.polanguages/quizwizz.pot
The 8 post-packet-mutation rows — in the packet, but current bytes no longer equal the sealed afterSha256:
assets/css/qwizz-admin-responsive.cssassets/css/qwizz-admin-settings-core.cssassets/css/qwizz-builder.cssassets/css/qwizz-finetune.cssassets/js/qwizz-admin-settings.jsassets/js/qwizz-finetune.jsincludes/Frontend/views/builder-view.phpincludes/Frontend/views/finetune-editor.php
How the movement reconciles, from the counts above: packet-on-drifted-base lost exactly those 8 files, which is why it falls 13 → 5. inherited-catalog-artifact lost 3 and inherited-unpacketed lost 2, so 5 previously classified rows moved into post-sep8-unattributed; the three catalog rows are the .mo, .po and .pot artifacts in the list above, because round F regenerated them and the class requires current = before. That leaves 8 of the 13 as rows that were not among the original 41 at all, which is the arithmetic behind 41 + 8 = 49. The per-row identity of the 2 rows that left inherited-unpacketed is in census-refresh.json and was not re-derived for this section; section e already anticipated two of its five Settings files being touched, qwizz-admin-settings-workspace.css and settings-page.php.
What this does to the owner’s options in section e:
- the 8
post-packet-mutationpaths have no option (i). Their hunks intoday-source-final.patchdescribe bytes that are no longer on disk, so staging that patch would discard round-F work. They need either the live bytes accepted whole-file against the round-F receipt, or a fresh capture. - the 13
post-sep8-unattributedpaths are attributable, not orphaned: the round F receipt names the change, the slice and the anchors for each. That is what the class name asks for and what the original census had none of. - the 5 remaining
packet-on-drifted-baseand 6packet-clean-baserows are unchanged by round F and their section e options stand as written.
Nothing here stages, commits or hand-edits anything, and no languages/ artifact was hand-edited: the catalog files moved class because round F regenerated the .mo through the normal path. releaseEligible: false.
Refresh after phase G
The 2026-09-14 Settings premium restyle changed six plugin files after the round-F refresh above, two of which were not tracked-modified before, so the census moves from 49 rows to 51 at the same head 715474f with 0 ??. Sections a through f and the round-F refresh are left exactly as they were measured; this section states what moved. The artifact is evidence/2026-09-14-mirror-decision/census-refresh-g.json, created 2026-09-14T06:15:40Z, and it carries both limits of its predecessor: it recorded row_count 51 against the script’s expected_rows 41, so the original row invariant did not run, and apply_check is null — no canonical apply-check exists for the round-F tree or for this one.
| Class | Rows after round F | Rows after phase G |
|---|---|---|
post-sep8-unattributed | 13 | 16 |
post-packet-mutation | 8 | 9 |
packet-clean-base | 6 | 6 |
packet-on-drifted-base | 5 | 4 |
inherited-unpacketed | 3 | 2 |
inherited-catalog-artifact | 14 | 14 |
| total | 49 | 51 |
Four movements account for the whole delta, and they reconcile the counts exactly:
assets/css/qwizz-admin-settings-layout.cssmovedpacket-on-drifted-base→post-packet-mutation, which is why the first class falls 5 → 4 and the second rises 8 → 9. Its live bytes no longer equal the sealedafterSha256.assets/css/qwizz-admin-settings-workspace.cssmovedinherited-unpacketed→post-sep8-unattributed, soinherited-unpacketedfalls 3 → 2.assets/css/qwizz-admin-settings-search-preview.cssis a new row inpost-sep8-unattributed.assets/css/qwizz-tokens.cssis a new row inpost-sep8-unattributed.
post-sep8-unattributed therefore rises 13 → 16: one file moved in and two are new rows, which is also the arithmetic behind 49 + 2 = 51. The two remaining phase G files were already carried by the round-F refresh — assets/css/qwizz-admin-settings-core.css as post-packet-mutation and includes/Admin/views/settings-page.php as post-sep8-unattributed — so their class did not change even though their bytes did.
What this does to the owner’s options in section e:
- nine
post-packet-mutationpaths now have no option (i), one more than after round F.today-source-final.patchdescribesqwizz-admin-settings-layout.cssbytes that are no longer on disk, so staging it would discard phase G work on that sheet as well. - all four new or moved rows are attributable rather than orphaned: the phase G receipt names the owned files, their live SHA-256 values and the rounds that changed each one.
assets/css/qwizz-tokens.cssdeserves separate attention because it is not a Settings-only sheet: phase G added three admin tokens at:91-93and an accent block scoped to.qwizz-settings.qwizz-settings--premiumat:398-406, so the file is shared while the accent is not. - the 4 remaining
packet-on-drifted-baseand 6packet-clean-baserows are unchanged by phase G and their section e options stand as written.
Nothing here stages, commits or hand-edits anything, and no languages/ artifact moved in this refresh. releaseEligible: false.