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:

  1. **Hallucination Amplification:** The agent retrieves LLM-generated summaries of hallucinated content, treats them as factual, and generates further summaries, compounding the hallucination.
  2. **Source Attribution Loss:** The agent cites a model-generated summary as if it were a human-authored source, misleading downstream consumers.
  3. **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

  1. **`source_authenticity_signature`:** Per result, the cryptographic classification of the source (human-authored, model-generated, or hybrid), signed by the source originator.
  2. **`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").
  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.
  4. **`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

  1. **Do the retrieved results contain any model-generated content?** If no, standard retrieval applies. If yes, proceed.
  2. **Is the `source_authenticity_signature` present for each result?** If no, the agent cannot distinguish authenticity. It must treat all results as unverified.
  3. **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.
  4. **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

  1. **Hallucination Containment:** Prevents the agent from amplifying hallucinations by tracking synthetic generation chains.
  2. **Source Attribution:** Ensures agents cite correct source types, preserving trust.
  3. **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}")
        )