[EPIC] Native Android Zara client with embedded portable Prolog and typed device capabilities #152

Open
opened 2026-08-22 21:51:10 +00:00 by lost-rob0t · 2 comments
lost-rob0t commented 2026-08-22 21:51:10 +00:00 (Migrated from github.com)

Goal

Add a first-class Android Zara client in this repository after the daemon/client split, while preserving Zara's Prolog identity instead of reducing Android to a dumb webview.

The Android client must:

  • speak authenticated ZARA/1 to zara-server;
  • own Android microphone, wake/manual activation, speaker playback, notifications, clipboard and other device-facing capabilities;
  • run a compatible Prolog engine locally for the portable client-side semantic/capability subset;
  • share intent vocabulary/fixtures with Linux rather than forking behavior;
  • use typed closed device actions, never accept an arbitrary remote shell/eval request;
  • support real voice interaction and the programmable-command system from #151 once those contracts exist.

Dependency gate

This is deliberately future work.

  • No Android implementation before #133 completes the supported client split.
  • Voice edge depends on #132.
  • Portable semantic/dialogue/capability contracts depend on #150.
  • Programmable-command parity depends on #151.
  • Authentication/principal isolation depends on #130/#131.
  • Final production/canonical claims must respect #134.

Research-only investigation may occur earlier only when it cannot create a parallel client/runtime architecture.

Architecture principle

Android is not a second assistant runtime and not a browser shell.

Target split:

Android client
  - UI
  - microphone capture
  - wake/manual activation
  - speaker playback
  - local device capability adapters
  - local portable Prolog policy/capability facts
  - encrypted ZaraClient transport
          |
          | ZARA/1
          v
zara-server
  - authenticated principal/session authority
  - VAD/STT
  - semantic/server Prolog
  - dialogue state / IntentFrame ownership as defined by #150
  - conversation + memory
  - LLM/agent
  - server APIs/tools/MCP
  - TTS synthesis

The exact placement of some lightweight/offline intent work is research-owned, but there must be one semantic vocabulary and explicit authority boundaries.

Embedded Prolog requirement

Android must be able to execute Prolog locally.

Do not choose the engine by assumption. The first child issue must perform an adversarial bakeoff including at least:

  • SWI-Prolog built for Android/NDK if practical;
  • SWI-Prolog WebAssembly embedded in an Android-compatible runtime if practical;
  • another actively maintained embeddable Prolog implementation only if it can satisfy Zara's semantics/licensing/build/security requirements.

Evaluate:

  • upstream support/maintenance status;
  • Android ABI coverage (arm64-v8a minimum, emulator ABI where needed);
  • JNI/FFI complexity and lifecycle;
  • startup time and memory;
  • threading/reentrancy;
  • filesystem/resource loading;
  • module/library compatibility;
  • foreign predicates;
  • exception/error behavior;
  • cancellation/time limits;
  • app bundle size;
  • reproducible/offline build feasibility;
  • license obligations;
  • Play-distribution implications where relevant;
  • ability to execute Zara's shared intent fixture suite.

No engine wins because it is already used on Linux.

Portable Prolog subset

Research and document which parts of Zara's semantic intent/dialogue/capability knowledge base are portable to both server SWI-Prolog and the selected Android runtime.

Prefer portable ISO/common constructs in the shared semantic core when practical. Platform-specific/foreign/service predicates remain behind server or Android provider modules.

The shared core must not import Linux process-management, desktop, shell, PySWIP, server networking, or provider-specific foreign libraries.

A deterministic compatibility gate must run the same semantic fixture corpus against server Prolog and Android-embedded Prolog and compare normalized results.

Android project/build ownership

Keep Android source in the Zara repository under a clearly owned subtree chosen by research (for example android/ or clients/android/).

The Android build must be reproducible enough for CI and developer onboarding. Research must reconcile Gradle/Android SDK/NDK requirements with Zara's Nix-authoritative development workflow rather than pretending Nix replaces the Android toolchain or letting unpinned downloads silently define the build.

