UTS — Open-items punchlist (don't-forget tracker)
Built 2026-07-02 from a hand read of every web-phase doc (1–21) + a 3-agent cross-check (web-phase docs · Flutter-22.x docs · memory+git), reconciled. The web track (Phases 1–21) is shipped + on prod; the Flutter parity track (22.x) is in flight. None of the OPEN items is a live prod defect — every 🔴 broken-behavior bug (dishonest completion page, multi-user O2M lock/Spartacus, hydration-green loss, double headings, picker XSS, cover/scroll bugs) was fixed and, where prod-relevant, deployed. The items below are deferred features, deferred engineering, a security follow-up, and owed verifications — the loops most at risk of being forgotten now that "web is done."
🔴 OPEN — web-side (deferred, not lost)
| # | Item | Kind | Source |
|---|---|---|---|
| ~~W1~~ | → VERIFIED + BROADENED + FILED as RI issue 2539 (2026-07-05). Not just episodes/series: a guard-trace of every media-edge setter found the same missing media.HasSiteWith(site) check in 9 service files / ~19 sites (series, events, contacts, categories, posts, weblinks, content_blocks, cover_variants, media_collections); only guides/materials/steps were guarded. Real authenticated cross-tenant disclosure IDOR (the /media/ FileServer is unauthenticated, picker is site-scoped → id-enumeration is the only path to foreign media); Medium severity, inert in single-owner dogfood. Merged with W8 (the shared-helper extraction is the fix vehicle). Full scope + exploit chain + fix in issue 2539. |
🔒 security → filed | phase-19:263-269; RI issue 2539 |
| W2 | Guide-lightbox reset modal not g-styled. The post-body block reset modal is a g-card; the guide-lightbox showResetModal is still plain Bootstrap. Flagged to the web team; Flutter deliberately leads (accepted 22.4 divergence). |
parity | phase-22.4-cook-lightbox-parity-audit.md (ACCEPTED-DIVERGENCE) |
| W3 | Step deep-link (b) — location.hash → open the lightbox + scroll to the step (then re-add the per-step url, dedupe in-collection slugs, guarantee slug population). Only (c) "drop the url" shipped. |
feature | phase-13:138-160,215-217 (D13.6b) |
| W4 | Material tags → chip discovery (142 tagged materials in prod; chip render exists) — spun OUT of Phase 13 into the American Graffiti program (needs its own mockup; the cook-lightbox chip UX is unresolved). |
feature (→ AG) | phase-13:174-180 (D13.5) |
| W5 | Ratings feature. Guide rating metadata renders as generic Rating: 4 text; stars / aggregate / an authoring surface is a proper later feature (deliberately NOT a metadata special-case). |
feature | phase-9:141 |
| W6 | Playthrough guide-scoped media aggregation. A future guide "playthrough" must aggregate guide media as a guide-scoped group, NOT by adding step/material media to the page-wide {{ if .Hidden }} data-spans (would break the isolated-experience intent). Architectural guard. |
architecture guard | overview :112 (Phase 15) |
| W7 | Search/pagination on the 4 other bespoke pickers + the media-library page (event_cover, category_media, contact_photo, weblink_thumbnail + the media_library grid). Endpoint already supports it → front-end-only. Deferred to AFTER the Flutter parity pass. | engineering | phase-19a:173-184 |
| ~~W8~~ | → MERGED into RI issue 2539 (2026-07-05). The shared validateMediaOwnership extraction is the fix vehicle for the broadened-W1 IDOR (materials/steps/guide have copies #1–3; 9 more files need the guard). Doing it once as a shared helper closes W1+W8 together — tracked in issue 2539, not here. |
cleanup → filed | phase-19:164-166; RI issue 2539 |
| W9 | Studio "Block interaction insights." Guide progress has a Studio Insights view; block interactions have NO analytics view (coverage asymmetry). Out-of-scope / future. | feature | phase-21:102-109 (D21.3) |
| W10 | ?v= asset version doesn't bump on restart — CSS/JS changes need a hard refresh in dev; flagged for a build fix. Dev-ergonomics, out of scope. |
dev-tooling | phase-9:51 |
| W11 | Google modal-content policy watch-item. D13.6(c) still emits recipeInstructions text from lightbox-only (user-openable) steps; defensible today. Re-confirm if Google tightens its "don't mark up content not visible" policy. |
watch-item | phase-13:157-160 |
| W12 | Flutter learn-flow leads → propose to web. The 22.5 audit found 3 places where Flutter's learn lightbox is intentionally richer than web (operator-approved to keep on Flutter). Web team to review as candidate web additions: (a) review answers as pill boxes + "YOUR ANSWER"/"CORRECT ANSWER" labels (web = inline text + ✓/✗ icons); (b) explanation box shown in the review section (web review has none); (c) "flashcards not included in score" note on the completion page (web omits). → Proposal written 2026-07-03 (w12-flutter-leads-web-proposal.md); web-side review verified all claims (14/14) + folded in 4 findings. ✅ DONE — IMPLEMENTED ON WEB + dev-smoked 2026-07-04: all three + the F2 companion (correct_option_id in the hydration blob, answered-steps-only = redaction-safe; review pills survive a pure-hydration reload — the previously-impossible case, verified). Operator live-confirmed on dev during the smoke: label measured 11/600/uppercase/#9AA0A6 = Flutter's exact values. Dead Phase-4h fns (GetProgressForGuides/ExportProgressForJS) retired; tests rewritten onto the live BuildProgressJSON path (which had zero coverage). Full go test ./... green; button-driven smoke on guide 3/post 48, console clean. As-built + deviations in the proposal doc. Web and Flutter learn lightboxes reconverged on D22.5.a/b/c. |
UX proposal (→ web) | phase-22.5-learn-parity-audit.md D22.5.a/b/c |