Validation Engine
The validation engine checks that the references in a prompt (document paths, section numbers, identifiers) actually resolve against a versioned knowledge base before the prompt reaches a model.
validate For: governance & controlIt is a pure framework: you supply an extractor that finds references and a resolver that checks them, and the engine orchestrates the layers and records the commit it validated against.
How it works
- Extract — your extractor finds candidate references in the prompt. No references means the prompt passes immediately.
- Resolve — your resolver checks each reference against the versioned
knowledge base and returns a
ValidationErrorfor anything that fails. - Semantic (optional) — if there are no errors, an optional
semantic_validatorcan add warnings based on the prompt’s meaning. - Stamp — the engine records the knowledge-base commit it validated against, so the result is reproducible.
Install
pip install briefcase-ai[validate]from briefcase.validation import PromptValidationEnginefrom briefcase.validation import ValidationError, ValidationErrorCodeValidate a Prompt
import re
from briefcase.validation import PromptValidationEnginefrom briefcase.validation import ValidationError, ValidationErrorCode
class HandbookExtractor: """Finds ``handbook/*.md`` paths and ``Section X.Y`` references in a prompt."""
_REF = re.compile(r"handbook/[\w/]+\.md|Section\s+[\d.]+")
def extract(self, prompt: str) -> list: return self._REF.findall(prompt)
class KnowledgeBaseResolver: """Resolves references against an allowlist of known documents."""
def __init__(self, known_references: set): self._known = known_references
def resolve_all(self, references: list) -> list: errors = [] for ref in references: if ref not in self._known: errors.append( ValidationError( code=ValidationErrorCode.REFERENCE_NOT_FOUND, message=f"Reference not found in knowledge base: {ref}", reference=ref, severity="error", layer="resolution", remediation="Add the document to the knowledge base or fix the reference.", ) ) return errors
class DemoKnowledgeBase: """Stand-in for VersionedClient.get_commit() so the example runs offline."""
def get_commit(self, repository: str, branch: str) -> str: return "demo0000000000000000000000000000000000000"
engine = PromptValidationEngine( extractor=HandbookExtractor(), resolver=KnowledgeBaseResolver( known_references={"handbook/onboarding.md", "Section 4.2.3"}, ), lakefs_client=DemoKnowledgeBase(), repository="knowledge-base", branch="main", mode="strict", # fail on errors)
prompt = """Follow the onboarding policy in handbook/onboarding.md and referenceSection 4.2.3 for account-setup steps. Also see handbook/missing.md."""
report = engine.validate(prompt)
print(report.status) # "failed" — handbook/missing.md is unknownprint(report.references_checked) # 3print(report.lakefs_commit[:8]) # "demo0000"
if report.has_errors: for error in report.errors: print(error.reference, "->", error.message) print(" fix:", error.remediation)In production, pass any versioned-data client (the bundled
briefcase.integrations.lakefs.VersionedClient, or your
own via the vcs protocol) as lakefs_client, to resolve references against a
live, version-controlled knowledge base. The engine calls
lakefs_client.get_commit(repository, branch) to stamp every report with the
commit it validated against.
Pluggable Protocols
You provide objects that satisfy two protocols.
# briefcase.validation exports these as runtime-checkable protocols; any object# with the right method signature satisfies them (no base class required).from typing import Protocol
# Extractor: find references in a prompt.class Extractor(Protocol): def extract(self, prompt: str) -> list: ...
# Resolver: check each reference, return a list of ValidationError.class Resolver(Protocol): def resolve_all(self, references: list) -> list: ...A resolver returns ValidationError objects. Errors with severity="error"
become report.errors; any other severity becomes report.warnings.
An optional third layer runs only when there are no errors: pass a
semantic_validator with a validate_semantic(prompt, references) -> list
method to attach warnings based on the meaning of the prompt.
class KeywordSemanticValidator: def validate_semantic(self, prompt: str, references: list) -> list: return [] # return ValidationError warnings based on the prompt's meaning
engine = PromptValidationEngine( extractor=HandbookExtractor(), resolver=KnowledgeBaseResolver(known_references=set()), lakefs_client=DemoKnowledgeBase(), repository="knowledge-base", semantic_validator=KeywordSemanticValidator(), # optional third layer)Validation Layers
flowchart LR
A["Prompt"] --> B["extractor.extract()"]
B -- "no refs" --> P["status: passed"]
B -- "refs found" --> C["resolver.resolve_all()"]
C --> D{"errors?"}
D -- "yes" --> F["status: failed"]
D -- "no" --> E["semantic_validator (optional)"]
E --> G["status: passed / warning"]
ValidationReport
validate() returns a ValidationReport.
| Field | Description |
|---|---|
status | "passed", "warning", or "failed" |
errors | List of ValidationError with severity="error" |
warnings | List of ValidationError with other severities |
references_checked | Number of references the extractor found |
validation_time_ms | Wall-clock validation time |
lakefs_commit | Commit SHA the validation ran against |
has_errors | True when errors is non-empty |
has_warnings | True when warnings is non-empty |
ValidationError
Each error carries structured remediation context.
ValidationError( code=ValidationErrorCode.REFERENCE_NOT_FOUND, message="Reference not found in knowledge base: handbook/missing.md", reference="handbook/missing.md", severity="error", layer="resolution", remediation="Add the document to the knowledge base or fix the reference.",)ValidationErrorCode is an enum of the conditions the engine reports:
| Code | Meaning |
|---|---|
INVALID_SYNTAX | Reference is malformed |
REFERENCE_NOT_FOUND | Reference does not exist in the knowledge base |
REFERENCE_AMBIGUOUS | Reference matches more than one document |
REFERENCE_GONE | Reference existed but was removed |
VERSION_MISMATCH | Reference resolves to an unexpected version |
SCHEMA_INVALID | Resolved document fails schema checks |
LAKEFS_UNAVAILABLE | The versioned knowledge base could not be reached |
Validation Modes
The mode argument controls how status is derived.
| Mode | Errors | Warnings only | Clean |
|---|---|---|---|
"strict" | failed | warning | passed |
"tolerant" | failed | passed | passed |
"warn_only" | passed | passed | passed |
Where this fits
Validation is a Control act: it stops a prompt with stale references before it runs, and stamps the commit it checked against so the result is reproducible. It pairs naturally with versioned retrieval.