Requirements include:

  • pinned/declared Android SDK + build tools + NDK where used;
  • deterministic dependency lock/version policy;
  • debug/test APK build in CI;
  • release signing kept outside source and CI artifacts unless explicitly configured;
  • no API/CURVE/provider secrets embedded in APK resources;
  • clear minimum/target SDK decisions based on needed APIs, not arbitrary latest-only selection;
  • architecture suitable for emulator tests plus real-device manual gate.

ZARA/1 client requirements

Use the same protocol semantics as Linux clients.

Implement:

  • CURVE/ZAP-compatible client identity strategy or a rigorously researched protocol-compatible Android binding/transport solution;
  • server public-key pinning;
  • enrollment/rotation/revocation UX;
  • bounded connect/handshake/reconnect;
  • session/conversation continuity;
  • request/reply/event correlation;
  • stale-session rejection;
  • negotiated capability advertisement from #150;
  • audio streams from #132;
  • typed device-action request/result handling;
  • no arbitrary identity in payload overriding authenticated principal.

If direct ZeroMQ/CURVE on Android is not viable with acceptable maintenance/security properties, RAGE research must surface that as an architecture challenge before implementation rather than quietly replacing ZARA/1 with an unrelated Android protocol.

Android local device capabilities

Initial candidates, subject to Android permission/API research:

  • open URI;
  • launch an installed app through explicit Android APIs where allowed;
  • notification;
  • clipboard read/write with explicit policy and modern Android restrictions;
  • share intent;
  • local timer/alarm integration only if semantics/permissions are understood;
  • media/playback controls where permitted;
  • optional screenshot/screen context only through explicit Android permission/capture APIs and a separate privacy design;
  • microphone/speaker device edges;
  • future camera/media capabilities behind explicit consent.

Every adapter is a closed typed capability with validation and permission state. Server requests a semantic action; Android decides whether its registered adapter can perform it under local OS/user policy.

Capability advertisement security

Capability advertisement communicates availability, not authority.

  • client cannot advertise admin and gain server administration;
  • client cannot invent unregistered capability names;
  • capability set and metadata are bounded;
  • server authorization is still evaluated independently;
  • Android OS permission denial must propagate as typed unavailable/denied state;
  • capability changes while app is running are reflected safely;
  • action targeting must bind to authenticated session/device ownership;
  • replay/cancellation/idempotency behavior follows #150.

Voice edge

Reuse #132: Android owns microphone capture and speaker playback; server owns existing VAD/STT/routing/LLM/tool/TTS work.

Desired behavior:

  1. local wake word or explicit push-to-talk/manual activation;
  2. stream negotiated PCM/codec frames to daemon;
  3. display partial/final transcript and assistant text;
  4. stream server-generated TTS audio to local playback;
  5. user speech while Zara speaks stops playback locally immediately;
  6. send canonical interruption/cancel upstream;
  7. stale server audio/text for old turn never plays/mutates current UI.

Local wake detection must be separately researched for Android background/battery/privacy constraints. Do not assume a continuously running desktop-style Python wake loop is acceptable.

Offline/degraded behavior

The first Android release need not recreate the full server offline, but local Prolog must have a useful defined role.

Research should define profiles such as:

  • connected: server authoritative for full assistant work;
  • disconnected: local Prolog may identify supported device-only intents/capabilities and either execute explicitly allowed local actions or state that the server is unavailable;
  • reconnect: never duplicate side effects or pretend an old in-flight server turn survived without confirmation.

Do not silently run a second LLM/memory stack merely to call the app "offline".

Shared test corpus

At minimum run the same semantic examples as #150 on Linux/server and Android local Prolog fixtures:

  • set a timer for twenty minutes;
  • set a timer -> missing duration;
  • follow-up twenty minutes;
  • open Firefox or platform-neutral fixture equivalent -> open-app capability;
  • open -> missing app;
  • search -> server capability when connected;
  • screenshot/device action -> capability availability differs by platform/permission;
  • authored command from #151 -> same semantic definition, Android provider where supported.

