Install
$ agentstack add skill-ethanolivertroy-compliance-trestle-skills-trestle-validation ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Trestle Validation and Troubleshooting
Validation Commands
Validate All Models
trestle validate -a
Validates every OSCAL model in the workspace. (-a is shorthand for --all; this skill uses -a throughout.)
What a clean run looks like: On a freshly initialized workspace with no models, trestle validate -a finds nothing to validate and exits successfully with little or no output. Silence is a pass, not a failure. Once models exist, a passing run reports each validated model with no ERROR lines and exits 0.
Validate by Type
trestle validate -t catalog -n my-catalog
trestle validate -t profile -n my-profile
trestle validate -t component-definition -n my-compdef
trestle validate -t system-security-plan -n my-ssp
trestle validate -t assessment-plan -n my-assessment
trestle validate -t assessment-results -n my-results
trestle validate -t plan-of-action-and-milestones -n my-poam
Validate Specific File
trestle validate -f catalogs/my-catalog/catalog.json
Common Validation Errors
Schema Validation Errors
| Error | Cause | Fix | |-------|-------|-----| | Additional properties not allowed | Extra fields in JSON not in OSCAL schema | Remove the unexpected field | | required property 'uuid' missing | Missing required UUID field | Add a valid UUID (python -c "import uuid; print(uuid.uuid4())") | | is not of type 'string' | Wrong data type for a field | Check the OSCAL schema for expected type | | does not match pattern | Value doesn't match expected regex | Check format requirements (e.g., UUID, date-time) |
Workspace Structure Errors
| Error | Cause | Fix | |-------|-------|-----| | Not in a trestle workspace | No .trestle/ directory found | Run trestle init or navigate to workspace root | | Model not found | Model directory or file doesn't exist | Check spelling, ensure model was imported | | Duplicate model names | Two models share the same name | Rename one of the conflicting models |
Authoring Errors (Generate/Assemble)
| Error | Cause | Fix | |-------|-------|-----| | Markdown directory not found | Generated markdown directory missing | Run trestle author *-generate first | | YAML header parse error | Invalid YAML in markdown frontmatter | Fix YAML syntax in the control markdown file | | Unexpected markdown structure | Manual edits broke expected format | Regenerate markdown and reapply changes | | Parameter not found | Reference to non-existent parameter ID | Check parameter IDs in catalog/profile |
Import Errors
| Error | Cause | Fix | |-------|-------|-----| | Invalid OSCAL model | Source file isn't valid OSCAL | Validate the source file against OSCAL schema | | Model type mismatch | File content doesn't match -t flag | Verify the model type or omit -t for auto-detection | | File format not supported | Unsupported file extension | Use .json or .yaml/.yml |
Troubleshooting Guide
Step 1: Check Workspace Health
# Verify workspace
ls -la .trestle/
# Check config
cat .trestle/config.ini
# List all models
ls catalogs/ profiles/ component-definitions/ system-security-plans/ 2>/dev/null
Step 2: Run Full Validation
trestle validate -a 2>&1
Step 3: Check Individual Models
For each model that fails validation:
# Validate specific model with verbose output
trestle validate -t -n
# Check the model file directly
python -c "import json; json.load(open('/model.json'))"
Step 4: Common Fixes
Fix Invalid UUIDs
import uuid
print(str(uuid.uuid4()))
Replace any malformed or missing UUIDs with fresh ones.
Fix YAML Header Issues in Markdown
Common YAML problems in control markdown:
- Missing quotes around values with special characters
- Incorrect indentation (YAML requires consistent spaces, not tabs)
- Missing
---delimiters around frontmatter
Fix Broken Import References
Profiles reference catalogs by href. Check:
"imports": [
{ "href": "trestle://catalogs/nist-800-53/catalog.json" }
]
The referenced catalog must exist at that path in the workspace.
Fix Assembly Failures
If assemble fails after markdown edits:
- Check the YAML header hasn't been corrupted
- Verify no structural markdown elements were deleted (headers, dividers)
- Try regenerating and re-applying changes:
``bash trestle author ssp-generate --name --output -fresh `` Then diff the fresh output against your edited version.
Step 5: Reset and Recover
If a model is badly corrupted:
- Check if
dist/has a previously assembled good copy - Re-import from the original source
- Use git history to recover previous versions
Validation Best Practices
- Validate after every change: Run
trestle validateafter imports, edits, and assemblies - Validate before committing: Add validation to your pre-commit workflow
- Use CI/CD validation: Run
trestle validate -ain pipelines - Keep backups: Assemble to
dist/regularly as validated snapshots - Version control: Use git to track all changes to OSCAL models
- One format per directory: Don't mix JSON and YAML in the same model directory
Error Message Reference
Trestle validation errors follow this pattern:
ERROR: [model_type] [model_name]: [error_description]
When reporting issues:
- Include the full error message
- Note which command triggered the error
- Provide the trestle version (
trestle version) - Include the Python version (
python --version)
What Each Validator Checks
Trestle includes several specialized validators that go beyond basic schema validation:
| Validator | What It Checks | What It Misses | When to Use | |-----------|---------------|----------------|-------------| | duplicates | Duplicate UUIDs within a single model | Cross-model UUID collisions | After manual UUID edits or model merges | | refs | Internal UUID cross-references resolve (e.g., a finding's related-observations points to a real observation UUID) | References to external models | After editing assessment-results or POA&M files with UUID references | | links | href values point to files and resources that exist | Whether the linked content is valid OSCAL | After restructuring workspace directories or renaming files | | catalog | Catalog-specific structure: valid groups, controls, parameters, and back-matter | Semantic correctness of control text | After importing or manually editing catalogs | | rules | Component-definition rule consistency: rule IDs, parameter references, and control mappings | Whether rules are actually testable | After csv-to-oscal-cd or manual component-definition edits |
Run specific validators with:
trestle validate -t -n
All validators run automatically as part of trestle validate -a.
Validating Split Files
After using trestle split, individual fragment files are not standalone valid OSCAL documents. Validation must follow the correct workflow:
- Never validate mid-split — a split model's root file references child files via the trestle split convention. The individual pieces won't pass schema validation on their own.
- Always merge before validating:
``bash trestle merge -e catalog.* # merge all split parts back trestle validate -t catalog -n my-catalog ``
- Partial sanity check — while you shouldn't schema-validate split files, you can verify they are valid JSON:
``bash python -c "import json, pathlib; [json.loads(p.read_text()) for p in pathlib.Path('.').rglob('*.json')]" ``
- Pattern: The correct workflow is always split → edit → merge → validate. Never skip the merge step before validation.
CI/CD Validation Patterns
CI/CD integration is optional for initial testing and evaluation. Running trestle validate -a locally is sufficient while you explore the workflows; add the pipeline patterns below once models are under version control and changing regularly.
GitHub Actions Workflow
name: OSCAL Validation
on:
pull_request:
paths:
- 'catalogs/**'
- 'profiles/**'
- 'component-definitions/**'
- 'system-security-plans/**'
- 'assessment-results/**'
- 'plan-of-action-and-milestones/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install trestle
run: pip install compliance-trestle
- name: Initialize trestle workspace
run: |
cd ${{ github.workspace }}
trestle init --govdocs
- name: Validate all OSCAL models
run: |
trestle validate -a 2>&1 | tee validation-report.txt
if grep -q "ERROR" validation-report.txt; then
echo "::error::OSCAL validation failed"
exit 1
fi
- name: Validate governed docs
run: trestle author docs validate -tn policies -hv
- name: Upload validation report
if: always()
uses: actions/upload-artifact@v4
with:
name: validation-report
path: validation-report.txt
Pre-commit Hook
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: trestle-validate
name: Validate OSCAL models
entry: bash -c 'trestle validate -a'
language: system
pass_filenames: false
files: '\.(json|yaml|yml)$'
Tip: For faster feedback during development, validate only the model you changed:
trestle validate -t system-security-plan -n my-ssp
Reserve trestle validate -a for CI/CD pipelines.
Validation After Assessment and POA&M Edits
Assessment results and POA&M documents use JSON-based workflows (split/merge rather than generate/assemble). Validation is critical after every merge because these models have dense UUID cross-references.
Common Assessment Validation Issues
| Issue | Cause | Fix | |-------|-------|-----| | Missing import-ap href | Assessment results must reference an assessment plan | Set import-ap.href to a valid path (e.g., trestle://assessment-plans/my-plan/assessment-plan.json) | | Findings without target.status | Every finding needs a determination status | Add target.status.state with value satisfied or not-satisfied | | Orphaned observation UUIDs | A finding references an observation that was deleted | Update the finding's related-observations list or restore the observation |
Common POA&M Validation Issues
| Issue | Cause | Fix | |-------|-------|-----| | Broken observation UUID references | POA&M item references a non-existent observation | Check poam-items[].related-observations UUIDs match actual observations | | Broken risk UUID references | POA&M item references a non-existent risk | Check poam-items[].related-risks UUIDs match actual risks in the model | | Missing import-ssp href | POA&M must reference its parent SSP | Set import-ssp.href to the SSP path |
Tip: Always validate with the specific type for faster feedback:
trestle validate -t assessment-results -n my-results
trestle validate -t plan-of-action-and-milestones -n my-poam
Cross-References
- trestle-authoring-workflow: The generate → assemble cycle where validation catches structural errors before they propagate
- trestle-assessment: JSON-based assessment-results workflow where
refsvalidation is essential - trestle-poam: JSON-based POA&M workflow with dense UUID cross-references requiring
refsandduplicatesvalidation - trestle-governance: Combining OSCAL schema validation with document structure validation for complete coverage
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ethanolivertroy
- Source: ethanolivertroy/compliance-trestle-skills
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.