
GOLDGUARD
Jewelry intelligence. In real time.
An AI + hardware + computer-vision security system that turns jewellery display surfaces into continuously weighed zones, so a piece leaving a tray becomes an event instead of a discovery at closing time.
GoldGuard is a real-time physical inventory intelligence and loss-prevention platform for jewellery stores. Four load-cell zones under a display surface feed a 24-bit delta-sigma ADC and an ESP32-S3 controller; the backend runs a DSP filter cascade, a stability state machine, an event classifier and a cross-zone correlation engine that recognises zero-loss internal transfers. Results stream over WebSocket into a React dashboard with roles, share links and a morning report.
A parallel vision subsystem adds camera-based person and hand tracking with the load cell remaining authoritative: a wrong association degrades to AMBIGUOUS, never to a false theft alert. The repository is self-auditing about its own status — the software platform is functional and covered by an automated suite, the simulation is verified, the firmware builds for ESP32-S3, and physical validation is explicitly awaiting hardware.
Overview
The gold itself is the shield. GoldGuard makes every gram on a showcase into data — continuously weighed, classified into business events, correlated across zones and delivered to the store in real time.
Problem
Jewellery loss is discovered at closing time, when a count comes up short and nobody can say which tray, which hour or which hand. Cameras record everything and explain nothing. A scale under a single tray tells you a weight, not an event.
“A piece leaving a tray becomes an event — ITEM_REMOVED, ITEM_ADDED, INTERNAL_TRANSFER, TRAY_REMOVED, TAMPER_EVENT — rather than a discovery at closing time.”
System
Layer 1 is transducers: four single-point strain-gauge load cells rated 5 kg per zone, a TMP117 temperature sensor and a LIS2DW12 accelerometer for vibration and tamper. Layer 2 is the ESP32-S3 edge firmware sampling 10–80 Hz per channel with on-device DSP and a stability state machine. Layer 3 is a clean-architecture backend — domain, application, infrastructure, API — with Express, a ws hub and PostgreSQL behind a repository contract with an in-memory fallback.
The weight pipeline is an outlier rejection → moving median → EMA → moving-average cascade, then drift compensation, then a statistical stability engine and an event classifier. A cross-zone correlation engine matches ΣΔW ≈ 0 across zones inside a 1.5 s window to recognise a piece moved from one tray to another as an internal transfer, not a loss.
Architecture
- LOAD CELLS ×45 kg / zone
- ADS1234 24-BIT ADCgain 128
- ESP32-S3 FIRMWAREDSP · FSM · offline queue
- STORE-AND-FORWARD INGESTsequence guard
- WEIGHT ENGINEfilters · drift · stability · classifier
- CROSS-ZONE CORRELATIONΣΔW ≈ 0 in 1.5 s
- VISION FUSIONhand-carried identity · cells authoritative
- POSTGRESQL27 tables · migrations
- WEBSOCKET HUBtoken-gated
- DASHBOARD · DESKTOP · PORTALReact · Tauri · Cloudflare
Repository surface
- 01backend — Express API, ws hub, engines, migrations, 36 test files
- 02frontend/goldguard-dashboard — React 19 + Vite, 23+ views, Arabic / Hebrew / English
- 03apps/marketing — Next.js static export, scroll-driven three.js product story, 5 languages
- 04apps/desktop — Tauri 2 shell with Windows and macOS release workflows
- 05apps/twin-studio + simulator/goldguard-twin — visual and headless digital twin
- 06services/goldguard-vision + goldguard-vision-runtime — pure-TS vision domain and ONNX runtime
- 07services/goldguard-vision/ml — PyTorch training, evaluation, ONNX export
- 08firmware/goldguard-controller — ESP-IDF C++ for ESP32-S3
- 09hardware/cad/fusion360 — parametric Fusion 360 scripts; geometry exported to the web
AI & Vision
The vision architecture starts from a measured constraint rather than a wish list: on 3840×2160 shop footage a ring on the tray has a median footprint of 28 px, and after the detector's 800 px resize it is 5.8 px against a smallest anchor of 32 px. Whole-frame inference found 0 rings where 32 native tiles found 7. So the design runs two streams — people and hands on a downscaled frame at 10 Hz, tray census on native-resolution tiles gated by hand presence — and lets a piece inherit identity from the hand that carried it.
“Individual continuous identity for ~50 static, touching, near-identical rings is a problem degeneracy, not a model-quality limit. Track the hand; let the piece inherit identity from its carrier.”
Design
The gold itself is the shield.
Two opposed gold faces form a shield with a bar on a weighing platform at its dark heart. Straight geometry only, legible from a billboard to a 16 px favicon. Sensor cyan is reserved for live measurement inside the dashboard and is deliberately kept out of the mark.
- —GOLD in #F5F7FA, GUARD in the gold gradient
- —Inter ExtraBold, letter-spacing 2.5
- —Compact cut for 16–31 px, mono cut for engraving
Challenges
- 01A first filter tuning cancelled real weight changes as outliers — an 8 g pull produced 0 events. Fixed on 2026-08-23; the same pull now yields exactly one ITEM_REMOVED with Δ −8.05 g.
- 02v1.0.0-rc was 67/67 green while the PostgreSQL path was broken: green tests that never touch the production path prove nothing about it. The real-Postgres suite is now part of CI.
- 03The product briefly split across two trees with 44 conflicted files and six semantic conflicts a merge tool would not flag. A written merge plan and an architecture audit precede the merge.
- 04No load cell has ever been connected. Every mass, noise and latency number in the repository is labelled a design target, not a measurement.
Results
The client receives a permanent, tunnel-free progress portal on Cloudflare Workers — percentage, the five-week plan, what was completed and what comes next — while live measurements and the operational console never reach it.