This page explains the core concepts you’ll encounter when working with Noēsis. Understanding these will help you make the most of the framework.
Episodes
An episode is the fundamental unit of execution in Noēsis. Every time you run a task, you create an episode with a unique identifier.
import noesis as ns
episode_id = ns.run("Draft release notes")
# episode_id = "ep_2024_abc123_s0"
Episode lifecycle
Episodes progress through a defined lifecycle:
queued → running → completed | errored | vetoed
| Status | Meaning |
|---|
queued | Episode created, waiting to start |
running | Cognitive loop in progress |
completed | All phases finished successfully |
errored | An exception occurred during execution |
vetoed | A policy blocked execution |
Episode IDs
Episode IDs follow the format ep_<timestamp>_<hash>_s<seed>:
ep_ prefix identifies it as an episode
<timestamp> provides chronological ordering
<hash> ensures uniqueness
s<seed> enables reproducible runs with the same seed
import noesis as ns
# Reproducible runs with the same seed
ns.set(seed=42)
ep1 = ns.run("task")
ns.set(seed=42)
ep2 = ns.run("task")
# ep1 and ep2 will have matching behavior
The cognitive loop
Every episode flows through a sequence of nine phases that make reasoning explicit:
Observe → Interpret → Plan → Direction → Governance → Act → Reflect → Learn → Insight
In meta mode (default), all nine phases execute. In minimal mode, Direction, Governance, and Insight are skipped for faster execution.
| Phase | Purpose | What gets recorded |
|---|
| Observe | Capture raw task and context | Task text, tags, timestamp |
| Interpret | Extract signals and intent | Signals, risks, constraints |
| Plan | Decide what to do | Steps, tools to use |
| Direction | Apply policy mutations | Directives, diffs |
| Governance | Pre-action audit | Allow/audit/veto decisions |
| Act | Execute the plan | Tool calls, adapter results |
| Reflect | Evaluate outcomes | Success/failure, reasons |
| Learn | Update for future runs | Proposals, adaptations |
| Insight | Compute KPIs | Metrics, plan adherence |
See the cognitive loop explanation for a deeper dive.
Faculties
Noēsis organizes capabilities into four faculties that execute in a canonical order. Each faculty emits events so you can audit (or veto) what happened.
observe → interpret → plan → direction → governance.pre_act → act → reflect → finalize
Intuition
Intuition provides policy-driven guidance during interpretation. It observes state and emits events.
class MyPolicy(ns.DirectedIntuition):
def advise(self, state: dict):
if "dangerous" in state["task"]:
return self.veto(advice="Blocked dangerous operation")
return None
Key types: IntuitionEvent, DirectedIntuition, HeuristicIntuition, LLMIntuition
Actions:
hint(): Advisory guidance (confidence: 0.5)
intervene(): Modify state via patch (confidence: 0.6)
veto(): Block execution (confidence: 0.8)
Direction
Direction handles plan mutations through versioned directives.
Key types: PlannerDirective, DirectiveDiff, DirectiveStatus
Directive kinds: HINT, INTERVENTION, VETO
Directive statuses: APPLIED, SKIPPED, BLOCKED
Governance
Governance is the pre-action audit layer with the PreActGovernor. It is the gate that enforces approvals and can veto before tools execute.
Key types: GovernanceResult, GovernanceDecision, PreActGovernor
Decisions:
ALLOW: Action proceeds normally
AUDIT: Action proceeds, flagged for review
VETO: Action blocked entirely
Use it for: human-in-the-loop approvals, safety allowlists/blocklists, “two-person rule” for destructive tools, and recording audit reasons right before execution.
Insight
Insight computes metrics from episode traces during finalization.
Key types: InsightMetrics, compute_metrics, build_insight_metrics
Metrics: veto_count, branching_factor, plan_adherence, plan_revisions, tool_coverage, phase_ms
Artifacts
Every episode produces structured artifacts that capture the full cognitive trace:
runs/
demo/ # label
ep_2024_abc123_s0/ # episode
summary.json # metrics and outcomes
state.json # cognitive state
events.jsonl # timeline
manifest.json # integrity checksums
learn.jsonl # learning signals (optional)
summary.json
The summary captures episode outcomes, flags, metrics, and insight:
{
"schema_version": "1.2.0",
"episode_id": "ep_2024_abc123_s0",
"task": "Draft release notes",
"seed": 42,
"started_at": "2024-01-15T10:30:00Z",
"duration_sec": 5.12,
"flags": {
"intuition": true,
"mode": "meta",
"using": "langgraph",
"direction": {
"applied": 1,
"vetoed": 0,
"policy": "SafetyPolicy@1.0",
"threshold": 0.75,
"last_diff": [
"plan.steps[0].params.limit: null → 100"
]
}
},
"ports": {
"model": "openai:gpt-4o-mini"
},
"agents_config_hash": "sha256:9f7d...",
"answer": {},
"metrics": {
"success": 1,
"plan_count": 2,
"act_count": 3,
"veto_count": 0
},
"insight": {
"plan_adherence": 0.95,
"tool_coverage": 1.0
},
"tags": {
"team": "platform"
},
"manifest": {
"path": "manifest.json"
}
}
state.json
The state captures the cognitive context:
{
"version": "1.0",
"episode": {
"id": "ep_2024_abc123_s0",
"adapter": "baseline"
},
"goal": {
"task": "Draft release notes",
"context": {}
},
"plan": {
"steps": [
{"kind": "detect", "description": "Gather changelog entries"},
{"kind": "act", "description": "Generate summary"}
]
},
"outcomes": {
"status": "ok",
"actions": []
}
}
events.jsonl
The event timeline records every phase:
{"phase": "observe", "payload": {"task": "Draft release notes"}, "metrics": {"started_at": "...", "completed_at": "...", "duration_ms": 1.2}}
{"phase": "interpret", "payload": {"signals": []}, "caused_by": "abc...", "metrics": {"started_at": "...", "completed_at": "...", "duration_ms": 2.3}}
{"phase": "plan", "payload": {"steps": [...]}, "caused_by": "def...", "metrics": {"started_at": "...", "completed_at": "...", "duration_ms": 1.0}}
{"phase": "act", "payload": {"tool": "generator"}, "caused_by": "ghi...", "metrics": {"started_at": "...", "completed_at": "...", "duration_ms": 4.8}}
{"phase": "reflect", "payload": {"success": true}, "caused_by": "jkl...", "metrics": {"started_at": "...", "completed_at": "...", "duration_ms": 0.6}}
manifest.json
The manifest provides integrity verification:
{
"schema_version": "manifest/1.0",
"episode_id": "ep_2024_abc123_s0",
"created_at": "2024-01-15T10:30:05Z",
"files": [
{"name": "summary.json", "sha256": "sha256:abc123...", "size_bytes": 1234, "kind": "summary"},
{"name": "events.jsonl", "sha256": "sha256:def456...", "size_bytes": 5678, "kind": "events"}
]
}
Adapters
Adapters connect Noēsis to your existing agent runtimes. They’re simply callables that Noēsis wraps with cognition:
import noesis as ns
# Plain function adapter
def my_adapter(task: str) -> dict:
return {"result": task.upper()}
# LangGraph adapter
def langgraph_adapter(task: str) -> dict:
return graph.invoke({"task": task})
# Use with Noēsis
ns.solve("task", using=my_adapter)
Noēsis doesn’t replace your runtime—it makes it observable.
Policies
Policies are Python classes that implement guardrails. They extend DirectedIntuition and implement the advise method:
import noesis as ns
class SafetyPolicy(ns.DirectedIntuition):
__version__ = "1.0"
def advise(self, state: dict):
# Return None to allow, or use hint/intervene/veto
return None
Policies are:
- Testable: Pure Python, no async or threading requirements
- Versioned: Track policy evolution in event logs
- Composable: Chain multiple policies together
Configuration
Noēsis is configured through multiple sources:
| Source | Example | Precedence |
|---|
ns.set() | ns.set(planner_mode="meta") | Highest |
| Environment | NOESIS_PLANNER=meta | Medium |
noesis.toml | planner_mode = "meta" | Lowest |
Key configuration options:
runs_dir: Where artifacts are stored
planner_mode: meta (full governance) or minimal
seed: For reproducible episodes
label: Subdirectory name for organizing runs
Mental model
Here’s how the pieces fit together:
- A task creates an episode
- The episode runs through the cognitive loop
- Faculties (Intuition, Direction, Governance, Insight) process each phase
- Artifacts capture everything for replay and analysis
Next steps