A Zero-Split-Brain Android application for tracking work targets, cumulative balances, and billable ratios using the EARLY API (formerly Timeular).
The project is structured to enforce a strict local-first separation of concerns:
- WASM Brain (
brain/): A Rust-based core compiled to WebAssembly. It handles all business logic, UTC-to-ET timezone adjustments, Daylight Savings rules, expected target math, and comp-time calculations. - Ignorant Host (
android/): A Jetpack Compose application. It contains zero business logic, performing only UI rendering, secure credential storage, API requests, and delegation of math computations to the WASM brain.
+------------------------+
| Jetpack Compose UI |
+-----------+------------+
| UDF State
v
+-----------+------------+
| TimeTrackerViewModel |
+-----------+------------+
/ \
Network Fetch / \ Run Calculations
v v
+-------------+ +-------------+
| ApiClient | | BrainHost |
+------+------+ +------+------+
| | Chicory
v HTTPS v Interpreter
[ Early API ] [ brain.wasm ]
The codebase maintains two independent work pipelines that serve different purposes and use separate math definitions:
graph TD
subgraph Android Flow (Current Dashboard)
A1[WASM Brain] -->|Unified Strict Math| A2[Android App]
A2 -->|Displays Live Data| A3[User Dashboard]
end
subgraph Ruby Archive Flow (Legacy CLI)
B1["legacy/export.rb"] -->|Historical Math| B2["legacy/hack/since_the_start.sh"]
B2 -->|Populates CSVs| B3[history/ Directory]
B3 -->|Aggregates| B4[history/summary_report.md]
end
- Components: WASM brain (brain) + Jetpack Compose host (android).
- Purpose: Provides the real-time, local-first daily dashboard and targets tracking.
- Math: Unified Strict Math. Every month is computed independently using inclusive weekday math (each month counts all weekdays fully). It does not count or read from the Ruby CSV history archives.
- Components: export.rb + since_the_start.sh + summary_report.md.
- Purpose: Produces and updates the long-term, read-only historical CSV files in the history folder (gitignored). Used for retrospective devlog archives.
- Math: Historical Math. Preserves the pre-April 2026 "jubilee math" (which excluded the last day of each month for reprieves) so that historical monthly comp-time balances do not change retrospectively over time.
- Rust (for compiling the WASM brain)
- Android SDK and JDK 17+
-
Install WASM target:
make setup
-
Compile the app and run tests:
make build
This will:
- Run unit tests for the Rust WASM brain (
cargo test). - Compile the Rust WASM brain (
brain.wasm). - Copy
brain.wasminto the Android assets directory. - Run Android JVM unit tests (
./gradlew test). - Assemble the final Android debug APK (
./gradlew assembleDebug).
- Run unit tests for the Rust WASM brain (
-
Deploy to a connected device:
make install
- Rust Brain: Run cargo tests directly:
cd brain && cargo test
- Android Host: Run JVM integration tests directly (no emulator needed since the WASM brain runs in Chicory's pure Java interpreter):
cd android && ./gradlew test
- Code Formatting / Linting:
make lint make format
The legacy Spin-based web dashboard and Ruby CLI tools have been relocated to the legacy/ directory, but their core functionality has been preserved and integrated into the root Makefile for seamless backward compatibility.
make spin-watch: Start the local development loop. Auto-rebuilds the React frontend and runs the Python Wasm API under Spin with live reloading athttp://localhost:3000.make spin-up: Build and launch the production Spin service.make spin-build: Build the React frontend (web/dist) and compile the Python API Wasm component.
make summary-json: Monthly Month-Close Archival. Automatically detects and backfills completed past months from the Early API intohistory/YYYY_MM_history.csv, recalculates the 4-month moving averages, and synchronizeshistory_summary.jsonacross bothweb/public/andandroid/app/src/main/assets/. Run this at the start of each new month (e.g., September 1 for August).make this: Quick progress report for the current month (this_month.csv).make today: Generates a report of today's activities (today.csv).make weekly: Generates a 7-day nonbillable report (weekly.csv).make six: Generates a 6-day all-entry mixture report (six.csv).
For detailed documentation, prerequisites, and environment setup of these legacy features, refer to LEGACY.md.