orchex learn: Turn Plans into Parallel Streams

orchex learn is orchex's flagship feature. Give it a markdown plan document, and it generates executable parallel stream definitions — complete with file ownership, dependency inference, and anti-pattern detection.

No other tool does this. You write a plan in natural language, and orchex turns it into a parallel execution graph.

What is orchex learn?

Traditional orchestration requires you to manually define every stream, its dependencies, file ownership, and verification commands. For a 10-stream feature, that's a lot of boilerplate.

orchex learn automates this:

Markdown plan document
        ↓
  orchex learn
        ↓
Stream definitions with:
  • File ownership (owns/reads)
  • Dependency inference
  • Wave ordering
  • Verification commands
  • Anti-pattern warnings

Before orchex learn

You manually write this:

orchex.init({
  feature: "user-auth",
  streams: {
    "auth-types": {
      name: "Auth Types",
      owns: ["src/types/auth.ts"],
      plan: "Define User, Session, AuthToken interfaces",
      verify: ["npx tsc --noEmit"]
    },
    "auth-middleware": {
      name: "Auth Middleware",
      owns: ["src/middleware/auth.ts"],
      reads: ["src/types/auth.ts"],
      deps: ["auth-types"],
      plan: "Create JWT validation middleware",
      verify: ["npx tsc --noEmit"]
    },
    // ... 8 more streams, all manually wired
  }
});

After orchex learn

You write a plan document, and orchex generates the stream definitions:

You: "Use orchex learn on docs/plans/auth-feature.md"

orchex parses the document, infers dependencies, and generates all stream definitions automatically.

Write Your First Plan

Create a markdown document with H2 headings for each deliverable. Each deliverable becomes a stream.

Plan Structure

# Feature: User Authentication

## Auth Type Definitions

- Create: `src/types/auth.ts`
- Read: `src/config.ts`

Define TypeScript interfaces for the auth system:
- `User` — id, email, role, createdAt
- `Session` — userId, token, expiresAt
- `AuthToken` — JWT payload structure

## Auth Middleware

- Create: `src/middleware/auth.ts`
- Read: `src/types/auth.ts`

Create Express middleware that:
1. Extracts JWT from Authorization header
2. Verifies token with jsonwebtoken
3. Attaches decoded user to req.user
4. Returns 401 on invalid/expired tokens

```typescript
import { Request, Response, NextFunction } from 'express';
import { AuthToken } from '../types/auth';

Auth Routes

  • Create: src/routes/auth.ts
  • Read: src/types/auth.ts
  • Read: src/middleware/auth.ts

Implement login and logout endpoints:

  • POST /login — validate credentials, return JWT
  • POST /logout — invalidate session
  • GET /me — return current user (protected)

Auth Tests

  • Create: tests/auth.test.ts
  • Read: src/middleware/auth.ts
  • Read: src/routes/auth.ts

Write vitest integration tests covering:

  • Valid login flow
  • Invalid credentials
  • Expired token handling
  • Protected route access

### Key Elements

1. **H2 headings** — Each `## Section` becomes one stream
2. **File markers** — `Create:` and `Modify:` → `owns`, `Read:` and `Import:` → `reads`
3. **Natural language plan** — The prose becomes the stream's `plan` field
4. **Code examples** — Import statements are analyzed for additional `reads` inference

## Run orchex learn

Ask your AI assistant to run learn on your plan:

Use orchex learn on docs/plans/auth-feature.md


### What orchex Does

1. **Parses** — Extracts H2 sections as deliverables
2. **Infers ownership** — `Create:` / `Modify:` markers become `owns`, `Read:` / `Import:` become `reads`
3. **Infers dependencies** — If Stream B reads a file owned by Stream A, a dependency edge is created
4. **Detects cycles** — Mutual file-ownership reads are automatically resolved. True cycles are reported as errors
5. **Validates paths** — Checks `owns`/`reads` paths against the filesystem, auto-corrects obvious mismatches
6. **Analyzes complexity** — Warns about streams with too many files, overly long plans, or context budget risks
7. **Generates streams** — Produces ready-to-execute stream definitions

### Output

orchex returns the generated streams for review:

```json
{
  "streams": {
    "auth-type-definitions": {
      "name": "Auth Type Definitions",
      "owns": ["src/types/auth.ts"],
      "reads": ["src/config.ts"],
      "deps": [],
      "plan": "Define TypeScript interfaces...",
      "verify": ["npx tsc --noEmit"]
    },
    "auth-middleware": {
      "name": "Auth Middleware",
      "owns": ["src/middleware/auth.ts"],
      "reads": ["src/types/auth.ts"],
      "deps": ["auth-type-definitions"],
      "plan": "Create Express middleware...",
      "verify": ["npx tsc --noEmit"]
    }
    // ...
  },
  "diagnostics": {
    "warnings": [],
    "streamCount": 4,
    "waveCount": 3,
    "estimatedTokens": 45000
  }
}

Review the output, then initialize and execute:

The streams look good. Initialize and execute with orchex.

Plan Document Structure

YAML Stream Blocks

For precise control, embed YAML stream definitions directly in your plan:

## Database Models

```yaml
id: db-models
owns:
  - src/models/user.ts
  - src/models/session.ts
