Skip to content

SPLIT v0.2.0 — repository and quality release

Pre-release
Pre-release

Choose a tag to compare

@GPTmadeit GPTmadeit released this 09 Aug 05:16
· 15 commits to main since this release

A repository and quality release. Detection, timing and app behaviour are unchanged from v0.1.0 — this release is tests, CI, documentation and licensing.

▶ Try it in your browser · no install, works on a phone


Added

  • 42 unit tests covering :core — split derivation, split σ, standards grading, USPSA hit factor, the watch↔phone wire contract round-trip, timer delay modes, and drill library invariants. Expectations are hand-computed, not taken from the implementation.
  • Continuous integration — unit tests, both APK assemblies, Android Lint, ktlint, and a structural check on the browser prototype, on every push and PR.
  • Security automation — CodeQL (security-extended), gitleaks across full git history, dependency review on PRs, and a weekly scheduled scan.
  • Release automation — tagging v* verifies, builds, and attaches APKs plus SHA256SUMS.txt.
  • Dependabot for Gradle and GitHub Actions, with grouped updates.
  • DocumentationARCHITECTURE.md, CONTRIBUTING.md, SECURITY.md, SUPPORT.md, CODE_OF_CONDUCT.md, ROADMAP.md, CHANGELOG.md. The README was rewritten for someone who has never held a shot timer, and now covers requirements, quick start, usage, configuration, troubleshooting and an FAQ.
  • Issue templates for bugs, features, and a dedicated detection-accuracy report; plus a PR template.
  • MIT licence, so the repository has a detected licence.
  • Branding — banner and social preview assets.

Changed

  • Kotlin sources formatted with ktlint 1.8.0 (intellij_idea ruleset — chosen so CI agrees with what Android Studio produces on save). Whitespace only; the full build and all 42 tests pass unchanged.
  • .gitignore hardened for signing material (*.jks, *.keystore, keystore.properties), .env files and service-account JSON.
  • .gitattributes added, normalising line endings to LF.

Fixed

  • gradlew was not executable. The repository was authored on Windows, which carries no POSIX executable bit, so it was committed as mode 100644. Every Linux and macOS clone hit ./gradlew: Permission denied — including CI, which is how it surfaced. Now 100755.
  • Two unit test expectations that were wrong when first written (an incorrect hand-computed variance, and a drill invariant that treated independent ceilings as a time budget). Both were test bugs; the implementation was correct.

Removed

Nothing.

Breaking changes

None. The Data Layer wire format is unchanged, so a v0.2.0 watch and a v0.1.0 phone still interoperate.

While the version is 0.x, the wire format may change in any minor release.


Install

Both APKs are debug-signed — fine for sideloading, not for Play distribution. Publishing requires your own signing key.

adb -s <watch-serial> install -r split-wear-v0.2.0-debug.apk
adb -s <phone-serial> install -r split-mobile-v0.2.0-debug.apk

Run adb devices to list serials. Verify your download against SHA256SUMS.txt:

sha256sum -c SHA256SUMS.txt

The two apps share an applicationId on purpose — that is what makes Play deliver the watch APK to a paired watch when the phone app installs.

What was actually verified

Check Result
./gradlew build (debug + release, both modules) pass
Unit tests 42 / 42 pass
Android Lint no issues on :wear and :mobile
ktlint 0 violations
Packaged APK manifests com.carlb.split, versionName 0.2.0, versionCode 2
APK signatures (apksigner verify) both verify
Secret scan across full history clean
Browser prototype loads over HTTPS, pure ASCII, full string runs correctly

Known limitations

Nothing has been run on real hardware, and no live fire has ever been recorded through this code.

The four detector constants are reasoned estimates, not measurements:

Constant Value Basis
Clip-run threshold 3 samples estimate
Echo blanking 60 ms estimate
Recoil window ±40 ms estimate
Recoil threshold 18 m/s² estimate

Also:

  • No instrumented tests. Unit tests cover :core logic only — the audio, sensor and UI layers have no automated coverage.
  • The browser prototype cannot truly pin an unprocessed audio source; browsers apply AGC and noise suppression by default and the page can only request they be off.
  • compileSdk is pinned at 36 with dependencies held back to match, because platform 37 is not published yet. Dependabot will open PRs bumping past those pins; they are expected to fail CI until the platform ships.

If you take this to a range, a detection accuracy report is by far the most valuable thing you can contribute.

Full changelog: v0.1.0...v0.2.0