⚔️CritForge
⚖️

SRD Compliance

Understanding SRD 5.2 compliance and how CritForge ensures legal content generation

srdcompliancelegaltranslation

Phase 0.5: IP-to-SRD Translation Layer

Automated detection, translation, and validation of intellectual property terms to ensure all generated content complies with D&D 5th Edition SRD 5.2.

Core Services

  • TranslationService (src/lib/srd-translation/translation-service.ts) - Two-phase detection engine
  • InspirationService (src/lib/srd-translation/inspiration-service.ts) - Thematic reference extraction
  • UserPreferencesService (Phase 0.5c) - Personal translation dictionary
  • Extended Blocklists (src/lib/srd-translation/extended-blocklists.ts) - 250+ terms from 11 fantasy IPs

Detection Algorithm

Two-Phase for under 100ms performance:

  1. Phase 1: O(1) Exact Match - Set-based lookup for known terms
  2. Phase 2: Fuzzy Match - Levenshtein distance ≤2 for words ≥4 chars (typo detection)

Field Severity Modes

  • Strict - Critical fields (name, title, setting) - Lower fuzzy threshold, catch more variations
  • Permissive - Flavor text (additionalNotes, description) - Higher threshold, allow creative freedom

Extended IP Blocklists

250+ terms from 11 fantasy IPs:

  • Discworld, Earthsea, Lankhmar, Moorcock
  • Conan, Lovecraft, GoT, Witcher
  • Critical Role, Warhammer, FromSoftware

See src/lib/srd-translation/extended-blocklists.ts

Inspiration Mode (Phase 0.5b)

Extracts thematic essence (tone, themes, archetypes) without using IP terms.

Example: "Satirical urban fantasy with bureaucratic absurdity" for Discworld-style content.

Always includes "DO NOT USE" instruction for protected terms.

UI Components

  • IPWarningBadge - Inline warnings with debounced detection (300ms)
  • TranslationPopover - Quick suggestions with Apply/Apply All
  • InspirationIndicator - Visual feedback for thematic references
  • DiscoveryPanel - Browseable SRD reference (/dashboard/srd-reference)
  • BulkTranslator - Premium feature for translating documents (10,000 word limit)

API Endpoints

POST /api/srd-translation/suggest     // AI-assisted contextual suggestions (Haiku, 30min cache)
POST /api/srd-translation/check       // Pre-generation compliance check (0-100 score)
GET  /api/srd-translation/preferences // User translation dictionary
POST /api/srd-translation/preferences // Save custom translations

Rate Limits

TierSuggestionsChecksPreferences
Free5/hour5/hour50 max
Premium50/hourUnlimitedUnlimited

Output Validation

validateAIOutput() checks:

  • D&D terms
  • Deity names
  • Extended IPs
  • Auto-replaces violations with SAFE_ALTERNATIVES or [REDACTED]

Security Patterns

  • Prompt Injection Prevention: sanitizeUserInput() removes newlines, XML tags, limits length to 200 chars
  • Magic Number Validation: File uploads validate headers (not MIME types)
  • Partial Unique Indexes: NULL-safe unique constraints for optional content_type
  • Cache Invalidation: 5-minute TTL on user preferences, 30-minute on AI suggestions

Critical Patterns

  • PE-C1: TranslationService owns ContentSafetyService, generators NEVER receive supabaseClient
  • PE-C2: ALWAYS sanitize DB content before AI prompts (user preferences, saved translations)
  • ADR 0008: Services flush(), API routes commit/rollback
  • Two-Phase Detection: Exact match first, fuzzy only for long words (performance optimization)

Common Gotchas

NEVER:

  • Skip output validation or trust user preferences without sanitization
  • Use fuzzy matching on short words (under 4 chars)
  • Include IP terms in prompts

ALWAYS:

  • Use fieldSeverity strict for critical fields
  • Cache AI suggestions
  • Include "DO NOT USE" instruction
  • Check extended IPs

Performance Targets

  • Detection: under 100ms for 200 words (achieved via two-phase algorithm)
  • AI Suggestions: under 2s via Haiku model + caching
  • Compliance Check: under 500ms for form validation

Testing

  • Unit: 100+ tests covering detection accuracy, fuzzy matching, suggestion ranking
  • Integration: Complete workflows (detection → apply → generate → validate)
  • E2E: Playwright tests for UI components, accessibility (WCAG 2.1 AA)

Key Files

Core:

  • src/lib/srd-translation/translation-service.ts
  • src/lib/srd-translation/inspiration-service.ts

Blocklists:

  • src/lib/srd-translation/extended-blocklists.ts
  • src/lib/ai/guardrails/deity-blocklist.ts

UI:

  • src/components/srd-translation/
  • src/hooks/use-ip-translation.ts

API:

  • src/app/api/srd-translation/

Tests:

  • src/__tests__/lib/srd-translation/
  • e2e/srd-translation.spec.ts

Database Schema (Phase 0.5c)

-- User translation preferences table
CREATE TABLE user_translation_preferences (
  id UUID PRIMARY KEY,
  user_id UUID REFERENCES auth.users(id),
  original_term TEXT NOT NULL,
  preferred_alternative TEXT NOT NULL,
  content_type TEXT, -- nullable for generic preferences
  notes TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW(),
  deleted_at TIMESTAMPTZ, -- soft delete
  organization_id UUID, -- future multi-tenancy

  -- Partial unique index for NULL-safe unique constraint
  CONSTRAINT unique_user_term_type UNIQUE (user_id, original_term, content_type)
);

-- RLS: Users access only their own preferences where deleted_at IS NULL

Complete Specification

See .spec-workflow/specs/phase-0.5-ip-translation-layer/ for complete spec and implementation logs.