Before FreqCraft ships, it has to earn it. This is the actual release procedure the app is
held to — the one that answers a single question under pressure:
is this build safe to release? Reproduced in full below, sanitized only of
internal file paths. Nothing hidden — including what the tests caught.
The Problem
"It works on my machine" is not a release decision. A shipping app needs a repeatable, defensible answer to whether it's ready — one that survives a deadline, a tired developer, and a feature added last week.
Memory and good intentions don't scale. The process has to be written down, ordered, and gated.
The Approach
Three layers, narrowest net first: an automated adversarial test suite, then emulator validation, then a physical-device release gate. Every test has an explicit pass condition.
Known issues are triaged by severity and disclosed — not buried. The gate states, in writing, ship or don't ship.
56
Automated tests
22
Manual procedures
2
Physical test devices
Sev
Triaged known issues
Gate
Written ship / no-ship
56 automated tests (44 on-device adversarial checks + 12 unit tests) and 22 manual procedures, run on two physical handsets. Counts verified against the source before publishing. The automated suite has already earned its keep twice — it caught a readout-overflow defect, and later a teardown race that four rounds of code review missed (both documented below).
FreqCraft Mobile — QA Test SOP
Version 1.3 · 2026-07-05 · Directive Craft LLC
App: FreqCraft Android 1.0.0 (Flutter/Dart) · Status: ACTIVE — release QA procedure
Purpose. Define and execute pre-launch QA across three layers — an automated
adversarial integration suite, emulator validation (Phase A), and physical-device release
qualification (Phase B). Phase B is the release gate; the app bundle is not submitted to the
store until every Phase B criterion is met.
Scope. FreqCraft 1.0.0 release candidate, Android only, including the live
waveform visualizer and timed-session behavior. Out of scope: iOS, accessibility/TalkBack
(deferred). Trigger: developer declares the build ready for QA — run the
automated suite first, then Phase A, then Phase B.
Automated Coverage — Run First
The adversarial integration suite is the first gate. It runs the build through input it was never meant to receive, on a tethered device, and must pass clean before a human tests anything.
Location: integration_test/app_test.dart (44 on-device) · test/ (12 unit) Run:flutter test integration_test -d <device-id> Gate: 44 on-device adversarial checks + 12 unit tests — 56 total, all green before manual testing begins.
SUITEAdversarial Integration Suite
Confirm the app survives malformed and absurd input, mode and state transitions, and edge cases — automatically and repeatably.
Malformed numeric input: multiple dots, minus signs, letters, whitespace, leading zeros.
Absurd-value handling: a 14-digit carrier must not overflow the readout. (This case caught a real defect before it reached a device.)
Implementation note — no pumpAndSettle: the live waveform animates continuously, so it never returns and the suite would hang. Use pump(Duration) only.
Pass — 44/44 adversarial checks green on the tethered device, plus 12/12 unit tests. Any failure is fixed and the suite re-run before Phase A.
Phase A — Emulator Test Procedure
Environment: Android Studio AVD, Pixel 6 / API 33 / Android 13, 2048 MB RAM, 4 cores, flutter run from project root. Result codes: PASS · FAIL · NOTE (emulator artifact — log and continue). Known emulator limitations (channel reversal at low beat frequencies, soft isochronic below 6 Hz, fade-timing drift under CPU load) are logged, not fixed.
A-1First Launch — Disclaimer Flow
Verify the disclaimer runs once on first launch and is not skippable.
Tap each numeric field (Carrier, Beat, Fade In/Out, Timer); verify all text is selected on tap.
Enter 120 then 999 in Fade In; verify the value displays in full (field accommodates 3 digits).
Enter 150 in Beat; verify the out-of-range advisory appears, then clears when the value returns to range.
Regression — type a value, then collapse the numpad with the system back gesture (not Done). Verify no text stays highlighted with selection handles, and no selection persists into the session. Values still apply only on Done/Begin.
Pass — fields select-on-tap, accept valid values, show/clear advisories at threshold, and clear focus cleanly however the numpad is dismissed.
A-5Fade Field Alignment
Verify visual alignment of the fade controls and stability under toggling.
Verify both fade input fields share the same right edge (label expanded, field pushed right).
Toggle Fade In off then on; verify the field disappears and reappears at the same position with no layout jump.
Pass — fields right-aligned; toggling causes no layout shift.
A-6Audio Playback — Basic
Verify audio starts, produces output, and stops cleanly in both modes.
Load default parameters (200 Hz carrier, 10 Hz beat, Binaural). Start the session; verify the button changes state and audio is audible.
End the session; verify audio stops and the button reverts.
Repeat in Isochronic mode. (Emulator audio may differ from device — log as NOTE, not FAIL.)
Pass — audio starts and stops cleanly; button state follows session state.
A-7Fade In / Fade Out — Perceptual Curve
Verify the fade curve is perceptually gradual across the full duration. Validates the fix for a prior linear fade that sounded complete in roughly one-third of the intended time.
Set a 30-second fade in. Start the session and monitor: very low for the first ~10s, rising through the middle third, full only near the 30s mark — never "done" early.
Enable a 30-second fade out and end the session; verify it is perceptually gradual, not abrupt.
Pass — fade feels linear to the human ear across the full duration. (A quadratic curve produces this perception; linear does not.)
A-8Race Condition Regression — Volume Spike
Verify the "alarm-clock" volume spike is gone. History: volume spiked in the final seconds before fade-out when a timer was used with fade enabled (overlapping fade coroutines).
Set Timer = 1 minute, Fade In = 5s, Fade Out = 5s, at a comfortable (non-max) volume.
Start the session and monitor the full 60 seconds, focusing on the last 10.
Verify no sudden volume increase before fade-out, smooth fade from ~55s, and a clean end at 60s with audio at zero.
Fail — any sudden volume spike or "alarm clock" effect in the final 10 seconds is a regression. Do not ship.
A-9Session Timer
Verify timer countdown, auto-stop, and fade-out display behavior.
Set a 2-minute timer, Fade Out off. Start; verify the countdown begins, audio auto-stops at zero, and the button reverts.
Set a 1-minute timer with a 10-second fade out. Verify the fade begins at ~50s.
Timer / fade display — verify the REMAINING countdown keeps ticking through the fade-out and reaches 0:00 exactly as the audio goes silent. It must not jump to 0:00 early while audio is still fading. (1-minute timer, 5s in / 5s out = 5s fade-in, 50s full, 5s fade-out, silent at 0:00.) Manual END hides REMAINING immediately; ELAPSED persists by design.
Pass — counts down correctly, auto-stops at zero, fade triggers at the right offset, and the countdown reaches 0:00 in sync with audio silence — no early jump.
A-10Preset Persistence — Cold Start
Verify stored presets survive a full app restart. (Hot reload does not test persistence — cold start required.)
Save a user preset with custom parameters and a unique name.
Kill the app and cold-start it.
Open the Presets screen; verify the preset is present and loads with all parameters restored.
Pass — all saved values survive a cold restart.
A-11Presets Screen
Verify factory and user preset display and behavior in the single-open accordion UI.
Verify all 7 factory presets are listed (Deep Sleep, Recovery, Deep Calm, Theta Schumann, Alpha Calm, Beta Focus, Gamma Clarity), each with badge, band/Hz chip, and explore line.
Expand a factory preset; verify the drawer shows parameters, attributed note, source, safety note, and Load — with no delete on factory presets.
Verify user presets offer quick-Load on the collapsed row and Delete only inside the expanded drawer (with a confirm dialog).
Load a factory preset; verify parameters reach the main screen and Gamma Clarity loads in Isochronic mode.
Pass — all presets present, accordion behavior correct, factory vs. user controls correct, modes load correctly.
A-12Footer Disclaimer
Verify the sourcing disclaimer is present at the bottom of the Presets screen.
Scroll to the bottom of the Presets screen; verify the sourcing/exploration disclaimer text is present, small, gray, and centered.
Pass — footer disclaimer present, correct text and styling.
A-13Live Waveform Visualizer
Verify the live waveform renders continuously, matches the selected type and mode, stays readable across the Hz range, idles correctly, and does not stutter during a session.
Continuous scroll — watch ≥10s; verify smooth scrolling with no seam, snap-back, or repeating-interval jump. It must read as a continuous feed, not a loop.
Shape matches type — in Binaural, cycle Sine / Square / Sawtooth / Triangle; verify the on-screen shape changes to match each and matches the engine.
Isochronic density — vary carrier and pulse across low and high values; verify visual density tracks the values and stays readable at low Hz (no lonely hump with dead gaps).
Readout overflow — enter an absurd 14-digit carrier; verify the readout shrinks to fit and shows the full number — no overflow, no error, no truncation box. Normal values render unchanged.
Idle behavior — stop the session; verify the wave freezes to a clean static silhouette (no mid-wave smear) and re-animates smoothly on restart.
No stutter — during a timed session, watch ≥10s; verify no per-second hitch as ELAPSED / REMAINING tick.
Pass — continuous, type- and mode-accurate, readable at all Hz, readout never overflows, idles and re-animates cleanly, no per-second stutter.
Phase B — Physical Device Release Gate
Prerequisites: automated suite green; all Phase A items PASS or NOTE (no unresolved FAILs). Devices: Moto G7 Power (wired-audio reference, 3.5mm jack); Pixel 6 Pro (stock Android, USB-C). The release-validation install sideloads the signed app bundle.
B-0Device Setup
Prepare the physical device for testing.
Enable Developer Options and USB Debugging.
Connect via USB and confirm adb devices recognizes the device.
Install the build (debug install, or signed bundle via bundletool for release validation).
B-1All Phase A Tests — Repeat on Device
Confirm every emulator-verified behavior holds on real hardware.
Run A-1 through A-13 on the physical device.
Treat emulator-only artifacts (channel reversal, soft low-Hz isochronic) as data, not failures, unless audio is clearly wrong.
Pass — all Phase A items pass on device, or differences are logged and confirmed as emulator artifacts.
B-2Binaural Audio Quality
Verify binaural beat perception on stereo headphones — different frequencies per ear.
On headphones, load Theta Schumann (7.83 Hz beat, 136.1 Hz carrier); verify an audible beating sensation at ~7–8 Hz.
Step up through Alpha Calm (10 Hz) and Beta Focus (14 Hz); verify the perceived rate increases. Verify a high carrier stays centered, not pushed to one ear.
Remove one headphone; verify the beat perception diminishes — confirming binaural, not isochronic, processing.
Pass — rhythmic pulsing at the correct rate, stereo-dependent, tone centered.
B-3Isochronic Audio Quality
Verify isochronic pulses are audible and clean on both speakers and headphones.
Load Gamma Clarity (40 Hz isochronic); verify rapid pulsing on speakers and the same pulsing (not a beat) on headphones.
Set pulse rate to 4 Hz; verify slow, distinct pulses with clean edges. Set to 40 Hz; verify rapid pulsing stays clean — no buzzing or overflow artifacts.
Pass — pulses audible on speakers, clean edges, no artifacts at any rate.
B-4Background Audio Mixing
Verify the app runs alongside other audio rather than muting it — a key design differentiator (ducking, not interrupting).
Start playback in a music app, switch to the app, and start a session.
Verify both are audible simultaneously (slight ducking of the music is acceptable).
End the session; verify the music app is unaffected.
Fail — if the app mutes or pauses the music app entirely. Do not ship.
B-5Screen Lock / Background Playback
Verify audio continues when the screen locks.
Start a session (no timer, no fade), lock the screen, and wait 30 seconds; verify audio is still audible.
Unlock; verify the session is still active. End the session; audio stops.
Note — if audio stops after lock, investigate the foreground-service path and log it. This blocks launch only if audio stops within 5 minutes (see B-6).
B-6OEM Battery Management — Extended Run
Detect audio termination by Android battery optimization — the primary real-device risk not testable in an emulator.
Start a continuous session at comfortable volume, lock the screen, and set the phone down.
Monitor audio at 5, 10, 15, and 20 minutes; document whether and when audio stops.
Pass — audio runs continuously for 20+ minutes screen-locked.
Blocker — audio stops within 5 minutes; the core use case is non-functional. Resolve before submitting. (Stops after 5 minutes: log and triage by device.)
B-7Volume Control
Verify system volume buttons and the in-app slider both affect output.
During a session, verify system volume up/down affects output, and the in-app slider adjusts level independently.
Pass — both system and in-app controls govern audio level.
B-8Cold Start After Device Reboot
Verify stored state persists across a full device reboot.
Save a user preset and fully reboot the device.
Open the app; verify the disclaimer does not reappear and the saved preset is present.
Pass — all state persists through a full reboot.
Release Gate Checklist
Every item must be checked before the app bundle is submitted.
Automated suite: 44/44 adversarial checks + 12/12 unit tests green on device.
B-1: all Phase A tests pass on the physical device.
B-2 / B-3: binaural beat perception and isochronic pulses confirmed.
B-4: background mixing confirmed — does not mute other apps.
B-7: volume controls functional. B-8: persistence confirmed through reboot.
GATE STATUS: [ ] OPEN [ ] PASSED [ ] BLOCKED
Known gaps and open issues — disclosed and triaged, not hidden.
ID
Severity
Description
Status / Plan
STOP
Low
Teardown race in the stop path — a reference used after an await without a mounted-check could log an error if the screen was dismissed mid-stop. Surfaced by the expanded test suite, not by four rounds of code review (including a maximum-effort audit).
Fixed + verified
P4
Low
A dead validation method in the engine — never called; validation handled in the UI.
Later release
P5
Low
Emulator channel reversal at low beat frequency; reproducible cause not identified.
Version log — change control is part of the deliverable.
v1.0 2026-06-12 — Initial release. Built from the QA SOP handoff. v1.1 2026-06-14 — Accordion preset UI, preset names, contact email; Phase A + Phase B. v1.2 2026-06-22 — Stamped to app 1.0.0. Added the automated adversarial suite (29 tests) as the first gate; added the Live Waveform Visualizer section (A-13); added the timer fade-out display spec (A-9) and the numpad-focus regression (A-4). Sanitized internal paths; defect forensics tracked separately in the bug log. v1.3 2026-07-05 — Adversarial suite expanded 29 → 44 on-device checks; added 12 unit tests (56 automated total). Physical testing run on two handsets (Moto G7 Power + Pixel 6 Pro). Logged the teardown-race defect (STOP) the suite caught after code review missed it — fixed and verified. Counts verified against source.
This is the app it ships.
FreqCraft is built and tested the way this page describes — precision audio, zero data collection, one-time purchase. See it for yourself.