The vision-language model that reads each bin — a Qwen3-VL-8B class open-weight model — is commodity. The local LLM used for higher-order judgment is a commodity quantized local model, where that higher-order judgment is used. The Strands Agents SDK is an AWS open-source project (Apache 2.0) with production deployments at Amazon Q Developer. None of these components constitute a defensible competitive advantage. They are replicable by any team with the relevant skills, and they will be superseded by their successors within 12–18 months.
What is not easily replicated is the system around them: the deterministic harness that makes commodity AI trustworthy on a noisy factory floor where a wrong replenishment command wastes material, delays a line, or generates a purchase order to an ERP that cannot be recalled. The harness does three things the model cannot do on its own: it bounds belief update magnitude to resist sensor noise, it validates provenance before allowing any tool call, and it records every decision in a queryable lineage. Together, these properties make the agent reliable by construction.
The local on-box provenance store is SQLite — an embedded graph store that adds zero extra network service to the edge node. The downstream queryable provenance layer is Apache Iceberg + AWS S3 Tables, sitting outside the edge node in a cloud-resident lakehouse. These are two distinct tiers with distinct roles. The Software-Defined Industrial Edge’s Part 6: The Data Substrate covers the Iceberg layer in depth; this post covers how the edge agent produces the Episode and DecisionTrace records that flow into it. The broader pattern of why production pilots fail without this harness — the 88-percent wall — is the subject of the parent series’ Part 5; the BeforeToolCallEvent gate, the bounded belief update, and the Episode lineage described below are the concrete instantiation of that general harness pattern.
This post is Part 4 of The Factory That Pays for Itself. Part 3 established that gated local inference is the load-bearing cost decision. This post establishes what happens when the LLM does run: the belief update, the provenance gate, and the lineage record. Part 5 will close the series with the three-year TCO comparison and the market context. The governance question the harness raises — who decides how much autonomy the agent holds and what the escalation path looks like when it commits a purchase order — is examined in When the Agent Places the Order: Governing Autonomy That Spends Money on javatask.systems.
From BinObservation to belief#
The sensor layer (Part 2) produces a BinObservation JSON per bin per duty cycle. The stability layer converts that observation into an updated belief about the bin’s fill state.
The belief update is a bounded update that incorporates new evidence while weighting prior state, and that caps how far belief can move in any single cycle. A genuine depletion event produces a consistent sequence of aligned observations that accumulate gradually across many cycles, eventually crossing the threshold. A transient anomaly — an operator’s hand visible in the ROI, a shadow, a tool dropped momentarily into the bin — produces a one-cycle spike that the bound clips. The spike does not accumulate; it does not trigger a replenishment.
“Lipschitz-clamped stability filter” is the author’s name for this design choice, not the name of an off-the-shelf component. The underlying mechanism — bounding the rate of change of a state variable — is standard in control theory. The parameters L and the update rate are calibration outputs, specific to each deployment environment, that must be validated against a real recorded depletion sequence during NRE. They are not set analytically from the hardware spec.
The BeforeToolCallEvent provenance gate#
The strands-py agentic control framework (AWS open source, Apache 2.0) supports lifecycle event hooks that intercept agent execution at defined points. The critical hook for production e-Kanban is BeforeToolCallEvent — which fires before any tool call is executed.
The gate is deterministic and synchronous — it runs before any tool execution and adds no token cost to the cycle. Its contract is simple to state: no tool call proceeds without a valid Episode context and a complete DecisionTrace, and no duplicate order goes out for a SKU that already has one outstanding. The validation logic behind that contract — the specific checks, their ordering, and the failure modes they catch — is deliberately not reproduced here. It is harness engineering of exactly the kind this post’s title claims as the IP, hardened against failure modes that only show up in deployment.
The gate has three practical effects:
No orphan commands. A replenishment command without traceable provenance cannot be emitted. If the Episode context was lost — agent restart, context compaction failure, framework crash — the gate catches it before the call reaches the ERP.
No duplicate orders. The open_order_exists() check prevents a second replenishment command for the same SKU when one is already outstanding. Duplicate orders are the most common source of over-purchasing in autonomous replenishment systems: the agent fires twice on the same depletion event because the first command’s ERP acknowledgment has not yet propagated back.
Auditable block events. When the gate blocks, it logs the reason. Block events are part of the DecisionTrace lineage — they are not silently discarded. An auditor can reconstruct every case where the gate fired, why it fired, and what the agent attempted to do.
The BeforeToolCallEvent hook does not invoke the LLM.
Episode and DecisionTrace lineage#
Every replenishment decision the agent produces — and every block event where the gate prevented a command — generates records stored in the local SQLite graph store on the EE-3200.
ReWOO — Reasoning WithOut Observation — is the plan-then-execute pattern behind that SOLVE phase: instead of interleaving a model call with each observation the way a ReAct loop does, the orchestrator plans the full sequence of tool calls up front (Plan → Work), executes them, then synthesizes a final answer (Solve). That structure suits a gated duty cycle for two reasons: fewer LLM round-trips per decision, which matters when local inference is already rationed, and a plan that is inspectable before any tool call fires — the same moment the BeforeToolCallEvent gate acts on it.
The Episode record captures:
- The input observations that led to the decision: the
BinObservationsequence from the consensus window - The belief state Bₜ at the time of the decision
- The agent’s reasoning trace (the SOLVE phase output from the ReWOO orchestrator)
- The tool call proposed and the gate’s verdict
- The timestamp and session context
The DecisionTrace captures the structured decision metadata:
sku_id,bin_slot,cell_idreorder_quantityandreorder_justificationepisode_id— foreign key linking back to the Episode recordgate_result—"allowed"or"blocked"with reason code
SQLite on the EE-3200 provides low-latency local graph writes as an embedded, in-process store — no separate database service to run — with graph queries over the stored relationships; on-device benchmark requires measurement at the EE-3200’s target configuration. The graph structure captures relationships between bins, SKUs, cells, and decision events — enabling operational queries such as “what is the belief history of bin slot B2 in cell 4 over the last 7 days?” running locally without a cloud round-trip.
The downstream queryable layer: Apache Iceberg + AWS S3 Tables#
The SQLite graph on the EE-3200 is the hot, local store: fast writes, local queries, bounded retention. Production deployments require a second tier — a cloud-resident, long-retention, queryable provenance archive for compliance, trend analysis, and multi-factory aggregation.
That downstream layer is an Apache Iceberg table family on AWS S3 Tables. Episode and DecisionTrace records are exported from the edge node to the Iceberg layer in periodic batches at configurable intervals — a lightweight pull pattern that tolerates intermittent connectivity and needs no persistent streaming infrastructure on the edge. The Iceberg layer provides:
Audit-durable reads. The Episode record is written once, at decision time, capturing the full belief state and observation sequence as fields. Because Iceberg writes are append-only and each committed snapshot is immutable, querying a specific episode (WHERE episode_id = X) returns exactly the inputs the agent considered — unchanged by later compaction. Iceberg’s snapshot history is a secondary guarantee: the record stays readable at its original snapshot ID for compliance review. This is the core audit capability for any governance review: “show me every input the agent considered before emitting this purchase order.”
ACID transactions. Multiple edge nodes — cells across the same factory, or factories across the enterprise — can write to the same Iceberg table family without a centralized coordinator. S3 Tables implements Iceberg’s optimistic concurrency control via atomic conditional writes at the object-store level: each writer attempts an atomic commit; on the rare collision the losing writer retries against the updated snapshot. For OT write patterns with staggered intervals, collision rates are negligible in practice.
Schema evolution. As the DecisionTrace schema grows (new event types, new metadata fields), Iceberg’s schema evolution rules allow safe additions without breaking existing readers.
SQL accessibility. Any engine with Iceberg support (Athena, Spark, Trino, DuckDB via the Iceberg extension) can query the provenance archive directly. No bespoke query language, no proprietary API.
The SQLite store and the Iceberg layer are separate systems with separate roles. The local store is on-box, millisecond-latency, bounded-retention, and queryable for operational decisions. The Iceberg layer is cloud-resident, long-retention, and queryable for compliance and analytics. The Iceberg layer does not replace the local store; the local store does not require the Iceberg layer to operate. The /series/apache-iceberg-for-industrial-ot/ series on this blog covers the Iceberg table format, partitioning strategies for OT telemetry, and the S3 Tables integration in depth — the lineage pattern described here is one instantiation of the broader OT-to-lakehouse pipeline that series develops.
Why the harness is defensible#
The vision-language model and the local LLM will be replaced by their successors. Model performance improves continuously; the specific weights in use today will be superseded. The model is not the moat.
The harness — the stability filter, the BeforeToolCallEvent gate, the Episode lineage, the calibration methodology — does not become obsolete when the model changes. The gate works the same whether the vision model is an 8B VLM or a larger successor. The belief update structure is independent of the vision model’s internal architecture. The Episode records in the SQLite store are model-agnostic. The Iceberg schema accepts new event types as the harness evolves.
What took real deployments to develop is the gate logic, the calibration protocol, and the consensus window parameters that make the harness work reliably in specific OT environments — dusty cells, glare-prone lighting, high-vibration tables, SKU mix changes. That operational knowledge is encoded in the code, the NRE methodology, and the calibration procedures. It does not transfer via a blog post or a GitHub repository. It requires deployments.
This is the “model is commodity, harness is IP” claim stated in full. The economic advantage of gated local inference (Part 3) and the audit guarantee of the provenance gate are both properties of the harness, not of the model. Replace the model and the harness continues working. Remove the harness and both the economics and the auditability collapse.
What comes next#
The harness establishes that the agent produces reliable, auditable replenishment decisions and that every decision is traceable from belief state to command to queryable Iceberg archive. The remaining question is the CFO question: what does the whole stack cost over three years, and how does that number compare to the alternatives?
Part 5 closes the series with the canonical three-year TCO comparison table (financial-architecture-specialist rebuild, June 2026), the cost decomposition showing what actually drives the per-bin headline, and the market context explaining why the high-mix discrete C-parts segment is where this system’s structural advantages compound.
Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.