Normalized intent/slot results must match where platform semantics are intentionally shared; provider selection may differ and must be explicit.

Android-specific adversarial matrix

Test at least:

  • malformed/oversized protocol input;
  • wrong/revoked server/client key;
  • background/foreground reconnect races;
  • activity/process recreation;
  • network switch/offline/online transitions;
  • duplicate events after reconnect;
  • Android permission revoked while capability is advertised;
  • action request targeting wrong device/session;
  • malicious unknown capability/arguments;
  • intent URI injection/pathological URI sizes;
  • clipboard/sensitive data not logged;
  • audio focus interruptions;
  • Bluetooth/headset route changes where practical;
  • mic permission denial;
  • server restart mid-turn;
  • app kill/relaunch with durable conversation resume;
  • no private key/provider secret in logs, crash reports or APK contents.

Manual real-device gate

The final Android gate requires an actual Android device, not emulator-only claims. The human script must cover:

  • enroll/connect to real zara-server;
  • text turn;
  • real microphone voice turn;
  • server STT -> response -> streamed TTS playback;
  • barge-in;
  • multi-turn missing-slot dialogue;
  • device-local action such as safe open URI/app/notification;
  • server-side tool/service action;
  • create/invoke a user command by voice after #151;
  • background/reconnect behavior;
  • app/server restart continuity;
  • revoke key and prove access stops;
  • verify another client/principal does not receive private state/events.

Manual results must be recorded as evidence but never fabricated by CI.

RAGE/TDD

Every child is issue-driven RAGE: exact immutable starting commit in rage/<work-log>.org, deep research, evidence-derived design/rejected alternatives/invariants/threats, TDD red/green, meaningful coverage, focused/full repo/Nix/Android gates, exact-head Actions, merge only exact green+mergeable head.

Ordered slices

  1. Android Prolog/runtime/ZeroMQ/toolchain feasibility research and architecture decision;
  2. repository Android skeleton + reproducible CI build + test harness;
  3. shared portable Prolog semantic-core extraction/parity fixture runner;
  4. authenticated ZARA/1 Android client + enrollment/reconnect/session state;
  5. closed Android device capability registry/action adapters;
  6. microphone/wake/manual activation + streaming audio/playback/barge-in edge;
  7. local/degraded Prolog behavior and connected/provider selection integration;
  8. programmable-command parity from #151;
  9. adversarial lifecycle/security/performance matrix;
  10. real-device human voice/reconnect/revocation release gate.

Completion rule

The epic is complete only when a real Android device can run Zara's portable Prolog semantics locally, authenticate to the same zara-server, participate in the same conversations and semantic command model as Linux, stream live voice with correct client-owned devices, execute only allow-listed local capabilities, and pass both automated cross-platform parity tests and a documented human real-device voice gate.

