Prepared for the University of California, Berkeley. Master of Information and Data Science.
Denver, Colorado · builder of intelligent decision systems
I design and build AI-native systems end to end, from architecture through deployment. My work sits where messy real-world information meets software: I take unstructured inputs, warehouse floors, litigation documents, county property records, camera feeds, and turn them into structured representations that support decisions.
I am most drawn to systems rather than isolated models. The interesting engineering is usually in the connective tissue: the event backbone that keeps thirty services consistent, the governed state machine that decides what a system is allowed to believe, the retrieval layer that degrades instead of failing, the audit trail that makes an automated decision defensible. Retrieval, agents, and probabilistic reasoning show up in my products because they make the product work better, not because they are on a roadmap.
I work across domains on purpose. A problem in litigation looks a lot like one in property data, and a grading decision on a warehouse conveyor is the same shape as a routing decision in a document pipeline. Recognizing those shared structures is what lets me move quickly without cutting corners on data models, testing, or deployment.
A warehouse and reverse-logistics platform built as an event-driven service mesh.
Reverse logistics is a coordination problem. A returned or liquidated item has to be received, identified, graded, placed, and then routed to the right outcome (resale, refurbishment, salvage, auction, or disposal), and every one of those steps is owned by a different team and a different system. When those systems drift out of sync, inventory lies, listings go stale, and items get lost. QuickWMS is my answer to keeping many specialized workflows consistent without collapsing them into one monolith.
Warehouse operators at receiving and grading stations, inventory and listings managers, and administrators, each with a dedicated interface rather than one overloaded dashboard.
| Monorepo | Turborepo + pnpm workspaces, ~1,200 TypeScript source files |
| Frontend | 11 Next.js 16 / React 19 apps, shared component library |
| Services | 35+ Express / TypeScript microservices |
| Messaging | Redis Streams event bus, saga orchestrator |
| Data | PostgreSQL 16, 55 tables, raw-SQL migrations |
| Vision | Groq / Claude / OpenAI multi-provider router |
| Gateway | Express reverse proxy, JWT, Swagger / OpenAPI |
| Deploy | PM2 on a single VPS behind Nginx |
A hand-written PostgreSQL layer (no ORM) of 55 tables across seven migrations. An items hub links to manifests, receiving sessions, suppliers, and pallets. A self-referential grading-history chain records condition over time. Separate sub-schemas cover consignment, multi-tenant third-party logistics, salvage and parts, analytics, and the event store itself.
A central API gateway fronts the platform with Helmet, CORS, rate limiting, JWT auth, and generated OpenAPI docs, reverse-proxying path prefixes to ten backend services. Listing services synchronize to external marketplaces (Shopify, eBay, Amazon). The computer-vision service enriches item identity against a third-party UPC and EAN lookup API. The main architectural constraint is deliberate: services never reach into each other's tables. They communicate only through the event bus and the gateway, which is what makes the topology safe to grow.
Litigation modeled as a dynamic information and decision system, not a single prediction.
Case strategy is usually reasoned from intuition and anecdote. Juricratic treats a matter as what it actually is: a multi-party game played over incomplete, evolving information, where each side has payoffs and moves. That framing turns strategy into something you can represent, reason over, and stress-test, provided the system is honest about what it knows and rigorous about what it is allowed to assert.
State is event-sourced: the next matter state is a pure transform of the current state and an incoming event, which makes every change a traceable delta. On top of that sits a governed canonical matter state that is fail-closed. A fact cannot be promoted into canonical belief unless it is sourced and attorney-reviewed. A hard firewall separates the live matter from simulation branches, so a hypothetical can never write itself back into what the system treats as true.
A typed, in-memory knowledge graph models parties, evidence, motions, authorities, and judges with bi-temporal edges that supersede rather than delete, preserving history. An optional Neo4j mirror is code-complete but runs in a degrade-not-fail mode when the store is not provisioned.
| Core | Python, event-sourced engine and solver |
| Agents | LangGraph StateGraph subgraphs |
| Reasoning | Claude tool-use, constrained to legal action tokens |
| Graph | typed in-memory graph, optional Neo4j mirror |
| Retrieval | feature-hash embeddings, optional legal 768-d + Qdrant / OpenSearch |
| Verify | Z3 SMT contradiction checking |
| Surface | FastAPI (~60 endpoints), Next.js 15 + react-three-fiber |
The solver runs bounded simulation over settlement dynamics: seeded Monte Carlo rollouts, determinized information-set Monte Carlo tree search, pure-Nash equilibria, and a best-response exploitability gap. A transparent Bayesian case model with Kalman belief updates and Dirichlet shrinkage priors carries uncertainty explicitly. The design rule is stated in the code itself: this is simulation, not prediction, and it does not emit a calibrated win probability.
Implemented: the engine, solver, agent subgraphs, FastAPI surface, 3D interface, Z3 verifier, and a large test suite under a strict branch-coverage gate.
Partial: the external memory stores (Neo4j, Qdrant, OpenSearch) are code-complete but not yet provisioned; the app deploy is pending while the public landing site is live.
Research direction: opponent modeling with I-POMDPs, value-net training in the ReBeL style, and a regret-matching solver are documented as design only, with no code riding on them.
An edge computer-vision system that identifies and grades items on a conveyor, then prints a label.
Identifying returned products by hand is slow and inconsistent. QuickVisionz runs a real-time vision pipeline on a Raspberry Pi at the point of capture, so an item is detected, read, graded, labeled, and registered before it leaves the station. Heavy segmentation work is offloaded to a serverless GPU that scales to zero when idle, which keeps an edge-first system affordable.
| Edge | Raspberry Pi 5, OpenCV, Python, systemd |
| Detection | YOLOv11-nano + ByteTrack tracking |
| Preprocess | Kornia GPU: CLAHE, denoise, normalize |
| Read | pyzbar barcode (7 variants), UPC lookup |
| Fallback | GPT-4.1-mini vision when no barcode resolves |
| Segment | SAM 2.1 + GroundingDINO on Modal H100 |
| Output | Zebra ZPL over TCP, FastAPI + WebSocket dashboard |
End-to-end computer vision under real constraints: detection with tracking and stability gating, multi-strategy barcode reading with an LLM vision fallback, a rule-based routing engine, raw-socket thermal printing, and a split between edge and elastic GPU inference. The edge pipeline carries roughly 3,800 lines of tests.
A real-estate data platform: multi-source ingestion, a scoring engine, and a research agent over a property graph.
| Data | PostgreSQL, 25+ tables, 37 raw-SQL migrations; PostGIS |
| Services | Node API + FastAPI / Celery scoring service |
| AI | Claude agents; GPT-4.1 and Claude Vision analysis layer |
| Web | Next.js / TypeScript: search, favorites, alerts |
| Ops | Hetzner VPS, GitHub Actions CI/CD, JWT, rate limiting |
The lead score is a deterministic weighted heuristic by design, not a trained model. Main-app property search proxies external APIs (Zillow, PropData) with a Postgres cache; the proprietary geospatial scoring lives in the off-market service.
An AI-native video editor that cuts from the transcript.
Problem and contribution. Editors spend most of a session scrubbing for a moment they already remember. Cutroom transcribes first and makes the transcript the timeline: strike a sentence and the cut happens. It is built as a real non-linear editor, not a wrapper, with a media pool, multi-track timeline, color, and delivery. The engine is a worker of roughly forty FFmpeg operations (reframe, chromakey, transcription, text-to-speech, captions, color), each with its own test, driven by a Claude agent server that plans multi-step edits with forced tool-use and prompt caching, exposed over web, MCP, and CLI.
| Stack | TypeScript, React, Vite, Hono, FFmpeg, Claude · web / MCP / CLI |
| Link | github.com/connorodea/cutroom |
Measures when AI assistants recommend a merchant's store.
Problem and contribution. Search is moving inside assistants, where there is no rank to check and no analytics to read. Sightline fans a set of tracked buyer queries across multiple AI answer engines on a schedule, with bounded concurrency and cost caps, detects whether and how a store surfaces, and computes a visibility score and share-of-voice from a clean rubric. It reads naturally as data science: the interesting work is metric design and scoring over noisy generative output.
| Stack | Next.js, TypeScript, PostgreSQL · answer-engine query fan-out + scoring |
| Status | private repository; listed at connorodea.com/work |
Batch-writes correct EXIF GPS to photos from a map pin.
Problem and contribution. Local businesses are told to geotag their photos and given no usable tool to do it. GeoStamp writes correct EXIF GPS across a batch on both desktop and web. It is a compact, shipped systems piece: a Rust core wrapped in a Tauri desktop app, chosen for correct low-level metadata handling and a small install footprint.
| Stack | Rust, Tauri, React · desktop + web |
| Link | github.com/connorodea/geostamp · geostamp.app |
Each capability points to the projects where it is actually implemented.
Multi-source scrapers, adapter frameworks, manifest and record ingestion.
Null-safe normalizers, idempotent upserts, large relational schemas.
Redis Streams bus, consumer groups, sagas, event sourcing.
Typed, bi-temporal entity and relation graphs with optional Neo4j.
Feature-hash and legal embeddings, Qdrant / OpenSearch, degrade-not-fail.
LangGraph subgraphs; router plus specialist agents with forced tool-use.
YOLOv11 detection and tracking, SAM 2.1 segmentation, OCR and barcode.
Multi-provider cost-aware cascades; serverless GPU with scale-to-zero.
Monte Carlo, ISMCTS, Bayesian and Kalman updates, Dirichlet priors.
Nash equilibria, best-response and exploitability over bounded branches.
Signal-weighted propensity scores; answer-engine visibility scoring.
Fail-closed review gates, append-only audit, governed egress.
| Area | What is implemented | Where |
|---|---|---|
| API design | REST services behind a reverse-proxy gateway with JWT auth, rate limiting, and generated OpenAPI docs; ~60-endpoint FastAPI surface. | QuickWMS · Juricratic · AIWholesail |
| Service boundaries | Domain-driven services that communicate only through events and the gateway; an AST-enforced dependency ladder in the Python core. | QuickWMS · Juricratic |
| Data architecture | Hand-written PostgreSQL layers, 55 and 25+ table schemas, PostGIS geospatial graph, event store, bi-temporal graph. | QuickWMS · AIWholesail · Juricratic |
| Messaging and jobs | Redis Streams event bus with consumer groups, DLQ, and sagas; Celery workers; PM2-managed background processes. | QuickWMS · AIWholesail |
| Caching | Redis for cache and pub/sub; Postgres-backed API response caching for external data feeds. | QuickWMS · AIWholesail |
| Auth and access | JWT auth, tiered rate limiting; relationship-based access control with a privilege gate and PII scrubbing on egress. | AIWholesail · Juricratic |
| Deployment | GitHub Actions CI/CD to a Hetzner VPS; Turborepo + pnpm builds; systemd services on edge devices; Modal for serverless GPU. | AIWholesail · QuickWMS · QuickVisionz |
| Testing | Vitest, Jest, and pytest suites; per-operation tests in the video engine; a strict branch-coverage gate in the Python core. | Juricratic · Cutroom · QuickVisionz · QuickWMS |
| Observability and audit | Append-only event and audit stores; health-check and rollback scripts; monitoring services. | QuickWMS · Juricratic |
| Security posture | Fail-closed governed egress, secrets kept out of source, Helmet and CORS hardening at the gateway. | Juricratic · QuickWMS |
A curated subset chosen for technical depth and relevance, not a full repository dump. Public repositories are linked.
| Project | Purpose | Languages | Status | Repository |
|---|---|---|---|---|
| QuickWMS | Event-driven warehouse and reverse-logistics platform | TypeScript, SQL | Core built | private |
| Juricratic | Litigation modeled as a governed decision and simulation system | Python, TypeScript | Core built | private |
| QuickVisionz | Edge CV item identification and grading with GPU offload | Python | Edge built | private |
| AIWholesail | Real-estate data platform, ETL, scoring, research agents | TypeScript, Python, SQL | In service | github.com/connorodea/aiwholesail |
| Cutroom | Transcript-driven AI video editor with an agent engine | TypeScript | Building | github.com/connorodea/cutroom |
| Sightline | AI answer-engine visibility scoring for merchants | TypeScript | Building | private |
| GeoStamp | Batch EXIF GPS geotagging, desktop and web | Rust, TypeScript | Live | github.com/connorodea/geostamp |
| APIDistributed | Agent-native, edge-deployed API marketplace (MCP surface) | TypeScript | Building | private |
Full public shipping log at connorodea.com. Private repositories are described in this document but not linked; they can be shared directly on request.
I am drawn to systems where machine learning, probabilistic reasoning, distributed software, and human judgment meet. The work I care about ingests messy real-world information, turns it into a structured representation, and improves the quality of a decision through data, inference, and feedback.
I design systems, not isolated features. A model is rarely the hard part. The hard part is the pipeline that feeds it, the state it updates, the events that keep everything consistent, and the interface a person actually trusts. I spend my effort on that connective tissue.
I turn unstructured reality into structured representations. Warehouse items, legal documents, county records, and camera frames all start as noise. Giving them a schema, a graph, or an event stream is what makes downstream reasoning possible.
I connect machine learning to operational workflows. Inference is only useful when it moves through to a routed item, a published listing, a reviewed claim. I build the path from a prediction to an action.
I design for auditability and human review. Consequential systems should be able to explain what they believed and why. Append-only histories, fail-closed review gates, and governed state are defaults in my work, not afterthoughts.
I model uncertainty honestly. When a system cannot know something, it should say so. I would rather ship a calibrated simulation that refuses to fake a probability than a confident number with nothing behind it.
I balance experimentation with discipline. Tests, migrations, and deployment are how a prototype becomes software that runs. I move fast, but I leave a clean seam for the next model, the next service, and the next engineer.
Private repositories described here (QuickWMS, Juricratic, QuickVisionz, Sightline) can be shared directly with the admissions committee on request.
Thank you for reading. Everything in this portfolio is something I designed, built, and can walk through in depth. I would welcome the chance to do exactly that.