home / skills / zpankz / mcp-skillset / non-linear

non-linear skill

/non-linear

This skill orchestrates uncertainty-aware non-linear reasoning with recursive think-act-observe loops to synthesize multi-domain insights and validate findings

npx playbooks add skill zpankz/mcp-skillset --skill non-linear

Review the files below or copy the command above to add this skill to your agents.

Files (8)
SKILL.md
19.3 KB
---
name: non-linear
description: Uncertainty-aware non-linear reasoning system with recursive subagent orchestration. Triggers for complex reasoning, research, multi-domain synthesis, or when explicit commands `/nlr`, `/reason`, `/think-deep` are used. Integrates think skill (reasoning), agent-core skill (acting), and MCP tools (infranodus, exa, scholar-gateway) in recursive think→act→observe loops. Uses coding sandbox for execution validation and maintains deliberate noisiness via NoisyGraph scaffold. Supports `/compact` mode for abbreviated outputs and `/semantic` mode for rich exploration.
---

# Non-Linear Reasoning

Execute uncertainty-aware reasoning through recursive think→act→observe loops using Anthropic's orchestrator-worker pattern with effort scaling.

## Quick Reference

| Need | Go To |
|------|-------|
| Research orchestration | [references/RESEARCH-ORCHESTRATION.md](references/RESEARCH-ORCHESTRATION.md) |
| Subagent patterns | [references/SUBAGENTS.md](references/SUBAGENTS.md) |
| MCP integration | [references/MCP-INTEGRATION.md](references/MCP-INTEGRATION.md) |
| State persistence | [references/STATE-PERSISTENCE.md](references/STATE-PERSISTENCE.md) |
| NoisyGraph schema | [references/NOISY-GRAPH.md](references/NOISY-GRAPH.md) |
| Sandbox execution | [references/SANDBOX.md](references/SANDBOX.md) |

## Triggers

| Trigger | Mode | Effort Level |
|---------|------|--------------|
| `/nlr`, `/reason`, `/think-deep` | Full | Adaptive (1-10 subagents) |
| `/compact` | Abbreviated | Minimal (1-3 subagents) |
| `/semantic` | Exploratory | Maximum (5-10 subagents) |
| `/research [topic]` | Research | Full orchestrator-worker |
| Complex query auto-detect | Adaptive | Score-based scaling |

## Architecture: Orchestrator-Worker Pattern

Based on Anthropic's multi-agent research system architecture:

```
┌─────────────────────────────────────────────────────────────────────┐
│                      LEAD RESEARCHER (Orchestrator)                  │
│  • Analyzes query complexity → determines effort level              │
│  • Develops research strategy → saves to Memory                      │
│  • Spawns specialized subagents → coordinates parallel execution     │
│  • Synthesizes findings → handles citation attribution               │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐                │
│   │  MAPPER     │  │  SKEPTIC    │  │  SEARCHER   │    ...         │
│   │  SUBAGENT   │  │  SUBAGENT   │  │  SUBAGENT   │                │
│   └──────┬──────┘  └──────┬──────┘  └──────┬──────┘                │
│          │                │                │                        │
│          └────────────────┴────────────────┘                        │
│                           │                                         │
│                   ┌───────▼───────┐                                 │
│                   │    MEMORY     │  (State persistence)            │
│                   │  checkpoint   │                                 │
│                   └───────────────┘                                 │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
```

## Effort Scaling (Anthropic Pattern)

Query complexity determines subagent allocation:

| Complexity | Subagents | Tool Calls | Use Case |
|------------|-----------|------------|----------|
| Simple | 1 | 3-10 | Single fact-finding |
| Moderate | 2-4 | 10-30 | Multi-source synthesis |
| Complex | 5-10 | 30-100+ | Deep research, comparison |

### Complexity Classification

```python
def classify_effort(query: str, context: dict) -> EffortLevel:
    score = 0
    
    # Domain complexity
    domains = detect_domains(query)  # medical, legal, technical, etc.
    score += len(domains) * 2
    
    # Reasoning indicators
    if any(w in query.lower() for w in ['compare', 'analyze', 'synthesize']):
        score += 3
    if any(w in query.lower() for w in ['mechanism', 'pathway', 'causation']):
        score += 4
    
    # Stakes multiplier (medical/legal = high stakes)
    if 'medical' in domains or 'legal' in domains:
        score *= 1.5
    
    # Novelty (requires verification)
    if requires_current_information(query):
        score += 2
    
    return EffortLevel.from_score(score)
    # < 4: SIMPLE, 4-8: MODERATE, > 8: COMPLEX
```

