OpenClaw Configuration

OpenClaw is the agent orchestration layer between greenhouse events and Iris (our OpenClaw AI agent). The ingestor does not call a model directly. It gathers the greenhouse context, builds an event-specific prompt, posts it to the OpenClaw gateway, and records whether the gateway accepted the delivery. Iris then uses MCP tools to write bounded plans and tunables, and posts a human-readable summary to Slack Operations so the operator sees the plan, forecast reasoning, watch items, and task context.

Verdify’s launch posture is local-first, not local-only. Routine checks use Gemma 4 26B A4B (MoE), served locally under the gemma4-26b alias. Heavyweight reviews use the cloud peer only when the route is explicitly selected and stamped in the audit trail.

The important boundary is simple: OpenClaw routes reasoning. MCP validates writes. The ESP32 controls relays. The exact parameters Iris can write are documented in AI-Writable Tunables.

Runtime Configuration

The production settings live in ingestor/config.py and config/ai.yaml. Secrets are external environment variables or token files and are not published.

SettingProduction valueWhy it exists
Gateway URLOPENCLAW_URL, default loopback http://127.0.0.1:18789Local HTTP handoff from iris_planner.py to the OpenClaw gateway.
Local agentiris-planner-localRoutine path backed by Gemma 4 26B A4B (MoE), served locally under the gemma4-26b alias.
Cloud peer / public labeliris-plannerExplicit heavyweight review path; public-facing copy labels this as a cloud peer, not an invisible fallback.
Local session prefixagent:iris-planner-local:mainPrefix for trigger-scoped local sessions.
Cloud session prefixagent:iris-planner:mainPrefix for trigger-scoped cloud sessions.
Gateway authBearer token from environmentPrevents unauthenticated local hook calls.
Write auditX-Trigger-Id, X-Planner-Instance, X-Planner-TypeLets plan_journal, setpoint_changes, and delivery logs correlate one planning event end to end.
Delivery modedeliver: falseWakes the agent without sending a public message as the transport payload.

Every delivery generates a fresh UUID. The final session key is the configured prefix plus :trigger:<uuid>. This prevents old chat history from overflowing the local model context. Durable memory comes from the gathered database context, static site context, plan journal, scorecards, and lessons, not from unbounded chat accumulation.

Event Delivery

ingestor/iris_planner.py posts a JSON payload to /hooks/agent:

{
  "message": "standing directives + planner knowledge + event context + audit headers",
  "agentId": "iris-planner-local",
  "sessionKey": "agent:iris-planner-local:main:trigger:<uuid>",
  "wakeMode": "now",
  "deliver": false
}

The request also carries:

Authorization: Bearer <openclaw token>
X-Trigger-Id: <uuid>
X-Planner-Instance: local | opus
X-Planner-Type: SUNRISE | SUNSET | MIDNIGHT | TRANSITION | FORECAST | DEVIATION | MANUAL

The gateway response only means the event was accepted. It does not prove Iris wrote a plan. A separate heartbeat/SLA path verifies that required planning events produced a set_plan, set_tunable, or acknowledge_trigger with the same trigger ID.

Slack In The Agent Loop

Slack is not the OpenClaw transport and it is not a control API. It is the operator surface after the agent has reasoned about the greenhouse. A successful planning cycle creates three related artifacts:

Machine deliveryOpenClaw + audit headers

The ingestor sends the trigger-scoped prompt to the selected Iris instance and records delivery status with trigger metadata.

Validated writeMCP + dispatcher + ESP32

Iris writes set_plan or set_tunable; MCP validates bounds and audit fields; the dispatcher pushes setpoints; firmware enforces relay safety.

Human briefSlack

Iris explains the plan ID, previous scorecard, forecast, tactical posture, experiment, and watch items in the greenhouse channel.

That is why the Slack screenshots belong beside the OpenClaw story: they show the same planning event from the operator’s point of view, while the database and public archive keep the auditable source of truth.

Routing Policy

Verdify is local-first, but not local-only.

Planner instanceDefault workCurrent launch posture
Local routeRoutine heartbeats, transitions, minor forecast checks, minor deviationsUses trigger-scoped sessions and the slim local prompt with Gemma 4 26B A4B (MoE), served locally under the gemma4-26b alias.
Cloud peerHeavyweight milestone reviews and explicit escalationRequired full plans route here until the local full-plan context trimming passes a clean bake; plan records must label the route.

The May 7 launch hardening change matters: Gemma 4 26B A4B (MoE), served locally under the gemma4-26b alias, overflowed during required full-plan cycles when persistent context grew too large. The fix is not silent fallback. Required full plans are explicitly routed through the cloud planner path with audit stamps, while routine checks stay local.

Tool Boundary

Iris is told to use MCP tools only. The standing prompt advertises 22 tools across monitoring, control, knowledge, crops, topology, operations, and meta planning. It explicitly forbids direct shell, psql, or docker exec workarounds.

Write tools must include the trigger ID and planner instance:

set_plan(plan_id=..., hypothesis=..., transitions=..., trigger_id=..., planner_instance=...)
set_tunable(parameter=..., value=..., reason=..., trigger_id=..., planner_instance=...)
acknowledge_trigger(trigger_id=..., reason=..., planner_instance=...)

MCP validates names against the shared tunable registry, rejects missing audit metadata, clamps unsafe values, and drops crop-band fields from routine plans. The dispatcher then pushes validated setpoints to ESPHome; firmware readbacks land in setpoint_snapshot through cfg_* sensors.

Failure Behavior

OpenClaw can fail without endangering the greenhouse. If the gateway is down, a delivery log records gateway_status=0 or the HTTP failure. If Iris accepts the event but does not write the required output within the SLA, alerting opens a planner-required miss. In both cases, the ESP32 continues enforcing the last valid bounded setpoints plus hard firmware safety rails.

Public evidence for this contract lives in: