Your closet as governed data in DataHub. An AI roasts your wear habits using only verified stats. No cap.
A wardrobe agent that models your clothes as governed data assets in DataHub — tracking real wear history, ownership, and staleness — so an AI can roast your habits with only verified numbers, and a buyer can trust a garment's condition on resale.
Built for Build with DataHub: The Agent Hackathon by Ishani Kathuria & Yasaa Usman Khan. 📄 Full submission writeup: DEVPOST.md · 🎥 Demo video:
[PASTE DEMO VIDEO URL]
Your closet has two hidden problems, and both are really metadata & provenance problems — DataHub's home turf:
- You don't know your own wardrobe. You wear ~20% of your clothes 80% of the time, buy duplicates, and forget things exist.
- Resale runs on blind trust. "Worn twice, like new" is unverifiable.
Slaydar models each garment as a DataHub Dataset entity with real ownership, usage stats, staleness flags, and cross-owner lineage. On top of the graph sit three AI agents (vision extraction, check-in matching, and a stat-backed roast persona). The roast is architecturally forbidden from citing any number that isn't in the DataHub record — a small, legible proof of an LLM grounded in governed metadata.
We don't just read DataHub — every catalog, check-in, staleness sweep, and resale writes back to the graph.
| Step | What happens | DataHub write |
|---|---|---|
| Catalog | Upload closet photos or paste a product link → vision agent extracts category/color/material/brand/tags | creates a Dataset entity + Ownership + GlossaryTerms + properties |
| Check in | Photograph today's outfit → match agent finds the garment → you confirm | wear_count, last_worn_date, cost_per_wear, condition_score updated |
| Roast | Slaydar delivers one stat-backed line using only real stats | (reads the graph) |
| Flag | 4+ wears in 7 days = overworn; 30 days untouched = never-worn | native Deprecation aspect |
| Resell | List a flagged item with a verified Condition Score; transfer ownership | new dataset URN + UpstreamLineage → live lineage graph |
Next.js app (frontend + runtime agents) FastAPI service (the only DataHub writer)
- upload / check-in / roast / listing UI --> - POST /garments (create entity)
- Gemini agents run in-app at runtime: - POST /garments/{id}/checkin
· vision extraction - POST /garments/evaluate-staleness
· check-in matching - POST /garments/{id}/transfer-owner
· roast generation - GET /garments/{id}/lineage
- GET /closet/{owner_id}
|
acryl-datahub Python SDK
| (MetadataChangeProposals)
DataHub GMS (docker quickstart, v1.7.0)
:9002 UI · :8080 GMS
Two services, one shared DataHub instance, a small REST contract (docs/api-contract.md) between them. Only /api talks to DataHub; the frontend talks only to /api.
No forked entity types — every garment is a DataHub Dataset (urn:li:dataset:(urn:li:dataPlatform:slaydar,<garment_id>,PROD)), and each concept maps to a built-in aspect it genuinely fits:
| Garment concept | DataHub aspect |
|---|---|
| Owner (reassigned on resale) | Ownership |
| Style tags | GlossaryTerms |
| category / color / material / brand / wear_count / last_worn_date / cost_per_wear / condition_score / cataloged_date / status | DatasetProperties.customProperties |
| Overworn / never-worn | Deprecation |
| History across owners | new URN per ownership period + UpstreamLineage |
Full detail in docs/datahub-schema.md.
Prerequisites: Docker, Python 3.10–3.12 (not 3.13+), Node 18+, a Gemini API key (free tier), and the DataHub CLI (pip install acryl-datahub).
cd api
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
# One command brings up the whole stack: DataHub -> glossary -> API -> tunnel -> seed
./scripts/demo_up.sh --seedThis starts DataHub (datahub docker quickstart, ~1 min), seeds the glossary + a coherent demo closet, and runs the API on :8000. DataHub UI is at http://localhost:9002 (datahub/datahub).
Running the API by hand instead:
uvicorn app.main:app --reload --port 8000. If DataHub is unreachable the client runs in dry-run mode (logs the MetadataChangeProposal it would emit) so the API still boots for frontend work.
cd web
npm install
# .env.local:
# GEMINI_API_KEY=your_key_here
# API_BASE_URL=http://localhost:8000
npm run devOpen http://localhost:3000.
cd api && source .venv/bin/activate
pip install -r requirements-dev.txt
pytest # hermetic: forced dry-run, never touches the shared DataHubMirrors the recorded video (see PLAN.md §7):
- Upload closet photos → extraction agent tags items live.
- Daily check-in → Slaydar roasts a repeat outfit, citing a real wear count.
- Overworn / never-worn flag triggers a resale suggestion.
- Paste a product link → resolves to a canonical item.
- Close on the listing's Condition Score → then pull up the live DataHub lineage graph showing the garment's ownership chain. This is the moment that proves the DataHub integration is real.
| Path | What | Owner |
|---|---|---|
web/ |
Next.js 16 (TypeScript) frontend + runtime Gemini agents | Yasaa |
api/ |
FastAPI service wrapping the acryl-datahub SDK |
Ishani |
docs/api-contract.md |
REST contract between /web and /api |
shared |
docs/datahub-schema.md |
DataHub entity/aspect mapping | shared |
PLAN.md |
Full build plan, schema rationale, locked agent prompt, demo script | shared |
DEVPOST.md |
Devpost submission writeup | shared |
Frontend: Next.js 16 (App Router, React 19) · TypeScript · Tailwind v4 · Google Gemini 2.5 Flash (@google/genai)
Backend: FastAPI · Python · acryl-datahub SDK · Pydantic · pytest
Infra: DataHub v1.7.0 (datahub docker quickstart) · Docker · ngrok