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.
| Setting | Production value | Why it exists |
|---|---|---|
| Gateway URL | OPENCLAW_URL, default loopback http://127.0.0.1:18789 | Local HTTP handoff from iris_planner.py to the OpenClaw gateway. |
| Local agent | iris-planner-local | Routine path backed by Gemma 4 26B A4B (MoE), served locally under the gemma4-26b alias. |
| Cloud peer / public label | iris-planner | Explicit heavyweight review path; public-facing copy labels this as a cloud peer, not an invisible fallback. |
| Local session prefix | agent:iris-planner-local:main | Prefix for trigger-scoped local sessions. |
| Cloud session prefix | agent:iris-planner:main | Prefix for trigger-scoped cloud sessions. |
| Gateway auth | Bearer token from environment | Prevents unauthenticated local hook calls. |
| Write audit | X-Trigger-Id, X-Planner-Instance, X-Planner-Type | Lets plan_journal, setpoint_changes, and delivery logs correlate one planning event end to end. |
| Delivery mode | deliver: false | Wakes 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 | MANUALThe 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:
The ingestor sends the trigger-scoped prompt to the selected Iris instance and records delivery status with trigger metadata.
Iris writes set_plan or set_tunable; MCP validates bounds and audit fields; the dispatcher pushes setpoints; firmware enforces relay safety.
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 instance | Default work | Current launch posture |
|---|---|---|
| Local route | Routine heartbeats, transitions, minor forecast checks, minor deviations | Uses trigger-scoped sessions and the slim local prompt with Gemma 4 26B A4B (MoE), served locally under the gemma4-26b alias. |
| Cloud peer | Heavyweight milestone reviews and explicit escalation | Required 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:
- Planning Archive: visible plans and missed cycles.
- Slack Operations: operator-facing plan summaries, task queues, and deviation explanations.
- Operations: current controller state, relays, alerts, and plan age.
- Planning Quality: planner score, compliance, stress hours, and validated plan status.
- AI-Writable Tunables: the actual write surface.