From 1a51cbc323b8103514ecce676eb4aaed980b814f Mon Sep 17 00:00:00 2001 From: Mikkel Georgsen Date: Fri, 10 Apr 2026 00:04:27 +0000 Subject: [PATCH] docs: create roadmap (7 phases) --- .planning/REQUIREMENTS.md | 104 ++++++++++++------------- .planning/ROADMAP.md | 125 ++++++++++++++++++++++++++++++ .planning/STATE.md | 63 +++++++++++++++ CLAUDE.md | 157 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 397 insertions(+), 52 deletions(-) create mode 100644 .planning/ROADMAP.md create mode 100644 .planning/STATE.md create mode 100644 CLAUDE.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index df2ec91..4648ee0 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -112,61 +112,61 @@ | Requirement | Phase | Status | |-------------|-------|--------| -| NB-01 | — | Pending | -| NB-02 | — | Pending | -| NB-03 | — | Pending | -| NB-04 | — | Pending | -| NB-05 | — | Pending | -| NB-06 | — | Pending | -| NB-07 | — | Pending | -| AI-01 | — | Pending | -| AI-02 | — | Pending | -| AI-03 | — | Pending | -| AI-04 | — | Pending | -| AI-05 | — | Pending | -| AI-06 | — | Pending | -| AI-07 | — | Pending | -| AI-08 | — | Pending | -| AI-09 | — | Pending | -| LBL-01 | — | Pending | -| LBL-02 | — | Pending | -| LBL-03 | — | Pending | -| LBL-04 | — | Pending | -| LBL-05 | — | Pending | -| CBL-01 | — | Pending | -| CBL-02 | — | Pending | -| CBL-03 | — | Pending | -| CBL-04 | — | Pending | -| CBL-05 | — | Pending | -| CBL-06 | — | Pending | -| CBL-07 | — | Pending | -| UI-01 | — | Pending | -| UI-02 | — | Pending | -| UI-03 | — | Pending | -| UI-04 | — | Pending | -| UI-05 | — | Pending | -| UI-06 | — | Pending | -| ADV-01 | — | Pending | -| ADV-02 | — | Pending | -| ADV-03 | — | Pending | -| ADV-04 | — | Pending | -| ADV-05 | — | Pending | -| USB-01 | — | Pending | -| USB-02 | — | Pending | -| USB-03 | — | Pending | -| USB-04 | — | Pending | -| PWA-01 | — | Pending | -| PWA-02 | — | Pending | -| PWA-03 | — | Pending | -| INF-01 | — | Pending | -| INF-02 | — | Pending | -| INF-03 | — | Pending | +| NB-01 | Phase 1 | Pending | +| NB-02 | Phase 1 | Pending | +| NB-03 | Phase 1 | Pending | +| NB-04 | Phase 1 | Pending | +| NB-05 | Phase 1 | Pending | +| NB-06 | Phase 1 | Pending | +| NB-07 | Phase 1 | Pending | +| AI-01 | Phase 2 | Pending | +| AI-02 | Phase 2 | Pending | +| AI-03 | Phase 2 | Pending | +| AI-04 | Phase 7 | Pending | +| AI-05 | Phase 2 | Pending | +| AI-06 | Phase 2 | Pending | +| AI-07 | Phase 2 | Pending | +| AI-08 | Phase 2 | Pending | +| AI-09 | Phase 2 | Pending | +| LBL-01 | Phase 4 | Pending | +| LBL-02 | Phase 4 | Pending | +| LBL-03 | Phase 4 | Pending | +| LBL-04 | Phase 4 | Pending | +| LBL-05 | Phase 4 | Pending | +| CBL-01 | Phase 5 | Pending | +| CBL-02 | Phase 5 | Pending | +| CBL-03 | Phase 5 | Pending | +| CBL-04 | Phase 5 | Pending | +| CBL-05 | Phase 5 | Pending | +| CBL-06 | Phase 5 | Pending | +| CBL-07 | Phase 5 | Pending | +| UI-01 | Phase 3 | Pending | +| UI-02 | Phase 3 | Pending | +| UI-03 | Phase 7 | Pending | +| UI-04 | Phase 3 | Pending | +| UI-05 | Phase 3 | Pending | +| UI-06 | Phase 3 | Pending | +| ADV-01 | Phase 6 | Pending | +| ADV-02 | Phase 6 | Pending | +| ADV-03 | Phase 6 | Pending | +| ADV-04 | Phase 6 | Pending | +| ADV-05 | Phase 6 | Pending | +| USB-01 | Phase 4 | Pending | +| USB-02 | Phase 4 | Pending | +| USB-03 | Phase 4 | Pending | +| USB-04 | Phase 4 | Pending | +| PWA-01 | Phase 3 | Pending | +| PWA-02 | Phase 3 | Pending | +| PWA-03 | Phase 3 | Pending | +| INF-01 | Phase 1 | Pending | +| INF-02 | Phase 1 | Pending | +| INF-03 | Phase 1 | Pending | **Coverage:** - v1 requirements: 46 total -- Mapped to phases: 0 -- Unmapped: 46 +- Mapped to phases: 46 +- Unmapped: 0 --- *Requirements defined: 2026-04-09* -*Last updated: 2026-04-09 after initial definition* +*Last updated: 2026-04-09 after roadmap creation — all 46 requirements mapped* diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md new file mode 100644 index 0000000..1496aa9 --- /dev/null +++ b/.planning/ROADMAP.md @@ -0,0 +1,125 @@ +# Roadmap: HWLab + +## Overview + +HWLab is built in seven phases, each delivering a complete, independently verifiable capability. The foundation establishes the NetBox integration and project scaffold before any feature work. AI photo intake — the core value proposition — is validated as a standalone backend capability before the UI is built around it. USB hardware (arriving 2026-04-13) is characterized and the USB Manager infrastructure is established before cable testing features are layered on top. The Lab Advisor and SearXNG research agent close out the roadmap as enhancement layers that require all primitives to already exist. + +## Phases + +**Phase Numbering:** +- Integer phases (1, 2, 3): Planned milestone work +- Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED) + +Decimal phases appear between their surrounding integers in numeric order. + +- [ ] **Phase 1: Foundation** - Go binary scaffold, NetBox integration, custom fields, write-ahead queue +- [ ] **Phase 2: AI Pipeline** - oMLX + Gemma 4 setup, three-tier orchestrator, photo intake endpoint, quality gate +- [ ] **Phase 3: Dashboard & Intake UI** - React SPA embedded in binary, inventory dashboard, intake flow, item detail view +- [ ] **Phase 4: USB Manager & Label Printing** - USB hardware characterization (2026-04-13), goroutine-per-device manager, QR label printing +- [ ] **Phase 5: Cable Test Integration** - Treedix USB/DP/HDMI testers, FNIRSI FNB58, cable test workflow UI +- [ ] **Phase 6: Lab Advisor** - Claude Opus chat interface, NetBox context assembly, streaming SSE, chat history +- [ ] **Phase 7: Research Agent & Search** - SearXNG Tier 2 research agent, natural language inventory search, quality gate automation + +## Phase Details + +### Phase 1: Foundation +**Goal**: The Go binary connects to NetBox with all custom fields provisioned and a write-ahead queue buffering operations during downtime +**Depends on**: Nothing (first phase) +**Requirements**: INF-01, INF-02, INF-03, NB-01, NB-02, NB-03, NB-04, NB-05, NB-06, NB-07 +**Success Criteria** (what must be TRUE): + 1. Running Go binary serves a health endpoint and embeds a stub React SPA + 2. All HWLab custom fields (hw_id, catalog_status, photo_urls, etc.) are readable and writable via the NetBox API with round-trip test coverage + 3. A new item can be created in NetBox with a sequential HW-XXXXX ID auto-assigned + 4. catalog_status transitions from draft through complete are enforced by the backend quality gate + 5. A write-ahead queue in SQLite buffers failed NetBox operations and retries them on reconnect +**Plans**: TBD + +### Phase 2: AI Pipeline +**Goal**: Users can submit 1-3 photos and receive a structured NetBox-ready record with AI-extracted specs, suggested category/tags, and a quality gate status reflecting confidence +**Depends on**: Phase 1 +**Requirements**: AI-01, AI-02, AI-03, AI-04, AI-05, AI-06, AI-07, AI-08, AI-09 +**Success Criteria** (what must be TRUE): + 1. oMLX serves Gemma 4 on Mac Mini M4 with measured memory budget documented + 2. POST /api/intake with 1-3 photos returns serial number, model, manufacturer, specs, category, and tags extracted by AI + 3. Items with AI confidence below threshold are automatically set to needs_research; high-confidence items advance to indexed + 4. Quick add mode skips review for high-confidence items and creates the NetBox record in one step + 5. Any AI tier (local oMLX, OpenRouter) can be swapped by changing a config JSON value with no code changes +**Plans**: TBD +**UI hint**: no + +### Phase 3: Dashboard & Intake UI +**Goal**: Users can browse their full inventory, run intake for new items, and view item detail — all through the React SPA served by the Go binary +**Depends on**: Phase 2 +**Requirements**: UI-01, UI-02, UI-03, UI-04, UI-05, UI-06, PWA-01, PWA-02, PWA-03 +**Success Criteria** (what must be TRUE): + 1. Inventory dashboard loads with grid/list toggle, item cards showing photo, HW ID, status, and key specs + 2. User can filter inventory by category, tags, catalog status, and location without a page reload + 3. User can view full item detail including photos, specs, test data, and audit history + 4. Intake flow accepts 1-3 photo uploads, shows AI classification result inline, and allows correction before creating the NetBox record + 5. App is installable as a PWA on Android and the camera-based QR scanner resolves items by HW ID +**Plans**: TBD +**UI hint**: yes + +### Phase 4: USB Manager & Label Printing +**Goal**: USB peripherals are managed by a goroutine-per-device subsystem and any cataloged item can have a QR-coded label printed by the PRT Qutie without operator intervention after intake +**Depends on**: Phase 3 +**Requirements**: USB-01, USB-02, USB-03, USB-04, LBL-01, LBL-02, LBL-03, LBL-04, LBL-05 +**Success Criteria** (what must be TRUE): + 1. USB Manager discovers the PRT Qutie by VID/PID and reconnects automatically after unplug/replug without path reconfiguration + 2. USB device connect/disconnect events appear in the frontend in real time via SSE + 3. A QR label with HW ID, item name, key spec line, and QR code is printed for any item from the dashboard quick actions + 4. Cable-specific label template correctly shows USB version, speed, wattage, and test date + 5. Label printing completes as the final step of the AI intake workflow without leaving the intake screen +**Plans**: TBD +**UI hint**: yes + +### Phase 5: Cable Test Integration +**Goal**: Any cable can be tested, its results written to NetBox, and a label printed in a rapid test-verify-print workflow without leaving the Cable Test Station view +**Depends on**: Phase 4 +**Requirements**: CBL-01, CBL-02, CBL-03, CBL-04, CBL-05, CBL-06, CBL-07 +**Success Criteria** (what must be TRUE): + 1. Plugging any Treedix tester into USB triggers auto-detection by VID/PID and activates the correct test flow + 2. USB, DisplayPort, and HDMI cable test results (continuity, version, eMarker, PD, resistance) are displayed in the Cable Test Station UI and written to the NetBox cable record as structured JSON + 3. FNIRSI FNB58 live voltage/current/PD protocol data streams to the UI and is persisted to the cable record + 4. A cable can go from test to label printed in under 30 seconds using the rapid workflow +**Plans**: TBD +**UI hint**: yes + +### Phase 6: Lab Advisor +**Goal**: Users can ask strategic homelab questions and receive streaming answers from Claude Opus with full inventory context, with conversation history persisted across sessions +**Depends on**: Phase 5 +**Requirements**: ADV-01, ADV-02, ADV-03, ADV-04, ADV-05 +**Success Criteria** (what must be TRUE): + 1. Chat interface sends a question and receives a streaming response from Claude Opus via OpenRouter with no page reload + 2. Each conversation automatically includes a pre-loaded NetBox inventory context summary + 3. Conversation history persists across browser sessions and is viewable in the chat UI + 4. Model can be switched from Opus to any OpenRouter-compatible model via the dropdown without restarting the server +**Plans**: TBD +**UI hint**: yes + +### Phase 7: Research Agent & Search +**Goal**: Items flagged needs_research are automatically enriched by a SearXNG research agent, and any inventory question can be answered via natural language search +**Depends on**: Phase 6 +**Requirements**: AI-04 +**Success Criteria** (what must be TRUE): + 1. An item at needs_research status is automatically enriched with product specs, datasheet links, and pricing by the SearXNG Tier 2 agent and advances to researched + 2. Natural language search ("show me all free 10GbE NICs") returns filtered inventory results drawn from NetBox + 3. SearXNG queries are sanitized before dispatch — no raw AI output reaches the search engine + +**Note:** AI-04 is the sole unmapped requirement from Phase 2 that belongs here — it requires the full orchestrator, SearXNG client, and NetBox inventory all in place. The other Phase 2 requirements cover Tier 1 intake; this requirement covers the Tier 2 research loop. +**Plans**: TBD + +## Progress + +**Execution Order:** +Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 + +| Phase | Plans Complete | Status | Completed | +|-------|----------------|--------|-----------| +| 1. Foundation | 0/TBD | Not started | - | +| 2. AI Pipeline | 0/TBD | Not started | - | +| 3. Dashboard & Intake UI | 0/TBD | Not started | - | +| 4. USB Manager & Label Printing | 0/TBD | Not started | - | +| 5. Cable Test Integration | 0/TBD | Not started | - | +| 6. Lab Advisor | 0/TBD | Not started | - | +| 7. Research Agent & Search | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md new file mode 100644 index 0000000..1a86d34 --- /dev/null +++ b/.planning/STATE.md @@ -0,0 +1,63 @@ +# Project State + +## Project Reference + +See: .planning/PROJECT.md (updated 2026-04-09) + +**Core value:** Any physical item can be cataloged by uploading a photo — AI extracts data, creates a NetBox record, and prints a QR-coded label — with zero manual data entry for 80-90% of items. +**Current focus:** Phase 1 — Foundation + +## Current Position + +Phase: 1 of 7 (Foundation) +Plan: 0 of TBD in current phase +Status: Ready to plan +Last activity: 2026-04-09 — Roadmap created, all 46 v1 requirements mapped to 7 phases + +Progress: [░░░░░░░░░░] 0% + +## Performance Metrics + +**Velocity:** +- Total plans completed: 0 +- Average duration: — +- Total execution time: 0 hours + +**By Phase:** + +| Phase | Plans | Total | Avg/Plan | +|-------|-------|-------|----------| +| - | - | - | - | + +**Recent Trend:** +- Last 5 plans: — +- Trend: — + +*Updated after each plan completion* + +## Accumulated Context + +### Decisions + +Decisions are logged in PROJECT.md Key Decisions table. +Recent decisions affecting current work: + +- Init: NetBox as sole data store (no local inventory DB) +- Init: Three-tier AI pipeline (oMLX Gemma 4 → OpenRouter research → Claude Opus advisor) +- Init: ClickHouse design system (pure black #000000, neon volt #faff69) + +### Pending Todos + +None yet. + +### Blockers/Concerns + +- USB hardware (PRT Qutie, Treedix testers, FNIRSI FNB58) arrives 2026-04-13 — Phase 4 cannot begin until protocol characterization spike completes on that date +- Gemma 4 memory budget on Mac Mini M4 (16GB) must be measured empirically in Phase 2 before model tier is finalized +- PRT Qutie USB protocol is completely unknown — first action on 2026-04-13 is Wireshark USB capture, not feature development + +## Session Continuity + +Last session: 2026-04-09 +Stopped at: Roadmap created — ready to run /gsd-plan-phase 1 +Resume file: None diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..1be2315 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,157 @@ + +## Project + +**HWLab** + +HWLab is a self-hosted, AI-powered hardware inventory management system for homelab environments. It combines local multimodal AI (Gemma 4 via oMLX) for photo-based intake and categorization, NetBox as the authoritative inventory database, and automated label printing with integrated cable testing workflows. Built with Go + React, running entirely on a Mac Mini M4. + +**Core Value:** Any physical item can be cataloged by uploading a photo — AI extracts data, creates a NetBox record, and prints a QR-coded label — with zero manual data entry for 80-90% of items. + +### Constraints + +- **Hardware**: Mac Mini M4 with 16GB — Gemma 4 model must fit in memory (E4B confirmed, 26B A4B needs testing with TurboQuant) +- **No cloud dependency**: Standard operations must work fully local — OpenRouter only for Tier 2/3 AI +- **NetBox is source of truth**: HWLab stores no inventory data locally (only advisor chat history + config in SQLite) +- **USB protocols**: Printer and tester protocols need reverse-engineering once hardware arrives +- **Tech stack**: Go backend, React TypeScript frontend, Tailwind CSS + + + +## Technology Stack + +## Recommended Stack +### Core Technologies +| Technology | Version | Purpose | Why Recommended | +|------------|---------|---------|-----------------| +| Go | 1.22+ | Backend API, USB/serial control, AI orchestration | Native concurrency for USB polling + HTTP serving; single binary deployment; no runtime dependency; best-in-class serial I/O on macOS | +| React | 18.x | SPA frontend | Mature ecosystem, hooks-based state management, excellent TypeScript support; right level of complexity for a single-operator tool | +| TypeScript | 5.x | Frontend type safety | Catches API contract drift early; NetBox has complex nested types that benefit from strict typing | +| Tailwind CSS | 3.x | Utility-first styling | ClickHouse-inspired design system maps well to utility classes; no CSS file sprawl; dark theme with arbitrary values is trivial | +| SQLite (via mattn/go-sqlite3) | 3.x / v1.14+ | Local-only storage (chat history, config, session state) | Zero-dependency embedded DB; perfectly suited for single-operator append-heavy chat logs; no separate process | +| oMLX | latest | Local LLM inference server on Mac Mini M4 | Native Apple Silicon MLX backend, OpenAI-compatible API endpoint, paged SSD KV caching, continuous batching; supports Gemma 4 VLM natively; drop-in for any OpenAI-SDK client | +### Go Backend Libraries +| Library | Version | Purpose | When to Use | +|---------|---------|---------|-------------| +| github.com/netbox-community/go-netbox/v4 | v4.x | NetBox REST API client | All CRUD against NetBox — officially maintained, generated from NetBox OpenAPI spec | +| go.bug.st/serial | v1.x | USB serial communication | Printer + cable tester I/O; actively maintained, cross-platform, better API than tarm/serial; supports port enumeration | +| github.com/gin-gonic/gin | v1.9+ | HTTP router and middleware | Fast, well-documented, large middleware ecosystem; handles file uploads for photo intake cleanly | +| github.com/mattn/go-sqlite3 | v1.14+ | SQLite driver (cgo) | Standard Go SQLite driver; use with database/sql for portability | +| github.com/jmoiern/sqlx | v1.3+ | database/sql extension | Named params and struct scanning reduce boilerplate for chat history queries | +| github.com/sashabaranov/go-openai | v1.x | OpenAI-compatible client | Handles both oMLX local endpoint and OpenRouter remote; single client, swap base URL per tier | +| github.com/skip2/go-qrcode | v0.0.0 | QR code generation | Generate HW-XXXXX QR codes server-side before sending to printer | +| github.com/google/uuid | v1.x | UUID generation | HW-XXXXX ID assignment; deterministic or random depending on design choice | +| github.com/spf13/viper | v1.x | Config management | YAML/env config for AI endpoints, NetBox URL/token, USB port paths | +### Frontend Libraries +| Library | Version | Purpose | When to Use | +|---------|---------|---------|-------------| +| Vite | 5.x | Build tool and dev server | Fastest HMR in class; Go backend runs separately, Vite proxies API calls in dev | +| TanStack Query (React Query) | v5 | Server state management | NetBox data is server state not client state; handles caching, refetch, stale-while-revalidate | +| TanStack Router | v1 | Type-safe routing | Better TypeScript integration than React Router v6 for complex nested routes | +| Zustand | v4 | Client state (UI state, chat) | Lightweight, no boilerplate, perfect for chat message buffer and USB device status | +| shadcn/ui | latest | Component primitives | Radix UI + Tailwind, fully owned code (not a dependency), dark mode first, ClickHouse aesthetic compatible | +| react-dropzone | v14 | Photo drag-and-drop | Standard library for file upload UX; works with multipart form to Go backend | +| react-hot-toast | v2 | Toast notifications | Inventory actions (label printed, test passed) need lightweight non-blocking feedback | +| lucide-react | latest | Icon set | Consistent, tree-shakeable, TypeScript-native, pairs well with shadcn/ui | +### Development Tools +| Tool | Purpose | Notes | +|------|---------|-------| +| Air (cosmtrek/air) | Go hot reload in development | Watch + rebuild backend on save; configure alongside Vite proxy | +| golangci-lint | Go linting | Run in CI; catches serial/concurrent code issues early | +| ESLint + typescript-eslint | Frontend linting | Strict TypeScript rules; catch NetBox API type drift | +| Prettier | Frontend formatting | Single config, no debates | +| Bruno (or httpie) | API testing | Test NetBox integration and Go endpoints locally without Postman account | +## Installation +# Go backend — initialize module +# Core Go dependencies +# Frontend — scaffold +# Frontend core dependencies +# shadcn/ui init (run in frontend dir) +# Dev dependencies +## Alternatives Considered +| Recommended | Alternative | When to Use Alternative | +|-------------|-------------|-------------------------| +| go.bug.st/serial | tarm/serial | tarm/serial is adequate if you only need basic read/write and already have it; go.bug.st/serial is preferred for new projects due to active maintenance and port listing | +| gin-gonic/gin | chi, echo, fiber | chi if you want stdlib-compatible handlers; echo for similar feature set; fiber if you need extreme HTTP throughput (not relevant here) | +| go-openai (sashabaranov) | Custom HTTP client | Custom client only if you need streaming SSE to browser — go-openai supports streaming too, prefer it | +| TanStack Router | React Router v6 | React Router v6 is fine if team is already familiar; TanStack Router has stronger TypeScript guarantees for route params | +| TanStack Query | SWR | SWR is lighter but TanStack Query has better devtools and mutation handling for NetBox writes | +| mattn/go-sqlite3 (cgo) | modernc.org/sqlite (pure Go) | Use modernc.org/sqlite if you want zero cgo dependency (simpler cross-compilation); slightly slower but avoids gcc requirement | +| oMLX | Ollama | Ollama works but oMLX has better Apple Silicon performance via MLX backend; Gemma 4 VLM continuous batching support is oMLX-specific | +## What NOT to Use +| Avoid | Why | Use Instead | +|-------|-----|-------------| +| GORM | Heavy ORM abstraction for what is essentially two tables (chat logs, config); migrations and reflection overhead not worth it for SQLite local-only store | database/sql + sqlx directly | +| tarm/serial | Last commit 2018, unmaintained, no port enumeration, open issues unaddressed | go.bug.st/serial | +| Redux (React) | Massive boilerplate for a solo-operator SPA; overkill when TanStack Query handles server state | Zustand + TanStack Query | +| axios | Unnecessary HTTP client abstraction; TanStack Query works with native fetch; one fewer dependency | fetch API directly inside TanStack Query | +| Next.js | SSR/SSG overhead not needed — Go handles the API, React is a pure SPA served as static files | Vite + React SPA | +| llama.cpp Go bindings | Not optimized for Apple Silicon; MLX backend (oMLX) is 2-4x faster on M-series; cgo binding complexity | oMLX via OpenAI-compatible HTTP | +| Direct NetBox HTTP calls (no client) | NetBox v4 API has 200+ endpoints; go-netbox generates typed structs from OpenAPI spec — manual HTTP is brittle | go-netbox/v4 | +## Stack Patterns by Variant +- Use a single `go-openai` client instance per tier, configured with `BaseURL` pointing to oMLX (`http://localhost:PORT/v1`) for Tier 1, and `https://openrouter.ai/api/v1` for Tier 2/3 +- Switch by returning the appropriate client from a factory based on model config +- Do NOT hardcode tier selection in business logic — make it config-driven from the start +- Use `go.bug.st/serial` with a dedicated goroutine per device, communicating via channels +- Do not share a serial.Port across goroutines — open one port per device, serialize writes in the owning goroutine +- USB device paths on macOS follow `/dev/cu.usbserial-*` or `/dev/cu.usbmodem*`; use `serial.GetPortsList()` to enumerate at startup +- Accept multipart/form-data in Gin; decode image in Go; send as base64 in the OpenAI vision API call to oMLX +- Store the original photo in a local temp directory only until the NetBox record is created; do not persist photos in HWLab itself +- Gemma 4 E4B fits comfortably in 16GB; Gemma 4 26B A4B needs TurboQuant KV offload — benchmark before committing to 26B +- go-netbox v4 represents custom fields as `map[string]interface{}`; define typed wrapper structs in your own code to handle `hw_id`, `condition`, `quality_gate` etc. +- Custom fields must be created in NetBox admin before the Go code can write them — treat this as infrastructure provisioning (Phase 1 task) +## Version Compatibility +| Package | Compatible With | Notes | +|---------|-----------------|-------| +| go-netbox/v4 | NetBox 4.x | Generated from NetBox 4.x OpenAPI; not compatible with NetBox 3.x API responses | +| mattn/go-sqlite3 v1.14+ | Go 1.21+ | Requires cgo; needs gcc or Xcode CLT on macOS | +| shadcn/ui | React 18, Tailwind 3.x | shadcn v2+ requires Tailwind 3.x; not yet tested with Tailwind 4 alpha | +| oMLX | macOS 15+, Apple Silicon M1+ | Won't run on Intel Mac or Linux | +| go-openai v1.x | OpenAI API v1, OpenRouter, oMLX | Any OpenAI-compatible endpoint works; set `BaseURL` in `ClientConfig` | +## Sources +- [github.com/jundot/omlx](https://github.com/jundot/omlx) — oMLX feature set, Gemma 4 VLM support confirmed (HIGH confidence) +- [github.com/netbox-community/go-netbox](https://github.com/netbox-community/go-netbox) — Official Go client, v4 confirmed (HIGH confidence) +- [go.bug.st/serial pkg.go.dev](https://pkg.go.dev/go.bug.st/serial) — Active maintenance confirmed, preferred over tarm/serial (HIGH confidence) +- [omlx.ai](https://omlx.ai/) — macOS 15+ requirement, 16GB minimum RAM, MLX backend (HIGH confidence) +- WebSearch: tarm/serial maintenance status — last substantive commit 2018, multiple forks active (MEDIUM confidence) +- Training data: gin, TanStack Query, Zustand, Vite, shadcn/ui versions — standard 2025 React/Go stack (MEDIUM confidence, verify pinned versions before first install) + + + +## Conventions + +Conventions not yet established. Will populate as patterns emerge during development. + + + +## Architecture + +Architecture not yet mapped. Follow existing patterns found in the codebase. + + + +## Project Skills + +No project skills found. Add skills to any of: `.claude/skills/`, `.agents/skills/`, `.cursor/skills/`, or `.github/skills/` with a `SKILL.md` index file. + + + +## GSD Workflow Enforcement + +Before using Edit, Write, or other file-changing tools, start work through a GSD command so planning artifacts and execution context stay in sync. + +Use these entry points: +- `/gsd-quick` for small fixes, doc updates, and ad-hoc tasks +- `/gsd-debug` for investigation and bug fixing +- `/gsd-execute-phase` for planned phase work + +Do not make direct repo edits outside a GSD workflow unless the user explicitly asks to bypass it. + + + + + +## Developer Profile + +> Profile not yet configured. Run `/gsd-profile-user` to generate your developer profile. +> This section is managed by `generate-claude-profile` -- do not edit manually. +