Skip to main content
Noēsis separates faculties (capabilities/subsystems in the runtime) from phases (observable events emitted into the episode trace).
  • Faculties describe what kind of cognition runs: Intuition, Direction, Governance, Insight (other runtime faculties like Memory can participate too).
  • Phases describe what gets recorded: observe → intuition → interpret → plan → direction → governance → act → reflect → learn → terminate → insight → memory
Faculties exist even when they emit nothing; a faculty can be active and still produce no events for a given episode.
Most users configure faculties via noesis.set() and noesis.run(), then observe results in artifacts (events.jsonl, summary.json). Python imports are only needed for writing custom policies—see Advanced: Writing policies.

Cognitive loop hook order

The runtime emits phases in a canonical order:
observe → intuition → interpret → plan → direction → governance → act → reflect → learn → terminate → insight → memory
Hook ordering is enforced by validate_hook_sequence(). Any violation raises an error.

Veto semantics (canonical)

A veto is a fail-closed stop before action execution:
  • Governance emits the veto decision event; runtime outcome depends on configuration:
  • default (governance_pause_on_veto=false): a terminate event with status="vetoed" is emitted.
  • pause mode (governance_pause_on_veto=true): run.interrupt and run.checkpoint are emitted instead of terminate/finalization.
  • No act events are emitted on veto paths.
  • Failure policy decides how governance exceptions resolve (e.g., enforce-veto).
  • veto_count is computed from governance decisions where decision="veto" (not from terminate status) to avoid double-counting.

Overview

FacultyRolePhase(s)Artifact keys
IntuitionPolicy guidanceintuitionphase="intuition" events
DirectionPlan mutationsdirectionphase="direction" events
GovernancePre-act auditgovernancephase="governance" events
InsightMetrics computationinsightsummary.json metrics

Intuition

Intuition provides policy-driven guidance during the interpret phase. It observes episode state and emits events that can hint, intervene, or veto.

Configuration

import noesis as ns

# Configure via noesis.set()
ns.set(intuition_mode="advisory")  # advisory | interventive | hybrid

# Or pass a policy directly
ns.run(task="...", intuition=my_policy)

IntuitionEvent (artifact schema)

Intuition events appear in events.jsonl with phase="intuition":
{
  "phase": "intuition",
  "payload": {
    "kind": "intervention",
    "advice": "Added safety bounds",
    "confidence": 0.8,
    "policy_id": "SafetyPolicy",
    "policy_version": "1.0.0",
    "policy_kind": "rules",
    "rationale": "Unbounded query detected",
    "patch": {"limit": 100},
    "evidence_ids": ["event:observe:1"],
    "risk_level": "moderate",
    "salience_signals": ["policy_hint"],
    "strategy_hints": ["verify_first"],
    "tool_constraints": ["require_double_check"],
    "scrutiny_level": "elevated",
    "target": "input",
    "scope": "episode",
    "blocking": false
  }
}
FieldDescription
kindhint | intervention | veto
confidence0.0 – 1.0
patchState modifications (for interventions)
blockingtrue for vetoes
risk_levelOptional risk posture: low | moderate | high | critical
salience_signalsOptional cues for Direction: task_complexity, normalization_gap, policy_hint, safety_boundary
strategy_hintsOptional planning hints: conservative, verify_first, retrieve_more, narrow_scope
tool_constraintsOptional tool constraints: no_side_effects, read_only, require_double_check
scrutiny_levelOptional review level: normal | elevated | strict

Structured steering contract (runtime handoff)

Before planning, runtime converts IntuitionEvent into a typed IntuitionAssessment via derive_intuition_assessment(). This guarantees Direction receives a canonical steering shape even when an intuition policy omits optional fields. Defaulting rules in derive_intuition_assessment():
  • risk_level: critical for veto/blocking, moderate for intervention, otherwise low
  • scrutiny_level: strict for veto/blocking, elevated for intervention, otherwise normal
  • salience_signals: policy_hint for hint/intervention, safety_boundary for veto/blocking
  • strategy_hints: conservative + verify_first for veto/blocking, verify_first for intervention
  • tool_constraints: no_side_effects + require_double_check for veto/blocking
The event lineage is preserved into Direction through:
  • payload.intuition_event_id on phase="direction" events
  • top-level evidence_ids on the direction event record

Intuition modes

ModeBehavior
advisoryHints only, non-blocking
interventiveCan modify state
hybridContext-dependent

Direction

Direction handles plan mutations through versioned directives. It runs after plan, before governance, and does not perform vetoes—fail-closed gates live in Governance.

