A working demonstration of an agent-first integration between an enterprise asset management (EAM) system and heterogeneous robot fleets: a work order is released, an AI agent turns it into a physical mission, a router dispatches it to whichever robot can do it, the robot executes it in simulation, and results flow back with a full audit trail.
This is a portfolio project built by one person on a laptop over a few
weeks. It is not a product, not fleet-scale, and not run on real
hardware. See CLAUDE.md for the full brief — what this is,
the non-negotiable honesty rules, the architecture, and the exact build
order this repo follows.
All 15 build-sequence steps (CLAUDE.md section 6) are done. eam,
mcp_server, telemetry, and console run together end to end via
docker compose or on a local k3d cluster; agent runs as a manual CLI
trigger against them. Each component directory has its own README.md
stating what it does and which step built it; docs/decisions/ has an
ADR for every non-obvious choice along the way. The requirements table
below is the honest summary of what that adds up to against the actual
job spec.
eam/— mock business system (OData v4 + REST)worldmodel/— graph over assets, locations, robots, work ordersagent/— mission planning agent (Pydantic AI)router/— fleet abstraction and dispatchmcp_server/— MCP tools over the router and EAM, for the agentadapters/— one package per robot ecosystem (vda5050_amr,unitree,spot)telemetry/— MQTT ingestion into a time-series storeaudit/,identity/— append-only audit log, machine identityconsole/— thin operator UI (TypeScript, Vite + React)deploy/— docker-compose and k3d (kustomize) manifestsdocs/— job spec, architecture, ADRs, security, edge deployment, standards
Requires uv and Docker.
uv sync --all-packages --all-groups
uv run pytest --ignore=adapters/unitreeadapters/unitree is its own standalone uv project, not a member of this
workspace: its SDK dependency (unitree_sdk2py) needs a native CycloneDDS
build that the rest of the repo has no reason to carry, and CLAUDE.md
section 4.5 flags CycloneDDS as something that must never share an
environment with the ROS 2 adapter's own DDS stack. See
adapters/unitree/README.md for how to set it up and run its tests on
their own.
docker compose -f deploy/docker-compose.yml upStarts Mosquitto, eam (:8000), mcp_server's HTTP API (:8001),
telemetry, and the console (:5173). Release a work order in the
console, then process it with the agent (needs ANTHROPIC_API_KEY):
ANTHROPIC_API_KEY=... docker compose -f deploy/docker-compose.yml run --rm agent <work_order_id>See deploy/docker-compose.yml's own comments for exactly what's
not included (the ROS 2 + Gazebo half of adapters/vda5050_amr,
adapters/unitree/adapters/spot which have no server component of
their own, and why the agent is a manual step rather than automatic).
deploy/k3d/README.md has the same stack running on a local k3d
cluster instead.
Every line of docs/job-spec.md's "What you will do" and "Technical
depth expected" sections (CLAUDE.md section 8's format). The "Job spec
requirement" column paraphrases; docs/job-spec.md has the verbatim
text. One row can only carry one status, so where a single bullet
bundles something built with something not, the strongest true claim
is the status and the gap is named in "Not covered" — never softened
away.
| Job spec requirement | Demonstrated by | Status | Not covered |
|---|---|---|---|
| Own the agent-first integration architecture, reference design to production | The whole repo; docs/architecture.md's four layers |
Built and run in sim | Production deployment, real scale, real IFS suite (eam/ is a mock) |
| Build the abstraction layer treating heterogeneous fleets as dispatchable, auditable executors | router/ (FleetAdapter protocol, capability/availability/distance selection), audit/ (append-only, audits before every command) |
Built and run in sim | More than three ecosystems; production traffic volume |
| Deliver working integrations hands-on: dispatch, mission/task orchestration, telemetry into asset/service records | agent/ + mcp_server/ (dispatch, supervise), telemetry/ (MQTT ingestion → EAM attachments) |
Built and run in sim | Real OEM hardware; a real ERP/EAM/FSM system on the receiving end |
| Evaluate OEM platforms on engineering merit; kill weak options early | ADR-005 (ROS 2/Gazebo feasibility investigation, stopped short of full Nav2 on purpose, given the time budget); the three adapters' differing status labels are themselves a merit call per ecosystem | Built and run in sim | A formal multi-vendor bake-off; no real commercial/licensing evaluation |
| Represent IFS in technical engagements with OEMs, foundation model providers, standards bodies | — | No direct experience | Nothing in this repo involves an external partner organization |
| Hire and lead a robotics integration engineering team | — | No direct experience | Built solo |
| Ship demonstrable outcomes on real customer scenarios and flagship events, on hard dates | This repo itself: built and shipped end to end for this application, in commits, on a defined build sequence | Built and run in sim | No real customer scenario; the only "hard date" was self-imposed |
| Brief executives and customers on the robotics roadmap in commercial terms | The 3-minute recording script below frames this repo for a non-engineering audience | Described, not built | No commercial/roadmap framing exercised against a real stakeholder |
A walkthrough script for a live or recorded demo, timed to CLAUDE.md section 9's definition of done.
0:00–0:20 — What this is. "This is robot-router: a demo of an
agent-first integration between a business system and a heterogeneous
robot fleet. A work order gets released, an AI agent turns it into a
mission, a router picks whichever robot can do it, the robot executes
in simulation, and everything — every decision, every command — gets
audited. Built solo, on a laptop, over a few weeks. Not a product, not
run on real hardware, and I'll say so again anywhere it matters."
0:20–1:10 — The happy path, live. Open the console. Point at the work order list ("this is a mock EAM — OData and REST, the same dialect a real ERP suite exposes"). Release "Visual inspect Pump P-101 for leaks." Run the agent CLI against it. While it runs: "the agent resolves this against a world-model graph — which robots have the right capability, which is idle, which is closest — dispatches to the cheapest match, and supervises it to completion." Switch to the audit trail: "every one of those decisions is right here, append-only, before the robot was ever called."
1:10–2:00 — The part that actually proves something. "Here's a real robot adapter — VDA 5050 over MQTT, a real broker, a real ROS 2 + Gazebo simulation underneath." (Show the sim boot, or the recorded clip if live boot is too slow for the format.) "And here's the degraded-mode scenario: I cut the MQTT link mid-mission —" (kill the connection) "— the adapter detects it within its timeout, the mission gets marked failed, the agent escalates, and it sits here waiting for a human." Approve or abort it in the console. "That loop, cut link to human decision, is fully tested against a real broker, not mocked."
2:00–2:40 — What's honestly not there. "Two of the three adapters — Unitree and Spot — are built against the real vendor SDKs and tested against a real fake of the onboard service, because neither vendor ships a simulator this laptop can run their high-level API against. Said plainly in each adapter's README, not glossed over. Same for Nav2: it boots, it doesn't yet drive to a goal end to end. The requirements table above has the complete, honest list — no keyword without a receipt."
2:40–3:00 — Close. "The point isn't that this is production software — it isn't. It's that every piece of it, from the MCP tool calls to the audit log to the degraded-mode escalation, is something I built and can defend line by line, right now, in this room."