## Core Workflow

### Phase 1: Initialize Lead Researcher

```python
# Extended thinking for strategy development
thoughtbox({
    thought: """
    LEAD RESEARCHER INITIALIZATION
    Query: {query}
    
    Strategy Development:
    1. Complexity assessment: {classify_effort(query)}
    2. Domain identification: {detect_domains(query)}
    3. Subagent allocation: {determine_subagents(effort_level)}
    4. Research plan: {develop_plan(query, context)}
    """,
    thoughtNumber: 1,
    totalThoughts: effort_level.max_iterations,
    nextThoughtNeeded: True,
    includeGuide: True
})

# Save plan to memory for context overflow recovery
checkpoint_state({
    "plan": research_plan,
    "subagents": allocated_subagents,
    "iteration": 0
})
```

### Phase 2: Spawn Subagents with Task Descriptions

Each subagent receives detailed instructions to prevent duplication:

```python
SUBAGENT_TEMPLATES = {
    "mapper": {
        "objective": "Extract entities, relationships, and structural gaps from {domain}",
        "output_format": {
            "entities": [{"label": str, "confidence": float, "evidence": list}],
            "relationships": [{"source": str, "target": str, "type": str}],
            "gaps": [{"description": str, "suggested_placeholder": str}]
        },
        "tool_guidance": "Use infranodus for graph analysis, exa for current info",
        "boundaries": "Focus on {domain} only. Do not search {excluded_domains}",
        "context": "{relevant_prior_findings}"
    },
    "skeptic": {
        "objective": "Challenge assumptions and quantify uncertainty for {topic}",
        "output_format": {
            "challenged_claims": [{"claim": str, "concern": str, "confidence_adjustment": float}],
            "missing_falsifiers": [str],
            "noise_budget_status": {"current": float, "target": float}
        },
        "tool_guidance": "Use Scholar Gateway for peer-reviewed counterevidence",
        "boundaries": "Only challenge claims with confidence > 0.7",
        "context": "{current_graph_state}"
    },
    "searcher": {
        "objective": "Gather evidence on {specific_question}",
        "output_format": {
            "findings": [{"fact": str, "source": str, "confidence": float}],
            "gaps_discovered": [str]
        },
        "tool_guidance": "Prioritize: Scholar Gateway > exa > web_search",
        "boundaries": "Max 5 tool calls. Return condensed findings only.",
        "context": "{search_focus_areas}"
    }
}

async def spawn_subagent(template_name: str, params: dict) -> SubagentResult:
    template = SUBAGENT_TEMPLATES[template_name]
    
    # Inject NoisyGraph reasoning framework
    system_prompt = f"""
    ## Subagent: {template_name}
    
    You are operating within the NoisyGraph reasoning framework.
    
    OBJECTIVE: {template['objective'].format(**params)}
    
    OUTPUT FORMAT: Return JSON matching:
    {json.dumps(template['output_format'], indent=2)}
    
    TOOL GUIDANCE: {template['tool_guidance']}
    
    BOUNDARIES: {template['boundaries'].format(**params)}
    
    UNCERTAINTY REQUIREMENTS:
    - Rate confidence 0-1 for each finding
    - Explicitly note assumptions
    - Flag low-confidence elements (≤0.5) for noise budget
    
    CONTEXT: {template['context'].format(**params)}
    """
    
    # Use extended thinking for reasoning trace
    result = await execute_with_thinking(system_prompt, params['query'])
    
    return parse_subagent_result(result, template['output_format'])
```

### Phase 3: Parallel Subagent Execution

```python
async def execute_subagents_parallel(
    subagent_configs: list[dict],
    scaffold: NoisyGraphScaffold
) -> list[SubagentResult]:
    """Execute subagents in parallel with isolated contexts."""
    
    # Emit spawn events
    for config in subagent_configs:
        await event_bus.publish({
            'type': 'nlr.subagent.spawned',
            'payload': {'agent_id': config['id'], 'type': config['type']}
        })
    
    # Parallel execution
    results = await asyncio.gather(*[
        spawn_subagent(config['type'], config['params'])
        for config in subagent_configs
    ], return_exceptions=True)
    
    # Handle failures gracefully
    valid_results = []
    for config, result in zip(subagent_configs, results):
        if isinstance(result, Exception):
            scaffold.self_correction.issues_found.append(
                f"Subagent {config['id']} failed: {result}"
            )
        else:
            valid_results.append(result)
    
    return valid_results
```

