Designed around reliability, auditability and self-hosted control rather than dependence on commercial cloud services.
The long-term aim is personalised modelling: learning behavioural and physiological patterns over time and using that knowledge to improve prediction and provide carefully constrained decision support around meals and insulin, with strong safety controls and transparent operation.
Architecture
The system runs 24/7 on a Raspberry Pi 5B as a systemd service. All primary data is stored locally in SQLite under self-hosted control. Nightscout polling remains available as a fallback.
Progress
The project followed a specification-first approach — every design decision was documented before implementation began.
- Phase 1 — Core Pipeline CompleteNightscout polling, SQLite storage, daemon with backfill, CLI. Hardened with dual-signal health monitoring, systemd timer, and 48-hour soak test.23 files · 1,070 lines · first implementation session
- Phase 1.5 — Meal Logging CompleteAI-assisted carb estimation via Gemini, Claude and GPT. Photo and text input, confirmation workflow, treatment storage. Flask API with session workflow.
- Phase 2.0 — glucore Engine CompleteIOB from oref0 exponential curves, trend analysis via linear regression, configurable prediction windows. Safety contract enforcement on all outputs.6 modules · 98 tests · validated against live data
- Phase 2.1 — glucore Enhancements CompleteCOB modelling with exponential carb absorption, autosens sensitivity adaptation, enhanced predictions combining IOB + COB + momentum, retrospective validation framework.
- Phase 3.1 — Ingest Endpoints CompleteDirect POST endpoints replacing Nightscout dependency. Nightscout-compatible format accepted from xDrip4iOS clones. Deterministic UUID-5 deduplication.
- Phase 3.2 — Nightscout Relay CompleteFire-and-forget relay to upstream Nightscout for redundancy. Circuit breaker with automatic recovery. Self-relay guard prevents infinite loops.
- Phase 3.3 — API-Only Cutover CompleteNightscout polling disabled. Both phones posting directly to islet API. Three commands, no data gap. Nightscout now receives relayed data only — optional infrastructure, not a dependency.
- Phase 4.0 — iOS Companion App CompleteNative SwiftUI app with glucose dashboard, AI-assisted food logging, camera capture, meal history, scrollable chart, component type-ahead, and Warm Amber theme. SwiftData offline cache with background sync.47 Swift files · 3,500+ SLOC · 23 tests
- Phase 4.0a — Platform Hardening CompleteSix infrastructure plans shipped in one session: meal-to-treatment relay, tiered rate limiter, AI vision upgrade, component meal architecture, server sync infrastructure (schema v7+v8), and iOS offline cache. Nightscout/Zukka compatibility verified with 113 integration tests.1,750 tests · 162 files · 24,000 lines added
- Phase 4.0b — Alerting & Time-in-Range CompleteAlert detection engine (hypo, hyper, stale CGM, rapid drop) with configurable thresholds. Time-in-range dashboard with daily trend charts across 7/14/30/90-day periods. Both deployed to production.30 new tests · TIR: 51.8% over 14K+ CGM entries
- Phase 4.1 — Direct BLE Ingestion PlannedDirect Libre 3 BLE sensor communication from the iOS app, replacing the xDrip4iOS dependency. Sensor lifecycle handling, background reliability and recovery.
- Phase 4.2 — Push Notifications PlannedAPNs/FCM push for follower hypo/hyper alerts. Backend alerting engine already deployed; needs mobile delivery infrastructure.
Direction
The objective is simple to state but difficult to build: a system that learns how a specific metabolism behaves in practice. From recording to understanding Today, most glucose systems are recorders. They collect data, display graphs and sometimes apply simple predictive models. They show glucose values, trends and basic predictions based on fixed assumptions such as static insulin sensitivity or standard absorption models. These tools are useful, but they do not truly understand how a specific body behaves. ...
Commit History
- dfa7763fix: ruff import sort + NS compat test timestamps use _now_ms()
- b952e5efeat: iOS TIR dashboard + alert banner
- 572f464fix: accept both sgv and sgv_mgdl keys in alert engine
- 5097d04feat: alert detection engine + TIR calculation + API endpoints
- 91bcf2afix: ruff lint + vibe cleanup pass
- 0b7fd1dfeat: add Nightscout compatibility test suite (21 tests)
- 48e6566feat: confidence_pct + sample_count on glucore endpoints, iOS cleanup
- 8e7405bfeat: evolve loop hardening + deployment verification + iOS improvements
- 441d559fix: use Z suffix in ISO timestamps for Nightscout/Zukka compatibility
- a6c7905fix: omit redundant zero/null insulin and carbs fields from treatments
- a12054bfix: add /treatments.json route alias for Nightscout client compatibility
- a15c1d3iOS: camera capture, meal duplicate fix, swift-engineering review fixes
- ca5cf92fix: delete linked treatment when meal deleted, refresh timeline after actions
- 37ca82cfix: skip live server tests without ISLET_LIVE_TEST env var
- 10b9c60Merge branch 'plan-5/ios-cache-rebased' (PR #3)
- 4821c16feat: prediction view tests, migration validation, lint fixes
- 715b5ebPlan 5: iOS offline cache with SwiftData
- 73f9635Plan 5: iOS offline cache with SwiftData
- 3d5ccaefix: resolve ruff lint errors and pyright type issues
- 196be8fPlans 1-4 + 6: full backend implementation
- a990505Add carb-assistant as submodule in tools/
- 23be473docs: comprehensive software documentation for humans and machines
- 90c51cciOS: single-finger chart scroll, long-press scrubber
- a3df60eiOS: screen-space annotation clustering, sorted cache, chart polish
- 36487e4iOS: chart scrubber, annotation clustering, scroll/zoom fixes
- bdb271eiOS: day-grouped timeline, time-of-day accuracy, settings profile
- dd3a37fglucore: bilinear COB curve, multi-horizon validation
- 892f818iOS: scrollable chart, meal search, meal duplication
- 90b8504glucore scoring: require paired bolus for meal events
- 1315facglucore tune: widen carb ratio grid to cover 1:18-22 range
- ab3bb2aiOS: prediction charts, food response views, accuracy display
- 77719bbglucore Phase A: parameter tuning, calibration, and forward prediction
- de2bc6cUpdate docs to reflect current state, fix basal treatment input
- 775d634evolve: fix android-dev-env check, add venv-bootstrap goal
- e2f55d9Android: quality pass — remove dead code, add detekt, expand test coverage
- 336d85echore: trigger reindex
- 41e53fdchore: trigger reindex
- 17678c1Android: add expandable Food & Treatments log
- 5595e8cAndroid: rename to islet Companion, move to android-companion/
- ccd25ddAndroid: fix cursor swipe direction to standard scroll
- 5b5c4c6Android: add cursor scrubber, pin metrics overlay, default to 3h
- 9d6f1b0Android: full-screen chart with duration picker and metrics overlay
- f45a245Android: auto-config, fix chart, add gradle test runner
- 123ea70Android: fix Gradle settings DSL and ApiError override
- 1037402Android: scaffold CGM follower app (Kotlin + Jetpack Compose)
- 2c3d18bUpdate griffiths-core submodule to latest
- 8fe2d7fAdd griffiths-core submodule with test and deploy configs
- be3cb1ciOS: surface template vs AI source in meal estimate chat
- c78bbcaFood templates: local data source for instant meal estimation
- 16ba91fUpdate docs for multi-user isolation: progress report, README, NEXT_PHASES
- 9760206Multi-user data isolation: per-user SQLite databases
- 4591bfaFix SSH helper scripts: quoting, arg forwarding, hostname detection
- e2971ccGoals: cross-platform checks, pyright config, 66% → 97%
- a737af1iOS: enlarge app icon, clean background
- 6a8b282iOS: add app icon (ChatGPT-generated neon waveform)
- 2b0e9c9iOS: enable real-device signing with personal team
- 5b596aaiOS: background refresh, stale data warning, polish sprint
- d19622fiOS UI sprint: HIG compliance, Keychain token, chart colour fix
- eec4d28iOS chart: add insulin/meal markers, threshold labels, now indicator
- 19c9aa8Fix council findings: DeleteResponse shape, MealListView migration, error clearing
- 0308645iOS hardening: shared TimelineActions, chart perf, token removal
- 38bdbb1iOS navigation overhaul: TabView, glucose chart, history page
- e5ae280Fix ruff import sorting in meal_routes.py
- 54ad23fUpdate progress report and roadmap for web UI overhaul
- 3ad0d4cWeb UI navigation overhaul: FAB, hamburger, CGM graph, history page
- 334c3ceAdd edit/delete buttons to web UI timeline
- ff33157Add meal editing, fix treatment edit crash, stable timeline
- 5f48c1cAdd food templates for Tunnock's Caramel Wafer and Penguin
- 6fce0a8Fix XSS: escape all user values in web UI timeline rendering
- 7d64173Add treatment CRUD tests and expand Swift model tests
- 3ed5d01Add Swift and Python testing goals
- 5ca3eaaAdd treatment edit/delete and timeline swipe actions
- 73ddef3Add treatment edit, meal edit, and timeline action goals
- c2c17b8Fix pyright error: add _messages attribute to GeminiFlashProvider
- 037a2b4Add smart polling to iOS dashboard using next_expected_ms
- 2b521e0Add next_expected_ms to glucore/status for smart client polling
- 229851bAdd treatment logger to iOS app and web UI
- 67224c8Add treatment input, live dashboard, and smart polling goals
- 22e9564Remove absorption speed tag — redundant with GI + fat/protein/fibre
- 65fc552Redesign web UI to match iOS warm clinical aesthetic
- ee73670Redesign iOS food logger: unified dashboard, colour-coded nutrition tags
- 9acbe6aPhase 4 restructure: iOS is in progress, not complete
- aae2f4aPromote iOS to Phase 4.0, restructure phase numbering
- 26ed032Add test coverage for /api/v1/meal/estimate endpoint
- b68b3c1Fix ios-meal-list goal check, update docs for Phase 3.3 completion
- f68c27fShow bearer token in plain text in settings
- b11b4f0Add date/time picker to food logger
- 8d71ab6Fix food logger: stateless estimate API, multi-turn chat, delete guards
- 163aad0Fix estimate endpoint: continue_estimate takes 1 arg, not 2
- 5dbf56cAdd server-side AI meal estimation endpoint for iOS app
- 83a044eFix JSON decoding: match Swift models to actual API response shapes
- 21ce267Default tag pickers to unknown (?), send nil to API when unset
- 1205d7fRegenerate islet.xcodeproj with new views and models
- 73858eeFix Swift build errors: lineLimit type mismatch, TagPickable AllCases constraint
- 434e840Add food logging, meal history, settings, and 4 new GOALS
- ea41eceAdd food input screen + Warm Amber/Blue Lows theme
- fa74c8dFix ios goal check paths: Sources/ → islet/ (Xcode app convention)
- 09afbc6Merge ios-scaffold: SwiftUI app with XcodeGen, models, network layer, dashboard
- 7ea0e53Add generated islet.xcodeproj
- ede8b38Fix missing CFBundleIdentifier in Info.plist
- 62618a0Scaffold iOS app with SwiftUI + XcodeGen
- 428d898Phase 3.3 cutover: API-only ingest mode live, Nightscout polling disabled
- e127041Post-mortem RPI: fix API logging, remove dead code, add device observability
- cad39a8Fix ruff import ordering regression in app.py
- 1d49bc2Add per-device token auth and conditional relay routing
- 19f043cAdd ruff linter, pyright type checking, and GitHub Actions CI
- 316facaAdd GOALS.yaml with 12 forward-looking fitness goals
- a3c4bf1Post-mortem RPI: module-level imports, narrow except, deploy script
- d6a3531Update docs: post-mortem cleanup complete, smoke test, SLOC/commit counts
- 31a3e4aFix smoke test: experiments/test requires auth (expect 401)
- 43ba801Post-mortem cleanup: document quality_flag policy, refactor SQL, add smoke test
- d3c2c4bMove inline json imports to module-level in ingest_routes.py
- f624b06Add sync_gwefan.py to update website stats from islet repo
- 595ca12Update docs: Phase 3.3 soak status, Zukka pipeline, sgv.json endpoint
- 40ae873Add GET /entries/sgv.json for Zukka CGM polling
- 9275fb8Update progress report: Zukka replaces Shuggah
- 37d0a3dReturn records with _id in POST response (Nightscout compat)
- 3bb88aaUpdate progress report: Phase 3.3 soak with Shuggah compatibility
- bd53deeShuggah/xDrip4iOS compatibility: status, treatments GET/DELETE, dedup
- d21e9a2Phase 3.3 prep: extract backoff helper, harden daemon, add 29 tests
- df05b19Add relay timeout and mixed-batch test scenarios
- 10cd4d0Add received count to ingest API responses for duplicate detection
- 9b51a95Fix post-mortem findings: complete fixture migration, add _relay_client default
- c01042dCache SHA-1 api-secret hash at init instead of recomputing per request
- 47135abStandardize API error format, consolidate relay config, shared test fixture
- a95b713Replace string-matching with typed CircuitBreakerOpenError exception
- ff2a626Add relay circuit breaker: open after 5 failures, probe after 60s
- d4ea7b9Fix relay _post() to not parse response body
- c8dd48fAdd Nightscout relay with self-relay guard and 5s timeout
- 4ef5c3dFix treatment validation gap, add conftest.py, centralize constants
- b2c126bSchema v6 quality flags, enhanced ingest validation, cross-platform test runners
- 6ec08ecHarden Phase 3.1 ingest: size limits, validation, CORS, error handling
- c0650ddUpdate progress report for Phase 3.1 deployment
- 6a91082Update docs for Phase 3.1: ingest mode, endpoints, architecture
- d4dfb29Add Phase 3.1: Nightscout-compatible ingest endpoints
- 4be74daUpdate progress report: Phase 2.1 soak test started, fix commit count
- 2245057Add glucore Phase 2.1: COB, autosens, validation, API endpoints
- 3db07f5Update progress report, fix test DB cleanup
- c6b101aAdd project icon and first food template
- 4c4b824Add glucore Phase 2 engine, update project docs
- 8c775c6Rewrite README to reflect metabolic intelligence positioning
- a3e9d3dfix(api): upgrade openapi.yaml to 3.1.0 for ChatGPT Actions compatibility
- d7ded4ffix(api): update openapi.yaml server URL to islet.griffiths.cymru
- 390b8d7Add temporary web UI for food entry
- e2c7fadrefactor(daemon): extract shared poll/backfill logic via _DataType callbacks
- 4d84cedrefactor(api): consolidate lookup-or-404 helpers and session validation
- df54226refactor(config): extract default_db_path() to eliminate platform-check duplication
- d343ef0Add ChatGPT App meal intake API (Flask, v5 schema, 56 tests)
- 6f2fd75fix(meal): enforce short-id confirm/reject and sync PR4 docs
- c79b35cSync all docs for PR3 completion and Phase 1 soak test pass
- b51dec0Add meal CLI commands with v4 schema migration
- 3e03d87Migrate google-generativeai to google-genai and pin all dependencies
- 1298198Harden Phase 1.5 meal logging from multi-agent review
- c265e96Add meal estimation providers, shared parsing, and sync all docs
- 5f46135Sync phase docs and update meal migration tests
- ab4fc2cHarden backfill cursor handling and sync docs
- aeaf49dReject NaN/inf in carbs and PCU validation, fix doc conflicts
- b31b382Add meals table, schema migration runner, and meal CRUD with validation
- 12c48e7Harden pagination cursor, fix threshold docs, add soak test results
- 6c0008bFix pagination gap, health check cold-start, treatments display; add tests
- 2671f1aMark all Phase 1 acceptance tests and failure simulations as passed
- 488e324Bump health check threshold from 330s to 420s
- 8ad39a5Update progress report: soak test start time, token redaction, commit count
- 0c86c49Redact token at source in Nightscout client connection errors
- 589a496Redact Nightscout token from error messages in daemon logs and status
- b7232ebAdd project documentation: hardening spec, progress report, contributor call
- c929c6dAdd Phase 1 hardening: staleness detection and health timer
- 509bf06Implement Phase 1: Nightscout → SQLite mirror
- a1be44eInitial commit: project docs and .gitignore