- Per-thread keyword search match highlighting — closes the named rev-129 next-sprint candidateRev 129's running state explicitly named 'per-thread search highlighting' as the natural rev-130 candidate, citing rev-128 keyword + author search as the load-bearing primitive that needed visible match locations. Rev 130 closes that. Every short-comment render (the renderCommentBody path that doesn't go through the rev-111 marked.js HTML projection) now wraps matched substrings in <mark className='ld-task-comment-match'> with a brand-color teal background gradient + soft inset underline so an operator searching long threads sees WHERE the match is at a glance instead of re-reading every body line. Pure client-side — splits the existing per-text-chunk render in renderCommentBody so @-mention pills stay intact and the highlight stays scoped to plain text segments. Pairs with the rev-128 keyword filter (which narrows the visible thread) for the full narrow→find→read trio across the per-thread comment surface.
- Reactions-only filter axis on the rev-128 thread filter — third axis on the per-thread comment filter clusterNew 'Reacted N' chip beside the rev-128 keyword + author filter row scopes the visible thread to comments with at least one reaction. Composes with keyword + author via intersection so operators can drill 'show me Steve's comments with reactions' in two taps. Pairs with the rev-128 aggregate engagement chip (which surfaces top-emoji + total-count in the active-work card pill row) for the queue→thread engagement-drill loop: see the engagement signal in the queue, expand the thread, narrow to exactly those reacted comments via the new chip. Auto-hides when the thread carries zero reactions. Esc clears every axis (keyword + author + reactions-only) in one keystroke. Brand-purple palette distinguishes the engagement axis from the rev-128 brand-color keyword/author chips so the three filter dimensions read with three distinct visual cues.
- Per-author identity avatars in comment thread + mentions inboxEvery comment row in the per-task discussion thread + every row in the rev-30 mentions inbox now carries a 22px circular initials chip on the left of the row head. Initials computed from the author's display name (first + last initial, falls back to first two chars for single-name authors). Background is a deterministic per-author HSL hue derived from the userId hash so each teammate gets a stable identity colour across every comment they post — same primitive across both surfaces. Pairs with the rev-105 blog author profile + rev-128 author filter chip row so the workspace's identity primitive reads consistently from the public marketing surface (rev 105) through the in-app discussion + inbox surfaces (rev 130). Multi-operator teams now spot 'Steve commented' vs 'Maria commented' from the avatar colour without reading the name. Required adding `authorUserId` to the rev-30 UserMention shape so the inbox can compute the same hue from the same primitive.
- OpenAPI typed coverage for the rev-106/107/108 blog cluster endpointsThe v1 blog cluster reaches eight axes (listing rev 102 + detail rev 103 + categories rev 104 + authors rev 105 + related rev 106 + neighbours rev 107 + tags rev 108 + by-tag rev 108 + keyword rev 122) but until rev 130 only five carried typed OpenAPI schemas — the rev-106/107/108 endpoints had self-describing index entries but no typed JSON schema in the OpenAPI 3.1 spec. Rev 130 closes that gap. Four new typed endpoints: `/blog/related/{slug}` (full source + related rows shape with sharedTagCount + author profile primitive), `/blog/{slug}/neighbors` (chronological newer/older with nullable sides at timeline edges), `/blog/tags` (full tag taxonomy with post counts), `/blog/by-tag/{slug}` (per-tag listing with archive summary stats). MCP-host code generators reading the spec now have typed contracts for every blog-cluster axis. The cadence pattern from rev 78 onward (every v1 enhancement gets typed in the OpenAPI spec) is now fully closed across the entire blog cluster.