Commit graph

7 commits

Author SHA1 Message Date
2af3c2043a docs: Plaud comparison + feature-gap backlog
Some checks failed
ci / openapi (pull_request) Failing after 31s
ci / emulator (pull_request) Failing after 32s
ci / firmware (pull_request) Failing after 38s
ci / server (pull_request) Failing after 32s
Reviews the Plaud line (Note, Note Pro, NotePin/S) to make sure the OpenScribe
roadmap covers expected capabilities, and records where OpenScribe deliberately
differs (bring-your-own-AI, self-hosted, open).

What changed:
- docs/plaud-comparison.md: feature map (Plaud vs OpenScribe status), a derived
  backlog, and what we deliberately do not copy. Sourced from Plaud's site (July 2026).
- state/TODO.md: adds a Plaud-derived backlog section (diarisation, summary templating,
  Ask-AI/RAG, custom vocabulary, multimodal, mark-a-moment, auto-title, tags/folders/
  search, share links, optional OLED display, calendar) and a pluggable-AI-providers
  milestone.

Why:
- The user asked to review Plaud for other todos; this captures them and frames the
  bring-your-own-AI differentiator that the next feature implements.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 13:20:29 +01:00
9237f4a37b docs(state): mark testing harness merged; M3 next
Some checks failed
ci / firmware (push) Failing after 37s
ci / openapi (push) Failing after 33s
ci / server (push) Failing after 32s
ci / emulator (push) Failing after 38s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 12:17:04 +01:00
f84bbca80b test(dev): emulation + linting harness (Wokwi, native tests, CI, docs)
Some checks failed
ci / openapi (pull_request) Failing after 30s
ci / firmware (pull_request) Failing after 35s
ci / server (pull_request) Failing after 28s
ci / emulator (pull_request) Failing after 36s
Answers "how do we emulate/lint this?" with runnable tooling for every part, and
factors the pure firmware logic out so it is unit-testable on the host.

What changed:
- firmware/src/wav.h, firmware/src/httprange.h: pure, header-only WAV header builder
  and HTTP Range parser (no Arduino deps), so the tricky byte-layout and range logic
  can be tested on a PC. storage.cpp and api_http.cpp refactored to use them.
- firmware/test/test_pure/: Unity tests for the WAV header fields and Range parsing
  (start-end, open-ended, clamped, unsatisfiable, non-bytes). Run: pio test -e native.
- firmware/platformio.ini: add [env:native] (host tests) and [env:esp32s3_wokwi]
  (emulator build with default WiFi = Wokwi-GUEST so the API comes up in the sim).
- firmware/wokwi.toml + firmware/diagram.json: Wokwi emulator harness (ESP32-S3 +
  microSD + button + LED). Note: Wokwi has no I2S mic part, so audio isn't emulated;
  the harness targets boot + WiFi + REST API.
- firmware/src/main.cpp + config.cpp: bring up WiFi + API even if audio/SD init fails
  (device stays reachable, reports the fault via GET /device); compile-time default
  WiFi honoured when NVS is empty (used by the Wokwi build).
- .forgejo/workflows/ci.yml: add native tests + cppcheck to the firmware job; new
  openapi job (openapi-spec-validator) and emulator job (Wokwi build, plus a full run
  when WOKWI_CLI_TOKEN is set).
- docs/testing.md: the full emulate/lint guide for firmware, server, API, app, case.
- state/: NOTES points at the guide; TODO reflects this branch.

Why:
- The firmware can't be flashed yet (no parts) and doesn't build on this dev host, so
  we need host-runnable checks. Pure-logic unit tests + OpenAPI validation run anywhere;
  Wokwi emulates boot/WiFi/API; CI compiles the real firmware. Verified locally: the
  OpenAPI spec validates (12 paths, 10 schemas).

Notes:
- Native tests and cppcheck run in CI (no compiler on the dev host). The Wokwi full run
  is skipped unless a WOKWI_CLI_TOKEN secret is present; the build is still verified.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 12:16:25 +01:00
87a00265a3 feat(firmware): M2 WiFi + on-device REST API
Some checks failed
ci / server (pull_request) Failing after 27s
ci / firmware (pull_request) Failing after 36s
Adds the WiFi-to-app sync path and the on-device open REST API implementing the
device paths of api/openapi.yaml, plus persistent config in NVS.

What changed:
- firmware/src/config.{h,cpp}: NVS (Preferences) store - stable device id from MAC,
  WiFi SSID/PSK, API bearer token, upload settings. Secrets stay off the SD card.
- firmware/src/net_wifi.{h,cpp}: station join with stored creds; SoftAP provisioning
  fallback when no creds / join fails; mDNS openscribe.local; reconnect in loop().
- firmware/src/api_http.{h,cpp}: synchronous WebServer on :80. Routes: GET /device,
  GET/PUT /device/config, GET /recordings, GET /recordings/{id}, GET
  /recordings/{id}/audio (HTTP Range -> 206 + Content-Range), DELETE /recordings/{id},
  POST /record/start|stop. Bearer-token auth on mutating calls (open when no token).
- firmware/src/storage.{h,cpp}: list/read/delete/count helpers + path builders.
- firmware/src/main.cpp: wire config + WiFi + API into setup/loop; bump fw to 0.2.0.
- firmware/platformio.ini: add bblanchon/ArduinoJson@^7 (only new dep).
- state/: ARCHITECTURE, NOTES, TODO updated; security + NTP follow-ups recorded.

