<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Retailbox Automation</title>
    <description>The latest articles on DEV Community by Retailbox Automation (@retailboxautomation).</description>
    <link>https://dev.to/retailboxautomation</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4188983%2F64ec5f97-9794-431e-a334-01d37b366538.png</url>
      <title>DEV Community: Retailbox Automation</title>
      <link>https://dev.to/retailboxautomation</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/retailboxautomation"/>
    <language>en</language>
    <item>
      <title>Provenance gate: no AI agent memory write without a source</title>
      <dc:creator>Retailbox Automation</dc:creator>
      <pubDate>Fri, 16 Oct 2026 13:35:11 +0000</pubDate>
      <link>https://dev.to/retailboxautomation/provenance-gate-no-ai-agent-memory-write-without-a-source-3h0g</link>
      <guid>https://dev.to/retailboxautomation/provenance-gate-no-ai-agent-memory-write-without-a-source-3h0g</guid>
      <description>&lt;p&gt;&lt;em&gt;By Mikhail Oskola, founder of &lt;a href="https://retailbox-automation.com" rel="noopener noreferrer"&gt;Retailbox Automation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A provenance gate is a rule that sits in front of an AI agent's memory: an agent can propose a fact, but it can't become memory until it names where the fact came from. No source, no write. We built one for a hackathon project called FleetMemory, then attacked it ourselves. The first version let a whole class of lies through, 6 out of 6 tries. The fixed version blocked 30 out of 30.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/SDFpU-z9h2w" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What a provenance gate actually checks
&lt;/h2&gt;

&lt;p&gt;Most agent memory systems trust whatever the agent writes. That's the failure mode: an agent infers a number, states it with confidence, and the system files it next to facts a customer actually said. Read it back in a month and there's no way to tell which is which.&lt;/p&gt;

&lt;p&gt;A provenance gate adds one deterministic check before any write commits: does this fact trace to a source? A customer saying "our budget is now $14,000" is sourced, and it supersedes the old value. An agent inferring a budget from context, with nothing a person actually said behind it, is not sourced. That claim quarantines instead of writing straight to memory.&lt;/p&gt;

&lt;p&gt;In the FleetMemory demo, a rogue agent asserts a budget of $1,800 through the exact same write path everything else uses. The gate can't tell that number is false; it isn't comparing values, it's checking for a citation. It quarantines the claim with a gold "held for review" stamp, and an adversarial verifier reads the case and rejects it, right above the real fact it contradicts: $18,000, sourced to an actual customer message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq38pmakkc7lsprn4aokn.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq38pmakkc7lsprn4aokn.webp" alt="FleetMemory demo screen: agent Alex's chat on the left, agent Maria's on the right, and the shared-memory panel in the middle, where a $1,800 budget card stamped Held for review sits above the $18,000 budget that passed the gate." width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The demo mid-attack: the rogue $1,800 budget is held for review, directly above the $18,000 fact Alex learned from the customer. Maria, the second agent, still answers from $18,000.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Junk and duplicate checks: malformed or already-known writes drop before they cost a verifier call.&lt;/li&gt;
&lt;li&gt;Contradiction checks: a new value that conflicts with an existing fact gets flagged, not silently overwritten.&lt;/li&gt;
&lt;li&gt;Confidence floor: a guess below a minimum confidence never reaches memory.&lt;/li&gt;
&lt;li&gt;Provenance check: a claim with no customer utterance behind it quarantines, no matter how confident the agent sounds.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The red-team run that found the hole
&lt;/h2&gt;

&lt;p&gt;A gate is only as good as what you throw at it. We ran 30 adversarial writes across 5 attack classes against the real gate and verifier, not a mock. The script and full results ship in the public repo.&lt;/p&gt;

&lt;p&gt;The first run caught a real gap: unsourced novel claims, facts that don't contradict anything already in memory because there's nothing to contradict, sailed past the deterministic gate 6 out of 6 times. A brand-new, confident, entirely made-up fact walked straight into the fleet's shared memory.&lt;/p&gt;

&lt;p&gt;The fix was a rule we call needs_provenance: a claim with no customer utterance behind it quarantines and faces the verifier, and claimed confidence alone can no longer auto-supersede a fact that already has a source. We re-ran the same 30 attacks. This time all 30 were blocked, including junk, oversized payloads, absurd-confidence guesses, unsourced contradictions, and the unsourced novel claims that got through the first time.&lt;/p&gt;

&lt;p&gt;The gate still let through 9 of 10 legitimate customer-confirmed updates, not 10 of 10. The one it missed is a disclosed race condition: a value looping back to what it originally was while an intermediate update sat unresolved. It's traced in the decision journal, not hidden or tuned away. Median gate latency across the run: 293 milliseconds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh5zlf4me6u0dvljrtv5w.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh5zlf4me6u0dvljrtv5w.webp" alt="psql output against CockroachDB Cloud: seven active facts for the demo customer with confidence scores, then the gate_decisions journal with six clean accepts and two quarantined writes that the verifier rejected." width="800" height="622"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Where that trace lives: the decision journal is an ordinary CockroachDB table. This view is the demo customer, not the red-team run: seven facts still active, six clean accepts, and two contradicting writes quarantined, then rejected by the verifier.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the verifier defaults to reject
&lt;/h2&gt;

&lt;p&gt;A quarantined claim doesn't just sit there. An adversarial LLM verifier reads it and rules on it, and its default is reject, not accept. If the verifier call itself fails for any reason, that also counts as a rejection.&lt;/p&gt;

&lt;p&gt;The verifier's job is to weigh provenance specifically: a direct customer statement supersedes an old fact; an unsourced value gets rejected, even if it sounds plausible, even if the agent stating it sounds confident. Every verdict, with a one-sentence reason, gets written back onto the same decision-journal row as the original write attempt.&lt;/p&gt;

&lt;p&gt;Corrections don't delete anything either. A fact that gets superseded keeps its old row, marked invalid and pointed at whatever replaced it. Ask the system what it believed on any past date and it can tell you, including beliefs it has since abandoned.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frdusez7lkh3k2tn3dn6i.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frdusez7lkh3k2tn3dn6i.webp" alt="The $1,800 budget card struck through and stamped Refused, with the verifier's reason: the value lacks a direct customer utterance and is unsourced agent-generated memory, while the existing fact comes from a direct customer statement." width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The verifier's ruling on that claim: refused, struck through, with its one-sentence reason on the card. The $1,800 had no customer statement behind it; the $18,000 did.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The strongest kind of proof: someone else validating it
&lt;/h2&gt;

&lt;p&gt;Anyone can claim their own system works. While building this we found LangChain's AsyncPostgresSaver checkpointer failing against CockroachDB, and filed it upstream with a standalone repro and a proposed fix direction (langchain-ai/langgraph#8620).&lt;/p&gt;

&lt;p&gt;A community contributor picked it up, built a complete fix along that direction, and verified it independently against both PostgreSQL 17.5 and CockroachDB v26.2.4. It's pending maintainer review as of this writing. Nobody on our team wrote that fix or ran that verification, which is a stronger signal than any benchmark we'd publish about ourselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to see it running
&lt;/h2&gt;

&lt;p&gt;FleetMemory is our own entry in the CockroachDB x AWS "Build with Agentic Memory" hackathon, not a paid client project. It's public and MIT-licensed so anyone can read the gate logic or rerun the red team.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fff26eit1yq8u96a4zmkn.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fff26eit1yq8u96a4zmkn.webp" alt="FleetMemory architecture: agents Alex and Maria (LangGraph) send every write through the write-gate; quarantined writes go to a verifier subagent that defaults to reject; facts, the C-SPANN vector index and the gate_decisions journal live in CockroachDB; AgentCore Memory, Bedrock and the Lambda demo run on AWS." width="800" height="415"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;How the pieces fit: every agent write goes through the gate, quarantined claims go to the verifier, and facts plus the decision journal live in CockroachDB. AWS runs session state (AgentCore Memory), the models (Bedrock) and the public demo (Lambda).&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live demo, no login required: talk to agent Alex, come back as agent Maria, then hit "hallucinate a fact" and watch the gate catch it. &lt;a href="https://pskmxv5sm4k3fj2rjoh2aoijka0ofgob.lambda-url.us-east-1.on.aws/" rel="noopener noreferrer"&gt;https://pskmxv5sm4k3fj2rjoh2aoijka0ofgob.lambda-url.us-east-1.on.aws/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Public repo (MIT license): the gate, the verifier, the red-team script, and the eval results. &lt;a href="https://github.com/retailbox-automation/fleetmemory" rel="noopener noreferrer"&gt;https://github.com/retailbox-automation/fleetmemory&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;1:15 demo video walking through the quarantine-and-reject moment. &lt;a href="https://youtu.be/SDFpU-z9h2w" rel="noopener noreferrer"&gt;https://youtu.be/SDFpU-z9h2w&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The upstream issue: a fix verified by a third-party contributor, pending maintainer review. &lt;a href="https://github.com/langchain-ai/langgraph/issues/8620" rel="noopener noreferrer"&gt;https://github.com/langchain-ai/langgraph/issues/8620&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a provenance gate in AI agent memory?
&lt;/h3&gt;

&lt;p&gt;A provenance gate is a check that runs before any fact commits to an agent's memory. It asks whether the fact traces to a named source, like a direct customer statement, rather than trusting the agent's own confidence. A claim without a source quarantines instead of writing straight to memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Isn't a confidence score enough to filter out bad facts?
&lt;/h3&gt;

&lt;p&gt;No, and that's the exact gap our red team found. An agent can state a brand-new, unsourced fact with high confidence, and if nothing already in memory contradicts it, a confidence-only filter has nothing to compare it against. It sailed through our first gate 6 out of 6 times. The fix checks for a source, not a confidence number.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens to a fact the gate rejects?
&lt;/h3&gt;

&lt;p&gt;It doesn't disappear. It's written to a decision journal with the reason for the rejection, so anyone can query what was attempted, when, and why it didn't pass. Accepted facts that later get corrected aren't deleted either. The old value is marked invalid and kept, so the system can answer what it used to believe.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this the same as citing sources in a RAG answer?
&lt;/h3&gt;

&lt;p&gt;Related, but earlier in the pipeline. RAG citations tell a user where an answer's text came from. A provenance gate decides whether a claim is even allowed to become a durable fact in memory in the first place, before any agent ever retrieves and repeats it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I run the red team myself?
&lt;/h3&gt;

&lt;p&gt;Yes. The repo is MIT-licensed and includes the red-team script and the eval results cited here. Point it at your own CockroachDB cluster and it reruns the same 30 attacks.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://retailbox-automation.com/blog/ai-agent-provenance-gate" rel="noopener noreferrer"&gt;https://retailbox-automation.com/blog/ai-agent-provenance-gate&lt;/a&gt;. The pattern behind it, agents that write to shared memory only through a verification gate, is one we can build into an agent project for a client: &lt;a href="https://retailbox-automation.com/ai-agent-development-company" rel="noopener noreferrer"&gt;AI Agent Development Company&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>database</category>
      <category>opensource</category>
    </item>
    <item>
      <title>AI agents for field service with a fail-closed write-gate</title>
      <dc:creator>Retailbox Automation</dc:creator>
      <pubDate>Fri, 16 Oct 2026 13:35:05 +0000</pubDate>
      <link>https://dev.to/retailboxautomation/ai-agents-for-field-service-with-a-fail-closed-write-gate-2gpf</link>
      <guid>https://dev.to/retailboxautomation/ai-agents-for-field-service-with-a-fail-closed-write-gate-2gpf</guid>
      <description>&lt;p&gt;&lt;em&gt;By Mikhail Oskola, founder of &lt;a href="https://retailbox-automation.com" rel="noopener noreferrer"&gt;Retailbox Automation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Foreman+ is an AI agent fleet for field service work. A technician photographs an equipment nameplate and describes the problem out loud, from a phone or from camera glasses. Three Google ADK agents turn that into a job record with an estimate, and every fact has to pass a write-gate before the fleet may remember it. If the gate's own verifier fails, the write is refused. It's our entry in Google's All Things Agentic hackathon: public, MIT-licensed, and running live.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/Ik2f3wC8_5c" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: numbers nobody checks, visits nobody remembers
&lt;/h2&gt;

&lt;p&gt;Picture a water heater call. The technician reads the nameplate, quotes a price, and leaves. The quote lives in their head or a text thread. A few weeks later a different technician arrives for a callback and starts from zero: what was diagnosed, what was quoted, what the homeowner actually said.&lt;/p&gt;

&lt;p&gt;Putting an AI agent in that loop doesn't fix it by default. An agent will happily file whatever it's told, and a homeowner saying "it's only a couple of years old" ends up stored right next to what the nameplate says. We wanted the opposite: the photo and the talking should cost the technician nothing, and the record should be something the next person can trust without re-diagnosing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the technician actually does
&lt;/h2&gt;

&lt;p&gt;Take a photo of the nameplate, say what's wrong, send. The intake agent reads the model and serial number from the image itself, not from the technician's words. When a plate is too worn to read, the field stays UNKNOWN instead of getting a plausible guess, and a later voice note can fill it in with its source attached.&lt;/p&gt;

&lt;p&gt;The capture path takes a photo and spoken notes as plain files, so it doesn't care what took them. A phone is the main path today: the technician seat opens in a mobile browser with a briefing on the property before the visit, then photo plus hold-to-talk after. The same intake is wired to Mentra Live camera glasses so a technician can file a job without putting the tools down. On the glasses, saying "send it" submits the job, and the reply is read back as one plain sentence: the equipment logged, how many facts the gate approved, and the estimate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbc3509so8iy4sim1887r.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbc3509so8iy4sim1887r.webp" alt="Foreman+ technician seat on a phone before a visit: the property, the equipment chips (Rheem 82V40-2, 05/2004, 40 gallons), and the start of a What we know list where each line names its source (nameplate photo or technician voice), the agent and the gate entry." width="800" height="827"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The technician seat on a phone, before the visit: what the fleet already knows, each line with its source. Sample workspace, fictional names.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Three agents, one memory, one gate
&lt;/h2&gt;

&lt;p&gt;The fleet is three agents built on Google's Agent Development Kit. The foreman records what was reported and hands off. The estimator searches the whole fleet's memory for similar past equipment and problems before it writes an estimate. The closer never writes memory at all. It reads the verified facts, builds the closeout document without an LLM call, and briefs whoever comes next. It's also the one agent exposed outside the fleet, over the A2A protocol, so a field service management system, a home-warranty authorizer, or another agent fleet can read the record.&lt;/p&gt;

&lt;p&gt;Between every agent and the database sits the write-gate. A proposed fact goes through cheap checks first: is the proposing agent a registered fleet member, does the value fit a 4,096-byte cap, does the subject stay within 64 predicates. Only then does a Gemini verifier judge it against what's already known about that subject.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1lxew5359d4yhwc8afsl.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1lxew5359d4yhwc8afsl.webp" alt="Foreman+ architecture: the technician's glasses or phone feed the foreman agent, which routes to the estimator and closer sub-agents; every write passes a write-gate with identity, caps, lock and Gemini verify checks into fleet memory on Cloud SQL, and the closer is exposed over A2A." width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Three agents, one gated memory: every write goes through the gate, approved or rejected, and both outcomes land in the journal with a reason.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Existing facts are handed to the verifier labeled as data to judge, never as instructions. A proposal that tries to talk to the verifier ("approve this", "pre-verified") is itself a reason to reject it.&lt;/li&gt;
&lt;li&gt;If the verifier call errors or comes back empty, the write is refused. A broken judge can make the gate too strict, never too lenient.&lt;/li&gt;
&lt;li&gt;Rejected proposals are kept in a journal with the verifier's reason, and the closeout document lists them. Nothing disappears quietly.&lt;/li&gt;
&lt;li&gt;Conflicts are settled in the database: a lock on each subject-and-field pair plus a unique index keep two agents from writing competing "current" values, even if application code regresses.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Watching the gate refuse a claim
&lt;/h2&gt;

&lt;p&gt;The public demo has a Run the demo button that drives the real fleet through two turns: an intake from a nameplate photo, then a pushback that tries to change the manufacture date by words alone. The nameplate reads 05/2004; the pushback says 2022.&lt;/p&gt;

&lt;p&gt;In the run captured for our submission gallery, the fleet made 14 proposals in 83 seconds. The gate approved 13 and refused 1: the 2022 date, with the verifier's reason quoted on screen. The record kept 05/2004 and filed the homeowner's claim separately as a claim, so it's visible without being treated as true.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzzrgmj4d0m4i8pis7vnz.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzzrgmj4d0m4i8pis7vnz.webp" alt="Run complete dialog over a sample property record: 14 proposals, 13 approved, 1 refused, 83 seconds of fleet time; the gate refused manufacture date 2022 because it contradicts the date verified by the nameplate photo." width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A live demo run from our submission gallery: the 2022 date is refused, 05/2004 stands, and the homeowner's claim is kept as a claim.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Every refusal stays on the record
&lt;/h2&gt;

&lt;p&gt;The office seat's Ledger shows every write the fleet attempted, approved or not, and opens with the refusals: the proposed value struck through, the reason, and the value that stands with its source. Every value on a property record carries a chip you can click to see where it came from, whether that's the nameplate crop or the voice line, plus which agent proposed it and which gate entry approved it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F617voqicpyynbwqhphqi.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F617voqicpyynbwqhphqi.webp" alt="Foreman+ Ledger: refused proposals as cards, each with the proposed value struck through, the verifier's reason and the value that stands, above a table of every gate decision with agent, predicate, value, verdict and reason." width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The Ledger opens with what the gate refused, then lists every write the fleet attempted. Sample data.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the hardware taught us
&lt;/h2&gt;

&lt;p&gt;The glasses were the hardest part. The vendor's documented single-shutter photo event never fired on current firmware when we tested on the real device, so the button handler now triggers the capture itself. The listener for the documented event is still in the code in case a firmware update brings it back. Switching photo compression to medium cut capture time from 34 seconds to 6.3 seconds; the uncompressed default was timing out over Bluetooth.&lt;/p&gt;

&lt;p&gt;For hands-free guidance, a Gemini Live session keeps the technician's latest camera frame as its eyes and answers in one or two spoken sentences, like "point the camera at the shutoff valve." The frame has to ride inside the question turn. Sent separately beforehand, the model didn't see it and answered from imagination; attached in the same turn it was correct 3 out of 3 times in our probe. With a frame attached, answers came back in 0.24 to 0.67 seconds per turn.&lt;/p&gt;

&lt;p&gt;One lesson came from the prompts rather than the hardware. A setup turn that named a job by its street address instead of its ID made the foreman write a technician's name onto a different job at the same address. The gate refused it as a contradiction, which is the gate doing its job, but the real fix was in the prompt: every seeded turn now starts with "Job :".&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limits
&lt;/h2&gt;

&lt;p&gt;This is a hackathon build, and the repo says so. Every service runs at a single instance on purpose, to keep costs predictable. There's no CI pipeline yet; tests run by hand. The glasses leg runs on the vendor's Cloud SDK, which is being retired, so moving to its successor means rewriting a roughly 300-line bridge while the fleet stays the same. And the glasses are optional: everything works from a phone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to see it
&lt;/h2&gt;

&lt;p&gt;Foreman+ is our own R&amp;amp;D project, built for Google's All Things Agentic hackathon, not a client engagement. The demo opens on a sample workspace, Ridgeline Mechanical, whose names and addresses are sample data. It was seeded through the real fleet, so every fact in it went through the gate; nothing was inserted directly into the database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live office seat, no login: &lt;a href="https://foreman-dash-112293816563.us-central1.run.app" rel="noopener noreferrer"&gt;https://foreman-dash-112293816563.us-central1.run.app&lt;/a&gt;. Open a property, click any provenance chip, or press Run the demo.&lt;/li&gt;
&lt;li&gt;Technician seat, best opened on a phone: &lt;a href="https://foreman-dash-112293816563.us-central1.run.app/tech" rel="noopener noreferrer"&gt;https://foreman-dash-112293816563.us-central1.run.app/tech&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Public repo (MIT license): the agents, the write-gate, the dashboard, and the glasses bridge: &lt;a href="https://github.com/retailbox-automation/foreman-plus" rel="noopener noreferrer"&gt;https://github.com/retailbox-automation/foreman-plus&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Submission page with the full write-up: &lt;a href="https://devpost.com/software/foreman-1j24g7" rel="noopener noreferrer"&gt;https://devpost.com/software/foreman-1j24g7&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What does an AI agent fleet do in field service?
&lt;/h3&gt;

&lt;p&gt;In Foreman+, three agents split the job: one records what the technician reported from a photo and voice notes, one estimates the work by searching past similar jobs, and one builds the closeout document and briefs the next person on site. They share one memory, and a write-gate decides which facts get into it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a write-gate for AI agent memory?
&lt;/h3&gt;

&lt;p&gt;It's a single path every proposed fact must pass before it's stored. Cheap checks run first, then an LLM verifier judges the fact against what's already known. If the verifier fails, the write is refused. Rejected proposals are kept with their reason instead of being deleted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do technicians need smart glasses to use it?
&lt;/h3&gt;

&lt;p&gt;No. The phone is the main path. The intake takes a photo and spoken notes as plain files, so glasses are just another way to capture them, handy when the technician's hands are busy.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens when a customer's claim contradicts the nameplate?
&lt;/h3&gt;

&lt;p&gt;In the demo, the nameplate reading holds. A claim that the unit is from 2022 is refused against a nameplate date of 05/2004. The claim is kept as a separate customer claim, next to the refusal and its reason, so the next technician can see it without it overwriting the verified date.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Foreman+ a product we can buy?
&lt;/h3&gt;

&lt;p&gt;Not as a packaged product. It's our public R&amp;amp;D build. The pattern behind it, agents that write to shared memory only through a verification gate, is one we can build into an agent project for a client.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://retailbox-automation.com/blog/ai-agents-for-field-service-foreman-plus" rel="noopener noreferrer"&gt;https://retailbox-automation.com/blog/ai-agents-for-field-service-foreman-plus&lt;/a&gt;. The pattern behind it, agents that write to shared memory only through a verification gate, is one we can build into an agent project for a client: &lt;a href="https://retailbox-automation.com/ai-agent-development-company" rel="noopener noreferrer"&gt;AI Agent Development Company&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>googlecloud</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
