Skip to content

Connect real pill captures to /pill and remove the mock path - #27

Open
viktorinkov wants to merge 19 commits into
mainfrom
codex/real-pill-integration
Open

viktorinkov wants to merge 19 commits into
mainfrom
codex/real-pill-integration

Conversation

@viktorinkov

@viktorinkov viktorinkov commented Sep 20, 2026 •

Copy link
Copy Markdown
Owner

This branch includes all PR 25 commits through 1199d67 and PR 26 through 7107184. Both are ancestors of this branch. The latest merge is 3ee44b3. Nothing was merged into main.

The mobile app uses captured instrument readings. It has no simulator button, PEEL_SIM startup mode, or generated-result fallback. It sends five water sweeps and five dissolved-pill sweeps to the real /pill classifier, then submits the classification and aligned raw readings to research. Skip omits hardware. Request failures stay on Retry. The app rejects responses from the old mock backend.

PR 25's synthetic reference matching remains in the pipeline, as requested. It compares real time traces with generated B12, acetaminophen, vitamin C, and caffeine curves. These comparisons are separate from the measured Advil/Pepto classifier. Synthetic matches retain their provenance and ambiguity limits. They are not confirmed chemical identities. The three-color spectrum is never treated as a time trace.

Deepgram leads with the verdict and ResearchReport headline. It gives a closest synthetic match when no measured classifier identity is available. The short prompt preserves recall information, sourced medication facts, unknown results, and report drafting. Raw telemetry stays out of the voice prompt. Research retains bounded sensor evidence.

The backend retains sensor storage fields and additive Elasticsearch migrations from PR 25. The old mock pill request is rejected. New simulated scans, graph demo requests, and graph sample-data fallbacks are disabled. Historical simulated records stay labeled.

Final local checks: 103 existing backend checks passed, Flutter analysis passed, and six existing mobile checks passed. These checks do not establish physical instrument accuracy. The measured library still has only two products and requires physical acceptance on the current instrument.

No Runpod deployment or resource changes. No new APK was built during this merge. Deploy a full repository checkout and rebuild the matching mobile app. The backend needs the sibling truepill/ package. Capture contract and limitations.

leopozh and others added 19 commits September 20, 2026 05:52
hardware/peel_app moves into mobile/ (lib/hardware, packages/usb_serial,
test/hardware). DeviceScreen connects to the real instrument over USB or
the simulator (PEEL_SIM), runs blank -> t=0 -> stream -> stop and sends
the raw absorbance trace as the scan's hardware payload; 'Continue without
device' keeps the POST /pill fallback. The bench screen is a long press
on the device step or PEEL_START=debug.
A self-contained package that turns 17_stream output into a verdict on the
tablet and maps it onto the backend's PillHardwareResult. Nothing imports it
yet: this adds files and modifies none, so no existing behaviour changes. The
backend keeps its mock until someone chooses to wire this in.

Relocatable by construction. Every intra-package import is relative and data
files resolve from the module that reads them, so the directory works at the
repo root, nested in another package, or renamed, and its generically named
modules (models, noise, library, server) cannot collide with the backend's.
tests/test_relocatable.py copies it elsewhere and proves it on every run.

- classify_capture(): firmware lines in (raw text, dicts, or the envelopes in
  hardware/data), ClassificationResult out. Reads red / yellow / green by
  name, so main's six-key sweep works unchanged.
- backend_bridge: the five PillHardwareResult fields, validated against the
  backend's real model. A reading the rig could not take maps to "unknown",
  never "fake".
- hardware.py: the rig's measured profile. On three all-positive channels the
  simulator's 0.935 cosine threshold rejected nothing (a grey filter scored
  "pepto, high confidence"); the rig's is 0.9995, validated on a held-out
  recording. INVALID_READING refuses what the optics cannot have produced.
- The default (simulator) path is bit-exact against the original code.

Left out on purpose: the published NIST / PhotochemCAD reference spectra and
the module that reads them. Their licence terms are unchecked and this
repository is public.

The tuning is provisional and the docs say so: the rig was faulted when
measured (slow detector, unstable light level), and the evidence is 45
independent noise pairs and two library entries. See HARDWARE_TUNING.md.
Path-scoped like hardware.yml and mobile.yml, so it runs for nothing else.
Python 3.10 (the package's floor) and 3.13 (what the backend runs).
…in/truepill-classification' into codex/real-pill-integration
at350 added a commit that referenced this pull request Sep 20, 2026
…n main

Parts, power, the wire protocol and commands, the fault engine, a run, the
simulator, captures and tools. The classification layer is described through
truepill (#26) and its /pill integration (#27) rather than hardware/classify,
which never reached main. Two boards, as the firmware has it: an ESP32-S3
sensor board and the ESP32-S3-BOX-3 face over ESP-NOW.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants