## Lens: Literal Extract only what is explicitly stated in the entry text. No inference, no filling gaps. Rules: - Read each word and phrase at face value. The text is evidence; your task is accurate transcription of its meaning, not interpretation. - Tags: extract short kebab-case tokens for every named activity, object, time anchor, person, state word, or pattern word in the text. - Time anchors are behavioral tags, not metadata. Capture them. - `stated_commitment`: only explicit statements of intent with a specific named object. - Do not infer what was not said. COMMAND_BLOCK:
Lens: Literal Extract only what is explicitly stated in the entry text. No inference, no filling gaps. Rules: - Read each word and phrase at face value. The text is evidence; your task is accurate transcription of its meaning, not interpretation. - Tags: extract short kebab-case tokens for every named activity, object, time anchor, person, state word, or pattern word in the text. - Time anchors are behavioral tags, not metadata. Capture them. - `stated_commitment`: only explicit statements of intent with a specific named object. - Do not infer what was not said. COMMAND_BLOCK:
Lens: Literal Extract only what is explicitly stated in the entry text. No inference, no filling gaps. Rules: - Read each word and phrase at face value. The text is evidence; your task is accurate transcription of its meaning, not interpretation. - Tags: extract short kebab-case tokens for every named activity, object, time anchor, person, state word, or pattern word in the text. - Time anchors are behavioral tags, not metadata. Capture them. - `stated_commitment`: only explicit statements of intent with a specific named object. - Do not infer what was not said. COMMAND_BLOCK:
Lens: Inferential Apply a charitable reading. Go beyond explicit words to what the text most plausibly means for this person's cognitive and behavioral state. Rules: - Read for pattern and meaning, not just surface vocabulary. What is this person experiencing? - Decision loops: when the user describes returning to the same choice with new framing and no resolution, capture it as a tag. - Avoidance sequences: when the user approaches a task and retreats, or states an intention then does something else, tag both the avoidance and the specific task. - User-coined idioms carry their meaning: tag the user's own phrasing verbatim and let it stand for the state it names. Inference limits: - Do not infer causes or motivations. - Do not infer emotional states the user did not name. - Retrieved history can corroborate inferences but cannot supply content that isn't anchored in the current entry. COMMAND_BLOCK:
Lens: Inferential Apply a charitable reading. Go beyond explicit words to what the text most plausibly means for this person's cognitive and behavioral state. Rules: - Read for pattern and meaning, not just surface vocabulary. What is this person experiencing? - Decision loops: when the user describes returning to the same choice with new framing and no resolution, capture it as a tag. - Avoidance sequences: when the user approaches a task and retreats, or states an intention then does something else, tag both the avoidance and the specific task. - User-coined idioms carry their meaning: tag the user's own phrasing verbatim and let it stand for the state it names. Inference limits: - Do not infer causes or motivations. - Do not infer emotional states the user did not name. - Retrieved history can corroborate inferences but cannot supply content that isn't anchored in the current entry. COMMAND_BLOCK:
Lens: Inferential Apply a charitable reading. Go beyond explicit words to what the text most plausibly means for this person's cognitive and behavioral state. Rules: - Read for pattern and meaning, not just surface vocabulary. What is this person experiencing? - Decision loops: when the user describes returning to the same choice with new framing and no resolution, capture it as a tag. - Avoidance sequences: when the user approaches a task and retreats, or states an intention then does something else, tag both the avoidance and the specific task. - User-coined idioms carry their meaning: tag the user's own phrasing verbatim and let it stand for the state it names. Inference limits: - Do not infer causes or motivations. - Do not infer emotional states the user did not name. - Retrieved history can corroborate inferences but cannot supply content that isn't anchored in the current entry. COMMAND_BLOCK:
Lens: Skeptical Apply an adversarial reading. Assume the charitable interpretation is wrong until the words force it. Challenge the obvious read — do not echo it. Populate every schema field, but extract only what the text directly supports. Where the natural read takes an inferential leap, refuse it: take the more conservative value the literal evidence backs, even when that disagrees with the other lenses. Adversarial layer — flag the leaps you refused to take: - `commitment-without-anchor` — a modal commitment with no specific object or deadline. - `unsupported-recurrence` — the user signals recurrence with no retrieved history to corroborate. - `vocabulary-contradiction` — the user's own words point in two directions in the same entry. - `time-inconsistency` — incompatible time anchors within the same entry for the same event. `flag` output format — one `flag:` line per flag: `flag: <kind> | <snippet> | <note>`. COMMAND_BLOCK:
Lens: Skeptical Apply an adversarial reading. Assume the charitable interpretation is wrong until the words force it. Challenge the obvious read — do not echo it. Populate every schema field, but extract only what the text directly supports. Where the natural read takes an inferential leap, refuse it: take the more conservative value the literal evidence backs, even when that disagrees with the other lenses. Adversarial layer — flag the leaps you refused to take: - `commitment-without-anchor` — a modal commitment with no specific object or deadline. - `unsupported-recurrence` — the user signals recurrence with no retrieved history to corroborate. - `vocabulary-contradiction` — the user's own words point in two directions in the same entry. - `time-inconsistency` — incompatible time anchors within the same entry for the same event. `flag` output format — one `flag:` line per flag: `flag: <kind> | <snippet> | <note>`. COMMAND_BLOCK:
Lens: Skeptical Apply an adversarial reading. Assume the charitable interpretation is wrong until the words force it. Challenge the obvious read — do not echo it. Populate every schema field, but extract only what the text directly supports. Where the natural read takes an inferential leap, refuse it: take the more conservative value the literal evidence backs, even when that disagrees with the other lenses. Adversarial layer — flag the leaps you refused to take: - `commitment-without-anchor` — a modal commitment with no specific object or deadline. - `unsupported-recurrence` — the user signals recurrence with no retrieved history to corroborate. - `vocabulary-contradiction` — the user's own words point in two directions in the same entry. - `time-inconsistency` — incompatible time anchors within the same entry for the same event. `flag` output format — one `flag:` line per flag: `flag: <kind> | <snippet> | <note>`. COMMAND_BLOCK:
Surface: State Captures the user's cognitive and energy state. - The state word the user uses for their physical or cognitive condition (drained, crashed, foggy, flat, wired). Use the user's exact word, not clinical paraphrase. It must describe the person, not the event — discard manner qualifiers and effects. - A before/after transition between two distinct states. What goes in the schema: - Append the state word to `tags` as a short lowercase kebab-case token. Single root word only — never a clause. Omit when the entry names no such condition. COMMAND_BLOCK:
Surface: State Captures the user's cognitive and energy state. - The state word the user uses for their physical or cognitive condition (drained, crashed, foggy, flat, wired). Use the user's exact word, not clinical paraphrase. It must describe the person, not the event — discard manner qualifiers and effects. - A before/after transition between two distinct states. What goes in the schema: - Append the state word to `tags` as a short lowercase kebab-case token. Single root word only — never a clause. Omit when the entry names no such condition. COMMAND_BLOCK:
Surface: State Captures the user's cognitive and energy state. - The state word the user uses for their physical or cognitive condition (drained, crashed, foggy, flat, wired). Use the user's exact word, not clinical paraphrase. It must describe the person, not the event — discard manner qualifiers and effects. - A before/after transition between two distinct states. What goes in the schema: - Append the state word to `tags` as a short lowercase kebab-case token. Single root word only — never a clause. Omit when the entry names no such condition. - What: Vestige—an ADHD-friendly Android app designed to point out the things you don't know you're doing every day. 30-second voice entries in, sourced behavioral patterns out. No grading, no gamification, no feelings prompts. - Gemma 4 doing real work: E4B handles native audio in (no SpeechRecognizer), transcription + persona-flavored follow-up in the foreground, then a 3-lens convergence extraction pass in the background. EmbeddingGemma 300M catches vocabulary drift over time: same state, different words. - Privacy is enforced, not claimed: sealed-by-default NetworkGate + a verifyNoTelemetry Gradle task with four independent scans (full list in §Code) that uploads privacy receipts as a CI artifact every run. After the model download, the app process has no remaining outbound code path. - Proof artifacts: GitHub repo · APK + SHA-256 - Architecture - Project Structure - Getting Started - Configuration - Security & Privacy - How to Contribute - What's Next - Known Limitations - Acknowledgements - Inference runtime: LiteRT-LM litertlm-android:0.11.0 (pinned) - Models: Gemma 4 E4B (~3.66 GB, native audio + text) · EmbeddingGemma 300M (~200 MB, tone-word Vocab Drift clustering) - Platform: Android 14+, Kotlin, Jetpack Compose, Material 3 - Persistence: ObjectBox (entries, patterns, embeddings); SharedPreferences for onboarding flags - Build: Gradle KTS with a custom verifyNoTelemetry task (four scans, CI artifact every run) - Pre-commit / pre-push: Lefthook running ktlint, detekt, secret-scan, actionlint, then full build + test - CI: GitHub Actions running CodeQL, Sonar, Kover, commitlint, and verifyNoTelemetry - Tests: JUnit 5 Jupiter on JVM (via useJUnitPlatform()), JUnit 4 + Robolectric + AndroidX Compose UI on instrumented; MockK, Turbine, coroutines-test - NetworkGate.kt—sealed AtomicReference, opened only for the model download, resealed in finally. The app's only HTTP path. - verifyNoTelemetry Gradle task—four independent scans (classpath, manifest, APK, host list); any fails the build. Receipts upload as a CI artifact every run. - Inferential