Release notes
What we shipped, and when.
This page is generated directly from the project's
CHANGELOG.md on every deploy. It is the same file we read
internally — no marketing layer in between.
Changelog
All notable changes to Audris are documented here. The format follows Keep a Changelog and the project adheres to Semantic Versioning once tagged releases begin at v0.1.0.
This file covers both the mobile app (Android + iOS) and the public marketing site. Entries that apply only to one are tagged [app] or [site]; everything else applies to the project as a whole.
[Unreleased]
Added
[a11y]Accessibility hooks library atsrc/lib/accessibility.ts—useHighContrast()(iOSAccessibilityInfo.isHighTextContrastEnabled),useScreenReader()(live subscription),useFontScale(cap?), namedFONT_SCALE_CAPS(reader 1.3 / chrome 1.6 / caption 1.4 / display 1.5). 9 unit tests.[a11y]A11y polish pass across 30 files inapp/andsrc/components/— every interactive element now hasaccessibilityLabel+accessibilityRole+accessibilityState+accessibilityHintwhere ambiguous. Tap targets audited for ≥48 dp with explicithitSlopwhere needed. Waveform exposesrole="adjustable"with ±15s seek viaaccessibilityActions. Mascot announces as "Audris, your narrator. Currently <state>." HighlightedText makes each sentence its own accessible button withonAccessibilityTap → seek. Speed slider, segmented controls (theme/font/sleep-timer/highlight-color/pause-profile) allrole="radio"withstate.checked. Live-regions for error toasts. Reduce-motion compliance audited and added where missing.[native]Native code review pass across all 19 Kotlin + Swift files — 14 bugs fixed including: (1)PlayerService.ktcold-start ANR —startForegroundServicerequiresstartForegroundwithin 5s on Android O+; now publishes notification inonCreate/onStartCommand; (2)PlayerControllerwas missingfun interfacemodifier — SAM-lambda wouldn't have compiled; (3) iOSAudrisTtsModule.swiftConstantswas eager dict form —engineconstant always read"supertonic"even afterOnCreateflipped to apple-speech; switched to closure form; (4) iOS error-code parity —NSError(code: Int)→Exception(name: "E_…")so JS sees consistent stringcode; (5)loadPlantimeout in module facade; (6)AudrisOcr.swiftguard-let-self left Promise pending; (7)AudioPlayer.swiftinit/deinit + setSpeed/setVoice now main-thread wrapped (AVAudioEngine, MPRemoteCommandCenter, varispeedNode.rate are main-thread-only); (8)AudioPlayerrendered.countrace with non-MainActor; (9) coroutine scope leaks inAudrisTtsModule.kt+AudrisPdfModule.kt(now cancelled inOnDestroy); (10)bundleOfByteArray case; (11)onErrorchunkIndex sentinel parity. Two real concerns documented inline asREVIEW(charles):LookaheadBuffer.kt::nextChunkseek-during-playback race,AudrisPdfModule.kt::onPage.bufferJS-side Uint8Array-vs-ArrayBuffer type ambiguity. Binary format byte-by-byte parity confirmed acrossBinaryEncoder.kt/BinaryEncoder.swift/packages/extractor-decode/index.ts.[docs]Architecture documentation atdocs/architecture.md— engineer-facing system overview of every layer (app, components, store, services, native modules, pure-TS domain, decoder, persistence, marketing site, testing). ASCII diagrams per layer, the bridging decision explained, the flush-to-SQLite pattern, the amplitude SharedValue contract, the "where to put your next commit" cheat-sheet.[docs]Native modules integration guide atdocs/native-modules.md— recipes for adding methods + events to the three local Expo Modules (audris-pdf,audris-tts,audris-ocr), the binary buffer format byte-by-byte, EAS Build validation cycle, common gotchas (Kotlin 2.x, ProGuard for ONNX,onnxruntime-objcversion pinning,--legacy-peer-deps, content URIs on Android, foreground service type, headless-modules rule), and the documented fallback path "if ONNX-on-iOS doesn't work."[perf]Performance benchmark scaffolding at__tests__/perf/— pure-TS benchmark runner (benchmark.ts) exposingbenchmark(name, fn, { runs, warmup, setup, teardown })returning min/max/mean/median/p95/p99 stats. Analyzer + formatter benchmarks against a 50-page synthetic document (analyzer.bench.test.ts, p95 budgets <500 ms / <100 ms / <600 ms). Decoder benchmarks against a 100-page synthetic input with UTF-8 mixed-script content (decoder.bench.test.ts, p95 budgets <50 ms / <25 ms). README documents what's measured today, what's deferred until real devices (time-to-first-audio, memory under playback, battery, model download), and the Phase 4 device-side plan.[perf]npm run benchmarkscript — runs the perf suite (separate fromnpm run testbecause benchmark timings are non-deterministic; CI continues to run the regular test suite on every push).[corpus]30-PDF test corpus harness —__tests__/fixtures/corpus/with 12 synthetic fixtures spanning business proposals, research papers, contracts, code-heavy technical docs, and scanned-document edge cases. Corpus-evaluation test runs the analyzer + formatter against every fixture and snapshots role assignments + pause counts. +37 tests; total now 141/141 passing.[site]Cornerstone blog post #4 — "How to listen to research papers on your phone." Academic-angle long-form covering why papers are hard for TTS, what structure-aware reading does for them, and a commute workflow.[site]Cornerstone blog post #5 — "What your PDF reader sends to the cloud." Privacy-investigation post comparing cloud-TTS vs on-device architectures across Speechify, NaturalReader, Voice Aloud Reader, @Voice, Voice Dream Reader, and Audris, based on each app's public documentation.[site]Cornerstone blog post #6 — "The best offline PDF-to-speech apps in 2026." Honest ranked listicle comparing Voice Aloud Reader, Voice Dream Reader, Speechify offline mode, NaturalReader offline tier, Audris, and Adobe Acrobat's built-in Read Out Loud across on-device fidelity, structure handling, privacy stance, and value.[site]Cornerstone blog post #7 — "Why your TTS app reads section headers like body text (and how to fix it)." Educational long-form on the flat-text problem, what PDF metadata actually encodes, and the cognitive-load argument for structural pauses in audio.[site]Cornerstone blog post #8 — "How we built Audris: a 6-month indie engineering retrospective." Build-in-public engineering retrospective covering the 13-day spike, architecture decisions that worked, decisions we got wrong, the numbers, and lessons for solo developers.[site]Public/changelogpage rendering this file athttps://audris.app/changelog, linked from the footer.[deploy]nginx vhost config atmarketing-site/deploy/nginx-audris.conf— long-cache fingerprinted assets, short-cache HTML, full security header set (HSTS preload, nosniff, strict-origin-when-cross-origin, restrictive Permissions-Policy),www → bareredirect, custom 404, Cloudflare real-IP trust.[deploy]Deploy script atmarketing-site/deploy/deploy.sh— git-state check, build, scp, remotenginx -t && reload, curl smoke test,--dry-runflag, color-coded output, idempotent.[deploy]Deployment README atmarketing-site/deploy/README.md— first-time setup checklist, day-to-day workflow, rollback procedure, troubleshooting, co-tenant safety reminder.[player]Player integration polish — real Mascot + ParticleField + sheet components wired in; sleep timer + bookmark-at-current end-to-end; amplitude SharedValue piped fromtts.onAmplitudeinto both Mascot and ParticleField; skip-direction tilt;getCurrentSegment()/getCurrentSection()selectors on playerStore.[ci]GitHub Actions CI workflow at.github/workflows/ci.yml— runs typecheck + the full vitest suite on every push tomainand every PR. Node 20, npm cache, 10-minute timeout, concurrency cancellation.[ci]Marketing-site build workflow at.github/workflows/marketing-site.yml— paths-filtered tomarketing-site/**, builds the Astro site and uploadsdist/as a 7-day artifact for PR review.[ci]Expo prebuild verification workflow at.github/workflows/expo-prebuild.yml— paths-filtered to native-affecting changes, runsexpo prebuild --no-install --platform androidand asserts the AndroidManifest contains theapp.audris.tts.PlayerServiceentry. CatcheswithAudrisconfig-plugin breakage early.[docs]Top-level README.md — public-facing project overview, quickstart, project structure, tech stack, architecture diagram, dev workflow, testing, build/submit, contributing, acknowledgements. Voice-compliant with MARKETING §3.3.[docs]MIT LICENSE — code under MIT; brand assets (name, mascot, icon, tagline, audio) explicitly reserved as © 2026 Charles Magno.[ci]Issue + PR templates —.github/PULL_REQUEST_TEMPLATE.mdwith the pre-merge handoff checklist;.github/ISSUE_TEMPLATE/bug_report.mdwith privacy reminder ("do not paste document content");.github/ISSUE_TEMPLATE/feature_request.mdwith the counter-positioning reminder;.github/ISSUE_TEMPLATE/config.ymldisables blank issues and routes to[email protected]+ the marketing site.[ci]Dependabot config at.github/dependabot.yml— weekly npm updates for the app and the marketing site (5 PRs/week cap each), monthly GitHub Actions updates, Charles auto-assigned as reviewer.
Changed
- Nothing yet.
Fixed
- Nothing yet.
Removed
- Nothing yet.
Foundation
The pre-changelog baseline as of project kickoff.
Added
[app]Initial scaffold — Expo SDK 53 + expo-router v4 + TypeScript strict.[app]Design system — Tamagui (chosen over NativeWind), Reanimated 3, Moti, Skia 1.5, Rive mascot viarive-react-native.[app]Three in-repo Expo Modules —audris-pdf(PdfBox-Android / PDFKit text extraction),audris-tts(Supertonic 3 via ONNX Runtime, with Apple Speech framework as the iOS fallback),audris-ocr(scanned-PDF OCR for the paid tier).[app]Pure-TypeScript pipeline — PDF decoder, structure analyzer (font/color/position heuristics → SegmentRole tree), speech formatter (SpeechPlan with PCM silence + Supertonic expression tags).[app]State and storage — Zustand 5, TanStack Query 5, MMKV, Drizzle + expo-sqlite.[app]Native audio — MediaSession (Android), MPRemoteCommandCenter (iOS), CarPlay + Android Auto wiring planned for V1.[site]Static Astro 5 marketing site ataudris.appwith hero, pricing, blog, press kit, privacy, terms, and support pages.[site]Three cornerstone blog posts — "How Audris reads documents like a human" (the structure-aware pipeline), "Why Audris doesn't have a free trial" (anti-subscription philosophy), and "Speechify vs NaturalReader vs Audris: an honest comparison."
This will be versioned at v0.1.0 once we have a buildable preview release that runs end-to-end on real hardware (Phase 0 milestone, see plan).