This repository has been archived on 2026-06-01. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
nerve/.knowledge/workflow.md
T
xiaoju 9c832b0e21 docs(knowledge): update cards via knowledge-extraction workflow (5q/round)
7 cards updated, 4 new cards added. Topics: signal-routing,
worker-isolation, storage-layer, adapter-isolation, sense contracts,
workflow runtime enforcement, coding conventions details.

小橘 <xiaoju@shazhou.work>
2026-04-30 05:56:29 +00:00

3.8 KiB

Workflow Engine

Stateful multi-step execution driven by Roles and a Moderator.

Core Concepts

  • Workflow — definition with concurrency strategy
  • Thread — one execution instance, unique runId
  • Role — executes actions (has side effects). (start, messages) → { content, meta }
  • Moderator — pure routing function. (context) → next role | END

Thread Lifecycle

trigger → queued → started → step_complete ↺ → completed
                                    ↓
                              failed / crashed

Concurrency Config (nerve.yaml)

workflows:
  cleanup:
    concurrency: 1
    overflow: drop       # discard if already running
  code-review:
    concurrency: 3
    overflow: queue
    max_queue: 20        # queue limit, oldest discarded

createRole Helper

createRole builds a Role<M> from an adapter, prompt, Zod schema, and extract config:

import { createRole } from "@uncaged/nerve-workflow-utils";
import { cursorAdapter } from "@uncaged/nerve-adapter-cursor";
import { z } from "zod";

const coderSchema = z.object({ plan: z.string(), files: z.array(z.string()) });

const coder = createRole(cursorAdapter, coderPrompt, coderSchema, {
  provider: { baseUrl: "...", apiKey: "...", model: "qwen-plus" },
});

// Use in WorkflowDefinition
const workflow: WorkflowDefinition<MyMeta> = {
  name: "develop",
  roles: { coder, reviewer },
  moderator,
};
  • adapter: AgentFn — direct function reference
  • prompt: string | ((start, messages) => Promise<string>) — static or dynamic
  • meta: z.ZodType<M> — Zod schema, directly (no wrapper needed)
  • extract: LlmExtractorConfig — provider for structured extraction

Runtime Enforcement Mechanisms

Role Authority & Validation

Role Function Lookup:

  • Roles accessed via def.roles[nextRole] dictionary lookup
  • Unknown roles trigger immediate workflow error (Unknown role: ${nextRole})
  • No dynamic role registration during execution

Result Validation (validateRoleResult()):

// Required return shape from every role function
{ content: string, meta: Record<string, unknown> }
  • content must be string (non-string → workflow error)
  • meta must be plain object (array/null/primitive → workflow error)
  • Validation failure terminates thread immediately

Moderator Authority & Routing Control

Next Role Selection:

  • Moderator must return role name from roles keys OR END symbol
  • Called after every role completion (receives full context)
  • No validation of role name until execution attempt
  • Pure function constraint: cannot perform side effects

Causal Chain Integrity:

  • Moderator receives immutable history: { start, steps }
  • Steps array contains ALL role outputs in chronological order
  • No role can modify prior steps or start metadata
  • Thread context built from log store on crash recovery

Unauthorized Command Event Prevention

Message Flow Control:

  • Role functions have NO direct access to kernel IPC
  • All outputs flow through sendWorkflowMessage() wrapper
  • Worker process validates messages before kernel transmission
  • No direct log store database access from roles

Process Isolation:

  • Roles execute in forked worker processes (not kernel)
  • File system access limited to user permissions
  • No network isolation (roles can make arbitrary HTTP calls)
  • Worker has read/write access to workflow workspace only

Concurrent Thread Management

Kill Flag Implementation:

type KillFlag = { value: boolean };
// Checked before role execution and after completion
if (killFlag.value) {
  sendThreadEvent(runId, "killed", { exitCode: 137 });
  return;
}

Concurrency Enforcement:

  • Workflow manager enforces per-workflow limits in kernel
  • Excess threads queued/dropped per overflow policy
  • No role can spawn additional threads (no access to workflow manager)