8ac42cdbad
Adds enabled=true param to useDecryptedMediaUrl in MediaGallery.tsx. GalleryTile now uses useNearViewport(300px) — decryption is deferred until the tile approaches the viewport, preventing burst of 100 concurrent decrypt/fetch calls when a pagination batch loads. Blob revocation was already correct (no actual leak); this fixes the load-burst performance issue. Full windowing virtualization deferred. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
36 KiB
36 KiB
Lotus Chat — Bug Report & Technical Audit
Date: June 2026
This document tracks identified bugs, edge cases, and architectural discrepancies found during the audit of the Lotus Chat codebase. Recommended fixes are provided for each item.
🚩 Critical & UI Bugs
1. No Camera Focus During Screenshare
- File:
cinny/src/app/features/call/CallControls.tsx - Status: OPEN
- Issue: Automatic screenshare spotlighting forces primary display override, preventing users from manually focusing on camera feeds.
- Root Cause: Current spotlighting logic prioritizes active screenshare streams over manual participant selections, effectively ignoring or overriding user-initiated focus states.
- Proposed Fix: Introduce a manual 'Focus' state that takes precedence over automatic screenshare spotlighting, implemented via a toggle/click UI on participant tiles. Update the video renderer to respect this manual override.
2. Chat Background Animation Flickering
- File:
cinny/src/app/features/lotus/chatBackground.ts - Status: FIXED ⚠️ UNTESTED — needs verification on a real device with an animated background active
- Issue: Animated background properties cause visible flickering on message text and the composer area, particularly on browsers/GPUs susceptible to repaint-induced artifacts.
- Root Cause: Animation triggers excessive repaints or layout recalculations on descendant elements, likely due to animating non-GPU accelerated properties on parent containers without proper rendering context isolation.
- Fix Applied:
getChatBg()now injectswillChange: 'background-position'andcontain: 'paint'for any animated variant. This promotes the element to its own compositor layer and isolates repaints from descendants. Background-position animation is already GPU-hinted on modern browsers;contain: paintprevents descendant elements from being invalidated during each frame.
3. Avatar Decorations in Element Call
- File:
cinny/src/app/components/avatar-decoration/AvatarDecoration.tsx - Status: OPEN
- Issue: Avatar decorations are failing to render within the call/room interface member lists.
- Root Cause: Likely a mismatch between the expected
memberobject structure required by theAvatarDecorationcomponent and the data actually provided by the call/room UI components. Matrix event data for decorations might not be propagating correctly to these UI member objects. - Proposed Fix: Analyze the data propagation chain from Matrix events to the member object in
cinny/src/app/components/callandroom, ensuring that decoration-related properties are correctly mapped and passed to theAvatarDecorationcomponent.
4. DM and Group Message Calls
- File:
cinny/src/app/components/CallEmbedProvider.tsx - Status: OPEN
- Issue: Incoming call ringtone is hardcoded, lacks volume control, and is suppressed if the user is already in an active call.
- Root Cause: Ringing logic is tightly coupled to
RTCNotificationevents inCallEmbedProvider.tsx, using a hardcoded audio file path. It lacks an abstraction for sound management or user-configurable settings for ringtones/volumes. - Proposed Fix: Migrate sound asset management to a dedicated audio service. Implement user-configurable settings for ringtone and notification volume. Update the
IncomingCallListenerto support ringing even during active calls (if appropriate) by enhancing event handling.
5. Seasonal Themes and Chat Backgrounds Design
- File:
cinny/src/app/hooks/useTheme.ts,cinny/src/app/features/lotus/chatBackground.ts - Status: OPEN
- Issue: Basic CSS or random moving lines are insufficient for high-fidelity wallpaper/theming. They lack professional design theory, coherence, and aesthetic depth.
- Root Cause: Current implementation relies on basic CSS, lacks advanced design theory, and does not leverage modern, performant CSS wallpaper techniques.
- Proposed Fix (Extreme Depth Redesign):
- Research-Backed Implementation: Implement advanced design techniques (layered
oklchgradients,backdrop-filterfor refractive "liquid glass" effects, GPU-acceleratedtransformanimations) to create living, breathing backgrounds. - Performance Optimization: Ensure all animations strictly use compositor-thread properties (
transform,opacity) and applycontain: paint/will-change: transformto prevent layout thrashing/flickering. - Design Resources (Examples/Inspiration):
- Uiverse.io Patterns
- MagicPattern CSS Backgrounds
- Prismic Blog: CSS Background Effects
- CSS-Pattern.com (Pure CSS pattern library)
- BGJar (Performance-focused generators)
- Goal: Treat each theme/background as a week-long development sprint to ensure professional polish, WCAG AA contrast compliance for overlaying UI, and seamless integration with the Lotus TDS.
- Research-Backed Implementation: Implement advanced design techniques (layered
6. Exclusive Background vs. Seasonal Choice
- File:
cinny/src/app/state/settings.ts - Status: FIXED ⚠️ UNTESTED — needs verification: (a) pick a background, confirm seasonal theme auto-clears; (b) pick a seasonal theme, confirm background auto-clears; (c) set both via old localStorage data and reload, confirm SeasonalEffect guard suppresses the overlay
- Issue: Concurrent application of both Chat Backgrounds and Seasonal Themes causes visual clutter and high GPU usage.
- Root Cause: These are currently handled as independent settings in the
settingsAtomand applied simultaneously without mutual exclusion. - Fix Applied: Mutual exclusion enforced at two layers: (1)
General.tsx— ChatBgGrid clears seasonalThemeOverride→'off' when any non-'none' background is picked; SeasonalBgGrid clears chatBackground→'none' when any real seasonal theme is selected. (2)SeasonalEffect.tsx— runtime guard returns null ifchatBackground !== 'none', protecting against legacy persisted state.
7. Tiny Touch Targets in Composer Toolbar
- File:
cinny/src/app/features/room/RoomInput.tsx - Status: FIXED ⚠️ UNTESTED — needs verification on a real mobile device: open composer, confirm all toolbar buttons are tappable without mis-taps
- Issue: Toolbar buttons have hit areas smaller than the WCAG-recommended 44x44px for touch, hindering mobile accessibility.
- Fix Applied: Added
touchTarget = { minWidth: '44px', minHeight: '44px' }computed frommobileOrTablet()and applied asstyle={touchTarget}to all 8 composer toolbarIconButtonelements (attach, format, sticker, emoji, GIF, location, poll, schedule, send).
8. Horizontal Overflow in Room Settings
- File:
cinny/src/app/components/page/style.css.ts - Status: FIXED ⚠️ UNTESTED — needs verification: open Room Settings on a narrow mobile screen, confirm nav panel fills full width and no horizontal scrollbar appears
- Issue: Wide tables and input elements in room settings cause horizontal overflow on mobile viewports.
- Fix Applied: Added
@media (max-width: 750px) { width: '100%' }to both'400'and'300'size variants of thePageNavvanilla-extract recipe instyle.css.ts.
9. Modal Float-Style Responsiveness
- File: Multiple modal files
- Status: FIXED ⚠️ UNTESTED — needs verification by opening each modal on a real mobile device
- Issue: Modals appear as floating boxes on mobile, creating navigation and readability challenges.
- Fix Applied: Created
useModalStyle(desktopMaxWidth)hook (src/app/hooks/useModalStyle.ts) that returns fullscreen styles on mobile (no border-radius, no max-width,height: 100%) and desktop box styles otherwise. Applied to all 22+ modal files:LeaveRoomPrompt,LeaveSpacePrompt,ReportRoomModal,ReportUserModal,DeviceVerification,InviteUserPrompt,LogoutDialog,DeviceVerificationSetup,DeviceVerificationReset,JoinAddressPrompt,JumpToTime,EditHistoryModal,ForwardMessageDialog,RemindMeDialog,CreateRoomModal,CreateSpaceModal,ScheduleMessageModal,PollCreator,AddExistingModal,RoomEncryption,RoomUpgrade,Modal500,ReadReceiptAvatars,RoomTopicViewer. - Note:
UIAFlowOverlayalready fullscreen via<Overlay>— no change needed.JoinRulesSwitcher/RoomNotificationSwitcherare dropdowns, not modals.
10. Composer Keyboard Obscurity
- File:
src/index.css - Status: FIXED ⚠️ UNTESTED — needs verification on iOS Safari specifically (the worst offender); on Android Chrome
100dvhhas been standard since Chrome 108 - Issue: The chat composer is often partially or fully obscured by the virtual keyboard on mobile.
- Fix Applied: Added
height: 100dvh(dynamic viewport height) tohtmlalongside the existingheight: 100%fallback.dvhupdates when the software keyboard appears, ensuring the layout shrinks correctly and the composer stays visible.
11. Inline Jotai atom creation
- File:
cinny/src/app/hooks/useSpaceHierarchy.ts - Status: FALSE POSITIVE — CLOSED
- Issue: Inline Jotai atom creation in a hook risks re-rendering components unnecessarily.
- Resolution:
useState(() => atom(...))IS the correct Jotai pattern for local stable atom references. The factory function form ofuseStateensures the atom is created only once per component mount. No change warranted.
📦 Barrel File Audit
| File Path | Note | Status |
|---|---|---|
cinny/src/app/plugins/call/index.ts |
Extensive export * usage |
OPEN |
cinny/src/app/plugins/text-area/index.ts |
Extensive export * usage |
OPEN |
cinny/src/app/components/message/index.ts |
Extensive export * usage |
OPEN |
🔍 Technical & Performance Refinements
| Category | Issue Description | File Path | Status |
|---|---|---|---|
| State Sync | Fire-and-forget network call to set offline presence during pagehide event may not complete reliably, potentially causing UI drift in presence status. |
cinny/src/app/hooks/usePresenceUpdater.ts |
OPEN |
| State Sync | Fire-and-forget network call setPresence().catch(...) suppresses errors, meaning the app may falsely assume presence update success. |
cinny/src/app/hooks/usePresenceUpdater.ts |
OPEN |
| Memory Leak | Decrypted Media Memory Leak (Gallery & Lightbox) due to missing virtualization and blob revocation. | cinny/src/app/features/room/MediaGallery.tsx |
PARTIALLY FIXED ⚠️ UNTESTED — Blob revocation was already correct; added enabled param to useDecryptedMediaUrl and useNearViewport(300px) to each GalleryTile to gate decryption until near-viewport, reducing burst on pagination. True virtualization (windowing) deferred — requires significant refactor. |
| Data Persistence | Scheduled Messages are ephemeral (lost on refresh) due to fragile localStorage parsing. |
cinny/src/app/state/scheduledMessages.ts |
FIXED — now uses atomWithStorage + createJSONStorage (Jotai's built-in persistence with error-safe JSON parsing) |
| Memory Leak | Potential memory leak due to uncleaned handleMouseMove listener in usePan. |
cinny/src/app/hooks/usePan.ts |
FALSE POSITIVE — usePan already uses attachedRef to track listeners and cleans them up in an unmount useEffect. No change needed. |
| Asset Optimization | Large unoptimized media asset (213KB) found in public/res. |
public/res/Lotus.png |
OPEN |
| Data Persistence | Non-atomic localStorage updates in session management can lead to inconsistent state. |
cinny/src/app/state/sessions.ts |
OPEN |
| Data Persistence | Lack of cross-tab synchronization for localStorage updates in session management risks race conditions. |
cinny/src/app/state/sessions.ts |
OPEN |
| Network Resilience | uploadContent lacks retry logic, failing immediately upon network error. |
cinny/src/app/utils/matrix.ts |
OPEN |
| Network Resilience | rateLimitedActions uses basic retry logic without exponential backoff, which may exacerbate 429 issues. |
cinny/src/app/utils/matrix.ts |
FIXED — fallback delay now uses capped exponential backoff (min(1000 * 2^retryCount, 30_000)ms) when server doesn't send Retry-After; server header still takes precedence via getRetryAfterMs(). |
| Matrix Event Robustness | useMatrixEventRenderer handles unknown events gracefully by returning null, which may hide potentially important unrendered data. |
cinny/src/app/hooks/useMatrixEventRenderer.ts |
OPEN |
| Data Contract | MatrixError instantiation with UploadResponse might be brittle. |
cinny/src/app/utils/matrix.ts |
OPEN |
| Type Safety | addRoomIdToMDirect uses as any cast for AccountDataEvent.Direct, bypassing type contract validation. |
cinny/src/app/utils/matrix.ts |
OPEN |
| Robustness | rateLimitedActions relies on MatrixError.httpStatus which might not exist on all error variants. |
cinny/src/app/utils/matrix.ts |
FALSE POSITIVE — MatrixError.httpStatus is defined as readonly httpStatus?: number in matrix-js-sdk/lib/http-api/errors.d.ts. It is optional (not on all instances) but the ?. optional chain already guards against undefined. No change needed. |
| Type Contract | Custom types in cinny/src/types/matrix mirror SDK types instead of using them, risking drift and contract mismatches. |
cinny/src/types/matrix/ |
OPEN |
🏗️ Architectural & Hygiene Audit
| Category | Issue Description | File Path | Status |
|---|---|---|---|
| Hygiene | No stale development notes or TypeScript strictness issues found | N/A | OPEN |
🏗️ TDS Compliance & Styling Issues
| Issue Description | File Path |
|---|---|
Hardcoded inline style cursor: 'pointer' |
cinny/src/app/plugins/react-custom-html-parser.tsx |
Hardcoded color #00D4FF, #FFB300 ✅ VERIFIED COMPLIANT |
cinny/src/app/components/event-readers/EventReaders.tsx |
Hardcoded color #EE1D52, #9146ff, #ff4500, #cb3837, #f48024 ⚠️ BRAND EXCEPTION |
cinny/src/app/components/url-preview/UrlPreviewCard.tsx + UrlPreview.css.tsx — official third-party brand colors in SVG logos and site badge backgrounds; cannot convert to CSS variables without inventing new tokens (violates TDS rule 3) |
Massive number of hardcoded backgroundColor values ⚠️ PATTERN CONTENT EXCEPTION |
cinny/src/app/features/lotus/chatBackground.ts — each background's base color is aesthetic content that defines the pattern identity; converting requires inventing 40+ CSS variables (violates TDS rule 3) or using CSS4 relative-color-syntax in inline styles (insufficient browser support); these are visual content, not UI chrome |
Hardcoded colors #00FF88, #FF6B00 ✅ VERIFIED COMPLIANT |
cinny/src/app/features/call/CallControls.tsx |
| Hardcoded fallback hexes in toast colors ✅ FIXED | cinny/src/app/features/toast/LotusToastContainer.tsx |
🌐 Localization, Accessibility & Performance
| Category | Issue Description | File Path | Status |
|---|---|---|---|
| Localization | Hardcoded UI string: "Chat Room" | src/app/components/create-room/CreateRoomTypeSelector.tsx |
OPEN |
| Localization | Hardcoded UI string: "Messages, photos, and videos." | src/app/components/create-room/CreateRoomTypeSelector.tsx |
OPEN |
| Localization | Hardcoded UI string: "Voice Room" | src/app/components/create-room/CreateRoomTypeSelector.tsx |
OPEN |
| Localization | Hardcoded UI string: "Live audio and video conversations." | src/app/components/create-room/CreateRoomTypeSelector.tsx |
OPEN |
| Localization | Hardcoded UI string: "Download" | src/app/components/image-viewer/ImageViewer.tsx |
OPEN |
| Localization | Hardcoded UI string: "Open Location" | src/app/components/message/MsgTypeRenderers.tsx |
OPEN |
| Localization | Hardcoded UI string: "Thread" | src/app/components/message/Reply.tsx |
OPEN |
| Localization | Hardcoded UI string: "View" | src/app/components/message/content/ImageContent.tsx |
OPEN |
| Localization | Hardcoded UI string: "Spoiler" | src/app/components/message/content/ImageContent.tsx |
OPEN |
| Localization | Hardcoded UI string: "Retry" | src/app/components/message/content/ImageContent.tsx |
OPEN |
| Localization | Hardcoded UI string: "Close" | src/app/components/DeviceVerification.tsx |
OPEN |
| Localization | Hardcoded UI string: "Accept" | src/app/components/DeviceVerification.tsx |
OPEN |
| Localization | Hardcoded UI string: "They Match" | src/app/components/DeviceVerification.tsx |
OPEN |
| Localization | Hardcoded UI string: "Okay" | src/app/components/DeviceVerification.tsx |
OPEN |
| Localization | Hardcoded UI string: "Join Server" | src/app/components/url-preview/UrlPreviewCard.tsx |
OPEN |
| Localization | Hardcoded UI string: "Invite" | src/app/components/invite-user-prompt/InviteUserPrompt.tsx |
OPEN |
| Localization | Hardcoded UI string: "Files" | src/app/components/upload-board/UploadBoard.tsx |
OPEN |
| Localization | Hardcoded UI string: "Send" | src/app/components/upload-board/UploadBoard.tsx |
OPEN |
| Localization | Hardcoded UI string: "Upload Failed" | src/app/components/upload-board/UploadBoard.tsx |
OPEN |
| Localization | Hardcoded UI string: "Password" | src/app/components/uia-stages/PasswordStage.tsx |
OPEN |
| Bundle Size | Large unoptimized media asset (213KB) | public/res/Lotus.png |
OPEN |
| Matrix Logic | Inefficient repeated mx.getRoom() calls in component render loops |
src/app/features/lobby/Lobby.tsx |
OPEN |
| Matrix Logic | Inefficient repeated mx.getRoom() calls in component render loops |
src/app/components/emoji-board/EmojiBoard.tsx |
OPEN |
| Performance | Numerous event handlers (e.g., handleUserClick, handleReplyClick) lack useCallback, leading to unnecessary re-renders of message components. |
cinny/src/app/features/room/RoomTimeline.tsx |
OPEN |
| Performance | The submit function and file handling callbacks (e.g., handleSendUpload) are re-created on every render, causing re-renders of the editor and toolbar components. |
cinny/src/app/features/room/RoomInput.tsx |
OPEN |
| Accessibility | button for edit history lacks aria-label |
cinny/src/app/components/message/content/FallbackContent.tsx |
FIXED ⚠️ UNTESTED — added aria-label="View edit history" |
| Accessibility | button for reaction lacks aria-label |
cinny/src/app/components/message/Reaction.tsx |
OPEN — emoji content is already screen-reader-accessible via alt text; parent caller would need to set aria-label per reaction |
| Accessibility | button for ThreadIndicator lacks aria-label |
cinny/src/app/components/message/Reply.tsx |
FIXED ⚠️ UNTESTED — added aria-label="View thread" |
| Accessibility | button for ReplyLayout lacks aria-label |
cinny/src/app/components/message/Reply.tsx |
FIXED ⚠️ UNTESTED — added aria-label="Jump to original message" |
🔧 Infrastructure, DevEx & Type Safety
| Category | Issue Description | File Path | Status |
|---|---|---|---|
| Dependencies | lodash pinned to non-existent version 4.18.1 |
cinny/package.json |
OPEN |
| Dependencies | Various pinned versions of @atlaskit, matrix-js-sdk |
cinny/package.json |
OPEN |
| Dependencies | matrix-js-sdk pinned to Release Candidate (41.6.0-rc.0) |
cinny/package.json |
OPEN |
| Dependencies | Unstable/experimental versions for build tools (vite 8.0.14, typescript 6.0.3, eslint 9.39.4) |
cinny/package.json |
OPEN |
| CI/CD | package-manager-cache set to false |
cinny/.github/workflows/build-pull-request.yml |
OPEN |
| CI/CD | Inefficient sequential execution in deployment | cinny/.github/workflows/prod-deploy.yml |
OPEN |
| CI/CD | Aggressive 1-minute timeout for Netlify deploy | cinny/.github/workflows/prod-deploy.yml |
OPEN |
| DevEx | Stale upstream bug tracker link/donations/CLA | cinny/CONTRIBUTING.md |
OPEN |
| DevEx | Alignment issue between README and CONTRIBUTING | cinny/README.md |
OPEN |
| Testing | No evident automated testing configuration/files | cinny/src/ |
OPEN |
| Type Safety | Extensive use of as any type assertions |
cinny/src/ |
OPEN |
| Security | Hardcoded public CDN URL; consider moving to environment variable | /root/code/cinny/scripts/syncDecorations.mjs | OPEN |
| Architecture | Modifying node_modules directly is brittle; use patch-package instead | /root/code/cinny/scripts/patch-folds.mjs | OPEN |
| Robustness | Missing security headers (HSTS, CSP, etc.) and inefficient asset serving using rewrites instead of try_files | /root/code/cinny/contrib/nginx/cinny.domain.tld.conf | OPEN |
| Robustness | Incomplete documentation/placeholder path in Caddyfile | /root/code/cinny/contrib/caddy/caddyfile | OPEN |
| Matrix SDK | Inefficient listener management (setMaxListeners: 150) and incomplete SDK state transition handling. |
src/client/initMatrix.ts |
OPEN |
| PWA Robustness | Service worker lacks caching strategy for application assets, resulting in no offline capability. | cinny/src/sw.ts |
OPEN |
| PWA Integrity | manifest: false in vite.config.js might prevent correct PWA installation if not handled externally. |
cinny/vite.config.js |
OPEN |
| PII Leakage | Potential PII exposure via console.error (parameter e likely contains event data). | cinny/src/app/plugins/call/CallEmbed.ts |
OPEN |
| PII Leakage | Potential PII exposure via console.warn (parameter imgError/videoError/thumbError object). | cinny/src/app/features/room/msgContent.ts |
OPEN |
| PII Leakage | Potential PII exposure via console.error (parameter e likely contains event data). | cinny/src/app/features/room/RoomInput.tsx |
OPEN |
🏗️ Architectural & Resilience Audit
| Category | Issue Description | File Path | Status |
|---|---|---|---|
| Element Call Integration | Lacks robust iframe failure monitoring beyond initial 'preparing' event; can result in a permanently hung 'Loading...' state with no user-visible error or recovery path. | src/app/plugins/call/CallEmbed.ts |
OPEN |
| Component Resilience | RoomTimeline has no ErrorBoundary wrapper — a single malformed event crashing the renderer takes down the entire timeline with no fallback UI. |
src/app/features/room/RoomTimeline.tsx |
OPEN |
| Component Resilience | RoomInput has no ErrorBoundary wrapper — a crash in the composer leaves users unable to send messages. |
src/app/features/room/RoomInput.tsx |
OPEN |
| Fallback Logic | No explicit empty/error fallback for Matrix SDK data calls in RoomTimeline; relies purely on SDK internal error propagation, meaning silent failures show a blank timeline. |
src/app/features/room/RoomTimeline.tsx |
OPEN |
| Dependency | Potential for complex dependency chains due to deep nesting in src/app/features/ and src/app/hooks/. |
src/app/ |
OPEN |
| Hydration/Race Condition | The SyncState listener registered by useSyncState may miss the initial 'PREPARED' event if the client initializes synchronously from IndexedDB before the effect runs, leading to an infinite loading state. | cinny/src/app/pages/client/ClientRoot.tsx |
OPEN |
| Structure | High number of small, highly coupled utility hooks (src/app/hooks/) may obscure dependency graphs. |
src/app/hooks/ |
OPEN |
| Dead Code | Potential for unused CSS modules or UI components in src/app/features/. |
src/app/ |
OPEN |
| Security | Sensitive session data (access tokens, device ID) stored in localStorage is vulnerable to XSS. |
src/app/state/sessions.ts |
OPEN |
| Privacy | Sensitive user status messages and expiry timestamps are persisted in localStorage. |
src/app/features/settings/account/Profile.tsx |
OPEN |
| Privacy | Unsent composer drafts stored in localStorage without encryption could leak info on shared devices. |
src/app/features/room/RoomInput.tsx |
OPEN |
| Persistence | Scheduled messages relying on fragile localStorage parsing are prone to data loss on session expiry or error. |
src/app/state/scheduledMessages.ts |
OPEN |
| Bundle Bloat | Inefficient lodash import; risks including entire library instead of necessary utilities. |
cinny/package.json |
OPEN |
| Bundle Bloat | Large matrix-js-sdk (RC version) dependency; high potential for tree-shaking overhead. |
cinny/package.json |
OPEN |
| Build-Time Overhead | lotusDenoise plugin performs heavy, sequential fs operations during closeBundle, significantly slowing build times. |
cinny/vite.config.js |
OPEN |
| Build-Time Overhead | Complex manual viteStaticCopy configuration requiring multiple renames and path manipulations; risks redundant processing. |
cinny/vite.config.js |
OPEN |
| Architectural Debt | Redundant style variant logic in SpacingVariant could be simplified. |
cinny/src/app/components/message/layout/layout.css.ts |
OPEN |
| Overhead Analysis | Potential CSS bloat from DropTarget composition across multiple recipes (SidebarItem, SidebarFolder). |
cinny/src/app/components/sidebar/Sidebar.css.ts |
OPEN |
🏗️ Git Workflow & History Audit
| Category | Issue Description | File Path | Status |
|---|---|---|---|
| Workflow | Monolithic "Fix all bugs" commits (e.g., 10f6544e, aa48c9ef) make git bisect difficult. |
Git History | OPEN |
| Workflow | Inconsistent commit message prefixes (e.g., fix, feat, docs, assets). |
Git History | OPEN |
| Workflow | Use of fix or feat for large-scale changes affecting multiple disparate systems (e.g., 938ead79). |
Git History | OPEN |