reads:
  - src/config/database.ts
verify:
  - npx tsc --noEmit
  - npx vitest run tests/models.test.ts

Create Prisma-style models for User and Session...


YAML blocks take priority over inferred properties. Use them when you need exact control over stream configuration.

### File Markers

orchex recognizes these markers in plan content:

| Marker | Maps To | Description |
|--------|---------|-------------|
| `- Create: path` | `owns` | Stream creates this file |
| `- Modify: path` | `owns` | Stream modifies this file |
| `- Read: path` | `reads` | Stream reads this file |
| `- Import: path` | `reads` | Stream imports from this file |

### Import Analysis

orchex parses code blocks in your plan for `import` statements:

```typescript
import { User } from '../types/user';
import { validateEmail } from '../utils/validation';

These are automatically resolved to file paths and added to reads.

Dependency Inference

Dependencies are inferred from file ownership:

Stream A owns: ["src/types/auth.ts"]
Stream B reads: ["src/types/auth.ts"]
→ Stream B depends on Stream A

This means you rarely need to declare explicit dependencies — orchex figures them out from file references.

Cycle Resolution

When two streams mutually read each other's files, orchex detects the false cycle and resolves it automatically:

Stream A owns: ["src/api.ts"], reads: ["src/types.ts"]
Stream B owns: ["src/types.ts"], reads: ["src/api.ts"]
→ Mutual file-ownership cycle detected → Auto-resolved (edges dropped)

This works because the reads represent context (the LLM wants to see the file), not sequencing requirements. True cycles involving explicit deps are preserved and reported as errors.

Tips for Better Plans

1. Include Code Examples

Code examples in your plan are appended to the stream's instructions. They help the LLM understand exactly what you expect:

## Auth Middleware

```typescript
// Expected structure:
export function authMiddleware(req: Request, res: Response, next: NextFunction) {
  const token = req.headers.authorization?.split(' ')[1];
  // ...
}

### 2. Complete Your Reads Lists

Every file a stream imports from should appear in its plan as a `Read:` marker or in a code block's `import` statement. Missing reads mean the LLM won't see the file contents and will guess.

### 3. Use Negative Constraints

Tell the LLM what NOT to do. This prevents common mistakes:

```markdown
## Auth Service

Do NOT use passport.js — implement JWT validation directly.
Do NOT import from 'src/old-auth/' — that code is deprecated.

4. One Deliverable Per Section

Each H2 section should produce one focused output. If a section uses "and" between distinct concepts, split it:

# Bad: Two concepts in one section
## Auth and Logging
Create auth middleware and set up request logging...

# Good: Separate sections
## Auth Middleware
Create JWT validation middleware...

## Request Logging
Set up structured request logging...

5. Verify Your Plan Locally

Before running orchex learn, check:

  • Do all file paths exist (or will be created)?
  • Are there any circular dependencies?
  • Is each section focused on one deliverable?
  • Have you included code examples for complex sections?

Common Warnings

"Stream X has high file count"

The stream owns too many files. Split it into focused sub-streams:

⚠ Stream "full-feature" owns 7 files across 3 directories.
  Suggestion: Split into "feature-types", "feature-core", "feature-tests"

"Wave count approaches tier limit"

Your plan generates more waves than your tier allows:

⚠ Generated 9 waves. Pro tier limit is 10.
  Consider reducing dependency chains.

"Cycle detected"

Two or more streams have circular dependencies:

✗ Cycle detected: auth-routes → auth-middleware → auth-routes
  Break the cycle by removing one dependency or restructuring file ownership.

"Path not found"

A file reference in the plan doesn't match the filesystem:

⚠ Path "src/util/helpers.ts" not found.
  Auto-corrected to "src/utils/helpers.ts" (basename match).

Using init-plan

Not sure how to structure your plan? Use orchex init-plan to generate an annotated template:

Use orchex init-plan for feature "user-authentication"

This generates a starter plan document with inline comments explaining what the learn pipeline parses.

End-to-End Workflow

  1. Write your plan — Create a markdown document with H2 deliverables
  2. Run orchex learn — Parse the plan into stream definitions
  3. Review the output — Check streams, deps, and warnings
  4. Initializeorchex.init() with the generated streams
  5. Executeorchex.execute({ mode: "auto" })
  6. Monitororchex.status() to track progress

This workflow — plan → learn → execute — is the core orchex experience. Write your intent in markdown, and let orchex handle the parallel execution.

  • Streams — Understanding stream definitions
  • Waves — How dependencies determine wave ordering
  • Context Budgets — Token limits per provider
  • MCP Tools — Full tool reference including learn