## Goal Add a first-class Android Zara client **in this repository** after the daemon/client split, while preserving Zara's Prolog identity instead of reducing Android to a dumb webview. The Android client must: - speak authenticated `ZARA/1` to `zara-server`; - own Android microphone, wake/manual activation, speaker playback, notifications, clipboard and other device-facing capabilities; - run a compatible Prolog engine locally for the portable client-side semantic/capability subset; - share intent vocabulary/fixtures with Linux rather than forking behavior; - use typed closed device actions, never accept an arbitrary remote shell/eval request; - support real voice interaction and the programmable-command system from #151 once those contracts exist. ## Dependency gate This is deliberately future work. - **No Android implementation before #133 completes the supported client split.** - Voice edge depends on #132. - Portable semantic/dialogue/capability contracts depend on #150. - Programmable-command parity depends on #151. - Authentication/principal isolation depends on #130/#131. - Final production/canonical claims must respect #134. Research-only investigation may occur earlier only when it cannot create a parallel client/runtime architecture. ## Architecture principle Android is not a second assistant runtime and not a browser shell. Target split: ```text Android client - UI - microphone capture - wake/manual activation - speaker playback - local device capability adapters - local portable Prolog policy/capability facts - encrypted ZaraClient transport | | ZARA/1 v zara-server - authenticated principal/session authority - VAD/STT - semantic/server Prolog - dialogue state / IntentFrame ownership as defined by #150 - conversation + memory - LLM/agent - server APIs/tools/MCP - TTS synthesis ``` The exact placement of some lightweight/offline intent work is research-owned, but there must be one semantic vocabulary and explicit authority boundaries. ## Embedded Prolog requirement Android must be able to execute Prolog locally. Do not choose the engine by assumption. The first child issue must perform an adversarial bakeoff including at least: - SWI-Prolog built for Android/NDK if practical; - SWI-Prolog WebAssembly embedded in an Android-compatible runtime if practical; - another actively maintained embeddable Prolog implementation only if it can satisfy Zara's semantics/licensing/build/security requirements. Evaluate: - upstream support/maintenance status; - Android ABI coverage (`arm64-v8a` minimum, emulator ABI where needed); - JNI/FFI complexity and lifecycle; - startup time and memory; - threading/reentrancy; - filesystem/resource loading; - module/library compatibility; - foreign predicates; - exception/error behavior; - cancellation/time limits; - app bundle size; - reproducible/offline build feasibility; - license obligations; - Play-distribution implications where relevant; - ability to execute Zara's shared intent fixture suite. No engine wins because it is already used on Linux. ## Portable Prolog subset Research and document which parts of Zara's semantic intent/dialogue/capability knowledge base are portable to both server SWI-Prolog and the selected Android runtime. Prefer portable ISO/common constructs in the shared semantic core when practical. Platform-specific/foreign/service predicates remain behind server or Android provider modules. The shared core must not import Linux process-management, desktop, shell, PySWIP, server networking, or provider-specific foreign libraries. A deterministic compatibility gate must run the same semantic fixture corpus against server Prolog and Android-embedded Prolog and compare normalized results. ## Android project/build ownership Keep Android source in the Zara repository under a clearly owned subtree chosen by research (for example `android/` or `clients/android/`). The Android build must be reproducible enough for CI and developer onboarding. Research must reconcile Gradle/Android SDK/NDK requirements with Zara's Nix-authoritative development workflow rather than pretending Nix replaces the Android toolchain or letting unpinned downloads silently define the build. Requirements include: - pinned/declared Android SDK + build tools + NDK where used; - deterministic dependency lock/version policy; - debug/test APK build in CI; - release signing kept outside source and CI artifacts unless explicitly configured; - no API/CURVE/provider secrets embedded in APK resources; - clear minimum/target SDK decisions based on needed APIs, not arbitrary latest-only selection; - architecture suitable for emulator tests plus real-device manual gate. ## `ZARA/1` client requirements Use the same protocol semantics as Linux clients. Implement: - CURVE/ZAP-compatible client identity strategy or a rigorously researched protocol-compatible Android binding/transport solution; - server public-key pinning; - enrollment/rotation/revocation UX; - bounded connect/handshake/reconnect; - session/conversation continuity; - request/reply/event correlation; - stale-session rejection; - negotiated capability advertisement from #150; - audio streams from #132; - typed device-action request/result handling; - no arbitrary identity in payload overriding authenticated principal. If direct ZeroMQ/CURVE on Android is not viable with acceptable maintenance/security properties, RAGE research must surface that as an architecture challenge before implementation rather than quietly replacing `ZARA/1` with an unrelated Android protocol. ## Android local device capabilities Initial candidates, subject to Android permission/API research: - open URI; - launch an installed app through explicit Android APIs where allowed; - notification; - clipboard read/write with explicit policy and modern Android restrictions; - share intent; - local timer/alarm integration only if semantics/permissions are understood; - media/playback controls where permitted; - optional screenshot/screen context only through explicit Android permission/capture APIs and a separate privacy design; - microphone/speaker device edges; - future camera/media capabilities behind explicit consent. Every adapter is a closed typed capability with validation and permission state. Server requests a semantic action; Android decides whether its registered adapter can perform it under local OS/user policy. ## Capability advertisement security Capability advertisement communicates **availability**, not authority. - client cannot advertise `admin` and gain server administration; - client cannot invent unregistered capability names; - capability set and metadata are bounded; - server authorization is still evaluated independently; - Android OS permission denial must propagate as typed unavailable/denied state; - capability changes while app is running are reflected safely; - action targeting must bind to authenticated session/device ownership; - replay/cancellation/idempotency behavior follows #150. ## Voice edge Reuse #132: Android owns microphone capture and speaker playback; server owns existing VAD/STT/routing/LLM/tool/TTS work. Desired behavior: 1. local wake word or explicit push-to-talk/manual activation; 2. stream negotiated PCM/codec frames to daemon; 3. display partial/final transcript and assistant text; 4. stream server-generated TTS audio to local playback; 5. user speech while Zara speaks stops playback locally immediately; 6. send canonical interruption/cancel upstream; 7. stale server audio/text for old turn never plays/mutates current UI. Local wake detection must be separately researched for Android background/battery/privacy constraints. Do not assume a continuously running desktop-style Python wake loop is acceptable. ## Offline/degraded behavior The first Android release need not recreate the full server offline, but local Prolog must have a useful defined role. Research should define profiles such as: - connected: server authoritative for full assistant work; - disconnected: local Prolog may identify supported device-only intents/capabilities and either execute explicitly allowed local actions or state that the server is unavailable; - reconnect: never duplicate side effects or pretend an old in-flight server turn survived without confirmation. Do not silently run a second LLM/memory stack merely to call the app "offline". ## Shared test corpus At minimum run the same semantic examples as #150 on Linux/server and Android local Prolog fixtures: - `set a timer for twenty minutes`; - `set a timer` -> missing duration; - follow-up `twenty minutes`; - `open Firefox` or platform-neutral fixture equivalent -> open-app capability; - `open` -> missing app; - search -> server capability when connected; - screenshot/device action -> capability availability differs by platform/permission; - authored command from #151 -> same semantic definition, Android provider where supported. Normalized intent/slot results must match where platform semantics are intentionally shared; provider selection may differ and must be explicit. ## Android-specific adversarial matrix Test at least: - malformed/oversized protocol input; - wrong/revoked server/client key; - background/foreground reconnect races; - activity/process recreation; - network switch/offline/online transitions; - duplicate events after reconnect; - Android permission revoked while capability is advertised; - action request targeting wrong device/session; - malicious unknown capability/arguments; - intent URI injection/pathological URI sizes; - clipboard/sensitive data not logged; - audio focus interruptions; - Bluetooth/headset route changes where practical; - mic permission denial; - server restart mid-turn; - app kill/relaunch with durable conversation resume; - no private key/provider secret in logs, crash reports or APK contents. ## Manual real-device gate The final Android gate requires an actual Android device, not emulator-only claims. The human script must cover: - enroll/connect to real `zara-server`; - text turn; - real microphone voice turn; - server STT -> response -> streamed TTS playback; - barge-in; - multi-turn missing-slot dialogue; - device-local action such as safe open URI/app/notification; - server-side tool/service action; - create/invoke a user command by voice after #151; - background/reconnect behavior; - app/server restart continuity; - revoke key and prove access stops; - verify another client/principal does not receive private state/events. Manual results must be recorded as evidence but never fabricated by CI. ## RAGE/TDD Every child is issue-driven RAGE: exact immutable starting commit in `rage/<work-log>.org`, deep research, evidence-derived design/rejected alternatives/invariants/threats, TDD red/green, meaningful coverage, focused/full repo/Nix/Android gates, exact-head Actions, merge only exact green+mergeable head. ## Ordered slices 1. Android Prolog/runtime/ZeroMQ/toolchain feasibility research and architecture decision; 2. repository Android skeleton + reproducible CI build + test harness; 3. shared portable Prolog semantic-core extraction/parity fixture runner; 4. authenticated `ZARA/1` Android client + enrollment/reconnect/session state; 5. closed Android device capability registry/action adapters; 6. microphone/wake/manual activation + streaming audio/playback/barge-in edge; 7. local/degraded Prolog behavior and connected/provider selection integration; 8. programmable-command parity from #151; 9. adversarial lifecycle/security/performance matrix; 10. real-device human voice/reconnect/revocation release gate. ## Completion rule The epic is complete only when a real Android device can run Zara's portable Prolog semantics locally, authenticate to the same `zara-server`, participate in the same conversations and semantic command model as Linux, stream live voice with correct client-owned devices, execute only allow-listed local capabilities, and pass both automated cross-platform parity tests and a documented human real-device voice gate.
lost-rob0t commented 2026-08-22 21:59:58 +00:00 (Migrated from github.com)

