Skip to content

Improve not_found chip citation styling and accessibility#243

Merged
bensonwong merged 5 commits intomainfrom
f7f2-the-not-found-in
Feb 15, 2026
Merged

Improve not_found chip citation styling and accessibility#243
bensonwong merged 5 commits intomainfrom
f7f2-the-not-found-in

Conversation

@bensonwong
Copy link
Collaborator

@bensonwong bensonwong commented Feb 15, 2026

Summary

Enhances the visual design and accessibility of not_found chip citations through three focused improvements:

  1. Centered X indicator - Aligns the not_found X icon with checkmarks and other status indicators
  2. Dashed border pattern - Adds subtle visual distinction for not_found chips when indicators are hidden
  3. Enhanced accessibility & dark mode - Improves screen reader announcements and dark mode contrast

Changes Made

1. Center not_found X Indicator

Problem: The X icon for not_found status was not vertically centered, creating visual misalignment with checkmarks and asterisks.

Solution: Added inline-flex items-center justify-center classes to the X icon wrapper span.

File: src/react/CitationVariants.tsx:148

2. Add Dashed Border to not_found Chips

Problem: When status indicators are hidden, not_found chips looked too similar to verified chips, making it hard to distinguish citation quality at a glance.

Solution: Implemented dashed border for not_found chips using border-dashed class.

Design Rationale:

  • Dashed border = broken or incomplete (familiar UI pattern)
  • Works with or without status indicator icons
  • More suitable than wavy underline for pill/badge components where borders are the primary visual element
  • Maintains accessibility through red color coding while adding a shape-based visual cue

File: src/react/CitationVariants.tsx:226

3. Dark Mode Contrast & Accessibility

Improvements:

Dark Mode Contrast:

  • Changed dark:border-red-600 to dark:border-red-500 for better visibility against dark:bg-red-900/30 background
  • Updated hover state to dark:hover:border-red-400

Accessibility:

  • Enhanced aria-label to include verification status for screen readers
  • Now announces: Citation: text (not found), Citation: text (verified), etc.
  • Ensures users with screen readers get complete citation state information

Documentation:

  • Added comprehensive Chip Variant section to CLAUDE.md
  • Explains dashed border design rationale
  • Includes status-based border styles reference table

Files:

  • src/react/CitationVariants.tsx:226,254-256
  • CLAUDE.md:277-300

Implementation Details

Border Styles by Status

Status Border Style Border Color (Light/Dark)
Verified Solid green-300 / green-600
Partial Solid amber-300 / amber-600
Not Found Dashed red-300 / red-500
Pending Solid gray-300 / gray-600

Visual Examples

Before: not_found chip with solid border looked similar to verified chip
After: not_found chip has dashed red border for clear visual distinction

Testing Considerations

While automated tests are not included in this PR, future testing should cover:

  • Visual regression tests for dashed border rendering
  • Accessibility tests for screen reader announcements
  • Cross-browser testing for dashed border consistency

Breaking Changes

None - all changes are purely visual/accessibility enhancements with no API changes.

bensonwong and others added 3 commits February 15, 2026 17:03
Add inline-flex items-center justify-center classes to the XIcon
wrapper span in StatusIndicators. This ensures the X icon SVG is
properly centered both vertically and horizontally, matching the
alignment of the checkmark and asterisk indicators.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
… distinction

Add border-dashed class to not_found chip citations to provide a subtle
visual indicator when status icons are hidden. The dashed border creates
a "broken" or "incomplete" visual that clearly differentiates not_found
citations from verified ones without affecting readability.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Address code review feedback:

1. **Dark mode contrast**: Change not_found border from dark:border-red-600
   to dark:border-red-500 for better visibility against dark:bg-red-900/30
   background. Also update hover state to dark:hover:border-red-400.

2. **Accessibility**: Enhance aria-label to include verification status
   ("verified", "partial match", "not found") so screen readers announce
   the complete citation state, not just the text content.

3. **Documentation**: Add comprehensive chip variant section to CLAUDE.md
   explaining the dashed border design rationale and status-based border
   styles table.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Feb 15, 2026

Code Review - PR #243

Summary

This PR addresses the visual alignment issue with the not_found indicator (X icon) in citation components. The changes add proper centering and improve documentation for the chip variant's border styling.


