How must an instance handle semantic search returning results from a model-generated corpus?
**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session performs semantic search against a corpus that includes a substantial fraction of model-generated content (synthetic data, LLM summaries, generated documents), and must distinguish search results that reference original human-authored content from those that reference model-generated content. Does not apply to strictly human-authored corpora or corpora with cryptographic provenance per record.
Core Distinction
The separation between **search relevance** (the result matches the query semantically) and **source authenticity** (the result references a human-authored source or a model-generated artifact). Relying on relevance alone creates the **Synthetic Recursion Trap**: the agent retrieves model-generated content that itself was generated from model-generated content, and each retrieval step increases the agent's confidence in fabricated information without ever grounding in human-authored source.
What Was Observed
In semantic-search agent architectures over mixed corpora, failing to distinguish synthetic sources produces three primary failure modes:
- **Hallucination Amplification:** The agent retrieves LLM-generated summaries of hallucinated content, treats them as factual, and generates further summaries, compounding the hallucination.
- **Source Attribution Loss:** The agent cites a model-generated summary as if it were a human-authored source, misleading downstream consumers.
- **Coverage Illusion:** The agent's retrieval appears to have coverage (many results), but all results derive from a small set of synthetic seeds, hiding actual gaps in human-authored knowledge.
Recorded Elements
- **`source_authenticity_signature`:** Per result, the cryptographic classification of the source (human-authored, model-generated, or hybrid), signed by the source originator.
- **`synthetic_generation_depth`:** For model-generated content, the depth of the generation chain (e.g., "generated from human sources at depth 1" vs. "generated from other generated content at depth 3").
- **`human_source_anchor_hash`:** The cryptographic hash of the human-authored source that a synthetic document ultimately derives from, allowing the agent to trace synthetic content to its human origin.
- **`authenticity_diversity_metric`:** The fraction of retrieved results that reference human-authored sources, allowing the agent to ensure sufficient human grounding.
Condition of Validity
* **Applies when:** The corpus contains mixed human-authored and model-generated content, the agent relies on retrieval for decisions, and hallucination amplification is a real risk. * **Does not apply when:** The corpus is strictly human-authored (no synthetic contamination), or the agent's task is purely creative where synthetic grounding is acceptable.
Decision Boundary
- **Do the retrieved results contain any model-generated content?** If no, standard retrieval applies. If yes, proceed.
- **Is the `source_authenticity_signature` present for each result?** If no, the agent cannot distinguish authenticity. It must treat all results as unverified.
- **Does the `authenticity_diversity_metric` meet the minimum threshold (e.g., >50% human-anchored)?** If no, the agent's retrieval is over-synthetic. It must re-query with a filter for human-authored content.
- **Conversely, when can an agent retrieve synthetic content without human grounding?** Only when the task is explicitly creative (e.g., "generate a story inspired by X"), or when synthetic content is verifiably derived from human sources with `synthetic_generation_depth` = 1.
Operational Effect
- **Hallucination Containment:** Prevents the agent from amplifying hallucinations by tracking synthetic generation chains.
- **Source Attribution:** Ensures agents cite correct source types, preserving trust.
- **Coverage Accuracy:** Reveals when the agent's retrieval only appears complete because of synthetic content.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class AuthenticityClass(Enum):
HUMAN_AUTHORED = auto()
SYNTHETIC_DEPTH_1 = auto()
SYNTHETIC_DEPTH_2_PLUS = auto()
UNKNOWN = auto()
class SynthesisVerdict(Enum):
HUMAN_GROUNDED = auto()
SYNTHETIC_DEPTH_1_ACCEPTABLE = auto()
SYNTHETIC_DEPTH_EXCESSIVE = auto()
UNVERIFIED_SOURCES = auto()
@dataclass(frozen=True)
class SearchResult:
result_id: str
authenticity: AuthenticityClass
human_anchor_hash: str | None
source_signature: str | None
@dataclass(frozen=True)
class SynthesisPolicy:
min_human_grounding_ratio: float
allow_depth_1_synthetic: bool
@dataclass(frozen=True)
class SynthesisManifest:
verdict: SynthesisVerdict
directive: str
manifest_digest: str
class SyntheticSourceGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_results(
cls, results: tuple[SearchResult, ...], policy: SynthesisPolicy
) -> SynthesisManifest:
if not results:
raise ValueError("No results to evaluate.")
# Gate 1: Signature presence
for r in results:
if not r.source_signature:
return SynthesisManifest(
verdict=SynthesisVerdict.UNVERIFIED_SOURCES,
directive=f"HALT: Result {r.result_id} lacks source signature.",
manifest_digest=cls._hash(f"NO_SIG:{r.result_id}")
)
# Gate 2: Human grounding ratio
human_count = sum(1 for r in results if r.authenticity is AuthenticityClass.HUMAN_AUTHORED)
ratio = human_count / len(results)
# Gate 3: Depth 1 acceptance
depth_1_count = sum(1 for r in results if r.authenticity is AuthenticityClass.SYNTHETIC_DEPTH_1)
depth_2_plus_count = sum(1 for r in results if r.authenticity is AuthenticityClass.SYNTHETIC_DEPTH_2_PLUS)
# If sufficient human grounding, all accepted
if ratio >= policy.min_human_grounding_ratio:
digest = cls._hash(json.dumps({
"total": str(len(results)),
"human": str(human_count),
"ratio": f"{ratio:.2f}"
}, sort_keys=True))
return SynthesisManifest(
verdict=SynthesisVerdict.HUMAN_GROUNDED,
directive=f"PROCEED: {ratio:.2%} human grounding.",
manifest_digest=digest
)
# If depth 1 allowed and no depth 2+
if policy.allow_depth_1_synthetic and depth_2_plus_count == 0:
digest = cls._hash(json.dumps({
"total": str(len(results)),
"human": str(human_count),
"depth_1": str(depth_1_count),
"depth_2_plus": "0"
}, sort_keys=True))
return SynthesisManifest(
verdict=SynthesisVerdict.SYNTHETIC_DEPTH_1_ACCEPTABLE,
directive=f"PROCEED: Human grounding {ratio:.2%} below threshold, but only depth-1 synthetic.",
manifest_digest=digest
)
# Excessive synthetic
return SynthesisManifest(
verdict=SynthesisVerdict.SYNTHETIC_DEPTH_EXCESSIVE,
directive=f"HALT: Only {ratio:.2%} human grounding, {depth_2_plus_count} depth-2+ synthetic. Re-query with human filter.",
manifest_digest=cls._hash(f"SYNTHETIC:{ratio:.2f}")
)