SDK reference: validation & events
Validation
Section titled “Validation”validateDag(nodes)
Section titled “validateDag(nodes)”Validate a directed acyclic graph for correctness.
function validateDag(nodes: DagNode[]): DagValidationResult;DagNode:
interface DagNode { id: string; needs: string[];}DagValidationResult (discriminated union):
// Valid graph with topological sort order{ valid: true; sortedOrder: string[] }
// Cycle detected{ valid: false; error: 'cycle'; nodesInCycle: string[] }
// Job depends on itself{ valid: false; error: 'self-reference'; nodeId: string }
// Job depends on non-existent job{ valid: false; error: 'missing-dependency'; nodeId: string; missingDep: string }Checks (in order): self-references, missing dependencies, cycles (Kahn’s algorithm).
const result = validateDag([ { id: 'lint', needs: [] }, { id: 'test', needs: ['lint'] }, { id: 'deploy', needs: ['test'] },]);
if (result.valid) { console.log(result.sortedOrder); // ['lint', 'test', 'deploy']}Event definitions
Section titled “Event definitions”The defineEvent() helper creates typed event definitions with Zod validation schemas. Event definitions serve as contracts for custom event payloads used with ctx.emit() and kiciEvent().
defineEvent(name, schema)
Section titled “defineEvent(name, schema)”function defineEvent<T extends z.ZodTypeAny>(name: string, schema: T): EventDefinition<T>;Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | yes | Unique event name |
schema | z.ZodType | yes | Zod schema for payload validation |
Returns: EventDefinition<T> — a frozen event definition with name and schema.
import { defineEvent, z } from '@kici-dev/sdk';
const deployComplete = defineEvent( 'deploy-complete', z.object({ env: z.string(), version: z.string(), services: z.array(z.string()), }),);The z (Zod) module is re-exported from @kici-dev/sdk so you can define event schemas without adding Zod as a direct dependency.
Emitting events
Section titled “Emitting events”Workflow steps can emit custom events via ctx.emit(). Emitted events are delivered immediately (mid-workflow, not queued until completion) and can trigger other workflows that listen with kiciEvent(), workflowComplete(), or jobComplete() triggers.
ctx.emit(eventName, payload?, options?)
Section titled “ctx.emit(eventName, payload?, options?)”emit( eventName: string, payload?: Record<string, unknown>, options?: EventEmitOptions,): Promise<{ deliveryId: string }>;Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
eventName | string | yes | Name of the event to emit |
payload | Record<string, unknown> | no | Event payload data |
options.target | { repos?: string[] } | no | Target specific repos for cross-repo delivery |
Returns: Promise<{ deliveryId: string }> — a delivery receipt after the event is persisted and routed.
Examples:
// Emit a simple eventstep('notify', async (ctx) => { await ctx.emit('deploy-complete', { env: 'prod', version: '1.2.3' });});
// Cross-repo targetingstep('notify-other-repos', async (ctx) => { await ctx.emit( 'deploy-complete', { env: 'prod' }, { target: { repos: ['org/other-repo', 'org/monitoring'] }, }, );});Cross-repo event delivery
Section titled “Cross-repo event delivery”Events emitted from one repo can trigger workflows in another repo, provided:
- A trust relationship exists between the source and target repos (configured via the admin API)
- The target workflow uses a trigger with
sourcefilter matching the emitting repo
// In repo A: emit eventstep('deploy', async (ctx) => { await ctx.emit( 'deploy-complete', { env: 'prod' }, { target: { repos: ['org/repo-B'] }, }, );});
// In repo B: listen for event from repo Aworkflow('post-deploy', { on: kiciEvent({ name: 'deploy-complete', source: 'org/repo-A' }), jobs: [postDeployJob],});System events
Section titled “System events”The orchestrator automatically emits system events for workflow and job completions. You do not need to call ctx.emit() for these — they are generated by the orchestrator after execution. Listen for them with workflowComplete() and jobComplete() triggers.