Core Concepts
The OODA loop
Section titled “The OODA loop”Every iteration follows four phases:
- Observe — Observers collect data: HTTP health checks, Kubernetes pod status, deployment activity, alerts. Each observer returns
Observation[]. - Orient — Orienters analyze the observations and produce
SituationAssessmentobjects. The framework merges these into aSituationwith a summary, anomalies, correlations, priority, and confidence score. - Decide — Decision strategies evaluate the situation and propose an action. Strategies declare
applicableWhenpredicates so only relevant strategies run. The output is aDecisionwith an action ID, parameters, rationale, confidence, and risk level. - Act — The chosen action executes. Actions can require approval (queued for a human), run automatically, or be skipped (
no-op). Each action returns anActionResultwith success/failure, duration, and optional side effects.
See The OODA Loop for the deep dive.
Plugins
Section titled “Plugins”Plugins are the extension mechanism. A plugin can contribute components to any phase:
| Component | Phase | Purpose |
|---|---|---|
observers | Observe | Collect signals from your systems |
orienters | Orient | Analyze observations into assessments |
decisionStrategies | Decide | Propose actions based on the situation |
actions | Act | Execute remediation or automation |
endpoints | API | Add custom REST routes |
Plugins also have lifecycle hooks: onLoopStart, onObserve, onOrient, onDecide, onBeforeAct, onAfterAct, onLoopComplete.
A minimal plugin:
import { definePlugin, createObserver } from 'zupdev';
export const myPlugin = () => definePlugin({ id: 'my-plugin', observers: { check: createObserver({ name: 'my-check', description: 'Check something important', observe: async (ctx) => [{ source: 'my-plugin/check', timestamp: new Date(), type: 'state', severity: 'info', data: { status: 'ok' }, }], }), },});See Plugin Overview for the full catalog and Writing a Plugin for a step-by-step guide.
Playbooks
Section titled “Playbooks”Playbooks are markdown files that get fed into the LLM during Orient and Decide. Plugins are deterministic code for execution; playbooks carry the operational knowledge — what your team learned from incident retros, system quirks, and runbooks.
playbooks/ high-error-rate.md # your team wrote this after an incident deployment-rollback.md # when to roll back vs. debug our-weird-legacy-api.md # tribal knowledge nobody wants to losePlaybooks are matched against current observations (by severity, keywords, source) and appended to the investigation system prompt. Anyone can write them — it’s just markdown.
See Playbooks for the full guide.
Agent lifecycle
Section titled “Agent lifecycle”import { createAgent } from 'zupdev';
// 1. Create -- plugins are initialized, capabilities registeredconst agent = await createAgent({ name: 'my-agent', plugins: [...] });
// 2. Run -- execute a single OODA loopconst result = await agent.runLoop();
// 3. Or start continuous modeconst stop = await agent.start();
// 4. Optionally start the REST APIconst server = agent.startApi({ port: 3000 });The agent exposes these methods:
| Method | Description |
|---|---|
runLoop() | Execute one full OODA iteration. Returns LoopResult. |
executeAction(id, params) | Run a specific action directly, bypassing the loop. |
start() | Start the agent in the configured mode (manual, continuous, event-driven). |
startApi(options) | Start the REST API server. |
getContext() | Return the current AgentContext. |
getCapabilities() | List registered observers, orienters, strategies, and actions. |
getHistory() | Return past LoopResult[] from this session. |
getState() | Return the StateStore for reading/writing agent state. |
State and persistence
Section titled “State and persistence”The agent maintains a key-value StateStore used by plugins and the approval queue. State can be persisted to memory (default), a JSON file, or a SQLite database.
See State & Persistence for configuration details.
Approvals
Section titled “Approvals”When an action’s risk is high, its confidence is below a threshold, or its autonomy mode is approval-required or human-only, the action is queued for approval instead of executing. Pending approvals can be listed, approved, or denied via the REST API.
See Approval Queue for details.
External systems can submit work items called runs via the REST API. A run flows through the OODA loop and its results are returned via polling or webhook callback.
See REST API for the runs endpoints.