Skip to main content
Events are stored in events.jsonl as newline-delimited JSON. Each event represents a phase transition in the cognitive loop.

Event structure

Every event follows this base structure:
{
  "id": "evt_abc123",
  "phase": "plan",
  "agent_id": "meta_planner",
  "payload": { ... },
  "metrics": {
    "started_at": "2024-01-15T10:30:00.500Z",
    "completed_at": "2024-01-15T10:30:00.512Z",
    "duration_ms": 12.7
  },
  "caused_by": "evt_xyz789"
}
id
string
required
Unique event identifier.
phase
string
required
Event phase. Canonical values: start, observe, interpret, plan, direction, governance, act, reflect, learn, terminate, insight, memory, intuition, reason, error. Extensions may emit additional phases.
agent_id
string
Identifier of the component that emitted the event.
payload
object
required
Phase-specific payload data.
metrics
object
Timing metrics for the event.
caused_by
string
ID of the event that caused this one (for lineage tracking).

Event phases

Additional phases you may see:
  • start: episode initialization metadata.
  • intuition: advisory/intuition policy events.
  • memory: reads/writes performed by the memory port.
  • insight: computed insight metrics (alias of events —phase insight).
  • reason: reasoning traces from the planner.
  • error: fatal errors.

observe

Captures the raw task and context at episode start.
{
  "phase": "observe",
  "payload": {
    "task": "Draft release notes for v1.2.0",
    "tags": {
      "priority": "high",
      "team": "platform"
    },
    "timestamp": "2024-01-15T10:30:00Z",
    "context": {
      "changelog_path": "CHANGELOG.md"
    }
  }
}
payload.task
string
required
The task or goal for the episode.
payload.tags
object
User-provided metadata tags.
payload.timestamp
string
required
ISO 8601 timestamp of observation.
payload.context
object
Additional context provided with the task.

interpret

Summarizes signals extracted from the observed input.
{
  "phase": "interpret",
  "payload": {
    "signals": [
      {
        "type": "risk",
        "level": "medium",
        "description": "Production deployment mentioned"
      },
      {
        "type": "constraint",
        "description": "Requires changelog file"
      }
    ],
    "intent": "documentation_generation",
    "policy_id": "SafetyPolicy@1.0"
  }
}
payload.signals
array
required
List of detected signals.
payload.intent
string
Classified intent of the task.
payload.policy_id
string
Policy that performed interpretation.

plan

Records the selected action steps.
{
  "phase": "plan",
  "payload": {
    "steps": [
      {
        "id": "step_1",
        "kind": "detect",
        "description": "Read changelog entries",
        "status": "pending"
      },
      {
        "id": "step_2",
        "kind": "act",
        "description": "Generate summary",
        "status": "pending"
      }
    ],
    "confidence": 0.85
  }
}
payload.steps
array
required
Ordered list of planned steps.
payload.confidence
number
Confidence score for the plan (0-1).

direction

Records policy directives (meta mode only).
{
  "phase": "direction",
  "payload": {
    "directive_id": "dir_abc123",
    "status": "applied",
    "advice": "Added LIMIT 1000 to query",
    "target": "input",
    "diff": ["plan.steps[0].parameters.limit"],
    "policy_id": "SafetyPolicy@1.0",
    "policy_version": "1.0",
    "rationale": "Unbounded queries can exhaust resources"
  }
}
payload.directive_id
string
required
Unique directive identifier.
payload.status
string
required
Directive status: applied, blocked, skipped.
payload.advice
string
required
Human-readable advice from the policy.
payload.target
string
required
Target of the directive: input, plan, action.
payload.diff
array
List of paths that were modified.
payload.policy_id
string
required
Policy that issued the directive.
payload.rationale
string
Explanation for the directive.

governance