Why:
- This is the WiFi transfer channel and the device half of the "completely open API":
  clients can list, download (resumable), delete and control without any cloud.

Notes:
- Not compiled locally (no PlatformIO on the dev host) or hardware-verified; CI builds
  both board profiles. Security follow-ups logged: API is open when no token is set,
  and the SoftAP uses a fixed default passphrase (make user-set at M4/BLE).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 12:09:41 +01:00
16e3460642 docs(state): mark M1 merged, clear in-progress
Some checks failed
ci / firmware (push) Failing after 29s
ci / server (push) Failing after 25s
Post-merge bookkeeping so the next session's TODO is accurate. Next: M2
(WiFi manager + on-device REST API).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:36:56 +01:00
054b2f6981 feat(firmware): M1 recording core - mic capture to WAV on SD
Some checks failed
ci / server (pull_request) Failing after 34s
ci / firmware (pull_request) Failing after 36s
Implements the first working feature: the device records audio to the microSD
card, toggled by the button, with LED status and per-recording JSON metadata.

What changed:
- firmware/src/audio.{h,cpp}: mic capture via the core-bundled ESP_I2S. Dev board
  uses I2S standard mode (INMP441/ICS-43434); XIAO uses PDM mode (onboard mic).
  Presents 16-bit PCM mono to callers regardless of board.
- firmware/src/storage.{h,cpp}: microSD on a dedicated HSPI bus + a streaming
  WavWriter that writes a 44-byte PCM header and patches RIFF/data sizes on close;
  plus sidecar JSON metadata writer.
- firmware/src/recorder.{h,cpp}: idle/recording state machine; creates
  /recordings/<id>.wav, pumps mic chunks in on update(), finalises + writes
  <id>.json (Recording schema from api/openapi.yaml) on stop.
- firmware/src/ux.{h,cpp}: debounced button (short press toggles) + status LED
  patterns (idle/recording/error), active-low aware.
- firmware/src/main.cpp: wires ux + recorder; loop toggles on button and drains
  the mic while recording.
- firmware/include/audio_config.h: 16 kHz mono 16-bit, chunk size, rec dir.
- firmware/include/pins.h: added XIAO PDM mic + onboard SD pins, LED active-low flag.
- state/: TODO, ARCHITECTURE, NOTES updated for M1 and the deferred follow-ups.

Why:
- Recording is the foundation every later milestone (transfer, upload, transcription)
  builds on. Kept dependency-free (only core-bundled ESP_I2S + SD) for simple CI builds.

Notes:
- Not compiled locally (no PlatformIO on the dev host) or hardware-verified; Forgejo
  Actions CI builds both board profiles. Follow-ups tracked in state/TODO.md:
  INMP441 16-bit level calibration, and real NTP timestamps (ids are uptime-based
  until M2 brings WiFi/NTP).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:35:34 +01:00
031074c9a9 scaffold: OpenScribe open-source self-hosted AI voice recorder
Some checks failed
ci / firmware (push) Failing after 2s
ci / server (push) Failing after 45s
Bootstrap of the project (M0). Sets up the monorepo, design docs, hardware BOM,
the open API contract, component skeletons, licensing and CI, following the
Default Workflow SOP.

What changed:
- CLAUDE.md + docs/: copied the Default Workflow so sessions load the SOP.
- state/: PROJECT, ARCHITECTURE, DECISIONS, TODO, NOTES filled in for OpenScribe.
  ARCHITECTURE captures the four-part design (firmware, server, app, case) and the
  three sync paths; DECISIONS records the hardware, AI-stack, storage, app and
  licensing choices; TODO lays out milestones M1-M9.
- hardware/BOM.md: two build options (compact XIAO ESP32-S3 Sense; dev ESP32-S3 +
  I2S mic + SD), wiring/pinout, indicative cost.
- api/openapi.yaml: the completely open API (device + server surfaces), including
  recording list/download/delete and exports (wav/ogg/txt/srt/vtt/md/json).
- firmware/: PlatformIO ESP32-S3 project, two board profiles, pin map, boot scaffold
  with module seams for M1-M4.
- server/: FastAPI skeleton mirroring the OpenAPI, config for self-hosted MinIO,
  faster-whisper and Ollama; stub routes browsable at /docs.
- app/, case/: Flutter app plan; parametric OpenSCAD enclosure.
- Licensing: GPL-3.0 (code), CERN-OHL-S-2.0 (hardware), CC-BY-SA-4.0 (case/docs),
  REUSE-style LICENSES/ with SPDX headers; LICENSING.md explains the split.
- CI: Forgejo Actions workflow builds firmware (both profiles) and lints/imports server.

Why:
- Everything self-hosted and openly licensed per the user's requirements: an open
  API, three sync paths (BLE control, WiFi transfer, independent WiFi upload on
  charge to generic cloud storage), and a full self-hosted transcription+summary stack.

Notes:
- No custom PCB in v1; off-the-shelf modules. Physical verification waits on parts.
- Component code is stubs at M0; features land milestone by milestone, each as its
  own branch/PR per the workflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 10:21:37 +01:00