Handoff Document Validation¶
Status: Active Last reviewed: 2026-02-12 Parent ADR: ADR-0.0.25 (Compounding Engineering & Session Handoff Contract) OBPI: OBPI-0.0.25-06
Overview¶
Session handoff documents must be validated before they can serve as reliable context for agent resume workflows. The validation module implements a fail-closed philosophy: every check returns a list of violations, and only an empty list means the document is clean.
Six validation checks run in sequence, with errors accumulated (not short-circuited) so that a single pass reveals all issues.
Validation Checks¶
1. Frontmatter Parsing¶
Extracts YAML frontmatter delimited by --- markers. Validates:
- Opening and closing
---delimiters are present - YAML is syntactically valid
- Content is a YAML mapping (not a list or scalar)
2. Frontmatter Schema¶
Validates the parsed frontmatter against HandoffFrontmatter (Pydantic model):
| Field | Type | Validation |
|---|---|---|
mode |
"CREATE" or "RESUME" |
Literal enum |
adr_id |
string | Matches ADR-X.Y.Z |
branch |
string | Required, non-empty |
timestamp |
string | ISO 8601 parseable |
agent |
string | Required, non-empty |
obpi_id |
string or null | Matches OBPI-X.Y.Z-NN |
session_id |
string or null | Optional |
continues_from |
string or null | Optional |
Extra fields are forbidden (extra="forbid"). Model is frozen (immutable after creation).
3. Placeholder Detection¶
Scans the document body (frontmatter stripped, HTML comments removed) for placeholder markers:
| Pattern | Examples |
|---|---|
TBD |
"TBD", "tbd" |
TODO |
"TODO: finish this" |
FIXME |
"FIXME later" |
PLACEHOLDER |
"PLACEHOLDER value" |
XXX |
"XXX needs work" |
CHANGEME |
"CHANGEME" |
... (standalone) |
Ellipsis on its own line |
Detection is case-insensitive and uses word boundaries to avoid false positives within longer words.
4. Secret Detection¶
Scans full content for potential leaked credentials:
| Pattern | Matches |
|---|---|
password= |
Password assignments |
secret= |
Secret assignments |
token= |
Token assignments |
api_key= |
API key assignments |
Bearer <token> |
Authorization headers |
PRIVATE KEY |
PEM key blocks |
sk-<20+ chars> |
OpenAI API keys |
ghp_<20+ chars> |
GitHub personal access tokens |
The sk- and ghp_ patterns use negative lookbehind (?<![a-zA-Z]) to avoid false positives (e.g., task-management does not match sk-).
5. Required Sections¶
Verifies all seven required ## section headings are present:
- Current State Summary
- Important Context
- Decisions Made
- Immediate Next Steps
- Pending Work / Open Loops
- Verification Checklist
- Evidence / Artifacts
Optional sections (e.g., "Environment State") are not checked.
6. Referenced File Existence¶
In the "Evidence / Artifacts" section, backtick-quoted strings that look like file paths (contain / or .) are resolved against the repository root. Missing files are reported.
Heuristics skip non-path content:
- Strings starting with
-,$,uv,git(commands) - Strings without
/or.(variable names, not paths)
Python API¶
from pathlib import Path
from gzkit.handoff_validation import (
HandoffFrontmatter,
parse_frontmatter,
validate_handoff_document,
)
content = Path("handoffs/session.md").read_text(encoding="utf-8")
# Structural parse (raises HandoffValidationError on missing delimiters
# or malformed YAML).
frontmatter = parse_frontmatter(content)
# Schema validation (raises pydantic.ValidationError on violation).
model = HandoffFrontmatter(**frontmatter)
print(model.mode, model.adr_id)
# Full fail-closed sweep — returns every violation as a list of strings.
errors = validate_handoff_document(content, Path("."))
for error in errors:
print(error)
Operational Validation¶
# Validate governance documents and surfaces
uv run gz validate --documents --surfaces
# Run interactive handoff interview flow
uv run gz interview handoff
Constants¶
| Constant | Value | Purpose |
|---|---|---|
HANDOFF_SCHEMA_VERSION |
"govzero.handoff.v1" |
Schema version identifier |
REQUIRED_SECTIONS |
7-element tuple | Required ## section headings |
Error Handling¶
HandoffValidationErroris raised byparse_frontmatter()for structural issues (missing delimiters, invalid YAML)pydantic.ValidationErroris raised byHandoffFrontmatterfor schema violationsvalidate_handoff_document()catches both and returns them as strings in the error list- All other validators return
list[str]— empty means clean, non-empty lists the violations
History¶
- 2026-04-14: Module implementation absorbed from
../airlineops/src/opsdev/governance/handoff_validation.pyvia OBPI-0.25.0-32. Adaptations: dual@coverslineage, CRLF normalization on every public validator for Windows line-ending safety. No functional or API changes relative to the absorbed source.
See Also¶
- Session Handoff Schema -- Schema specification
- Staleness Classification -- Multi-factor staleness system
- ADR-0.0.25 -- Architecture decision record
- Sources:
src/gzkit/handoff_validation.py - Tests:
tests/governance/test_handoff_validation.py