### Phase 4: NoisyGraph Integration

Build uncertainty-aware knowledge graph from subagent findings:

```python
def integrate_subagent_findings(
    scaffold: NoisyGraphScaffold,
    results: list[SubagentResult]
) -> None:
    """Integrate subagent findings into NoisyGraph scaffold."""
    
    for result in results:
        # Add entities as nodes
        for entity in result.get('entities', []):
            add_node(scaffold,
                label=entity['label'],
                description=entity.get('why_relevant', ''),
                node_type=infer_node_type(entity),
                confidence=entity['confidence'],
                evidence=entity.get('evidence', [])
            )
        
        # Add relationships as edges
        for rel in result.get('relationships', []):
            add_edge(scaffold,
                source_id=get_node_id(rel['source']),
                target_id=get_node_id(rel['target']),
                edge_type=EdgeType(rel['type']),
                description=rel.get('description', ''),
                strength=rel.get('strength', 0.5)
            )
        
        # Process gaps into placeholders
        for gap in result.get('gaps', []):
            add_placeholder(scaffold, gap)
        
        # Apply skeptic challenges
        for challenge in result.get('challenged_claims', []):
            apply_confidence_adjustment(scaffold, challenge)
```

### Phase 5: Self-Correction with Extended Thinking

```python
async def self_correct_with_reasoning(scaffold: NoisyGraphScaffold) -> None:
    """Run self-correction with explicit reasoning trace."""
    
    await thoughtbox({
        'thought': f"""
        SELF-CORRECTION PHASE
        
        Current State:
        - Nodes: {len(scaffold.graph.nodes)}
        - Edges: {len(scaffold.graph.edges)}
        - Topology ratio: {len(scaffold.graph.edges)/len(scaffold.graph.nodes):.2f}
        
        Checklist Evaluation:
        1. Duplicate labels: {check_duplicates(scaffold)}
        2. Dangling edges: {check_edge_integrity(scaffold)}
        3. Noise budget: {check_noise_budget(scaffold)}
        4. Falsifiability: {check_falsifiability(scaffold)}
        5. Topology target: {check_topology(scaffold)}
        
        Issues Found: {scaffold.self_correction.issues_found}
        
        Corrective Actions:
        {generate_corrective_actions(scaffold)}
        """,
        'thoughtNumber': scaffold.meta.iteration + 1,
        'totalThoughts': scaffold.meta.iteration_limit,
        'nextThoughtNeeded': True
    })
    
    # Apply corrections
    apply_corrections(scaffold)
```

### Phase 6: State Checkpoint

```python
def checkpoint_state(scaffold: NoisyGraphScaffold, checkpoint_id: str) -> None:
    """Save state for context overflow recovery."""
    
    checkpoint = {
        "id": checkpoint_id,
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "meta": scaffold.meta.__dict__,
        "graph_summary": {
            "node_count": len(scaffold.graph.nodes),
            "edge_count": len(scaffold.graph.edges),
            "topology_ratio": len(scaffold.graph.edges) / max(1, len(scaffold.graph.nodes)),
            "noise_ratio": calculate_noise_ratio(scaffold)
        },
        "key_findings": extract_key_findings(scaffold),
        "open_gaps": [g for g in scaffold.core.implied_relationships_and_gaps if not g.get('resolved')],
        "next_actions": scaffold.meta.get('next_actions', [])
    }
    
    # Save to filesystem for persistence
    save_checkpoint(checkpoint, f"/home/claude/nlr_checkpoints/{checkpoint_id}.json")
```

### Phase 7: Synthesis with Citation

