Match Criteria to Mission
If you require 3 quotes, your mission should explicitly ask for “at least 3 quotes.”
Looplia uses a hook-based validation system to ensure workflows complete all steps with quality outputs before finishing. This page covers how validation works and how to configure it.
When you define validate criteria on a workflow step, Looplia runs deterministic checks after each artifact is written. If validation fails, the workflow cannot complete until all criteria are satisfied.
Key concepts:
validated: falsevalidation.json in the sandbox tracks each step’s validation status┌─────────────────────────────────────────────────────────────────────┐│ VALIDATION LIFECYCLE │└─────────────────────────────────────────────────────────────────────┘
Write Tool PostToolUse Hook validation.json │ │ │ │ writes artifact │ │ ├──────────────────────────>│ │ │ │ │ │ ┌────────┴────────┐ │ │ │ post-write- │ │ │ │ validate.sh │ │ │ └────────┬────────┘ │ │ │ │ │ ┌────────┴────────┐ │ │ │ Read criteria │<───────────────────┤ │ │ from step │ │ │ └────────┬────────┘ │ │ │ │ │ ┌────────┴────────┐ │ │ │ validate.ts │ │ │ │ (deterministic │ │ │ │ checks) │ │ │ └────────┬────────┘ │ │ │ │ │ │ Update step.validated │ │ ├────────────────────────────>│ │ │ │ │ │ │ │ │ │
Stop Event Stop Hook validation.json │ │ │ │ workflow complete? │ │ ├──────────────────────────>│ │ │ │ │ │ ┌────────┴────────┐ │ │ │ Check all │<───────────────────┤ │ │ steps valid │ │ │ └────────┬────────┘ │ │ │ │ │ ┌─────────────────┴─────────────────┐ │ │ │ │ │ │ All validated? Any invalid? │ │ │ │ │ │ ▼ ▼ │ │ ✅ Allow stop ❌ Block stop │ │ (continue workflow) │Define criteria in your workflow’s validate field:
- id: summary skill: media-reviewer validate: required_fields: [contentId, headline, keyThemes] min_quotes: 3 min_key_points: 5 # ...Check that specific JSON fields exist in the output. Supports dot notation for nested fields.
| Property | Type | Description |
|---|---|---|
required_fields | string[] | List of field paths that must exist |
Examples:
# Simple fieldsvalidate: required_fields: [contentId, headline, tldr]
# Nested fields using dot notationvalidate: required_fields: [summary.headline, metadata.author, themes]Validation logic:
null or undefinedsummary.headline checks data.summary.headline)Require a minimum number of items in the importantQuotes array.
| Property | Type | Description |
|---|---|---|
min_quotes | number | Minimum items required in importantQuotes |
Example:
validate: min_quotes: 3 # Requires at least 3 quotesValidation logic:
data.importantQuotes array lengthRequire a minimum number of key points. Checks both bullets and keyPoints arrays, using the higher count.
| Property | Type | Description |
|---|---|---|
min_key_points | number | Minimum items required in bullets or keyPoints |
Example:
validate: min_key_points: 5 # Requires at least 5 bullets or key pointsValidation logic:
Math.max(data.bullets.length, data.keyPoints.length)Require a minimum number of outline sections. Used primarily with the writing-kit workflow.
| Property | Type | Description |
|---|---|---|
min_outline_sections | number | Minimum items required in suggestedOutline |
Example:
validate: min_outline_sections: 4 # Requires at least 4 outline sectionsValidation logic:
data.suggestedOutline array lengthRequire at least one hook in the artifact. Used for idea synthesis validation.
| Property | Type | Description |
|---|---|---|
has_hooks | boolean | When true, requires non-empty hooks array |
Example:
validate: has_hooks: true # Requires at least 1 hookValidation logic:
data.hooks array or data.ideas.hooks arrayEach sandbox contains a validation.json file tracking step completion:
{ "workflow": "writing-kit", "version": "1.2.0", "sandboxId": "article-2026-01-12-xk7m", "finalStepId": "writing-kit", "steps": { "summary": { "output": "outputs/summary.json", "validated": true }, "ideas": { "output": "outputs/ideas.json", "validated": true }, "writing-kit": { "output": "outputs/writing-kit.json", "validated": false } }}| Field | Description |
|---|---|
workflow | Workflow name |
version | Workflow version |
sandboxId | Current sandbox identifier |
finalStepId | Step ID used for final artifact extraction |
steps | Map of step ID to step state |
steps.<id>.output | Relative path to step output |
steps.<id>.validated | Whether step passed validation |
When validation fails, the system outputs which checks failed:
❌ Validation failed for step 'summary': - min_quotes: Found 1 quotes, need at least 3 - has_contentId: Missing required field: contentIdSolutions:
If the workflow keeps running after you think it’s complete:
# Check validation statecat ~/.looplia/sandbox/*/validation.jsonLook for steps with validated: false. These must be completed before the workflow can finish.
Validation only runs when:
validate field definedCheck that your workflow step has validation criteria:
- id: my-step skill: media-reviewer validate: # This is required! min_quotes: 3 output: ${{ sandbox }}/outputs/my-output.jsonFor nested fields, ensure you use dot notation:
# Wrong - checks for top-level "headline" fieldvalidate: required_fields: [headline]
# Correct - checks for nested "summary.headline"validate: required_fields: [summary.headline]Match Criteria to Mission
If you require 3 quotes, your mission should explicitly ask for “at least 3 quotes.”
Start Lenient
Begin with lower thresholds and increase as you tune your workflow.
Use Required Fields
Always validate that essential fields exist before marking a step complete.
Check Before Resume
Review validation.json before resuming to understand workflow state.