Skip to main content
Noēsis supports two planner modes that control the level of governance and observability in your episodes.

Understanding planner modes

ModeDescriptionUse when
meta (default)Full governance with MetaPlanner and PreActGovernorYou need auditability, vetoes, and insight KPIs
minimalSkips governance, uses legacy stepwise plannerQuick sanity checks or smoke tests

Setting the planner mode

Python API

import noesis as ns

# Set globally
ns.set(planner_mode="meta")  # Full governance (default)
ns.set(planner_mode="minimal")  # Skip governance

# Check current mode
config = ns.config()
print(config.planner_mode)

Environment variable

export NOESIS_PLANNER=meta
noesis run "my task"

# Or inline
NOESIS_PLANNER=minimal noesis run "my task"

Configuration file

Create a noesis.toml in your project root:
noesis.toml
[noesis]
planner_mode = "meta"
runs_dir = "./.noesis/episodes"

Precedence

Configuration is resolved in this order (highest to lowest):
  1. ns.set() call in code
  2. NOESIS_PLANNER environment variable
  3. noesis.toml configuration file
  4. Default value (meta)

Meta mode (default)

Meta mode enables full governance:
import noesis as ns

ns.set(planner_mode="meta")

episode_id = ns.run("Provision staging infrastructure")

# Check direction and governance events
events = list(ns.events.read(episode_id))
direction = [e for e in events if e["phase"] == "direction"]
governance = [e for e in events if e["phase"] == "governance"]

print(f"Direction events: {len(direction)}")
print(f"Governance events: {len(governance)}")

What meta mode provides

  • MetaPlanner: Threads through every episode for structured planning
  • PreActGovernor: Audits actions before execution, can veto
  • Direction events: Records directive status (applied, blocked, skipped)
  • Intuition steering handoff: Carries risk_level, strategy_hints, tool_constraints, and scrutiny_level into Direction
  • Governance events: Records decisions (allow, audit, veto)
  • Full insight metrics: Plan adherence, veto count, tool coverage

Direction event example

{
  "phase": "direction",
  "payload": {
    "schema_version": "1.2.0",
    "directive_id": "dir_0f7f...",
    "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"
      }
    ],
    "policy_id": "planner.meta",
    "policy_version": "1.0.0",
    "policy_kind": "rules",
    "intuition_event_id": "evt_2d3b...",
    "risk_level": "high",
    "strategy_hints": ["verify_first", "retrieve_more"],
    "tool_constraints": ["read_only"],
    "scrutiny_level": "strict"
  },
  "evidence_ids": ["event:observe:1"],
  "caused_by": "7e0f..."
}

Governance event example

{
  "phase": "governance",
  "payload": {
    "decision": "audit",
    "rule_id": "rules.audit.sensitive",
    "score": 0.6,
    "policy_id": "governance.rules",
    "policy_version": "1.0.0"
  },
  "caused_by": "5c12..."
}

Minimal mode

Minimal mode skips governance for faster execution:
import noesis as ns

ns.set(planner_mode="minimal")

episode_id = ns.run("Quick sanity check")

# No governance events
events = list(ns.events.read(episode_id))
governance = [e for e in events if e["phase"] == "governance"]
assert len(governance) == 0  # No governance in minimal mode

What minimal mode skips

  • MetaPlanner and PreActGovernor
  • Direction and governance events
  • Policy-based vetoes
  • Some insight metrics (veto_count, plan_adherence)

What minimal mode keeps

  • The cognitive loop (observe → interpret → plan → act → reflect → learn)
  • Event timeline (events.jsonl)
  • Summary artifacts (summary.json)
  • Basic metrics (success, act_count)

Inspecting governance metrics

When using meta mode, governance metrics are available in the summary:
import noesis as ns

ns.set(planner_mode="meta")
episode_id = ns.run("Sensitive operation", intuition=True)

summary = ns.summary.read(episode_id)
metrics = summary.get("insight", {}).get("metrics", {})

print(f"Plan revisions: {metrics.get('plan_revisions', 0)}")
print(f"Veto count: {metrics.get('veto_count', 0)}")
print(f"Plan adherence: {metrics.get('plan_adherence', 1.0):.2%}")
print(f"Tool coverage: {metrics.get('tool_coverage', 1.0):.2%}")

Governance decisions

The PreActGovernor can make three decisions:
DecisionEffectWhen it happens
allowAction proceeds normallyNo policy concerns
auditAction proceeds, marked for reviewMedium-risk operations
vetoAction blockedHigh-risk or policy violations

Handling vetoes

Vetoes are emitted by Governance (not Direction) and only block actions in governance_mode="enforce":
import noesis as ns

ns.set(planner_mode="meta")
ns.set(governance_mode="enforce")

episode_id = ns.run("DROP TABLE users", intuition=True)
events = list(ns.events.read(episode_id))

governance_veto = next(
    (
        e
        for e in events
        if e["phase"] == "governance" and e.get("payload", {}).get("decision") == "veto"
    ),
    None,
)

if governance_veto:
    print("Governance vetoed the action")
    print(governance_veto["payload"]["rule_id"])
If governance_pause_on_veto=true, enforce vetoes pause the run with runtime lifecycle events (run.interrupt, run.checkpoint) instead of immediate termination.

Switching modes dynamically

You can switch modes between episodes:
import noesis as ns

# Run with full governance
ns.set(planner_mode="meta")
governed_ep = ns.run("Critical operation", intuition=True)

# Run quick test without governance
ns.set(planner_mode="minimal")
test_ep = ns.run("Quick test")

# Back to governed mode
ns.set(planner_mode="meta")
another_governed_ep = ns.run("Another critical operation", intuition=True)

CLI usage

Toggle modes from the command line:
# Meta mode (default)
noesis run "Sensitive task"

# Minimal mode via environment
NOESIS_PLANNER=minimal noesis run "Quick test"

When to use each mode

Use meta mode for:

  • Production workloads
  • Compliance-sensitive operations
  • Operations requiring audit trails
  • Tasks with intuition policies
  • Any operation that might need to be vetoed

Use minimal mode for:

  • Development and testing
  • Quick sanity checks
  • Benchmarking adapter performance
  • Operations that don’t need governance overhead

Troubleshooting

You’re likely in minimal mode. Check with:
config = ns.config()
print(config.planner_mode)  # Should be "meta"
Set to meta mode: ns.set(planner_mode="meta")
Ensure Governance is enforcing:
ns.set(planner_mode="meta")
ns.set(governance_mode="enforce")
ns.run("task", intuition=True)
In governance_mode="audit" or off, veto-like risk signals can still appear in direction/intuition artifacts, but they do not block actuation.
Governance metrics only populate in meta mode with active policies:
ns.set(planner_mode="meta")
ns.run("task", intuition=MyPolicy())  # Need a policy

Next steps

Write policies

Create intuition policies for governance.

Export metrics

Export governance metrics to your observability stack.