```python
async def synthesize_findings(scaffold: NoisyGraphScaffold) -> SynthesisResult:
    """Final synthesis with proper citation attribution."""
    
    # Use extended thinking for synthesis
    synthesis = await thoughtbox({
        'thought': f"""
        FINAL SYNTHESIS
        
        Research Question: {scaffold.meta.topic}
        
        Key Findings (by confidence):
        {format_findings_by_confidence(scaffold)}
        
        Structural Analysis:
        - Central concepts: {identify_hubs(scaffold)}
        - Knowledge gaps: {identify_gaps(scaffold)}
        - Contradictions: {identify_contradictions(scaffold)}
        
        Uncertainty Summary:
        - High confidence (>0.8): {count_high_confidence(scaffold)} elements
        - Low confidence (≤0.5): {count_low_confidence(scaffold)} elements
        - Noise budget: {check_noise_budget(scaffold)}
        
        SYNTHESIS:
        [Integrate findings into coherent narrative with explicit uncertainty markers]
        
        RECOMMENDATIONS:
        [Identify areas requiring further research]
        """,
        'thoughtNumber': scaffold.meta.iteration,
        'totalThoughts': scaffold.meta.iteration,
        'nextThoughtNeeded': False,
        'includeGuide': True
    })
    
    # Process citations
    cited_synthesis = process_citations(synthesis, scaffold.graph.nodes)
    
    return SynthesisResult(
        synthesis=cited_synthesis,
        confidence=calculate_overall_confidence(scaffold),
        graph=scaffold.graph,
        uncertainties=extract_key_uncertainties(scaffold),
        recommendations=extract_recommendations(synthesis),
        trace=build_execution_trace(scaffold)
    )
```

## Mode Selection

### /compact Mode

Output format: `[NLR:i{iter}/{max}|n{nodes}|e{edges}|r{ratio}|c{conf}]`

```python
def compact_output(scaffold: NoisyGraphScaffold) -> str:
    return (
        f"[NLR:i{scaffold.meta.iteration}/{scaffold.meta.iteration_limit}|"
        f"n{len(scaffold.graph.nodes)}|"
        f"e{len(scaffold.graph.edges)}|"
        f"r{len(scaffold.graph.edges)/max(1,len(scaffold.graph.nodes)):.1f}|"
        f"c{calculate_confidence(scaffold):.2f}] "
        f"SYNTHESIS: {scaffold.synthesis[:200]}... "
        f"GAPS: {', '.join(scaffold.key_gaps[:3])}"
    )
```

### /semantic Mode

Full NoisyGraph JSON output with all subagent traces visible.

### /research Mode

Full orchestrator-worker pattern with maximum effort scaling.

## Integration Points

### Think Skill Integration

| Tool | Usage Pattern |
|------|---------------|
| `thoughtbox` | Extended reasoning with interleaved tool calls |
| `mental_models` | Framework selection per problem type |
| `notebook` | Computational validation |

### Agent-Core Integration

```typescript
const nlrConfig: SkillEventSystemConfig<'nlr'> = {
    skillName: 'nlr',
    displayName: 'NON-LINEAR-REASONING',
    groups: {
        orchestrator: defineEventGroup('orchestrator', {
            plan_created: event('plan_created'),
            effort_scaled: event('effort_scaled'),
            checkpoint_saved: event('checkpoint_saved')
        }),
        subagent: defineEventGroup('subagent', {
            spawned: event('spawned'),
            completed: event('completed'),
            failed: criticalEvent('failed')
        }),
        graph: defineEventGroup('graph', {
            node_added: event('node_added'),
            edge_added: event('edge_added'),
            self_corrected: event('self_corrected')
        }),
        synthesis: defineEventGroup('synthesis', {
            started: event('started'),
            completed: event('completed')
        })
    }
};
```

### MCP Tool Coordination

| Tool | Role in NLR |
|------|-------------|
| `infranodus:getGraphAndAdvice` | Structural gap detection, topic clustering |
| `infranodus:getGraphAndStatements` | Knowledge graph extraction |
| `exa:web_search_exa` | Current information retrieval |
| `exa:get_code_context_exa` | Technical documentation |
| `Scholar Gateway:semanticSearch` | Peer-reviewed literature |
| `atom-of-thoughts:AoT` | Deep atomic decomposition |

## Configuration

```python
NLR_CONFIG = {
    # Effort scaling
    "effort_levels": {
        "simple": {"subagents": 1, "max_tool_calls": 10, "iterations": 3},
        "moderate": {"subagents": 3, "max_tool_calls": 30, "iterations": 5},
        "complex": {"subagents": 7, "max_tool_calls": 100, "iterations": 9}
    },
    
    # NoisyGraph targets
    "noise_budget": 0.25,
    "topology_target": 4.0,
    "max_nodes": 60,
    "max_edges": 240,
    
    # Convergence
    "convergence_threshold": 0.95,
    "max_iterations": 9,
    
    # Checkpointing
    "checkpoint_interval": 3,
    "checkpoint_path": "/home/claude/nlr_checkpoints"
}
```

