Work / Mobile

Warrant Portal

Kotlin Android app that turns an estate engine’s blocked decisions into plain-language questions for the executor.

Status
built
Role
Directed Claude Code through the executor portal and the Android shell
Team
Part of Warrant + Forge, a team of 2 at an estate-settlement AI hackathon, San Francisco, Jul 2026
Timeline
Jul 2026 – Jul 2026
  • Kotlin
  • Android WebView and WebViewAssetLoader
  • Gradle Kotlin DSL
  • Android SpeechRecognizer
  • React
  • TypeScript
  • Vite
  • Service worker (offline PWA)

TL;DR

  • In the last hours of the hackathon I turned Warrant outward, toward the family settling the estate, and directed Claude Code through the build.
  • Every gap in the fact ledger becomes a plain-language task for the executor, and a blocked rule shows the statute behind the question.
  • Built as a native Kotlin shell that serves the portal offline; the APK went into the team’s repo about 15 minutes before the 3:30 PM presentations.

The problem

An estate engine that refuses to guess is only useful if someone answers its questions. The person who can answer is usually a grieving family member acting as executor, not a lawyer, and not someone who will read a rules engine’s output.

What I built

The portal’s task engine turns every gap in the ledger into one of five task types: provide a fact, answer a form question, review a form, resolve a quarantined claim, or approve an action. Each question says why it is being asked, and a blocked rule shows the statute behind it. Answers flow back into the ledger as attestations.

An executor can type, speak, or answer with a document. Documents are hashed with SHA-256 on the device, and the file stays on the phone. Partial answers always submit, and a test keeps internal fact keys off the screen.

The Android app is a native Kotlin shell that serves the Vite-built portal offline through WebViewAssetLoader and a service worker, with two product flavors: demo and portal.

Key decisions

  • Decision: a WebView shell around the web portal. Why: one portal codebase, packaged as an installable app within the event. Trade-off: Android’s WebView has gaps a browser doesn’t, and each one needs a native patch.
  • Decision: hash documents on the device. Why: the ledger can attest to a document without the file leaving the phone. Trade-off: the engine sees a fingerprint, not the contents.
  • Decision: “skip” and “decline” leave a fact unknown, never false. Why: the rules engine runs on three-valued logic, and a skipped question must not be read as a “no”. Trade-off: plans can stay blocked until someone answers.

The hard part

Two Android-only bugs surfaced in the shell. WebView’s MIME-type guesser returned nothing for .js files, so the portal’s ES modules were silently refused. And WebView has no SpeechRecognition API, so voice answers had nowhere to go. The shell now serves JavaScript with an explicit type, and a native SpeechRecognizer bridge implements the standard web API inside the WebView, so the portal’s speech code runs unchanged.

Results

  • A 1.65 MB APK (package app.warrant.portal, Android 8.0 and up) pushed to the team’s repo at 15:14 on presentation day.
  • A task engine covering five task types, wired back into the fact ledger as attestations.

What I’d do next

  • Test on physical devices and publish screenshots.
  • Sign a release build and publish the portal source with the rest of Warrant.

Verified numbers

MetricValueSource
Android APK (minSdk 26, targetSdk 35)1.65 MBlocal: WebstormProjects/accountward/warrant-portal.apk
Task types the portal turns ledger gaps into5local: warrant-backup/warrant-plus-final.bundle
Minutes before the presentations that the APK was pushedabout 15local: warrant-backup/warrant-plus-final.bundle
m.mittal
Home
Work
Research
Lab
About
Experience
Now
Résumé
Uses
Colophon
Contact
AccountWardin-build
Redlbuilt
The Councilresearch
BEMAresearch
EXIT LIQUIDITYin-build
NEXUSarchived
Warrant + Forgebuilt
Concordarchived
BlueCollarPalin-build
Chispenbuilt
Warrant Portalbuilt
JobAppin-build
Night/Dayexplored
BLACKSITE: NULLin-build
SlugBitesbuilt
Riptidebuilt
AeroBitesarchived
Internbuilt
CAD & 3D printingexplored
ForgeCouncilexplored
ADDE: adversarial due-diligence engineexplored
Model routing in practiceexplored
AI due-diligence market mapexplored
Quorumarchived
Colossus Wakeexplored
FitFindrbuilt
Project Omniexplored
Oblivionexplored
MeetWisebuilt
EyeOSexplored
LinkLeap AIexplored
Up-Toexplored
Offline speech-to-notes (Java)explored
AI-assisted game production pipelineexplored
COLLAPSEarchived
THE TRIALSarchived
EcoNodearchived
ESP32-S3 / LoRa benchexplored
CleanPlaybuilt
Rezonyrbuilt
Habit Tracker Telegram Botbuilt
Job Board Aggregatorin-build
Visual Hand Trackbuilt
CLI Task Trackerbuilt
All work44 entries
Can’t Hallucinate, Can Still Be Wrong: Calibration of a Typed-Decision Model Under Input Noisepaper
Disagreement as Signal: A Hybrid Multi-Agent and Council Architecture for Error Detection in LLM Systemspaper
Killing Good Ideasessay
Uncorrelated Failure Modesessay
ADDE: adversarial due-diligence engineexplored
AI due-diligence market mapexplored
AI-assisted game production pipelineexplored
Aura Chatexplored
Colossus Wakeexplored
EcoNodearchived
ESP32-S3 / LoRa benchexplored
EyeOSexplored
FitFindrbuilt
ForgeCouncilexplored
LinkLeap AIexplored
MeetWisebuilt
Model routing in practiceexplored
Offline speech-to-notes (Java)explored
Oblivionexplored
Print benchexplored
Project Omniexplored
Provably-fair outcome enginebuilt
Quorumarchived
Up-Toexplored
Copy hello@mitanshm.com
Switch theme
Play motion
RésuméPDF
Open GitHub ↗mit37
Open LinkedIn ↗
Toggle layout gridh
Toggle single-key shortcuts/ h