PlannerDirective (artifact schema)

Direction events appear in events.jsonl with phase="direction":
{
  "phase": "direction",
  "payload": {
    "schema_version": "1.2.0",
    "steps": ["meta:start", "intuition:risk-review", "intuition:read-only"],
    "status": "applied",
    "reason": "heuristic-adjustment",
    "diff": [
      {
        "key": "plan.steps[1].description",
        "before": "Execute goal: Review incidents",
        "after": "Execute read-only analysis for goal: Review incidents"
      }
    ],
    "applied": true,
    "policy_id": "planner.meta",
    "policy_version": "1.0.0",
    "policy_kind": "rules",
    "directive_id": "dir-abc123...",
    "intuition_event_id": "evt_2222...",
    "risk_level": "high",
    "salience_signals": ["policy_hint"],
    "strategy_hints": ["verify_first", "retrieve_more"],
    "tool_constraints": ["read_only"],
    "scrutiny_level": "strict",
    "evidence_ids": ["event:observe:1"]
  },
  "evidence_ids": ["event:observe:1"]
}

DirectiveStatus

StatusMeaning
appliedDirective was applied
skippedDirective was skipped
blockedDirective rejected/failed (does not stop execution)

DirectiveKind

KindMeaning
hintAdvisory, no state change
interventionModifies plan/input

Deterministic IDs

Directive IDs are computed from content for reproducible lineage.

How Direction consumes intuition

In meta mode, MetaPlanner.propose(..., intuition=IntuitionAssessment) applies explicit mutations:
  • high/critical risk_level appends risk review language to the first step
  • retrieve_more appends supporting-evidence retrieval on the first step
  • narrow_scope, read_only, no_side_effects constrain the second step description
  • elevated/strict scrutiny_level and verify_first tighten the verify step description
Direction does not enforce vetoes; enforcement happens in Governance.

Governance

Governance is the pre-action audit layer that evaluates proposed actions before execution. It operates in the governance phase.

Governed side effects (pre-act gating)

ns.governed_act(...) is the operating-system boundary for side effects. It uses the same canonical episode runtime boundary as ns.run(...) / ns.solve(...).
  • allow/audit: action_candidate → governance → act
  • enforce veto (governance_pause_on_veto=False): action_candidate → governance → terminate (no act)
  • enforce veto with pause enabled (governance_pause_on_veto=True): action_candidate → governance → run.interrupt → run.checkpoint (no act, no terminate)
Internal runtime seam constraint: graph execution (using=...) and explicit actuation bindings are mutually exclusive and fail fast if mixed.
import noesis as ns
from noesis.exceptions import NoesisVeto

def run_shell(*, command: str, cwd: str | None = None, timeout_ms: int | None = None):
    return {"stdout": "ok", "stderr": "", "exit_code": 0, "command": command}

ns.set(shell_executor=run_shell)

try:
    result = ns.governed_act(
        goal="List repository files",
        kind="shell",
        payload={
            "command": "ls -a",
            "cwd": ".",
            "timeout_ms": 2000,
        },
    )
    print(result)
except NoesisVeto as veto:
    # Raised only when governance is enforcing and the action is vetoed.
    print(f"Blocked by governance: {veto.advice}")

Configuration

import noesis as ns

# Configure via noesis.set()
ns.set(governance_mode="enforce")  # off | audit | enforce
ns.set(governance_failure_policy="fail_closed")  # fail_open | fail_closed

# Or supply a custom governor
ns.run(task="...", governance_policy=my_governor)

GovernanceResult (artifact schema)

Governance events appear in events.jsonl with phase="governance":
{
  "phase": "governance",
  "payload": {
    "decision": "veto",
    "rule_id": "rules.veto.protected",
    "score": 1.0,
    "message": "Task blocked by governance policy",
    "policy_id": "governance.rules",
    "policy_version": "1.0.0",
    "policy_kind": "rules",
    "mode": "enforce",
    "enforced": true
  }
}
Event stream convention: governance events keep phase="governance"; sub-hooks (e.g., pre_act) are carried inside the payload. This keeps the phase enum stable.

GovernanceDecision

DecisionEffect
allowAction proceeds normally
auditAction proceeds, flagged for review
vetoAction blocked entirely

Terminate on veto (default)

When a veto is issued and governance_pause_on_veto is disabled, the runtime emits a terminate event:
{"phase":"terminate","payload":{"status":"vetoed","message":"Blocked by governance"}}
With governance_pause_on_veto=true, runtime emits interrupt/checkpoint events instead:
{"phase":"runtime","event_type":"run.interrupt"}
{"phase":"runtime","event_type":"run.checkpoint"}
See events.v1 for canonical payload shapes.

Pause on veto (optional)

When governance_pause_on_veto=true, enforce-mode vetoes emit lifecycle events and keep the run unsealed:
{"phase":"runtime","event_type":"run.interrupt","payload":{"kind":"run.interrupt","status":"interrupted"}}
{"phase":"runtime","event_type":"run.checkpoint","payload":{"kind":"run.checkpoint","checkpoint_id":"chk_..."}}
On this paused path there is no act, no terminate, and no final.json / manifest.json yet.

Built-in rules

Rule IDTriggerDecision
rules.veto.danger”danger” in goal/stepsVETO
rules.veto.protected”veto”, “destroy”, “shutdown”, “wipe”VETO
rules.audit.sensitive”write”, “delete”, “drop”AUDIT
rules.allow.defaultNo matchesALLOW

Insight

Insight computes metrics from episode traces during the insight emission.

InsightMetrics (artifact schema)

Metrics appear in summary.json:
{
  "metrics": {
    "phase_ms": {"observe": 5, "interpret": 12, "plan": 150, "act": 2000, "reflect": 10},
    "veto_count": 0,
    "branching_factor": 2.0,
    "plan_adherence": 0.95,
    "success": true,
    "plan_revisions": 1,
    "tool_coverage": 3.0
  }
}

InsightMetrics fields

FieldTypeDescription
phase_msdict[str, int]Duration per phase in milliseconds (optional)
veto_countintNumber of governance vetoes issued (canonical fail-closed)
branching_factorfloatCount of direction events
plan_adherencefloatExecuted steps / planned steps (0-1)
successboolWhether episode succeeded (boolean for artifacts)
plan_revisionsintNumber of applied directives
tool_coveragefloatNumber of unique tools used

Computed roll-ups

When computing analytics from events, the insight faculty produces these roll-ups:
MetricShapeNotes
successboolFrom artifact
success_scoreint (0/1)Numeric roll-up
plan_countintNon-synthetic plan events
act_countintNon-synthetic act events
direction_appliedintDirectives with applied=true
direction_blockedintDirectives with status="blocked" (not a veto)
veto_countintGovernance veto decisions

Faculty boundaries

Each faculty has clear responsibilities:
Intuition observes and advises—it should never execute actions directly.
Direction handles plan mutations—it should never evaluate outcomes.
Governance audits pre-action—it should never modify plans.
Insight computes metrics—it should never modify state or plans.

Advanced: Writing policies

This section is for users writing custom intuition policies or custom governors. Most users can skip this.

DirectedIntuition

To write a custom policy, extend DirectedIntuition:
from noesis.direction import DirectedIntuition
from noesis.intuition import IntuitionEvent

class SafetyPolicy(DirectedIntuition):
    """Custom policy with hint, intervene, and veto methods."""
    
    def advise(self, state: dict) -> IntuitionEvent | None:
        task = state.get("task", "").lower()
        
        # Veto dangerous operations
        if "drop table" in task:
            return self.veto(
                advice="Blocked: destructive SQL operation",
                confidence=0.95,
                rationale="DROP TABLE requires manual approval",
            )
        
        # Intervene to add safety bounds
        if "select" in task and "limit" not in task:
            return self.intervene(
                advice="Added LIMIT 1000",
                patch={"task": f"{task} LIMIT 1000"},
                confidence=0.8,
            )
        
        return None
Then pass it to noesis.run():
import noesis as ns

ns.run(task="...", intuition=SafetyPolicy())

DirectedIntuition methods

MethodEffectDefault confidence
hint()Advisory guidance, non-blocking0.5
intervene()Modifies state via patch0.6
veto()Blocks execution, sets blocking=True0.8

Parsing artifact payloads

If you need to parse artifact payloads programmatically:
from noesis.direction import DirectiveKind, DirectiveStatus
from noesis.governance import GovernanceDecision
from noesis.insight import compute_metrics

# Parse direction event
if payload["status"] == DirectiveStatus.BLOCKED:
    print("Directive was blocked")

# Compute metrics from events
metrics = compute_metrics(summary={...}, events=[...])
print(metrics["veto_count"])

Next steps

Write policies

Implement Intuition with custom policies.

Configure governance

Control Direction and Governance behavior.

Export metrics

Use Insight metrics in dashboards.

Cognitive loop

Understanding the full execution flow.