feat(ai): prompt-injection delimiters + synonym-aware match scoring
Wave 4 hardening. Wrap untrusted CV/job-description/instruction text in tools/summarizer prompts with explicit delimiters and an ignore-embedded-instructions rule, since JD text, recruiter emails, and free-text candidate background all flow into rewrite/normalize prompts unescaped today. Match score previously normalized synonyms (JS/Kubernetes/K8s/etc) only when scanning the job posting, not when checking the CV corpus, so a CV using an abbreviation the job spelled out never matched. SkillTagger.MatchesTag reuses the same synonym regex for both sides.
This commit is contained in:
@@ -38,6 +38,18 @@ public static class SkillTagger
|
||||
("Attention to Detail", new Regex(@"attention to detail|detail-oriented|quality-focused", RegexOptions.IgnoreCase | RegexOptions.Compiled), 2),
|
||||
};
|
||||
|
||||
/// <summary>True if `text` matches the same synonym pattern used to detect `tag` in job postings.
|
||||
/// Lets CV-side matching accept variants (e.g. "JS" for "JavaScript", "K8s" for "Kubernetes").</summary>
|
||||
public static bool MatchesTag(string tag, string? text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text)) return false;
|
||||
foreach (var (t, pattern, _) in Patterns)
|
||||
{
|
||||
if (string.Equals(t, tag, StringComparison.OrdinalIgnoreCase)) return pattern.IsMatch(text);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string[] Detect(string? description)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(description)) return Array.Empty<string>();
|
||||
|
||||
Reference in New Issue
Block a user