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"
}
Event phase. Possible values: start, observe, interpret, plan, direction, intuition, insight, reason, governance, act, reflect, learn, terminate, error.
Identifier of the component that emitted the event.
Phase-specific payload data.
Timing metrics for the event. ISO 8601 timestamp when the phase started.
ISO 8601 timestamp when the phase completed.
Duration in milliseconds.
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.
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"
}
}
}
The task or goal for the episode.
User-provided metadata tags.
ISO 8601 timestamp of observation.
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"
}
}
List of detected signals. Signal type: risk, constraint, opportunity, warning.
Signal level: low, medium, high, critical.
Human-readable signal description.
Classified intent of the task.
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
}
}
Ordered list of planned steps. Step kind: detect, analyze, plan, act, verify, review.
Human-readable step description.
Step status: pending, running, done, skipped, failed, vetoed.
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"
}
}
Unique directive identifier.
Directive status: applied, blocked, skipped.
Human-readable advice from the policy.
Target of the directive: input, plan, action.
List of paths that were modified.
Policy that issued the directive.
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"
}
}
}
Unique governance event identifier.
Governance decision: allow, audit, veto.
Rule that determined the decision.
Confidence score for the decision (0-1).
Governance policy identifier.
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
}
}
Adapter that was invoked.
Truncated input for logging.
Action status: success, error, timeout.
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
}
}
}
Whether the episode succeeded.
Human-readable explanation of the outcome.
payload.expected_outcomes
List of expected outcomes.
List of issues encountered.
learn
Captures learning signals for future episodes.
{
"phase" : "learn" ,
"payload" : {
"updates" : [
{
"type" : "memory" ,
"key" : "changelog_format" ,
"value" : "keep-a-changelog"
},
{
"type" : "proposal" ,
"target" : "veto_threshold" ,
"suggested_value" : 0.8 ,
"confidence" : 0.75
}
],
"scope" : "session"
}
}
List of learning updates. Update type: memory, proposal, hint.
Value for memory updates.
Suggested value for proposals.
Confidence in the proposal (0-1).
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
}
}
Final status: completed, errored, vetoed, aborted.
Total episode duration in milliseconds.
Event order invariant
Events follow this order:
observe → (interpret → plan)* → (direction → governance)? → act+ → reflect → (learn)? → terminate
observe is always first
interpret and plan may repeat
direction and governance only appear in meta mode
Multiple act events are common
learn is optional
terminate is always last
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