[review-only] Recent batch diff (Polish #93-#122 + 7 dep bumps) for ultrareview retry#22
Closed
StephenSook wants to merge 34 commits into
Closed
[review-only] Recent batch diff (Polish #93-#122 + 7 dep bumps) for ultrareview retry#22StephenSook wants to merge 34 commits into
StephenSook wants to merge 34 commits into
Conversation
…olish #100) Stephen explicit "fresh Lighthouse CLI run to verify post-#94/#95 stability." Ran the canonical Lighthouse CLI v13.3.0 against http://127.0.0.1:5174/?demo=1 with the same headless flags as the Polish #62 capture. Results: Performance: 84 -> 81 (within run-to-run variance band) Accessibility: 100 (unchanged) Best Practices: 100 (unchanged) SEO: 54 (unchanged — intentional noindex) Agentic Browsing: 66 (unchanged) CLS: 0.04 -> 0.057 (BOTH within Good band <0.1) TBT: 0 ms -> 60 ms (run-to-run noise) LCP: 3.5 s -> 3.7 s (run-to-run noise) FCP: 3.2 s -> 3.4 s (run-to-run noise) The load-bearing verdict: Polish #94 BlockHash brand + Polish #95 README Fetch Domains sync did NOT regress the Polish #62 CLS fix. The structural invariant (ZERO_STATS-fallback + reserve-space wrappers + `contain: layout`) holds. Variance on Performance / TBT / LCP / FCP / Speed Index is within normal Lighthouse run-to-run noise band (±3-5 points / ±200ms is typical) — the unminified-mock-server caveat in the doc above explains why all the absolute numbers are slightly Poor: the dev:web bundle is not the prod Devvit bundle. Stored: docs/screenshots/lighthouse-2026-05-19-polish100-cli.html (full HTML report). Updated the lighthouse-2026-05-19.md Core Web Vitals table to a 3-column "Before / After Polish #62 / Polish #100 re-verify" comparison so future re-runs can be slotted in. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…sh #101)
comment-analyzer rescan on Polish #90-#100 (post-Polish-#91 scrub)
caught 4 new + 1 pre-existing line-ref drift. Polish #91 should have
been the last pass; #92-#100 + the prior scrub MISS regressed the
pattern. Scrubbed:
HIGH:
- tests/client/app.test.tsx:92 — `App line 256` -> actual 288 (Polish
#98 introduced this w/ a number). Replaced with symbolic ref to
`the !initialLoad check on the OnboardingTour render in App.tsx`.
- tests/routes/api-auth.test.ts:229 — pre-existing AD-wave comment
said `src/client/components/EventDetails.tsx:139 reads
data.explanation` but actual is line 205 (drifted since Polish #69
+ #84). Polish #91's scrub missed this file. Replaced w/ inline
setState shape reference.
MEDIUM:
- docs/screenshots/lighthouse-2026-05-19.md:51-54 — 5 stale App.tsx
numeric refs (157/174-181/200/201/186) from Polish #62 writeup
drifted with #94/#95/#98. Replaced w/ symbolic refs ("StatsRow
render" / "Sparkline section" / "FilterChips render" / "EventSearch
Input render") that survive future refactors.
- src/state/imageHashStore.ts:130-132 — pre-Polish-#64 behavior
described in present tense ("write paths preserved the array via
.slice(0, MAX_ENTRIES)"). Reworded to explicit past-tense
"pre-Polish-#64 the write path preserved... but ran no shape
validation, so a bad member round-tripped intact" so a future
reader doesn't think the bare slice is current behavior.
LOW:
- tests/state/recentEvents.test.ts:175 — "v0.5.x is well past
skeleton" reads as if v0.5 is current. Replaced w/ "every install
since Phase 2.3" — version-agnostic, future-proof.
types.ts:19 claim ("they were deleted") verified accurate via grep
on src/actions/{lock,distinguish}.ts — 0 matches for "throw new
Error" or "unexpected id prefix". The Polish #81 deletions DID happen.
812 tests green, tsc + lint clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…sion (Polish #102)
pr-test-analyzer HIGH gaps on Polish #94 BlockHash brand:
H1: asBlockHash throw paths uncovered. The validator has TWO throw
conditions (length !== 64 OR !/^[0-9a-fA-F]+$/) but only the
indirect "length=5 short hash" case was exercised via the
isValidImageHashEntry test. The charset-only failure path had no
test — a regression dropping the regex check while keeping the
length check would silently pass every existing test, and a corrupt
64-char NON-hex entry would reach hammingDistance's
parseInt('z', 16) = NaN computation.
H2: isValidImageHashEntry non-hex 64-char entry untested. The Polish
#94 try/catch wrapper drops the bad entry but no regression pinned
that path. A refactor removing the wrap would silently round-trip
the bad entry to findSimilar.
Fix — tests/image/hash.test.ts (7 new asBlockHash tests):
- accepts a valid 64-hex string
- accepts uppercase hex (case-insensitive)
- throws on length=63 (too short)
- throws on length=65 (too long)
- throws on empty string
- throws on 64 NON-hex (charset-only failure) <- the load-bearing one
- throws on mixed hex+single non-hex char
Fix — tests/state/imageHashStore.test.ts (1 new regression):
- findSimilar skips a charset-corrupt entry (64 z's) but still
finds the valid sibling — verifies the asBlockHash try/catch in
isValidImageHashEntry actually drops the bad entry instead of
letting it slip through
820 tests green (was 812). tsc + lint clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pr-test-analyzer M1 + Gemini P2-2: the Polish #98 CLS smoke test
queried for `style.contain === 'layout'` via a brittle
`querySelectorAll('div').find(...)` scan. A future refactor moving
`contain: layout` to a Tailwind utility class (e.g.
`contain-layout` arbitrary value) would silently:
1. Pass the runtime CLS fix (CSS still applies the contain rule)
2. BREAK the test (jsdom doesn't compute styles from stylesheets;
`style.contain` only reads inline)
Two-line hardening:
1. src/client/App.tsx — added `data-cm-cls-isolated="recent"`
sentinel attribute to the recent-actions container alongside the
existing `style={{ contain: 'layout' }}`. Inline comment forbids
removing the attribute without also updating the smoke test.
2. tests/client/app.test.tsx — replaced the div-scan with a
targeted `container.querySelector('[data-cm-cls-isolated="recent"]')`
plus a separate assertion that the inline `style.contain ===
'layout'` is still active. Sentinel survives CSS-class refactors;
style check ensures the runtime CLS isolation is actually present.
820 tests green (unchanged). tsc + lint clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…104)
gemini brutal-audit P2-4. Step 2 tour body framed the six mod-menu
entries as "first three drive day-to-day, the rest enable AI." That
phrasing mis-ranks "Simulate rule against history" — Simulate is the
dashboard's demo money shot (docs/STATUS.md flags S1 with ⭐), the
most-cited mod-UX win because it previews rule impact on the last 25
posts BEFORE saving the wiki. A judge reading the tour after watching
the demo would see the tour underweight what the demo highlights.
Reframed body into three groups:
- First three: day-to-day moderation
- Simulate: dashboard's demo highlight (preview rule impact on
last 25 posts before saving wiki)
- Last two: AI features
Reads more accurately + matches the demo-script Beat 4 emphasis
without inflating the language.
AI-tone scan: clean. 820 tests green (unchanged). tsc + lint clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
gemini brutal-audit P1-1 + P1-2. After Polish #62-#104 wave, 5 judge-facing surfaces drifted on test count + polish range: README.md:9 tests-777 badge -> 820 README.md:61 "777 tests passing" -> 820 PLAN.md:75 "777 tests green" -> 820; #1–#86 -> #1–#104 docs/STATUS.md:47 "Polish #1–#86" -> #1–#104 docs/STATUS.md:69 "777 tests passing" -> 820 ROADMAP.md:32 "polish #1–#88" -> #1–#104; 777 tests -> 820 The integer matters less than internal consistency — drift across 5 sites in 5 minutes reads as careless to judges grepping the README badge → repo. Single sed pass + commit. The 820 count is verified live from `npm test --silent -- --run`. Polish range bumped to #1–#104 spans the full AE wave through the post-Gemini brutal-audit P0/P1/P2 integration batch: #62-#71: post-CLS-audit (10 fixes) #72-#80: gemini brutal-audit P0/P1 (9 fixes) #81-#86: gemini P2 + type-design top-5 (6 fixes) #87-#100: docs restructure + agents-flagged gaps (14 fixes) #101-#104: comment-rot + asBlockHash coverage + CLS smoke harden + OnboardingTour reposition (4 fixes) All four files retain their distinctive framing — this is a number- sync sweep, not a content rewrite. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
gemini brutal-audit P2-3. README Fetch Domains row for api.openai.com
claimed the cache key was `cm:ai:cache:{hash}` per (sub, prompt-digest).
Real shape in src/state/keys.ts:64 is:
explainCache: (eventHash, sub) => `cm:${sub}:explain:cache:${eventHash}`
Three differences:
1. Namespace `explain` not `ai` (matches the V7 AI explainer feature
name, not a generic AI bucket)
2. Sub-segmented `{sub}` BEFORE the namespace (every Devvit key is
sub-scoped via the K.* factory — multi-tenant isolation invariant)
3. Keyed on `eventHash` (digest of the full event shape: runName,
checkName, matchedRule, matchedSubstring, actions[]) not a generic
`prompt-digest` — the docstring at src/state/keys.ts:55-63
explains why this auto-invalidates when the event shape changes
A judge or security reviewer cross-referencing the Privacy section
against the Redis key layout would catch the discrepancy. Replaced the
fake shape with the real one + the "auto-invalidates on event change"
detail that the explainCache docstring already documents.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…predicate (Polish #107)
gemini brutal-audit P2-1. Polish #94 added `asBlockHash` (a throw-on-
mismatch validator) and `isValidImageHashEntry` wrapped it in try/catch
to coerce the throw into a boolean — that path runs PER ENTRY inside
findSimilar's loop (up to MAX_ENTRIES=500 per call on a viral
image-post burst) and inside recordHash's filter. V8 try/catch overhead
is ~2-3x vs an inline boolean check even on the happy path. Total
estimated impact: ~1-2ms per 500-entry findSimilar call — comfortably
inside the per-action 8s timeout (Polish #47), but a clean micro-opt
with a clean separation:
Fix:
1. src/image/hash.ts — added `isBlockHash(raw: unknown): raw is BlockHash`
boolean predicate. Same shape check (length + regex) as asBlockHash
but returns false instead of throwing. Hoisted the regex to a
module-level `HEX_REGEX` const so the predicate doesn't recompile
per call. asBlockHash stays unchanged (still used at trust boundaries
that want descriptive throw messages).
2. src/state/imageHashStore.ts — replaced the try { asBlockHash(o.hash) }
catch { return false } block with `if (!isBlockHash(o.hash)) return
false`. The predicate also subsumes the prior `typeof o.hash !==
'string'` check (isBlockHash returns false on non-strings) — dropped
the redundant guard for clean code.
8 new isBlockHash tests added at tests/image/hash.test.ts:
- happy path (valid 64-hex, uppercase)
- length variants (63, 65, 0)
- charset (64 z's)
- non-string inputs (number, null, undefined, object)
- behavior-parity assertion: isBlockHash(x) === !throws(asBlockHash(x))
820 → 828 tests green. tsc + lint clean. No production behavior
change — same shape contract, faster hot path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…sh #108)
pr-review-toolkit:code-reviewer agent final pass on Polish #101-#106
returned "ship" with 2 sub-confidence-50 cosmetic items. Stephen
explicit "don't hold anything back" → addressing.
1. tests/image/hash.test.ts:63-67 — hammingDistance length-mismatch
test cast `'abc' as unknown as string`. The function signature post-
Polish-#94 is `hammingDistance(a: BlockHash, b: BlockHash)`. Cast
landed on `string` not `BlockHash`. Worked because tests/ aren't
tsc-checked (tsconfig include is src/**/* only — vitest just
esbuild-transpiles), but the test's type assertion didn't match
what the function actually accepts.
Fix: cast to `BlockHash` via `as unknown as
import('../../src/image/hash').BlockHash`. Test runtime behavior
unchanged (still exercises the length-mismatch throw); the cast
shape now matches the post-Polish-#94 type contract.
2. tests/state/imageHashStore.test.ts:225 — comment said "asBlockHash
throws, isValidImageHashEntry catches and returns false". Polish
#107 replaced that path with the isBlockHash boolean predicate
(no try/catch). Behavior identical, comment is stale by one polish
wave. Fix: comment now reads "isBlockHash returns false (Polish
#107 — was asBlockHash throw pre-#107), isValidImageHashEntry
rejects the entry."
828 tests green (unchanged). tsc + lint clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ish #109) Pre-launch AI-tone scan across 15 surface docs flagged 3 hits — all technically-correct usage but tripping the marketing-tone blocklist: 1. PLAN.md:58 (row 2.5.2 dryRun): "per-action dryRun can only ELEVATE to dry-run" — replaced ELEVATE → "PROMOTE a live config to dry-run" (semantically identical, no blocklist trigger). 2. CHANGELOG.md:1438 (Z4-X54 WCAG AA pass): "comprehensive AA" — replaced "comprehensive" → "full AA coverage" (drops the marketing-word, same meaning). 3. CHANGELOG.md:1717 (same Codex H1 dryRun line in the historical wave): "only ELEVATE to dry-run" — same fix as #1, replaced w/ "PROMOTE a live config to dry-run." Verified post-fix: `bash scripts/check-ai-tone.sh PLAN.md CHANGELOG.md` returns clean across both files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ish #110)
Codex + Gemini final brutal-audit passes both flagged test-count +
polish-range drift across the entire submission narrative surface.
Local `npm test --silent -- --run` returns 828 tests. Bulk sed sweep:
820 tests → 828 tests (README.md, PLAN.md, STATUS.md,
ROADMAP.md, e2e-scenarios.md)
758 tests → 828 tests (devpost-form-cheat-sheet.md ×5)
tests-820 → tests-828 (README.md badge URL)
Polish #1-#104 → #1-#108 (STATUS.md, PLAN.md)
Polish #1-#35 → #1-#108 (devpost-form-cheat-sheet.md)
"223 → 758" → "223 → 828" (submission-day-runbook.md
historical-context tightening)
9 files swept. Verified post-sweep: grep across the 10 enumerated
docs returns 0 matches for the prior numbers.
Single-pass sed (not per-file Edit) to keep this as one logical
commit — the drift was uniform across the doc surface, the fix is
uniform too. Per-file semantic fixes (Phase 4.7 status, action
count, $62.4M removal, blog-post v0.6.4) land as their own atomic
polishes in #111+.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…lish #111) Codex P1-1 + Gemini P0-1: Polish #73 deleted the fabricated 62.4M TAM math from pillar-5-numbers.md (self-violation of that file's own line-248 "DO NOT INVENT specific time-savings figures" rule). The deletion missed TWO downstream paste-targets: 1. docs/submission/devpost-form-cheat-sheet.md:229 — Project Impact section instructed Stephen to paste "9.5M scaled / 62.4M addressable / 6M+ conservative capture." Reworded to point at the conservative pillar-5-numbers.md section-11 framing only with an explicit warning not to paste a larger figure without a citation that did not exist when this hackathon shipped. 2. docs/submission/writeup-draft.md:80 — Section 2 bullet still had the "60K x 52 x 20 = 62.4M/yr at full capture" extrapolation as a live claim. Replaced with the measured baseline (3.4M/yr Li 2022) plus the section-B-scaled 9.5M/yr citation, plus a one-sentence note that the prior extrapolation was deleted in Polish #73 with a pointer to the doc own anti-invention rule. Net effect: both downstream paste-targets now align with the pillar-5-numbers.md conservative framing. Stephen pasting either into the Devpost form gets defensible numbers, not invented ones. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t-sheet (Polish #112) Gemini P0-3 + Codex P1-3 combined fix. Two stale claims across the two highest-judging-traffic surfaces: 1. README.md:299 (Concept-model section): listed only 7 actions `remove / approve / lock / comment / report / ban / userFlair`, missing `distinguish`. Internal contradiction inside README — the hero (line 6) + Status section (line 59) already say "8 action handlers" + include distinguish in the parenthetical. Judges reading top-to-bottom would see "8 ... 8 ... 7" and lose confidence. Fixed: added distinguish. 2. README.md:383 (Status checklist): same 7-action list, missing distinguish. Updated with the AE-wave context: "8 handlers shipped Phase 2 + Wave AE (distinguish for upstream parity, post- Polish #53)" + ThingId-branded ids cross-ref (Polish #81). 3. devpost-form-cheat-sheet.md:75 (Tool Overview): same 7-action list. Updated. 4. devpost-form-cheat-sheet.md:77 (concept-model): said "7 actions ship + Phase 4 stretch rules SHIPPED + Image-hash repost (Phase 4.7) deferred." Updated to "8 actions (including distinguish) + Phase 4 SHIPPED + Phase 4.7 image-hash SHIPPED 2026-05-18." The "Phase 4.7 deferred" framing was 2+ weeks stale. 5. devpost-form-cheat-sheet.md:248 (Port Completion Q): same 7-action + Phase 4.7 deferred framing. Updated. 6. devpost-form-cheat-sheet.md:294 (Pillar table): "7 action handlers" plus "13-wave hardening 70+ findings" stale framing. Updated to "8 action handlers" + "AE Polish #1-#108 100+ findings" + Phase 4.7 cited as shipped. Also bumped cm-devvit version from @0.2.4 to @0.6.7 since that older approved-unlisted is no longer the pending review version. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Gemini P0-2: blog-post-draft.md pinned to dead version v0.6.4 at lines 7 and 48. Tagged release is v0.6.7. Reads as "draft never updated" to any judge who clicks through. Sed bumped both occurrences. No semantic content change beyond the version string — the "What ships" bullets in the body of section 48 remain accurate at v0.6.7 (Phase 1+2+3+4 + Phase 4.7 shipped; 4.7 covered in the Wave AE bullet at line 57). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex P1-4: docs/migration-compatibility.md still told operators Phase 4 rules (history / attribution / recentActivity) were "Deferred to Phase 4" and image-mode repost was "Deferred (Phase 4.7)" — both shipped 2026-05-18. Operators reading this doc as the first-touch migration reference would believe the port was less complete than it is. Fix: - Top "Quick Answer" paragraph: dropped "Phase 4 stretch rules land post-hackathon" + "image-mode repost is deferred" language. Added Phase 4 + 4.7 to the list of supported rule kinds, bumped port version v0.2.0 -> v0.6.7, removed "are deferred" from the preamble. - Table rows for history / attribution / recentActivity: 🚧 Deferred -> ✅ Ported (Phase 4, 2026-05-18). history row also cites Polish #77 author-history thundering-herd lock fix. - Image-mode repost row: ⏸ Deferred -> ✅ Ported (Phase 4.7, 2026-05-18). Cites the pure-JS toolchain (upng-js + jpeg-js + blockhash-core), 256-bit hash, configurable Hamming threshold, and Polish #61 per-sub findSimilar+recordHash lock. - Operator migration walkthrough (step 1): replaced "stay in config but won't fire" framing for Phase 4 rules with "work today (shipped 2026-05-18)" + parallel sentence for Phase 4.7 image-hash repost. Stephen's cold-DM template (outreach-drafts.md §7) links this doc as the migration reference; the prior framing would have undersold the port to the 15+ FoxxMD operators it's targeting. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…115) Codex P1-5: PLAN.md row 6.1 said "Version 0.2.0 submitted for review" while docs/STATUS.md and the dev portal both reflect cm-devvit@0.6.7 in App Directory review. A judge reading PLAN.md as the team-coord doc would see "0.2.0 submitted" and conclude the project is 4 minor versions behind reality. Fix: rewrote the Status cell to enumerate the version timeline: - v0.2.0 first-submit 2026-05-16 - v0.5.5 approved unlisted 2026-05-17 - v0.6.7 re-uploaded 2026-05-19 (current pending re-review) Plus added the T-2 launch step Stephen runs: "Final npm run launch (Stephen, T-2 = 2026-05-25) publishes v0.6.x as the source the judges install." Makes the version-history coherent + names the load-bearing remaining action. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex P2-1/P2-2/P2-3: three cosmetic stale-comments in src/ + API.md
that misrepresent current behavior:
1. src/routes/triggers.ts:19-20 — kill-switch comment said "Ctrl+C
on playtest IS the kill switch. Revisit before any devvit publish
--public." App was already in public App Directory review before
this audit caught the comment. Rewrote: kill switch is the
firstSeen idempotency guard + dryRun:true global override via
wiki reload + uninstall path. Production-relevant.
2. src/routes/scheduler.ts:5-8 — header docblock listed
/image-hash-worker as a "Stub (not wired yet), gated on Phase 4.7
spike." Phase 4.7 shipped 2026-05-18, and the worker IS
implemented at lines 147-192. Rewrote: image-hash-worker is the
on-demand backfill path that runs ALONGSIDE the standard trigger
flow (which hashes on arrival via runImageRepostRule).
3. API.md:59 — /api/stats response said "production currently
returns empty pending Phase 4 stats-rollup wire-up." Production
reads the cm:stats:snapshot:{sub} key written hourly by the
stats-rollup cron + falls back to compute-on-fly. Polish #38
added the client-shape fields. Rewrote with the actual response
shape + cross-reference to statsRollup.ts.
Tests + lint clean (docs-only changes).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e 4.7 references (Polish #117) Gemini P1-7 + P1-9 + P2-10 combined: 1. writeup-draft.md:29 — Filter chips bullet said "8 chips" + listed only 8 (all/remove/comment/approve/lock/report/failed/dry-run). Polish #59 added ban/flair/distinguish for full ActionKind coverage. STATUS.md row already shows 11. Updated writeup to 11 chips + named the post-Polish-#59 context. 2. writeup-draft.md:19 — Capabilities preamble said "35 polish-tier fixes." Current tag is Polish #1-#108. Bumped 35 -> 108. 3. writeup-draft.md:13 — Section 1 opener: - "full Phase 1+2+3+4 stack" -> "Phase 1+2+3+4+4.7 stack" (Phase 4.7 was elided in the preamble; reads as if image-hash repost shipped LATER as a separate beat instead of being in the headline stack) - "Reddit cm-devvit@0.2.4 approved unlisted 2026-05-18" -> "Reddit cm-devvit@0.6.7 in App Directory review" (with the v0.5.5 + v0.6.7 version timeline cited inline) - Added "Phase 4.7 image-hash repost SHIPPED v0.6.0 2026-05-18" as a sibling sentence to the Phase 4 SHIPPED line - "13 distinct waves closed 70+ findings" -> "13 waves + AE Polish #1-#108 closed 100+ findings" + bumped the agent-rotation list to include vercel:performance-optimizer + repo-sentinel - Dropped "5 BLOCKERs + 8 CRITICAL + 50+ HIGH/WARN/MED surfaced by 6 parallel sub-agent reviews" framing — the unprefixed "100+ findings" + named rotations is more honest + less braggy. 4. demo-video-script.md:122 — Phase 4.7 image-repost bullet said "(v0.6.0)" implying that's the current version. Reworded to "shipped v0.6.0, hardened through v0.6.7" + added Polish #61 per-sub lock context Stephen + Vinh may reference during the demo voiceover. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…#118)
Gemini P0-4: CHANGELOG ended at Polish #80, but Polishes #81-#108
(28 entries) had landed on main + were referenced in STATUS.md
and the commit log. The doc Stephen will most-likely link from
Devpost contained a 28-polish hole.
Added new "Polish #87-#108 batch (post-Polish-#86 hardening + final
review chain)" section covering 22 entries with inline rationale
pulled from each commit body:
#87: README restructure -> docs/STATUS.md extraction
#88: demo-script rehearsal checklist + Vinh co-narrator
#89: GitHub-surface stale refs + AI-tone (ARCHITECTURE.md
"ecosystem", ROADMAP.md, THREAT-MODEL.md)
#90: examples AJV validation test — CAUGHT REAL SHIPPED BUG
(repost-image-watch.json5 broken JSON5)
#91: comment-rot scrub (1st pass post-polish)
#92: 3 lying-test pattern fixes from pr-test-analyzer
#93: 6 coverage-gap regression tests
#94: brand BlockHash via type-design-analyzer #4
#95: README Fetch Domains sync + blockhash size fix
#96: RunResult tagged sub-union via type-design-analyzer #3
#97: NEW EmptyState.test.tsx (9 tests for Polish #84 clipboard UX)
#98: App.tsx structural CLS smoke for Polish #62 invariant
#99: OnboardingTour "Three" -> "Six" mod-menu entries
#100: Lighthouse CLS re-verification (still Good band)
#101: comment-rot scrub (2nd pass)
#102: asBlockHash throw-path test coverage + non-hex regression
#103: CLS smoke hardened w/ data-cm-cls-isolated sentinel
#104: OnboardingTour reposition Simulate as demo highlight
#105: docs sync 777 -> 820 tests + Polish range #1-#86 -> #1-#104
#106: README AI cache key shape fix
#107: isBlockHash perf predicate (try/catch dropped on hot path)
#108: 2 cosmetic items from final code-reviewer pass
Header line updated: 52 polishes (#18-#80) -> 108 polishes
(#18-#108). Adversarial-review-round list expanded to 8 with
named per-agent counts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…lish #119)
Gemini P1-6: stephen-action-list.md per-section T-N headers used old
dates calculated from a prior (2026-05-20) deadline. Label table at
line 22 explicitly says "This file's labels updated for May 27
deadline. Both files now anchor on the same dates" — but the section
headers were never actually updated to match. Stephen following the
action list at recording time would see:
T-1 — 2026-05-19 (today!)
and conclude submission is tomorrow. Actual T-1 is 2026-05-26.
Fixed 5 per-section headers to match the label table:
T-6 — 2026-05-14 → 2026-05-21
T-5 — 2026-05-15 → 2026-05-22
T-3 — 2026-05-17 → 2026-05-24
T-2 — 2026-05-18 — Demo recording day → 2026-05-25 — Demo
recording + `npm run launch` (per Status update line 15
which schedules launch at T-2 inside the T-3-to-T-1
recording window)
T-1 — 2026-05-19 → 2026-05-26
T-0 — 2026-05-27 — Submission day was already correct.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… (Polish #120) comment-analyzer 3rd pass caught a stale describe-block header at tests/image/hash.test.ts:81-89. Polish #102 wrote the rationale as "would round-trip through isValidImageHashEntry catch (the catch returns false, dropping the entry)". Polish #107 replaced the try/catch with the isBlockHash predicate. Polish #108 caught the parallel staleness in tests/state/imageHashStore.test.ts:225 but missed this describe header. Rewrote rationale to reflect the post-Polish-#107 path: the isBlockHash predicate (same shape contract, no try/catch cost) drops the entry. Pre-Polish-#107 it was asBlockHash throw caught by try/catch. Both paths drop bad entries; predicate just skips the try/catch overhead. Cosmetic only. 828 tests green, tsc + lint clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…PPED (Polish #121) Stephen explicit deep dive caught: migration-from-upstream-cm.md (the operator action-list, paired with migration-compatibility.md per line 5 cross-ref) was also stale on Phase 4 status, parallel to the Codex P1-4 finding on migration-compatibility.md (Polish #114). Fixed 3 sites: - Line 7 "Last reviewed: 2026-05-18 (v0.4.0)" -> "2026-05-19 (v0.6.7 -- full Wave W-AE hardening + Phase 4 + 4.7 shipped + AE Polish #1-#108 closed)" - Line 112 "Phase 4 stretch rules ARE included in the schema but wont fire until Vinh ships them. Theyre no-ops" -> rewrote to "Phase 4 author-history rules AND Phase 4.7 image-hash repost shipped 2026-05-18 -- they fire today, no migration tweak needed." - Line 152 "Last verified against schema v0.2.0" -> "v0.6.7 (2026-05-19)" This file is what the cold-DM template (outreach-drafts.md section 7) points operators at. The prior framing underrepresented the port. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps [prettier](https://github.com/prettier/prettier) from 3.8.1 to 3.8.3. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](prettier/prettier@3.8.1...3.8.3) --- updated-dependencies: - dependency-name: prettier dependency-version: 3.8.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps @devvit/web from 0.12.23 to 0.12.24. --- updated-dependencies: - dependency-name: "@devvit/web" dependency-version: 0.12.24 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [hono](https://github.com/honojs/hono) from 4.12.19 to 4.12.21. - [Release notes](https://github.com/honojs/hono/releases) - [Commits](honojs/hono@v4.12.19...v4.12.21) --- updated-dependencies: - dependency-name: hono dependency-version: 4.12.21 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.14.0 to 1.16.0. - [Release notes](https://github.com/lucide-icons/lucide/releases) - [Commits](https://github.com/lucide-icons/lucide/commits/1.16.0/packages/lucide-react) --- updated-dependencies: - dependency-name: lucide-react dependency-version: 1.16.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.19.19 to 25.9.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.9.1 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@hono/node-server](https://github.com/honojs/node-server) from 1.19.14 to 2.0.3. - [Release notes](https://github.com/honojs/node-server/releases) - [Commits](honojs/node-server@v1.19.14...v2.0.3) --- updated-dependencies: - dependency-name: "@hono/node-server" dependency-version: 2.0.3 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.1 to 8.0.13. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v8.0.13/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 8.0.13 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
codex external review (false-positively framed as "828 tests near v0.6.4 context" — that v0.6.4 context doesn't exist, ROADMAP cleanly shows v0.6.7) caught one REAL stale range. ROADMAP.md line 32 still said "AE polish #1–#88" — Polish #110's bulk sed sweep replaced `#1–#86 → #1–#108` but missed the `#1–#88` baseline that was already in ROADMAP from an earlier polish (the sweep keyed on `#86` not `#88`). Verified via grep across all surface docs: 0 remaining `Polish #1–#88` strings post-fix. 828 tests still green; tsc + lint clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
…ot disable (Polish #123)
ultrareview bug_004: Polish #116 rewrote the kill-switch docstring at
triggers.ts:19-23 to claim "Kill switch: handled via the per-event
firstSeen idempotency guard ... + mod-menu Reload-config ... + uninstall."
That mischaracterizes firstSeen. The firstSeen guard is per-event
idempotency dedup (24h NX on `cm:proc:{thingId}`) against Devvit's
at-least-once trigger redelivery of the SAME event. It does NOT prevent
NEW events from processing — a new post submits → fresh thingId →
SET NX succeeds → handleActivity runs.
A future engineer reading the prior docstring could believe a real
disable mechanism already exists at the firstSeen layer and skip
designing one. An operator hitting an incident could waste time
looking for a "firstSeen kill switch" that doesn't exist.
Fix: rewrote the kill-switch sentence to name only the legitimate
mechanisms (mod-menu Reload-config publishing `{dryRun: true}` global
override + Reddit App Directory uninstall), with an explicit NOTE
correcting the firstSeen misframing so the dedup intent stays clear
for anyone reading the surrounding doc block.
Tests + lint clean (docs-only change).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… (Polish #124) ultrareview merged_bug_006: two consistency gaps from the dependabot wave. Both nit-severity but worth closing for SDK-family hygiene. 1. @devvit/web bumped to 0.12.24 (dependabot PR #19) while devvit (0.12.23) and @devvit/start (0.12.23) stayed pinned at .23. All three are exact-pinned per the repo's deliberate exact-pin policy. Lockfile shipped DUAL versions of @devvit/shared-types (0.12.23 + 0.12.24) plus duplicate @devvit/protos / cache / client / media / payments / realtime / reddit / redis / scheduler under the same tree. Exactly the SDK-family drift the exact-pin policy exists to prevent. Fix: bumped devvit + @devvit/start to 0.12.24 to match. Verified post-npm-install: `grep '@devvit/shared-types: \"' package-lock.json | sort -u` returns single 0.12.24 — drift gone. 2. vite bumped 7.3.1 → 8.0.13 (dependabot PR #13) declares engines node ^20.19.0 || >=22.12.0. Our package.json engines.node still said >=22.2.0 — a contributor on Node 22.2–22.11 satisfies the project pin but trips EBADENGINE against Vite 8. CI never tripped because setup-node@v4 with node-version: '22' resolves to latest 22.x (now >= 22.12). Fix: engines.node → ^20.19.0 || >=22.12.0 to match Vite 8's declared constraint. Aligns the project pin with what CI actually tests + what npm install warns on locally. Verified post-install: 828 tests green, tsc + lint clean, prod npm-audit 0 vulnerabilities. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…h #125)
ultrareview bug_001 (pre_existing class): README.md:299 Concept-model
Rule list enumerated 7 kinds (regex, author, history, attribution,
recentActivity, repost, ruleSet) and was missing imageRepost, while
the README hero (line 6) correctly claims "8 rule kinds incl. Phase
4.7 perceptual-blockhash image-repost." Self-contradiction within
the same doc.
Verified imageRepost is a distinct rule kind, not a mode of repost:
- src/shared/types.ts: ImageRepostRule is a separate Rule union member
w/ kind: 'imageRepost'
- src/schema/app.schema.json: { const: 'imageRepost' } separate constant
- src/core/runRule.ts: case 'imageRepost' dispatch arm separate from
case 'repost'
- src/rules/imageRepost.ts: its own module (perceptual blockhash
pipeline) alongside src/rules/repost.ts (URL-dedupe)
- tests/rules/imageRepost.test.ts: covers as a distinct rule kind
- examples/repost-image-watch.json5: uses kind: 'imageRepost'
Same Polish #112 touched line 301 (Action list — added distinguish)
but missed the parallel sync on line 299 (Rule list). Single-token
insert: `repost`, `imageRepost`, plus composite `ruleSet`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… #126) ultrareview merged_bug_002: Polish #105's sed sweep updated polish-range markers (#1-#86 -> #1-#108) but missed BARE COUNT WORDS sitting one segment over in the same sentences. Subsequent test-count bumps (777 -> 820 -> 828) hit the same pattern blindness. Result: 6 judge-facing surfaces with internally-contradictory or stale-vs-bundle claims. Fixed: 1. PLAN.md:75 -- "86 polishes (Polish #1-#108)" -> "108 polishes (Polish #1-#108)" (was 86 != 108 in same sentence) 2. docs/submission/stephen-action-list.md:12 -- "AE wave: 35 polishes shipped (Polish #1-#108)" -> "108 polishes shipped" (was 35 != 108) 3. docs/submission/submission-day-runbook.md:9 -- "AE wave shipped Polish #1-#35" -> "Polish #1-#108" (range was never bumped on this line; same line was edited for 223 -> 828 tests) 4. docs/submission/devpost-form-cheat-sheet.md:292 -- Rubric "Polish" row "9/9 tests passing" -> "828 tests passing". Adjacent "Port Completion" row at line 294 was bumped to 828 tests in earlier polish; the 9/9 outlier was visible in the SAME rubric table. 5. docs/submission/blog-post-draft.md:10 -- "MIT, 594 tests, CI green" -> "MIT, 828 tests, CI green" (~40% drift, largest absolute) 6. docs/screenshots/lighthouse-2026-05-19.md:7 -- "v0.6.7 + AE Polish #18-#62" -> "v0.6.7 + AE Polish #18-#108" (doc body has Polish #100 re-verify entries, but masthead was stuck at #62) All 6 are nit severity (docs-only, no runtime impact) but together they undermine the doc-vs-doc consistency a careful judge would check. Single sed pass covered the broader pattern that Polish #105 missed. 828 tests still green, tsc + lint clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Owner
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Retry of crashed PR #21. Narrower scope:
PR #21 crashed cloud-side at 76 files / +19558 / -7898. This narrower scope should fit in the cloud compute window.
Do not merge. Scope-hack vehicle for /ultrareview only. Close after review lands.