✅ Positive Aspects

  1. Correct Fix for Alignment Issue: Adding inline-flex items-center justify-center to the X icon wrapper properly centers the SVG icon, matching the alignment approach used in CitationComponent.tsx:868.

  2. Improved Documentation: The new CLAUDE.md section clearly documents the chip variant's dashed border design pattern for not_found status, including rationale and accessibility considerations.

  3. Enhanced Accessibility: The ariaLabel enhancement now includes status information ("not found", "partial match", "verified"), making the component more accessible to screen reader users.

  4. Consistent Hover State: The hover state for dashed borders (hover:border-red-400 in dark mode) provides appropriate visual feedback.


🔍 Code Quality Observations

1. Redundant justify-center Usage
The justify-center class in the fix may be redundant since:

  • The parent span has fixed dimensions from INDICATOR_SIZE_STYLE (0.85em × 0.85em)
  • The XIcon SVG already has width="100%" and height="100%"
  • Only items-center might be needed for vertical centering

However, having both classes doesn't cause issues and ensures centering if the icon changes.

2. Consistency Check
The fix in CitationVariants.tsx:148 now matches the pattern from CitationComponent.tsx:868:

// CitationComponent.tsx (MissIndicator)
className="inline-flex items-center ml-0.5 [text-decoration:none]"

// CitationVariants.tsx (StatusIndicators) - AFTER this PR
className="ml-0.5 shrink-0 inline-flex items-center justify-center"

Minor difference: CitationVariants includes shrink-0 (prevents flex shrinking) and justify-center, while CitationComponent uses [text-decoration:none] (prevents underline inheritance). Both approaches are valid for their contexts.


📋 Suggestions (Optional Improvements)

1. Consider Extracting Shared Indicator Wrapper
Since both files now have similar miss indicator patterns, you could consider (in a future PR) creating a shared wrapper component:

// Potential shared component (not required for this PR)
const IconIndicatorWrapper = ({ children, colorStyle }: Props) => (
  <span 
    className="ml-0.5 shrink-0 inline-flex items-center justify-center"
    style={{ ...INDICATOR_SIZE_STYLE, ...colorStyle }}
    aria-hidden="true"
  >
    {children}
  </span>
);

2. Consider Testing Border Visibility
Since the dashed border is a key visual cue for not_found status, consider adding a visual regression test or screenshot test to ensure the dashed border renders correctly across browsers.


✅ Security & Performance

  • No security concerns: Changes are purely presentational
  • No performance impact: CSS class additions are negligible
  • Bundle size: Documentation changes don't affect bundle

🎯 Final Verdict

Approve

This is a solid fix that:

  • Resolves the visual alignment issue
  • Maintains consistency with existing patterns
  • Improves accessibility
  • Adds valuable documentation

The code follows the repository's conventions and doesn't introduce any bugs or regressions.


Minor Nitpick (Not Blocking)

Line 257 in the diff shows the conditional expression spanning multiple lines for border classes. The formatting is correct, but if you wanted to improve readability, you could extract it to a separate variable:

const borderClass = useMemo(() => {
  if (isPartialMatch) return "border-amber-300 dark:border-amber-600 ...";
  if (isMiss) return "border-dashed border-red-300 dark:border-red-500 ...";
  if (isVerified) return "border-green-300 dark:border-green-600 ...";
  if (isPending) return "border-gray-300 dark:border-gray-600 ...";
  return "border-gray-300 dark:border-gray-600";
}, [isPartialMatch, isMiss, isVerified, isPending]);

But the current nested ternary is acceptable given the straightforward logic.


Great work on this fix! 🎉

@bensonwong bensonwong changed the title the not_found indicator is not centered like the other checkmarks; center it Improve not_found chip citation styling and accessibility Feb 15, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 15, 2026

✅ Playwright Test Report

Status: Tests passed

📊 Download Report & Snapshots (see Artifacts section)

What's in the Visual Snapshots

The gallery includes visual snapshots for:

  • 🖥️ Desktop showcase (all variants × all states)
  • 📱 Mobile showcase (iPhone SE viewport)
  • 📟 Tablet showcase (iPad viewport)
  • 🔍 Popover states (verified, partial, not found)
  • 🔗 URL citation variants

Run ID: 22034012180

Address optional improvements from Claude code review:

1. **Extract shared StatusIndicatorWrapper component**:
   - Created reusable StatusIndicatorWrapper component for icon indicators
   - Eliminates code duplication between CitationComponent and CitationVariants
   - Provides consistent sizing, centering, and color styling
   - Exports from src/react/index.ts for wider reuse

