No description
  • Rust 50.6%
  • Python 41.2%
  • Shell 6.6%
  • Just 1.6%
Find a file
Albert Armea 76fe892b40
All checks were successful
ci / android-portability (push) Successful in 1m50s
ci / rust-quality (push) Successful in 1m55s
docs: record the Forgejo-runner CI constraints + fixes
Capture how CI was diagnosed (forge API) and the runner facts
(forgejo-runner v6.4.0, node:20-bookworm image, data.forgejo.org action
mirror, node20-only runtime), the layered fixes (#3-#5), and the caching
tradeoff. v0.1.0 stays on the CI-green commit 4cf4e46; this doc is a
follow-up and does not move the tag.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CjtnpijqjewUGyLTeHyuLx
2026-06-22 02:57:24 +00:00
.forgejo/workflows CI: drop JS actions; manual checkout (runner only supports node20) 2026-06-22 02:51:18 +00:00
crates Release polish for external consumption (v0.1.0) 2026-06-21 12:32:06 +00:00
docs docs: record the Forgejo-runner CI constraints + fixes 2026-06-22 02:57:24 +00:00
keys Phase 0: bootstrap standalone shepherd-swipe repo 2026-06-21 03:57:56 +00:00
scripts Add scripts/publish-release.sh: one-command non-interactive release 2026-06-22 02:10:51 +00:00
training Release polish for external consumption (v0.1.0) 2026-06-21 12:32:06 +00:00
.gitignore Add release tooling: package-release.sh + docs/RELEASING.md 2026-06-22 01:56:11 +00:00
AGENTS.md Phase 0: bootstrap standalone shepherd-swipe repo 2026-06-21 03:57:56 +00:00
Cargo.lock Phase 0: bootstrap standalone shepherd-swipe repo 2026-06-21 03:57:56 +00:00
Cargo.toml Phase 0: bootstrap standalone shepherd-swipe repo 2026-06-21 03:57:56 +00:00
CHANGELOG.md Release polish for external consumption (v0.1.0) 2026-06-21 12:32:06 +00:00
CLAUDE.md Phase 0: bootstrap standalone shepherd-swipe repo 2026-06-21 03:57:56 +00:00
clippy.toml Phase 0: bootstrap standalone shepherd-swipe repo 2026-06-21 03:57:56 +00:00
CONTRIBUTING.md Phase 0: bootstrap standalone shepherd-swipe repo 2026-06-21 03:57:56 +00:00
DATA_SOURCES.md Phase 8: enlarge English corpus to shrink OOV 2026-06-21 11:33:39 +00:00
deny.toml Phase 0: bootstrap standalone shepherd-swipe repo 2026-06-21 03:57:56 +00:00
EVAL.md Phase 10: int8 quantization tried and rejected (tract limitation) 2026-06-21 12:09:55 +00:00
justfile Phase 0: bootstrap standalone shepherd-swipe repo 2026-06-21 03:57:56 +00:00
LICENSE Phase 0: bootstrap standalone shepherd-swipe repo 2026-06-21 03:57:56 +00:00
README.md Release polish for external consumption (v0.1.0) 2026-06-21 12:32:06 +00:00
rustfmt.toml Phase 0: bootstrap standalone shepherd-swipe repo 2026-06-21 03:57:56 +00:00

shepherd-swipe

A standalone, host-agnostic swipe-typing decoder: a pure-Rust inference library plus the training pipeline that produces signed, versioned model bundles. Given a finger gesture over a keyboard, it returns a ranked list of candidate words.

This repository is the decoder core and its training pipeline only. It has no dependency on any compositor, OS input stack, or shepherd-launcher. Whatever eventually hosts the IME (a Wayland input-method-v2 backend, an Android keyboard, something else) consumes this repo through a small, versioned, one-way contract (docs/integration.md).

Ethos (non-negotiable)

  • Offline only. No network at inference time. Ever.
  • No telemetry. The decoder reports nothing, anywhere.
  • No cloud training. Models are trained on hardware you control.
  • Auditable provenance. Every data source's license and origin is recorded in DATA_SOURCES.md.
  • Closed-vocabulary safety. A word absent from a profile's lexicon is unemittable — a structural guarantee, not a post-filter. This underpins the child profile's safety invariants (§4 of the spec, docs/spec.md).

Layout

crates/shepherd-swipe-core/   pure-Rust inference library — the portable contract
crates/shepherd-swipe-cli/    standalone decode/evaluate binary (no compositor)
training/                     Python (PyTorch) pipeline: data → models → signed bundles
docs/                         spec, integration contract, gesture interchange format
bundles/                      build output — gitignored, NEVER committed
scripts/setup-box.sh          provision a blank box (driver, Rust, Python, NDK)
DATA_SOURCES.md               provenance + licenses + verified dataset schema

The portability bar (compiles for an Android target, no OS deps) applies only to shepherd-swipe-core. The CLI and training pipeline are not constrained.

Profiles

adult and child bundles share the encoder (gesture geometry is profile- agnostic) and differ only in their lexicon and context language model. The child profile is built from a profanity-free-at-source corpus and enforces three tested safety invariants (INV-1/2/3 — see docs/spec.md §4).

Quick start

# 1. Provision the box (driver, Rust+Android target, uv Python 3.12, NDK, just).
./scripts/setup-box.sh

# 2. Build and test the Rust workspace.
cargo build --workspace
cargo test  --workspace

# 3. Reproduce a bundle end-to-end (downloads data, trains, signs).
just bundle adult
just bundle child

# 4. Decode a recorded gesture with the CLI.
cargo run -p shepherd-swipe-cli -- decode \
  --bundle bundles/adult --gesture crates/shepherd-swipe-core/tests/fixtures/hello.gesture.json

# ...or as a library (minimal consumer example):
cargo run -p shepherd-swipe-core --example decode -- \
  bundles/adult crates/shepherd-swipe-core/tests/fixtures/hello.gesture.json

Consuming this repo

See docs/integration.md. In short: pin a git tag of the crate and download a pinned, signed bundle from the forge releases; the decoder verifies the signature and per-file hashes before use.

License

Source code: MIT. Model bundles may carry separate terms — see DATA_SOURCES.md and each bundle's metadata.toml.