## Error Handling

```python
async def execute_with_recovery(scaffold: NoisyGraphScaffold) -> SynthesisResult:
    try:
        return await execute_nlr_loop(scaffold)
    except ContextOverflowError:
        # Load from checkpoint, spawn fresh subagents
        checkpoint = load_latest_checkpoint(scaffold.meta.topic)
        scaffold = restore_from_checkpoint(checkpoint)
        return await execute_nlr_loop(scaffold)
    except SubagentFailure as e:
        # Continue with remaining subagents
        scaffold.agents = [a for a in scaffold.agents if a.id != e.agent_id]
        return await execute_nlr_loop(scaffold)
    except MCPToolTimeout:
        # Graceful degradation with cached data
        return synthesize_with_partial_data(scaffold)
```

## References

- [references/RESEARCH-ORCHESTRATION.md](references/RESEARCH-ORCHESTRATION.md) - Orchestrator-worker pattern details
- [references/SUBAGENTS.md](references/SUBAGENTS.md) - Subagent specifications and task templates
- [references/STATE-PERSISTENCE.md](references/STATE-PERSISTENCE.md) - Checkpointing and recovery
- [references/MCP-INTEGRATION.md](references/MCP-INTEGRATION.md) - MCP tool coordination
- [references/NOISY-GRAPH.md](references/NOISY-GRAPH.md) - Complete NoisyGraph schema
- [references/SANDBOX.md](references/SANDBOX.md) - Code execution patterns

---

*Non-Linear Reasoning v2.0 - Orchestrator-Worker Pattern with Effort Scaling*

Overview

This skill is an uncertainty-aware non-linear reasoning system that runs recursive think→act→observe loops to handle complex, multi-domain problems. It orchestrates specialized subagents, integrates external MCP tools, and builds a NoisyGraph knowledge scaffold to represent findings with explicit confidence. Two compact modes (/compact and /semantic) let you switch between concise status outputs and rich exploratory synthesis.

How this skill works

On trigger (e.g., /nlr, /reason, /think-deep), the orchestrator assesses query complexity and spawns mapped subagents (mapper, skeptic, searcher, etc.) with isolated contexts. Subagents run in parallel, call MCP tools (infranodus, exa, scholar-gateway), and return structured outputs with confidence scores. The system integrates results into a NoisyGraph, performs self-correction through extended thinking, checkpoints state, and synthesizes final findings with citations and uncertainty summaries.

When to use it

  • When a question requires multi-step, multi-source synthesis across domains
  • For deep research tasks that need explicit uncertainty quantification and provenance
  • When you want recursive subagent orchestration or hypothesis testing
  • Use /compact for brief progress/status outputs
  • Use /semantic for broad, exploratory idea generation with rich traces

Best practices

  • Provide a clear research question and scope to limit domain drift
  • Flag high-stakes topics (medical/legal) so effort scaling increases scrutiny
  • Use the /compact mode for quick checks during long runs and /semantic when exploring possibilities
  • Review the NoisyGraph outputs and noted low-confidence nodes before acting on findings
  • Request checkpoints or export the graph to preserve context between sessions

Example use cases

  • Compare treatment mechanisms across recent literature with confidence-tagged findings
  • Synthesize multi-domain business intelligence combining web data and scholarly sources
  • Run a skeptic-driven audit of an internal claim to surface falsifiers and estimate noise budget
  • Explore new research directions with iterative subagent mapping and gap identification
  • Validate code snippets in the sandbox as part of a reasoning loop before recommending actions

FAQ

What triggers a full run vs compact mode?

Full runs start with /nlr, /reason, or /think-deep; /compact produces abbreviated status. /semantic raises effort and exploration depth.

How does uncertainty get represented?

Each finding and node carries a 0–1 confidence score; skeptics adjust confidences and low-confidence items are flagged in the noise budget.

Can the system run external tool calls?

Yes. Subagents are guided to use infranodus, exa, and Scholar Gateway according to role-specific tool guidance and call limits.

How are failures handled?

Parallel subagent failures are recorded in the scaffold self-correction log; valid results are synthesized and corrective actions are suggested.