Skip to content

Lab

Contributing·

How to contribute: proof tags, evidence files, the 3-minute docs budget.

  • contributors
  • 1 min read
  • 155 words

In 10 seconds

Every protocol claim carries a proof tag and an evidence/*.jsonl line. Never add a verb that sends 39, 67 or anything on FEF5. Docs have a budget: ≤ 750 visible words per page (3 minutes), ≤ 7 500 for the whole site, a TL;DR box on every page — make budget tells you where you stand.

The docs budget·

Every page promises to be readable in three minutes. tools/docs_scan_budget.py counts the words a reader sees without clicking (code blocks, HTML and the bodies of collapsed ??? boxes are free; their summary lines count) and CI fails when a nav page exceeds 750 (= 3 min at 250 wpm), the site exceeds 7 500, or a page lacks a !!! tldr "In 10 seconds" box under its H1. Put reference material in ??? note "…" boxes; keep tables over prose; the reading-time badge under each title comes from the same count.

CONTRIBUTING.md — process, tests, proof tags

Contributing·

Toolchain·

  • Python 3.11+, a Bluetooth LE adapter, and one ring. macOS (CoreBluetooth) and Linux (BlueZ) are the tested hosts via bleak.
  • ffmpeg is optional — it turns pulled .opus memos into .wav.
python3 -m venv .venv && . .venv/bin/activate
make install            # pip install -e ".[dev,docs]"
make test lint          # pytest + ruff
make docs               # mkdocs build --strict

Where things live·

path what
ring/ the driver: transport (bleak, macOS attach-to-bonded), codec (frames), commands (LoraFit sequences), audio (Opus mux), export (→ tiny), bridge (daemon), cli
tests/ codec/export unit tests — no ring needed
docs/ the site (mkdocs-material). docs/protocol/ is the contract; docs/dev/ is lane history
tools/ capture helpers (Pixel HCI snoop, btsnoop → ATT JSONL, scanner)
evidence/, captures/ raw bytes that prove a claim in the docs

Protocol changes·

Every statement in docs/protocol/ has a source tag: [APK] (decompiled LoraFit), [CAPTURE] (HCI snoop of the vendor app) or [LIVE] (this driver against a ring, with the JSONL line in evidence/). A new command needs at least one of those and a row in the commands table. Guesses are labelled inferred until proven.

Docs design·

The docs share one design system with the landing page, and both stay green on three gates.

you want do this
a colour, radius, easing use a token from docs/stylesheets/ring.css :root (--ember*, --accent-ink, --ink-*, --paper, --line, --ease, --fast/--slow) — never a literal
a grid of link cards wrap the table: <div class="cards" markdown></div> — last link in the row becomes the card's target
numbered steps title the h2s 1. …, 2. …docs.js draws the ember marks and the rail
a decoded frame chip `FE FC 07 00 01 00 01 00 00 00`{ .frame }
the ring with hotspots <figure class="anatomy" data-anatomy="protocol" data-base="../"></figure> — labels live in docs.js ANATOMY (JS-rendered → outside the word budget)
words that must not count render them from a template (docs/overrides/main.html) or JS; the budget counts markdown source only
motion transform only, first sight only, prefers-reduced-motion honoured — no opacity fades (axe/Lighthouse fail contrast mid-fade)

Gates before every push: mkdocs build --strict (0 warnings) · make budget · axe at 1440 and 390, light and dark (~/.tiny/ring-docs-design-20260920/axe.mjs is the reference script) — 0 content violations; Material's own landmark-unique nits are the accepted residue. landing.css / home.html / docs/js/landing/ belong to the landing lane.

Pull requests·

  • One change per PR, small enough to review in ten minutes. Say what and why.
  • make test lint docs green. make docs also enforces the docs budget (≤ 750 visible words per page — every page scans in 3 minutes — and a !!! tldr "In 10 seconds" box up top); make budget shows where you stand.
  • A new ring-cli command: write its docstring in ring/cli.py, run python3 tools/gen_cli_docs.py (CI fails if docs/driver/cli.md is stale), add a line in CHANGELOG.md.
  • No tokens, no phone MACs, no audio, no owner health values in the tree — .gitignore covers captures/*.opus|wav, evidence/audio.jsonl, apk/.
  • Never send deviceOperation (reboot / factory reset) or touch the SUOTA service to a ring you do not own.
  • Less code is more code. Deleting is a contribution.