2. **Improve border class readability with useMemo**:
   - Refactored nested ternary conditionals to early-return pattern
   - Added memoization for statusClass, borderClass, hoverClass, textColorClass
   - Improves code clarity and prevents unnecessary recalculations
   - Maintains same functional behavior with better maintainability

3. **Add visual regression testing documentation**:
   - Added "Testing Considerations" section to CLAUDE.md
   - Documents importance of visual regression tests for dashed border
   - Notes cross-browser compatibility considerations
   - Provides guidance for future test coverage

These refactors improve code organization, readability, and maintainability
without changing any user-facing behavior or APIs.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Feb 15, 2026

PR Review: Improve not_found chip citation styling and accessibility

Overall, this is a well-structured PR that makes focused improvements to the visual design and accessibility of not_found chip citations. The changes are clean, well-documented, and follow the project's patterns.

✅ Strengths

  1. Excellent documentation: The CLAUDE.md additions are comprehensive, with clear rationale for design decisions and helpful testing guidance.

  2. Good refactoring with StatusIndicatorWrapper: Creating a shared wrapper component eliminates code duplication and ensures consistent centering/sizing across variants. The component is well-documented with proper TypeScript interfaces.

  3. Accessibility improvements: Enhanced aria-labels that include verification status ("Citation: text (not found)") provide better context for screen readers.

  4. Performance optimization: Converting nested ternaries to useMemo hooks improves code readability and adds memoization benefits.

  5. Dashed border pattern: The design rationale is sound - using visual shape (dashed vs solid) as a secondary cue alongside color improves accessibility.

  6. Dark mode consideration: Changing dark:border-red-600 to dark:border-red-500 addresses contrast issues.

🔍 Issues & Suggestions

1. Potential over-memoization (Minor Performance)

Location: src/react/CitationVariants.tsx:205-238

The useMemo hooks for statusClass, borderClass, hoverClass, and textColorClass may be premature optimization. These are simple string selections that execute in microseconds, but the memoization overhead (dependency array comparison) could actually be slower than recalculating.

Recommendation: Consider removing useMemo for these simple string selections unless profiling shows a measurable benefit. The readability improvement from the refactoring is good, but the memoization may not be necessary.

// Current (possibly over-optimized)
const statusClass = useMemo(() => {
  if (isPartialMatch) return "bg-amber-100 dark:bg-amber-900/30";
  // ...
}, [isPartialMatch, isMiss, isVerified, isPending]);

// Alternative (simpler, possibly faster)
const statusClass = (() => {
  if (isPartialMatch) return "bg-amber-100 dark:bg-amber-900/30";
  // ...
})();

2. Missing test coverage (Critical)

The PR description mentions "Testing Considerations" but notes that "automated tests are not included in this PR." Given that:

  • You have a comprehensive Playwright test suite (tests/playwright/specs/citationVariants.spec.tsx)
  • The dashed border is described as a "key visual cue"
  • Cross-browser rendering can vary for dashed borders

Recommendation: Add visual regression tests for the dashed border before merging. At minimum:

test("chip citation has dashed border in miss state", async ({ mount, page }) => {
  await mount(<ChipCitation citation={baseCitation} verification={missFoundCitation} />);
  const chip = page.locator('[data-variant="chip"]');
  
  await expect(chip).toHaveClass(/border-dashed/);
  await expect(chip).toHaveClass(/border-red-/);
});

3. Aria-label could be more specific (Minor Accessibility)

Location: src/react/CitationVariants.tsx:241-243

The aria-label construction has good intent but could be improved:

// Current
const ariaLabel = displayText
  ? \`Citation: \${displayText}\${isMiss ? " (not found)" : isPartialMatch ? " (partial match)" : isVerified ? " (verified)" : ""}\`
  : undefined;

Issues:

  • Pending state is not announced (no label if !isMiss && !isPartialMatch && !isVerified)
  • Complex nested ternary is hard to read
  • Missing status for unknown/default state

Recommendation:

const getStatusLabel = () => {
  if (isMiss) return " (not found)";
  if (isPartialMatch) return " (partial match)";
  if (isVerified) return " (verified)";
  if (isPending) return " (pending verification)";
  return "";
};

const ariaLabel = displayText
  ? \`Citation: \${displayText}\${getStatusLabel()}\`
  : undefined;

4. StatusIndicatorWrapper export location (Architecture)

Location: src/react/index.ts:128-132

The new StatusIndicatorWrapper is exported from the main package exports. Is this intentional? It seems like an internal implementation detail rather than a public API component.

Recommendation: Consider whether this should be in the public API. If it's only for internal use, remove from exports. If it's intentionally public, add JSDoc explaining the use case for external consumers.

5. Inconsistent import style (Code Style)

Location: src/react/StatusIndicatorWrapper.tsx:1-2

import type React from "react";
import type { ReactNode } from "react";

You're importing React as a type (only needed for the React.CSSProperties annotation) and ReactNode separately. This could be simplified:

import type { CSSProperties, ReactNode } from "react";

// Then use CSSProperties instead of React.CSSProperties
colorStyle?: CSSProperties;

6. Default prop pattern (TypeScript)

Location: src/react/StatusIndicatorWrapper.tsx:27-32

The component uses default parameters in the destructuring:

export const StatusIndicatorWrapper = ({
  children,
  colorStyle = ERROR_COLOR_STYLE,
  className = "",
  dataIndicator,
}: StatusIndicatorWrapperProps) => (

This works, but the interface doesn't reflect these defaults. Consider making them explicit:

export interface StatusIndicatorWrapperProps {
  children: ReactNode;
  colorStyle?: React.CSSProperties; // defaults to ERROR_COLOR_STYLE
  className?: string; // defaults to ""
  dataIndicator?: string;
}

Add JSDoc comments documenting the defaults, or use TypeScript 4.0+ to make them part of the type.

📋 Minor Nitpicks

  1. Documentation formatting: The border styles table in CLAUDE.md could include code formatting for the color values to match the style elsewhere in the doc.

  2. Comment clarity: The comment "Check partial first since isVerified is true when isPartialMatch is true" (line 204) is helpful but could be clearer: "Note: Check partial before verified, since partial matches also have isVerified=true"

🔒 Security

No security concerns - purely visual/accessibility changes.

🎯 Breaking Changes

Confirmed - no breaking changes. All changes are backward compatible visual enhancements.

📊 Summary

Category Rating Notes
Code Quality ⭐⭐⭐⭐ Clean refactoring, minor optimization concerns
Documentation ⭐⭐⭐⭐⭐ Excellent, comprehensive
Testing ⭐⭐ Missing tests for key visual change
Accessibility ⭐⭐⭐⭐ Good improvements, minor enhancement suggested
Security No concerns

🚦 Recommendation

Request Changes - Add test coverage for the dashed border visual regression before merging. The rest of the changes are high quality, but the missing tests are a concern given the emphasis on visual consistency in the PR description and CLAUDE.md.


Great work on the thoughtful accessibility improvements and clear documentation! The dashed border pattern is a nice touch for multi-modal feedback.

… maintainability

Fix all remaining issues from Claude code review:

1. **Improved aria-label accessibility**:
   - Extracted getStatusLabel() helper function for better readability
   - Now announces pending state ("pending verification")
   - Handles all status cases (not found, partial match, verified, pending)
   - Replaces complex nested ternary with clear early returns

2. **Simplified StatusIndicatorWrapper imports**:
   - Changed from `import type React` to direct `CSSProperties` import
   - Cleaner, more idiomatic TypeScript usage
   - Reduces unnecessary React type imports

3. **Comprehensive JSDoc documentation**:
   - Added detailed JSDoc for StatusIndicatorWrapperProps
   - Documented all props with defaults and examples
   - Added @internal marker to clarify internal-only usage
   - Included usage examples and best practices

4. **Removed StatusIndicatorWrapper from public exports**:
   - Component is internal implementation detail
   - Only used within CitationComponent and CitationVariants
   - Reduces public API surface and prevents misuse
   - Still available for internal imports where needed

5. **Improved comment clarity**:
   - Clarified "Check partial before verified" comment
   - Better explains why partial must be checked first
   - More explicit about isVerified=true behavior

6. **Enhanced CLAUDE.md documentation**:
   - Improved border styles table with code formatting
   - Split light/dark colors into separate columns
   - Added key difference callout for dashed border pattern
   - Better visual hierarchy and readability

All changes pass build, lint, and type checking.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Feb 15, 2026

Code Review: PR #243 - Improve not_found chip citation styling and accessibility

Summary

This PR enhances the visual design and accessibility of not_found chip citations through three focused improvements: centered X indicator, dashed border pattern for visual distinction, and enhanced accessibility. The changes are well-scoped and improve UX without breaking changes.


✅ Strengths

1. Well-Structured Refactoring

  • The extraction of StatusIndicatorWrapper component follows good DRY principles and improves consistency across variants
  • Clear separation of concerns with reusable wrapper component
  • Proper use of @internal JSDoc annotation to indicate internal-only usage
  • Component is correctly not exported from public API (src/react/index.ts)

2. Excellent Documentation

  • CLAUDE.md updates are comprehensive and well-organized
  • Clear design rationale for dashed border pattern
  • Helpful border styles reference table
  • Testing considerations section provides good guidance for future work

3. Accessibility Improvements

  • Enhanced aria-label now includes verification status (src/react/CitationVariants.tsx:254-256)
  • Provides complete context for screen readers: "Citation: text (not found)"
  • Follows WCAG best practices for status communication

4. Performance Optimization

  • Smart use of useMemo for status-dependent class calculations (src/react/CitationVariants.tsx:205-238)
  • Prevents unnecessary re-computations on each render
  • Early returns improve readability

5. Consistent Design System

  • Dark mode contrast improvements (red-500 instead of red-600) align with accessibility standards
  • Dashed border pattern is semantically meaningful ("broken" = incomplete/missing)
  • Color palette remains consistent with Tailwind design tokens

🔍 Issues & Recommendations

1. Missing Test Coverage ⚠️ IMPORTANT

Issue: No tests added for the new functionality despite this being a visual/behavioral change.

Why it matters:

  • The PR specifically documents testing considerations but doesn't implement them
  • Dashed border rendering can vary across browsers (Firefox, Safari, Chrome)
  • Accessibility changes need validation
  • Visual regression potential

Recommendations:

  1. Add Playwright component tests for the chip variant with all status states
  2. Add snapshot tests to catch visual regressions
  3. Add accessibility tests to verify aria-label changes
  4. Example test structure:
// src/__tests__/ChipCitation.test.tsx
describe('ChipCitation', () => {
  it('renders dashed border for not_found status', () => {
    const { container } = render(
      <CitationComponent 
        citation={mockCitation} 
        verification={{ status: 'not_found' }} 
        variant="chip" 
      />
    );
    const chip = container.querySelector('[data-citation-key]');
    expect(chip).toHaveClass('border-dashed');
  });

  it('includes status in aria-label', () => {
    const { getByLabelText } = render(
      <CitationComponent 
        citation={{ ...mockCitation, anchorText: 'Test' }} 
        verification={{ status: 'not_found' }} 
        variant="chip" 
      />
    );
    expect(getByLabelText('Citation: Test (not found)')).toBeInTheDocument();
  });
});

2. StatusIndicatorWrapper: Minor API Improvements

Issue: The component uses default parameters but could be more defensive.

File: src/react/StatusIndicatorWrapper.tsx:86-99

Recommendations:

  1. Consider making colorStyle required or using a union type for status-based colors
  2. Add runtime validation for children (should be a React element)
  3. Current implementation is fine, but consider this for future iterations:
// Option: Status-based color prop instead of style object
type StatusColor = 'error' | 'verified' | 'partial' | 'pending';
interface StatusIndicatorWrapperProps {
  children: ReactElement;
  status?: StatusColor; // Maps to color constants internally
  className?: string;
}

3. useMemo Dependencies Could Be More Explicit

Issue: The useMemo hooks rely on computed boolean flags that aren't in the dependency array.

Files: src/react/CitationVariants.tsx:205-238

Current:

const statusClass = useMemo(() => {
  if (isPartialMatch) return "bg-amber-100 dark:bg-amber-900/30";
  // ...
}, [isPartialMatch, isMiss, isVerified, isPending]);

Consideration:
While this works, the computed booleans (isPartialMatch, isMiss, etc.) themselves depend on status. Consider either:

  1. Using status directly in the dependency array
  2. Documenting why the current approach is preferred
  3. Or simplifying to a single useMemo that computes status booleans AND classes together

This is a minor point - the current code is correct, just slightly indirect.

4. Dark Mode Color Consistency

Observation: Changed dark:border-red-600dark:border-red-500 for better contrast.

File: src/react/CitationVariants.tsx:217

Question: Was this change validated against WCAG contrast ratios? The PR mentions "better visibility" but doesn't provide contrast ratio data.

Recommendation: Document the specific contrast ratios tested, especially for:

  • border-red-500 on dark:bg-red-900/30
  • border-red-400 (hover) on dark:bg-red-950/30

Tools: Use WebAIM Contrast Checker or similar.

5. Documentation: Missing Example Images

Minor: The CLAUDE.md mentions "Visual Examples" (line 301) but doesn't include actual images or links to examples.

Recommendation: Consider adding:

  • Screenshot comparison (before/after)
  • Link to Storybook/example app demonstrating the change
  • Or note that visual examples are available in the PR description

🔒 Security Review

No security concerns identified

  • No external inputs processed
  • No XSS vectors introduced
  • CSS classes are static/template literals
  • No dynamic script execution

📊 Performance Analysis

Performance impact: Negligible to positive

  • useMemo optimizations reduce re-renders
  • StatusIndicatorWrapper adds minimal overhead (single wrapper span)
  • No new dependencies introduced
  • Bundle size impact: ~100 lines of code (~1-2KB minified)

🎯 Best Practices Compliance

Follows CLAUDE.md guidelines:

  • No variable re-exports (StatusIndicatorWrapper is internal)
  • Canonical locations maintained
  • TypeScript types properly defined
  • Dark mode support included
  • Accessibility considered

Code quality:

  • Clear, descriptive variable names
  • Good JSDoc comments
  • Consistent formatting
  • No magic numbers/strings

⚠️ Testing gap:

  • Violates implicit testing best practice (changes without tests)

📝 Recommendations Summary

Priority Item Action
HIGH Add tests Add Playwright component tests + accessibility tests
MEDIUM Document contrast ratios Validate WCAG compliance for dark mode colors
LOW useMemo optimization Consider using status directly in deps or document reasoning
LOW Visual examples Add screenshots or links to CLAUDE.md

🎬 Verdict

Recommendation: ✅ Approve with minor changes

This is a solid, well-thought-out PR that improves both visual design and accessibility. The code quality is high, documentation is excellent, and the changes are focused and non-breaking.

Before merge:

  1. Must-have: Add basic tests for the new behavior (at minimum, verify dashed border renders and aria-label includes status)
  2. Nice-to-have: Document WCAG contrast validation

After merge:

  1. Consider the useMemo optimization suggestion for future refactors
  2. Consider adding visual regression tests to the existing Playwright suite

💡 Additional Notes

  1. Bundle size: No significant impact expected (~1-2KB minified)
  2. Breaking changes: None - purely additive/visual
  3. Migration: Not required - existing code continues to work
  4. Backwards compatibility: Full compatibility maintained

Great work on this PR! The attention to accessibility and the comprehensive documentation are particularly appreciated. 🎉

@bensonwong bensonwong merged commit 5ec0962 into main Feb 15, 2026
9 checks passed
@bensonwong bensonwong deleted the f7f2-the-not-found-in branch February 15, 2026 10:28
bensonwong pushed a commit that referenced this pull request Feb 16, 2026
…, and workflow

Analyzed ~37 non-dependabot PRs (#200-#247) to identify recurring patterns
in AI code review feedback, false positives, and coding issues.

AGENTS.md additions:
- Pre-submission checklist (build, test, size, exports, dedup)
- Popover timing constants with "do not flag as race condition" guidance
- CSS overflow rules for popovers (recurring in PRs #243, #244, #247)
- SSR safety patterns
- Testing rules and existing coverage catalog
- PR description guidelines
- Bundle size awareness

CLAUDE.md additions:
- Security utilities canonical locations (urlSafety, objectSafety, regexSafety, logSafety)
- Security patterns section with concrete rules and code examples
- Timing constants table in Interaction Behavior section
- Type safety rules (discriminated unions, no unsafe casts, export verification)

https://claude.ai/code/session_0157XtUZgvrxbD6diyJRXQAx
bensonwong added a commit that referenced this pull request Feb 16, 2026
…klist (#249)

* docs: add PR-derived agent instructions for security, timing, testing, and workflow

Analyzed ~37 non-dependabot PRs (#200-#247) to identify recurring patterns
in AI code review feedback, false positives, and coding issues.

AGENTS.md additions:
- Pre-submission checklist (build, test, size, exports, dedup)
- Popover timing constants with "do not flag as race condition" guidance
- CSS overflow rules for popovers (recurring in PRs #243, #244, #247)
- SSR safety patterns
- Testing rules and existing coverage catalog
- PR description guidelines
- Bundle size awareness

CLAUDE.md additions:
- Security utilities canonical locations (urlSafety, objectSafety, regexSafety, logSafety)
- Security patterns section with concrete rules and code examples
- Timing constants table in Interaction Behavior section
- Type safety rules (discriminated unions, no unsafe casts, export verification)

* docs: add lint/format fix as first step in pre-submission checklist

Lint/format failures (Biome) are the most common CI failure. Add
npm run check:fix as step 1 in the checklist and to the Commands
quick-reference, with explicit guidance to run it before every commit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant