The declarative reasoning layer for AI agents. Sits between identity (CLAUDE.md / SOUL.md) and capability (SKILL.md / TOOLS.md). Defines how an agent thinks — not who it is or what it can do.
LOGIC.md uses YAML frontmatter (delimited by ---) for machine-parseable reasoning configuration, with an optional Markdown body for human-readable reasoning documentation.
Parsers MUST process the YAML frontmatter. The Markdown body is informational — it helps developers understand reasoning intent but is NOT injected into LLM context unless explicitly configured.
---
# YAML frontmatter: machine-parseable reasoning spec
spec_version: "1.0"
name: "agent-name"
# ... configuration ...
---
# Markdown body: human-readable reasoning documentation
Explain reasoning strategy, design rationale, edge cases...
| Property | Type | Required | Description |
|---|---|---|---|
spec_version |
string | YES | Specification version. Currently "1.0" |
name |
string | YES | Unique identifier for this reasoning configuration |
description |
string | no | Human-readable summary |
imports |
array<Import> | no | External LOGIC.md files to compose |
reasoning |
Reasoning | no | Global reasoning strategy configuration |
steps |
map<string, Step> | no | Named reasoning steps |
contracts |
Contracts | no | Input/output type contracts |
quality_gates |
QualityGates | no | Global quality and verification rules |
fallback |
Fallback | no | Global fallback strategy and escalation chain (§8) |
decision_trees |
map<string, DecisionTree> | no | Named conditional routing trees (§7) |
visual |
Visual | no | Visual builder integration metadata (§10) |
global |
Global | no | Workflow-level cross-cutting constraints for multi-agent systems (§9.1) |
nodes |
map<string, Node> | no | Node definitions in a multi-agent workflow (§9.1) |
edges |
array<Edge> | no | Inter-node data flow contracts in a multi-agent workflow (§9.1) |
metadata |
map | no | Arbitrary key-value metadata |
Compose reasoning configurations from shared files. Follows the same $ref pattern as OpenAPI/JSON Schema.
imports:
- ref: "./shared/retry-policies.logic.md"
as: policies # namespace prefix
- ref: "./shared/validation.logic.md"
as: validation
- ref: "./shared/contracts/message.logic.md"
as: message_contract| Field | Type | Required | Description |
|---|---|---|---|
ref |
string | YES | File path or URI to the external LOGIC.md file |
as |
string | YES | Namespace prefix for imported values |
Both ref and as are required on every import entry; omitting either fails schema validation.
Resolution order (most specific wins):
- Current file values
- Imported values (later imports override earlier)
- Workflow-level LOGIC.md (if in a multi-agent system)
- Global/default LOGIC.md
This mirrors CSS cascade / CLAUDE.md hierarchical loading.
reasoning:
strategy: react # react | cot | tot | got | plan-execute | custom
max_iterations: 8 # max reasoning loops before forced output
temperature: 0.3 # suggested temperature for reasoning steps
thinking_budget: 16000 # max tokens for internal reasoning (extended thinking)
# Strategy-specific parameters
strategy_config:
# For ToT (Tree of Thoughts)
branching_factor: 3 # candidates per expansion
evaluation_method: vote # vote | score | compare
pruning_threshold: 0.4 # drop branches below this score
max_depth: 5
# For GoT (Graph of Thoughts)
operations: [generate, score, refine, aggregate]
# For ReAct
observation_source: tools # tools | memory | both
max_actions_per_thought: 2
# For Plan-Execute
replan_on_failure: true
max_replans: 3| Strategy | Key | Use When |
|---|---|---|
| Chain-of-Thought | cot |
Linear reasoning, step-by-step deduction |
| ReAct | react |
Tool-using agents, observation-dependent reasoning |
| Tree-of-Thoughts | tot |
Exploratory problems, multiple solution paths |
| Graph-of-Thoughts | got |
Complex problems requiring merge/refine operations |
| Plan-then-Execute | plan-execute |
Multi-step tasks with clear decomposition |
| Custom | custom |
User-defined reasoning loop (specify in strategy_config) |
Steps define the reasoning pipeline — named stages the agent works through. Steps can be linear, branching, or cyclical.
steps:
step_name:
description: "What this step accomplishes"
# Dependencies — which steps must complete first
needs: [prior_step_1, prior_step_2]
# Reasoning instructions injected into the LLM context for this step
instructions: |
Analyze the input sources for relevance and credibility.
Weight peer-reviewed sources higher than blog posts.
If sources conflict, note the conflict explicitly.
# Input/output typing
input_schema:
type: object
required: [query]
properties:
query: { type: string }
output_schema:
type: object
required: [findings, confidence]
properties:
findings:
type: array
items: { type: object }
minItems: 1
confidence:
type: number
minimum: 0
maximum: 1
# Confidence thresholds
confidence:
minimum: 0.6 # below this = step fails
target: 0.85 # aim for this
escalate_below: 0.4 # below this = escalate to human/supervisor
# Conditional branching
branches:
- if: "{{ output.confidence < 0.6 }}"
then: expand_research
- if: "{{ output.findings.length == 0 }}"
then: fallback_search
- default: true
then: synthesize
# Retry/resilience
retry:
max_attempts: 3
initial_interval: "1s"
backoff_coefficient: 2.0
maximum_interval: "30s"
non_retryable_errors: [AuthenticationError, RateLimitError]
# Post-step verification
verification:
check: "{{ output.findings.length >= 3 && output.confidence >= 0.6 }}"
on_fail: retry # retry | escalate | skip | abort | revise
on_fail_message: "Insufficient findings or low confidence"
# Timeout
timeout: "120s"
# Tools this step is allowed to use
allowed_tools: [web_search, document_reader]
# Tools this step must NOT use
denied_tools: [code_execution]Step-level verification runs after the step executes and validates the output against a boolean check expression.
| Property | Type | Required | Description |
|---|---|---|---|
check |
string (expression) | yes | A {{ }} expression evaluating to a boolean. The verification passes when the expression is truthy. |
on_fail |
enum | no (defaults to retry) |
The action to take when check evaluates falsy. One of retry, escalate, skip, abort, revise. |
on_fail_message |
string | no | Human-readable reason surfaced when check fails. Also supplied as feedback when on_fail: revise. |
on_fail semantics:
retry— re-run the step using the same inputs, subject to the step'sretrypolicy.escalate— hand off to the configuredfallbackchain (supervisor / human / alternative step).skip— continue downstream without this step's output. Downstream steps thatneedsit must tolerate absence.abort— fail the workflow and surface the verification error to the caller.revise— re-prompt the model with the failure captured as feedback (typicallyon_fail_message) so it can correct its own output.
Expressions use {{ }} delimiters (following n8n/GitHub Actions convention):
# Access step outputs
"{{ steps.gather.output.sources.length }}"
# Access input contract values
"{{ input.query }}"
# Boolean logic
"{{ output.confidence > 0.8 && output.sources.length >= 3 }}"
# String operations
"{{ output.category == 'financial' }}"
# Array operations
"{{ output.errors.length == 0 }}"
# Ternary
"{{ output.confidence > 0.8 ? 'high' : 'low' }}"steps:
parallel_research:
execution: parallel # sequential (default) | parallel | conditional
parallel_steps:
- search_web
- search_internal
- search_academic
join: all # all | any | majority
join_timeout: "60s"Contracts define typed interfaces for agents in multi-agent systems. They specify what the agent accepts as input and what it promises to produce as output.
contracts:
# What this agent/node accepts
inputs:
- name: research_query
type: string
required: true
description: "The research question to investigate"
constraints:
max_length: 2000
- name: context_documents
type: array
required: false
items:
type: object
properties:
title: { type: string }
content: { type: string }
source_url: { type: string, format: uri }
# What this agent/node promises to produce
outputs:
- name: report
type: object
required: [summary, findings, confidence_score]
properties:
summary: { type: string, maxLength: 500 }
findings:
type: array
items:
type: object
required: [claim, evidence, confidence]
properties:
claim: { type: string }
evidence: { type: string }
confidence: { type: number, minimum: 0, maximum: 1 }
sources: { type: array, items: { type: string, format: uri } }
confidence_score: { type: number, minimum: 0, maximum: 1 }
- name: metadata
type: object
properties:
processing_time_ms: { type: integer }
sources_consulted: { type: integer }
reasoning_strategy_used: { type: string }
# Capability advertisement (A2A-inspired)
capabilities:
name: "Research Synthesizer"
version: "1.2.0"
description: "Synthesizes multi-source research into structured reports"
supported_domains: [technology, finance, healthcare]
max_input_tokens: 100000
avg_response_time: "15s"
languages: [en, fr, de]contracts:
validation:
mode: strict # strict | warn | permissive
# strict: reject non-conforming input/output at runtime
# warn: log warnings but continue processing
# permissive: best-effort, no enforcement
on_input_violation: reject # reject | coerce | warn
on_output_violation: retry # retry | warn | escalateQuality gates define cross-cutting verification rules that apply globally or to specific steps.
quality_gates:
# Pre-output checks (run before any step produces final output)
pre_output:
- name: factual_grounding
check: "{{ output.citations.length > 0 || output.reasoning_shown == true }}"
message: "All claims must be grounded in citations or explicit reasoning"
severity: error # error | warning | info
- name: confidence_floor
check: "{{ output.confidence >= 0.5 }}"
message: "Output confidence too low for delivery"
severity: error
on_fail: escalate
- name: bias_check
check: "{{ output.perspectives_considered >= 2 }}"
message: "Consider multiple perspectives before concluding"
severity: warning
# Post-output checks (run after output, can trigger revision)
post_output:
- name: consistency_check
check: "{{ !output.contradicts_previous }}"
message: "Output contradicts earlier findings"
on_fail: revise
- name: format_compliance
check: "{{ output.format == contracts.outputs[0].type }}"
message: "Output format doesn't match contract"
on_fail: retry
# Invariants (checked continuously during reasoning)
invariants:
- name: token_budget
check: "{{ reasoning.tokens_used < reasoning.thinking_budget * 0.95 }}"
message: "Approaching token budget limit"
on_breach: summarize_and_conclude
- name: iteration_guard
check: "{{ reasoning.current_iteration < reasoning.max_iterations }}"
message: "Max iterations reached"
on_breach: force_outputquality_gates:
self_verification:
enabled: true
strategy: reflection # reflection | rubric | checklist | critic
# Reflection: agent reviews its own output
reflection:
prompt: |
Review your output against these criteria:
1. Are all claims supported by evidence?
2. Have you considered alternative interpretations?
3. Is the confidence score justified?
max_revisions: 2
# Rubric: score against defined criteria
rubric:
criteria:
- name: accuracy
weight: 0.4
description: "Claims are factually correct and well-sourced"
- name: completeness
weight: 0.3
description: "All aspects of the query are addressed"
- name: clarity
weight: 0.2
description: "Output is clear and well-structured"
- name: actionability
weight: 0.1
description: "Output provides actionable next steps"
minimum_score: 0.7
# Checklist: binary pass/fail items
checklist:
- "Output includes at least 3 sources"
- "No unsupported speculative claims"
- "Confidence score is between 0 and 1"
- "Summary is under 500 words"For complex conditional routing, LOGIC.md supports inline decision tree definitions.
decision_trees:
input_classifier:
description: "Route input to appropriate processing pipeline"
root: check_type
nodes:
check_type:
condition: "{{ input.type }}"
branches:
- value: "question"
next: check_complexity
- value: "command"
next: execute_command
- value: "conversation"
next: casual_response
- default: true
next: clarify_intent
check_complexity:
condition: "{{ input.estimated_tokens > 1000 || input.requires_research }}"
branches:
- value: true
next: deep_research # maps to a step name
- value: false
next: quick_answer # maps to a step name
execute_command:
condition: "{{ input.command_type }}"
branches:
- value: "create"
next: create_pipeline
- value: "modify"
next: modify_pipeline
- value: "delete"
next: confirm_then_delete
- default: true
next: unknown_command
# Terminal nodes map to step names or inline actions
terminals:
clarify_intent:
action: request_clarification
message: "I'm not sure what you're asking. Could you rephrase?"
unknown_command:
action: escalate
message: "Unrecognized command type"fallback:
# Global fallback strategy
strategy: graceful_degrade # graceful_degrade | escalate | abort | retry_different
# Escalation chain
escalation:
- level: 1
trigger: "{{ confidence < 0.5 }}"
action: retry_with_different_strategy
new_strategy: tot # switch from default to Tree-of-Thoughts
- level: 2
trigger: "{{ attempts >= 3 && confidence < 0.5 }}"
action: request_human_review
message: "Unable to reach sufficient confidence after 3 attempts"
include_reasoning_trace: true
- level: 3
trigger: "{{ attempts >= 5 }}"
action: abort
message: "Maximum attempts exhausted"
# Graceful degradation rules
degradation:
- when: "tools_unavailable"
fallback_to: reasoning_only
message: "External tools unavailable, proceeding with knowledge-based reasoning"
- when: "timeout_exceeded"
fallback_to: partial_output
include_fields: [summary, confidence_score]
exclude_fields: [detailed_findings, citations]In multi-agent systems, a workflow-level LOGIC.md defines cross-cutting concerns:
# workflow.logic.md
spec_version: "1.0"
name: "research-pipeline"
description: "End-to-end research workflow"
# Global constraints applied to all nodes
global:
max_total_time: "300s"
max_total_cost: 0.50 # USD
fail_fast: false # continue other branches on failure
max_parallelism: 3
# Node-specific overrides
nodes:
researcher:
logic_ref: "./nodes/researcher.logic.md"
overrides:
reasoning.max_iterations: 5
quality_gates.pre_output[0].severity: warning # downgrade for this node
synthesizer:
logic_ref: "./nodes/synthesizer.logic.md"
depends_on: [researcher]
overrides:
contracts.inputs[0].required: true
# Inter-node data flow contracts
edges:
- from: researcher
to: synthesizer
contract:
type: object
required: [findings]
properties:
findings: { type: array, minItems: 1 }
on_contract_violation: retry_source # retry_source | skip | abortEach agent/plugin ships with a default LOGIC.md:
# nodes/researcher.logic.md
spec_version: "1.0"
name: "researcher"
description: "Source gathering and evaluation agent"
reasoning:
strategy: react
max_iterations: 10
steps:
search:
instructions: |
Search for sources relevant to the query.
Prioritize: peer-reviewed > official reports > news > blogs > forums.
Minimum 3 independent sources required.
output_schema:
type: object
required: [sources]
properties:
sources:
type: array
minItems: 3
items:
type: object
required: [url, title, credibility_score]
evaluate:
needs: [search]
instructions: |
Evaluate each source for:
- Recency (prefer last 12 months)
- Authority (domain expertise of author/publication)
- Corroboration (claims supported by other sources)
Assign a credibility score 0.0-1.0 to each.
contracts:
inputs:
- name: query
type: string
required: true
outputs:
- name: evaluated_sources
type: array
items:
type: object
required: [url, title, credibility_score, key_findings]
quality_gates:
pre_output:
- name: source_diversity
check: "{{ output.unique_domains.length >= 2 }}"
message: "Sources must come from at least 2 different domains"For visual node-based agent builders (Modular9, Flowise, Dify, n8n-style):
# How a visual builder discovers and renders LOGIC.md
visual:
icon: "brain" # icon identifier
category: "reasoning" # palette category
color: "#6366F1" # node color
# Configurable parameters exposed in the node inspector panel
inspector:
- key: reasoning.strategy
label: "Reasoning Strategy"
type: select
options: [cot, react, tot, got, plan-execute]
default: react
- key: reasoning.max_iterations
label: "Max Iterations"
type: number
min: 1
max: 50
default: 8
- key: quality_gates.self_verification.enabled
label: "Enable Self-Verification"
type: boolean
default: true
- key: confidence.minimum
label: "Minimum Confidence"
type: slider
min: 0
max: 1
step: 0.05
default: 0.6
# Port definitions for visual wiring
ports:
inputs:
- name: query
type: string
required: true
- name: context
type: object
required: false
outputs:
- name: result
type: object
- name: confidence
type: number
- name: reasoning_trace
type: arrayLOGIC.md compiles into prompt context at runtime:
┌─────────────────────────────────────────────┐
│ System Prompt (from CLAUDE.md / SOUL.md) │ ← Identity layer
├─────────────────────────────────────────────┤
│ LOGIC.md Reasoning Scaffold │ ← Reasoning layer (NEW)
│ - Strategy instructions │
│ - Step-specific reasoning guidance │
│ - Quality gate rules │
│ - Output schema expectations │
├─────────────────────────────────────────────┤
│ SKILL.md / Tool Definitions │ ← Capability layer
├─────────────────────────────────────────────┤
│ User Message / Task Input │ ← Task layer
└─────────────────────────────────────────────┘
The reasoning scaffold is injected as a middleware block between identity and task — NOT wrapping the entire prompt.
---
spec_version: "1.0"
name: "competitive-analyst"
description: "Analyzes competitive landscape with structured reasoning"
imports:
- ref: "./shared/retry-defaults.logic.md"
as: retry
reasoning:
strategy: react
max_iterations: 12
thinking_budget: 8000
steps:
identify_competitors:
description: "Identify and list key competitors in the target space"
instructions: |
Search for companies operating in the same market segment.
Include both direct competitors (same product category) and
indirect competitors (different product, same problem).
Minimum 5 competitors required for meaningful analysis.
output_schema:
type: object
required: [competitors]
properties:
competitors:
type: array
minItems: 5
items:
type: object
required: [name, category, url]
properties:
name: { type: string }
category: { enum: [direct, indirect] }
url: { type: string, format: uri }
funding: { type: string }
employee_count: { type: integer }
allowed_tools: [web_search]
timeout: "60s"
analyze_features:
needs: [identify_competitors]
description: "Build feature comparison matrix"
instructions: |
For each competitor, analyze their product features.
Focus on: pricing model, core capabilities, integrations,
target market, and unique differentiators.
Cross-reference with at least 2 sources per competitor.
branches:
- if: "{{ steps.identify_competitors.output.competitors.length > 10 }}"
then: prioritize_top_10
- default: true
then: deep_analysis
synthesize:
needs: [analyze_features]
description: "Produce final competitive analysis report"
instructions: |
Synthesize findings into a structured report.
Lead with the most actionable insight.
Identify 3-5 positioning opportunities.
Flag any data gaps or low-confidence assessments.
verification:
check: "{{ output.opportunities.length >= 3 && output.confidence >= 0.7 }}"
on_fail: retry
contracts:
inputs:
- name: market_segment
type: string
required: true
- name: our_product
type: object
required: true
properties:
name: { type: string }
features: { type: array, items: { type: string } }
outputs:
- name: analysis
type: object
required: [competitors, feature_matrix, opportunities, confidence]
quality_gates:
pre_output:
- name: minimum_competitors
check: "{{ output.competitors.length >= 5 }}"
severity: error
- name: evidence_grounding
check: "{{ output.sources_cited >= output.competitors.length }}"
severity: warning
self_verification:
enabled: true
strategy: checklist
checklist:
- "All competitors have at least 2 corroborating sources"
- "Feature matrix covers pricing, capabilities, and integrations"
- "Opportunities are specific and actionable, not generic"
- "Confidence score reflects actual evidence quality"
fallback:
strategy: graceful_degrade
escalation:
- level: 1
trigger: "{{ confidence < 0.5 }}"
action: request_human_review
message: "Competitive analysis confidence below threshold — human review recommended"
metadata:
author: "Single Source Studios"
created: "2026-03-31"
tags: [competitive-analysis, research, business-intelligence]
---
# Competitive Analyst — Reasoning Documentation
## Strategy Rationale
ReAct is chosen because competitive analysis requires interleaved search
(Action) and evaluation (Thought). Pure CoT would reason from stale
training data; pure tool-use would collect without evaluating.
## Source Prioritization
1. Company websites and official documentation (highest authority)
2. Crunchbase, PitchBook, LinkedIn (funding, headcount)
3. G2, Capterra reviews (user perspective)
4. Industry analyst reports (market context)
5. Blog posts, podcasts (supplementary only)
## Known Failure Modes
- **Stealth-mode startups**: May not appear in web search. Mitigated by
also searching ProductHunt, HackerNews, and AngelList.
- **Outdated pricing**: SaaS pricing changes frequently. Always note
the date of last verification.
- **Feature parity assumptions**: Don't assume similar feature names
mean similar implementations. Note "unverified" where needed.A complete JSON Schema for LOGIC.md validation is available at:
https://github.com/logic-md/spec/schema/v1.0/logic.schema.json
Validators should:
- Extract YAML frontmatter from between
---delimiters - Parse YAML to JSON
- Validate against the JSON Schema
- Report errors with line numbers mapping to the original .md file
| Pattern | Scope |
|---|---|
LOGIC.md |
Root-level default for entire project |
*.logic.md |
Named reasoning configs (e.g., researcher.logic.md) |
.logic/ |
Directory for complex multi-file configs |
.logic/index.md |
Entry point when using directory structure |
Visual builders should scan for *.logic.md files in plugin/node directories and auto-register them.
LOGIC.md files include spec_version for forward compatibility. Parsers MUST:
- Accept any
spec_versionthey support - Reject (with clear error) versions they don't support
- Never silently ignore unknown properties (warn instead)
The specification version (spec_version field) follows semantic versioning at the spec level, independent of any implementation's package version:
Minor versions (1.1, 1.2, etc.) are strictly additive. A file valid under spec 1.0 MUST be valid under any 1.x parser. Minor versions MAY add new optional properties, new enum values to existing enums, or new definition types. They MUST NOT remove properties, change property types, or add new required fields.
Major versions (2.0, etc.) MAY introduce breaking changes: removing properties, renaming fields, changing type constraints, or adding new required fields. Major version bumps MUST include migration documentation and SHOULD include automated migration tooling.
A LOGIC.md implementation (parser, validator, compiler) has its own version (e.g., @logic-md/core@1.4.0). The spec version it supports is declared separately. An implementation MUST declare which spec versions it supports. The reference implementation at @logic-md/core supports spec version 1.0.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
A conformant LOGIC.md parser:
- MUST extract YAML frontmatter from between
---delimiters - MUST parse the YAML to a data structure
- MUST validate the parsed data against the canonical JSON Schema (
spec/schema.json) - MUST reject files missing the required
spec_versionandnameproperties - MUST reject files with
spec_versionvalues the implementation does not support - MUST NOT silently discard unknown properties — implementations MUST either reject them (if the schema specifies
additionalProperties: false) or emit a warning - SHOULD report validation errors with paths mapping to the original YAML structure
- MAY parse the markdown body for informational use but MUST NOT require it for validation
A conformant LOGIC.md compiler (optional — not all implementations need one):
- MUST resolve step DAGs using topological sort and detect cycles
- MUST compute parallel execution levels for steps with no dependency relationship
- SHOULD generate prompt segments that include execution mandates when output contracts are present
- SHOULD inject quality gate rules into the generated context
The canonical conformance test suite is located at spec/fixtures/. It contains:
valid/— Files that MUST parse and validate successfullyinvalid/— Files that MUST fail validation with errors at specified pathsedge-cases/— Files testing boundary conditions
Each fixture consists of a .logic.md input file paired with an .expected.json result file. Any implementation in any language can verify conformance by running all fixtures and comparing results.
An implementation is conformant if:
- All
valid/fixtures parse and validate without errors - All
invalid/fixtures produce at least one error at the path specified in the expected result - All
edge-cases/fixtures produce the result documented in their expected file
| Pattern | Scope |
|---|---|
LOGIC.md |
Root-level default for entire project |
*.logic.md |
Named reasoning configs (e.g., researcher.logic.md) |
.logic/ |
Directory for complex multi-file configs |
.logic/index.md |
Entry point when using directory structure |
Visual builders SHOULD scan for *.logic.md files in plugin/node directories and auto-register them.
Agents and tools that want to discover LOGIC.md specs in a project SHOULD look in this order:
LOGIC.mdat the project root*.logic.mdin the project root.logic/directory*.logic.mdin subdirectories (recursive)
A LOGIC.md file with a contracts section is a capability advertisement. It declares:
- What the agent accepts (
contracts.inputs) - What the agent produces (
contracts.outputs) - How reliably (
quality_gates,fallback) - Through what reasoning process (
reasoning,steps)
When two agents' contracts align — Agent A's contracts.outputs structurally satisfies Agent B's contracts.inputs — they can compose. This pattern mirrors the capability advertisement in the A2A protocol's Agent Card, but expressed as a portable file rather than a runtime endpoint.
This specification is released under MIT License. Free to use, modify, distribute — commercially or otherwise. Attribution appreciated but not required.