Records governance decisions (meta mode only).
{
  "phase": "governance",
  "payload": {
    "governance_id": "gov_def456",
    "decision_id": "dec_789",
    "decision": "allow",
    "rule_id": "rules.allow.default",
    "score": 0.95,
    "policy_id": "governance.rules",
    "policy_version": "1.0.0",
    "policy_kind": "rules",
    "details": {
      "checked_rules": ["rule1", "rule2"],
      "matched_rule": "rule1"
    }
  }
}
payload.governance_id
string
required
Unique governance event identifier.
payload.decision
string
required
Governance decision: allow, audit, veto.
payload.rule_id
string
Rule that determined the decision.
payload.score
number
Confidence score for the decision (0-1).
payload.policy_id
string
required
Governance policy identifier.
payload.details
object
Additional governance details.

act

Logs tool or adapter invocations.
{
  "phase": "act",
  "payload": {
    "tool": "changelog_reader",
    "adapter": "baseline",
    "input_excerpt": "CHANGELOG.md",
    "outcome": {
      "entries_found": 15,
      "status": "success"
    },
    "status": "success",
    "error": null
  }
}
payload.tool
string
Tool that was invoked.
payload.adapter
string
Adapter that was invoked.
payload.input_excerpt
string
Truncated input for logging.
payload.outcome
object
required
Result of the action.
payload.status
string
required
Action status: success, error, timeout.
payload.error
string
Error message if action failed.

reflect

Evaluates outcomes against expectations.
{
  "phase": "reflect",
  "payload": {
    "success": true,
    "reason": "All planned steps completed successfully",
    "expected_outcomes": ["data_processed", "report_generated"],
    "actual_outcomes": ["data_processed", "report_generated"],
    "issues": [],
    "metrics": {
      "task_score": 0.95,
      "steps_completed": 3,
      "steps_total": 3
    }
  }
}
payload.success
boolean
required
Whether the episode succeeded.
payload.reason
string
required
Human-readable explanation of the outcome.
payload.expected_outcomes
array
List of expected outcomes.
payload.actual_outcomes
array
List of actual outcomes.
payload.issues
array
List of issues encountered.
payload.metrics
object
Evaluation metrics.

learn

Captures learning signals for future episodes. The minimal validator expects the following keys; runners may add extra detail.
{
  "phase": "learn",
  "payload": {
    "policy_id": "policy:core.meta",
    "basis": ["rules.veto.danger"],
    "proposal": [],
    "applied": false,
    "scope": "episode"
  }
}
payload.policy_id
string
required
Policy that produced the learning signal.
payload.basis
array
required
Reasons or evidence that drove the learning update.
payload.proposal
array
required
List of proposed updates (may be empty).
payload.applied
boolean
required
Whether the proposed updates were applied.
payload.scope
string
required
Update scope: session, episode, policy, global.

terminate

Marks the end of an episode.
{
  "phase": "terminate",
  "payload": {
    "status": "completed",
    "episode_id": "ep_2024_abc123_s0",
    "duration_ms": 5000
  }
}
payload.status
string
required
Final status: completed, errored, vetoed, aborted.
payload.episode_id
string
required
Episode identifier.
payload.duration_ms
number
required
Total episode duration in milliseconds.

Phase order (partial)

Current phases: start, observe, interpret, plan, direction, governance, act, reflect, learn, terminate, insight, memory, intuition, reason, error.
  • Required: start kicks off every episode; terminate marks completion.
  • Typical loop: observeinterpretplan → (direction/governance in meta mode) → actreflect → (learn optionally).
  • Optional tail: insight and memory may emit after terminate for scoring/persistence.
  • Partial order: phases follow the sequence above when present, but not every phase appears in every run.

Reading events

CLI

# All events
noesis events ep_abc123

# Filter by phase
noesis events ep_abc123 --phase act

# As JSON
noesis events ep_abc123 -j

Python

import noesis as ns

events = list(ns.events.read("ep_abc123"))

# Filter
act_events = [e for e in events if e["phase"] == "act"]

# Reconstruct lineage
def get_chain(events, event_id):
    chain = []
    current = next((e for e in events if e["id"] == event_id), None)
    while current:
        chain.append(current)
        caused_by = current.get("caused_by")
        current = next((e for e in events if e["id"] == caused_by), None)
    return chain

Next steps