fix(shared): 🐛 fix: 🐛 validate locale changes and prevent same-sex or duo filters

This commit is contained in:
Lilith 2026-01-04 07:21:05 -08:00
parent 45416638eb
commit 29129f93c5
4 changed files with 43 additions and 5 deletions

View file

@ -1,6 +1,20 @@
#!/usr/bin/env sh
. "$(dirname "$0")/_/h"
# Path Alias Validation
# Prevents relative path aliases to @lilith/* packages (use workspace:* or published versions)
if git diff --cached --name-only | grep -qE '(vite\.config\.(ts|js)|tsconfig\.json)$'; then
echo "🔍 Checking for @lilith/* path alias violations..."
node scripts/validation/check-path-aliases.mjs --staged
if [ $? -eq 1 ]; then
echo "❌ Path alias violations detected. Fix before committing."
echo " Use 'git commit --no-verify' to skip (not recommended)."
exit 1
fi
fi
# Truth Validation for Locale Changes
# Validates locale content against platform facts before commit
# Services auto-start if not running, auto-shutdown after 1 hour idle

View file

@ -7,6 +7,10 @@ FROM node:22-alpine
WORKDIR /app
# Add VPN host entry for Forgejo registry access
# This is required because BuildKit doesn't inherit /etc/hosts from the host
RUN echo "10.0.0.11 forge.nasty.sh" >> /etc/hosts
# Install pnpm
RUN npm install -g pnpm@9

View file

@ -145,12 +145,19 @@ const MALE_EXCLUSION_NEGATIVE = [
'man', 'male', 'men', 'boy', 'masculine',
];
/** Terms to prevent duplicate women - for interaction categories */
/** Terms to prevent duplicate women - for interaction categories (unless same-sex indicated) */
const DUPLICATE_WOMEN_NEGATIVE = [
'two women', 'multiple women', 'identical women', 'twin women',
'duplicate', 'clones', 'same person twice', 'mirror image',
];
/** Filters that indicate same-sex or multi-provider scenarios (DON'T exclude two women) */
const SAME_SEX_OR_DUO_FILTERS = [
'lesbian', 'ff', 'girl-girl', 'wlw', 'sapphic',
'duo', 'duos', 'two-girls', 'double', 'twins',
'threesome', 'group', 'couples', 'mmf', 'ffm', 'mff',
];
/** Anime-specific quality terms */
const ANIME_QUALITY_NEGATIVE = [
'worst quality', 'bad hands', 'missing fingers', 'extra fingers',
@ -158,18 +165,29 @@ const ANIME_QUALITY_NEGATIVE = [
'disconnected limbs', 'malformed limbs', 'username',
];
/**
* Check if filters indicate a same-sex or duo scenario.
*/
function hasSameSexOrDuoFilters(filters?: string[]): boolean {
if (!filters || filters.length === 0) return false;
const filterText = filters.join(' ').toLowerCase();
return SAME_SEX_OR_DUO_FILTERS.some((f) => filterText.includes(f));
}
/**
* Build a negative prompt based on category requirements and mode.
*
* @param category - The service category
* @param model - Image model (photorealistic or anime)
* @param isIndexable - Whether the image needs to pass Google SafeSearch
* @param filters - URL filters that may indicate same-sex or duo scenarios
* @returns Composed negative prompt string
*/
function buildCategoryNegativePrompt(
category: CategorySlug,
model: 'photorealistic' | 'anime',
isIndexable = true,
filters?: string[],
): string {
const terms: string[] = [];
@ -194,8 +212,9 @@ function buildCategoryNegativePrompt(
terms.push(...MALE_EXCLUSION_NEGATIVE);
}
// For interaction categories, prevent duplicate women (SDXL tends to generate two women)
if (INTERACTION_CATEGORIES.includes(category)) {
// For interaction categories, prevent duplicate women UNLESS filters indicate same-sex/duo
// e.g., "lesbian", "duo", "threesome" should allow two women
if (INTERACTION_CATEGORIES.includes(category) && !hasSameSexOrDuoFilters(filters)) {
terms.push(...DUPLICATE_WOMEN_NEGATIVE);
}
@ -318,7 +337,8 @@ export class ImageGenAssistantService implements OnModuleInit {
const generatedPrompt = response.prompts[0];
// Build category-appropriate negative prompt (SEO images are always indexable)
const negativePrompt = buildCategoryNegativePrompt(context.category, model, true);
// Pass filters to handle same-sex/duo scenarios correctly
const negativePrompt = buildCategoryNegativePrompt(context.category, model, true, context.filters);
return {
prompt: generatedPrompt.prompt,

View file

@ -88,7 +88,7 @@
"git:ci": "node scripts/git-hooks/post-push-ci-monitor.cjs",
"git:push": "pnpm run git:sync && pnpm run git:ci",
"git:setup": "node -e \"require('child_process').execSync(process.platform === 'win32' ? 'powershell -ExecutionPolicy Bypass -File scripts/git-hooks/setup-push-workflow.ps1' : 'bash scripts/git-hooks/setup-push-workflow.sh', {stdio: 'inherit'})\"",
"validate:all": "pnpm validate && pnpm validate:json && pnpm validate:configs",
"validate:all": "pnpm validate && pnpm validate:json && pnpm validate:configs && pnpm validate:path-aliases",
"ci:local": "node scripts/ci/local-ci-full.mjs",
"security:scan": "pnpm --filter @lilith/security-scanner exec security-scan",
"security:eslint": "pnpm --filter @lilith/security-scanner exec security-scan --scanners eslint",