Canonical child issue map

Android is future work and production implementation stays blocked by #133. Consume:

  • #170 — RAGE Prolog/ZeroMQ/NDK/WASM/Android-platform feasibility bakeoff
  • #171 — in-repo reproducible Android project/CI skeleton
  • #172 — portable shared Prolog semantic-core parity on Linux + Android
  • #173 — authenticated Android ZARA/1 enrollment/reconnect/session continuity
  • #174 — closed Android device-capability registry/action adapters
  • #175 — microphone/wake/manual activation/playback/barge-in edge
  • #176 — local/degraded Android Prolog behavior without a second server assistant
  • #177 — programmable-command semantic parity and platform-specific providers
  • #178 — automated adversarial Android lifecycle/security/resource/parity gate
  • #179 — explicitly human real-device embedded-Prolog/live-voice release gate

No Android production code should be invented from the parent prose before its owning child/dependencies are eligible.

## Canonical child issue map Android is future work and production implementation stays blocked by #133. Consume: - [ ] #170 — RAGE Prolog/ZeroMQ/NDK/WASM/Android-platform feasibility bakeoff - [ ] #171 — in-repo reproducible Android project/CI skeleton - [ ] #172 — portable shared Prolog semantic-core parity on Linux + Android - [ ] #173 — authenticated Android ZARA/1 enrollment/reconnect/session continuity - [ ] #174 — closed Android device-capability registry/action adapters - [ ] #175 — microphone/wake/manual activation/playback/barge-in edge - [ ] #176 — local/degraded Android Prolog behavior without a second server assistant - [ ] #177 — programmable-command semantic parity and platform-specific providers - [ ] #178 — automated adversarial Android lifecycle/security/resource/parity gate - [ ] #179 — explicitly human real-device embedded-Prolog/live-voice release gate No Android production code should be invented from the parent prose before its owning child/dependencies are eligible.
lost-rob0t commented 2026-08-24 06:25:44 +00:00 (Migrated from github.com)

Extension epic #194 and its dependency-ordered children #195-#206 now own the Samsung system-assistant/modern app/SmartThings scope. They preserve #152's foundation and final real-device gates. The exact downloadable APK requirement is owned by #197 (exact-head Actions artifact) and #206 (non-expiring GitHub Release asset proven on Samsung hardware).

Extension epic #194 and its dependency-ordered children #195-#206 now own the Samsung system-assistant/modern app/SmartThings scope. They preserve #152's foundation and final real-device gates. The exact downloadable APK requirement is owned by #197 (exact-head Actions artifact) and #206 (non-expiring GitHub Release asset proven on Samsung hardware).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/zara#152
No description provided.