Streams

A stream is the fundamental unit of work in orchex. Each stream represents an independent task assigned to one LLM agent, with explicit file ownership and optional dependencies on other streams.

Definition

A stream is a named task with:

  • Files it owns — files it can create or modify (exclusive access)
  • Files it reads — files it can read but not modify (shared access)
  • Dependencies — other streams that must complete first
  • A plan — natural language instructions for the LLM agent
  • Setup commands — shell commands to run before execution
  • Verify commands — shell commands to run after execution

Stream Properties

Property Type Required Description
id string Yes Unique identifier (e.g., "auth-middleware")
name string Yes Human-readable name
owns string[] No Files this stream can create or modify
reads string[] No Files this stream can read (not modify)
deps string[] No Stream IDs that must complete before this stream runs
plan string No Natural language instructions for the LLM agent
setup string[] No Shell commands to run before execution
verify string[] No Shell commands to run after execution
timeoutMs number No Per-stream timeout override (milliseconds)
provider string No LLM provider override for this stream

Example

orchex.init({
  feature: "user-auth",
  streams: {
    "auth-types": {
      name: "Auth Type Definitions",
      owns: ["src/types/auth.ts"],
      plan: "Define TypeScript interfaces: User, Session, AuthToken, LoginRequest, LoginResponse"
    },
    "auth-middleware": {
      name: "Auth Middleware",
      owns: ["src/middleware/auth.ts"],
      reads: ["src/types/auth.ts"],
      deps: ["auth-types"],
      plan: "Create Express middleware that validates JWT tokens from the Authorization header",
      verify: ["npx tsc --noEmit"]
    },
    "auth-tests": {
      name: "Auth Tests",
      owns: ["tests/auth.test.ts"],
      reads: ["src/middleware/auth.ts", "src/types/auth.ts"],
      deps: ["auth-middleware"],
      plan: "Write vitest tests for the auth middleware. Test valid tokens, expired tokens, and missing headers.",
      verify: ["npx vitest run tests/auth.test.ts"]
    }
  }
});

This creates three streams that execute in three waves: types first, then middleware, then tests.

Stream Lifecycle

Every stream moves through these states:

pending → in_progress → complete
                ↓
              failed → (fix stream generated)
  1. pending — Waiting for dependencies to complete
  2. in_progress — LLM agent is executing the task
  3. complete — Task finished, verify commands passed
  4. failed — Execution or verification failed

When a stream fails, orchex's self-healing system categorizes the error and generates a targeted fix stream.

The Plan Field

The plan field is the most important property. It's the natural language instruction set that the LLM agent receives. A good plan is specific, actionable, and includes constraints:

Good Plans

plan: "Create an Express middleware function that:
1. Extracts the JWT from the Authorization header (Bearer scheme)
2. Verifies the token using jsonwebtoken.verify() with process.env.JWT_SECRET
3. Attaches the decoded user to req.user
4. Calls next() on success, returns 401 on failure
Do NOT import or use passport.js."

Bad Plans

plan: "Make auth work"  // Too vague

Tips for writing effective plans:

  • Be specific about the implementation approach
  • Include negative constraints — "Do NOT use X" prevents wrong patterns
  • Reference file paths — "Import User from src/types/auth.ts"
  • Specify the testing framework if relevant — "Use vitest, not jest"

Owns vs Reads

The distinction between owns and reads is central to orchex's safety model.

`owns` — Exclusive Write Access

Files listed in owns can be created, modified, or deleted by this stream. Only one stream can own a given file. If two streams try to own the same file, orchex.init rejects the configuration.

"api-routes": {
  owns: ["src/routes/api.ts", "src/routes/users.ts"],
  // This stream can write to both files
}

`reads` — Shared Read Access

Files listed in reads are included in the stream's context (the LLM can see their content), but the stream cannot modify them. Multiple streams can read the same file.

"api-routes": {
  reads: ["src/types/api.ts", "src/config.ts"],
  // The LLM sees these files but cannot change them
}

Why This Matters

Without ownership enforcement, parallel agents overwrite each other's work. Consider two streams running simultaneously:

Stream A writes src/config.ts → { port: 3000, db: "postgres" }
Stream B writes src/config.ts → { port: 3000, auth: true }

The last one to finish wins, and the other's changes are lost. With ownership, this conflict is caught at initialization time.

Setup and Verify Commands

Setup

Commands that run before the LLM agent starts. Use for installing dependencies or preparing the environment:

setup: ["npm install jsonwebtoken @types/jsonwebtoken"]

Verify

Commands that run after the LLM agent completes. If any verify command fails, the stream is marked as failed and self-healing kicks in:

verify: [
  "npx tsc --noEmit",
  "npx vitest run tests/auth.test.ts"
]

Common verify patterns:

  • Type checking: npx tsc --noEmit
  • Tests: npx vitest run tests/specific.test.ts
  • Linting: npx eslint src/file.ts
  • Build: npm run build

Stream Slicing Best Practices

A well-sliced stream has one atomic deliverable. If your stream description uses "and" between distinct concepts, split it.

Stream Verdict Why
auth-middleware (one middleware file) Good Single focused deliverable
auth-types (type definitions) Good Predictable structure
auth-feature (middleware + routes + tests + types) Split it Multiple distinct outputs

Heuristics

  • owns > 4 distinct files — Consider splitting. Each file needing different content should be separate
  • reads > 4 files — High synthesis complexity increases timeout risk
  • Expected output > 6,000 tokens — The LLM may struggle to produce everything in one shot
  • Code + tests — Keep together. They must match, and splitting them adds a dependency hop

Context Budget

Each stream has a token budget based on its owned and read files. If the total context exceeds the LLM provider's limit, orchex warns you during init or learn:

  • Soft limit — Warning: "Stream X is using 85% of context budget"
  • Hard limit — Error: "Stream X exceeds context limit, split into smaller streams"

See Context Budgets for details.