npx agentspec-cli install 7a79a473-f2c3-4388-8578-67d9b898ed8e --file-type cursorrules→ .cursor/rules/
# Master Project Profile: Mobile Smart Braille Notetaker & Embosser
## 1. System Engineering & OS Architecture
- **Lead Architect**: Addison
- **Target Hardware**: Orange Pi 3B SBC (4GB LPDDR4, Rockchip RK3566) + Custom PCB HAT
- **Operating System**: DietPi Linux (Debian 13 Trixie, Vendor Kernel 6.1.115 for peripheral stability)
- **Firmware Runtime**: Arduino Micro (ATmega32U4, 5V Logic) acting as a real-time safety watchdog
- **Storage Protection Strategy (Prototype Stage)**:
- Core root filesystem (`/`) is mounted **Read-Only (RO)** to prevent SD/eMMC flash degradation
- Volatile directories (`/var/log`, `/var/tmp`, `/tmp`) are isolated in RAM via an **overlayfs** layer
- A background `rsync` script handles document persistence transactionally by mirroring serial blocks from a RAM write-buffer to a persistent flash folder. **A/B OTA is not implemented**; updates are `deploy/install.sh` or image refresh (V9 §6.5).
## 2. Workspace & Directory Topology
- `firmware-arduino/`: Real-time watchdog, hardware interrupt routines, MPU6050 freefall handling, local keyboard scanning.
- `daemon-dietpi/`: Core ScreenReader service, focus loops, asynchronous processing, spatial delay line filtration, telemetry trackers.
- `shared/`: Single source of truth for communication schemas, binary frame packet formats, and CRC validation rules.
- `specs/`: Product/software spec [Master Software Architecture V9](specs/Master%20Software%20Architecture%20V9.md). **Wiring SoT:** [Skeleton Prototype V5.1 Build Guide](specs/Skeleton%20Prototype%20V5.1%20Build%20Guide.md) + `firmware-arduino/src/pins.h` (power/keys/MPU/gate) and `klipper/printer.cfg` (Monster8 pins/endstops/currents). V9 solenoid, INT0, and active-high INT language is retired.
## 3. Subsystem Specifications & Hard Constraints
### 3.1 Unified I/O & The ScreenReader Paradigm
- **Interface UI Architecture**: Focus-based linear navigation state machine to process and route unified focused entries concurrently.
- **Built-in Physical Key Layout** (direct-pin, not a scanned matrix; `matrix_map.conf` is an obsolete identity leftover still loaded by the daemon): Standard 6-key Braille layout equipped with a center D-pad (Up/Down) and custom Action Keys.
- *Backspace Key*: Affixed left of the D-pad.
- *Enter Key*: Affixed right of the D-pad.
- *Shift / TTS Control Key*: Located beneath Enter. Functions as a global low-latency hardware interrupt to instantly pause/resume audio speech synthesis streams.
- *Speech Button*: Acts as a global Push-to-Talk (PTT) gate for the local Vosk Speech-to-Text (STT) audio capture engine buffer.
- *Menu*: Software overlay via backtick (`) — no dedicated physical key on skeleton V5.1.
- **Peripheral / Assistive Mappings**:
- QWERTY (USB/Bluetooth): Mirror desktop access patterns (Windows Key = Menu, Win + H = Dictation).
- Refreshable Displays (Mantis Q40): Integrated over USB/Bluetooth sockets leveraging direct BRLTTY or serial socket abstractions.
### 3.2 Production Keyboard Driver (Direct Pin Topology)
- **Electrical Layout**: Direct-pin wiring — one dedicated Arduino Micro GPIO per Cherry MX switch (**12 physical keys**). Common ground bus; INPUT_PULLUP active LOW. **Menu** is software-only (backtick overlay), not a 13th switch. Firmware may reserve A5 in the protocol map but leave it unwired on skeleton V5.1.
- **Processing Architecture Split**:
- *Arduino Micro*: Non-blocking 1 kHz main-loop scan (no delay()). Per-key 15 ms integrator debounce. 40 ms temporal chord assembly window for Braille dots; function keys transmit immediately as edge-triggered frames over USB CDC @ 115200 bps.
- *Orange Pi 3B*: Receives CHORD or KEYBOARD_MATRIX frames via `shared/protocol.h`. Host-side liblouis back-translates dot masks to ASCII (Grade 2 / Nemeth table selectable in ui.conf).
### 3.3 Y-Axis Paper Transport (Tractor Feed Kinematics)
- **Material Constraints**: Continuous-form 100 lb cardstock paper. Perforations are spaced exactly 0.5 inches (12.7 mm) apart center-to-center.
- **Motor Profile**: NEMA 17 Bipolar Stepper Motor ($1.8^{\circ}$ step angle, 200 full steps/revolution). Minimum holding torque $\ge 0.45\text{ N}\cdot\text{m}$ (45 N·cm). Operated between 1.2A and 1.5A RMS via TMC2209 driver UART configuration registers protected by 1N4148 steering diodes.
- **Mechanical Reduction Assembly**:
- Tractor Sprocket Wheel: 10-pin drive sprocket with an exact Pitch Circumference ($C$) of $10 \times 12.7\text{ mm} = 127\text{ mm}$.
- Driving Pulley: 20-tooth aluminum pulley ($Z_1$) mounted to the NEMA 17 motor shaft.
- Driven Pulley: 127-tooth custom pulley ($Z_2$) mounted to the 8 mm ground steel linear tractor shaft supported by twin KFL08 zinc flange bearings.
- Reduction Ratio ($R$): Exactly $\frac{Z_2}{Z_1} = \frac{127}{20} = 6.35$.
- **Mathematical Resolution Proof**:
$$\text{Linear Travel Per Motor Revolution} = \frac{C}{R} = \frac{127\text{ mm}}{6.35} = 20\text{ mm}$$
$$\text{Resolution Per Full Step} = \frac{20\text{ mm}}{200\text{ steps}} = 0.1\text{ mm/step}$$
- **Execution Rule**: To process an exact 10-mm paper line advance, the motion driver must execute exactly 100 full steps (or 1,600 microsteps when locked at 16x microstepping mode).
### 3.4 Embossing Head Carriage & Mechanical Linkage Mechanics
- **Actuators:** Six **NEMA14 steppers** on Monster8 slots 2–7 (`printer.cfg` `emboss_1…6`). **Do not order solenoids.** Slot pins and `run_current` live only in `printer.cfg`.
- **Actuator Spacing Topology**: Staggered dual-row layout to meet standard 2.5-mm Braille dot profiles.
- *Row A*: Handles Pins 1, 3, 5.
- *Row B*: Handles Pins 2, 4, 6.
- *Physical Offsets*: Staggered by exactly **2.5 mm along the X-axis only** (Row B deferred in `emboss_scheduler` / V9 §5.4). There is **no extra Y-axis row offset** — paper line pitch is 10 mm. The 20 mm figure in §3.3 is Y travel per motor revolution, not Row B spacing.
- **Spatial Delay Filter Strategy**: The carriage control daemon on the Pi must store outbound dot matrices inside a thread-safe circular delay line. Firing pulses for Row B actuators must be mathematically deferred until the carriage movement log registers exactly 2.5 mm of horizontal travel past Row A's execution strike coordinate.
- **Linkage Physics**: Slider-Crank / Eccentric Toggle Joint assembly.
- Generates a linear pin throw of 1.8 mm to 2.0 mm to produce a clean 0.5-mm deep indentation.
- Mechanical force amplification follows the function:
$$F_{\text{pin}} = \frac{\tau_{\text{motor}}}{r \cdot \cos(\theta)}$$
- As the linkage passes through its $90^{\circ}$ sweep toward Top Dead Center (TDC), the force advantage approaches infinity, lowering current draw and thermal dissipation at the peak of the impact stroke.
- Retraction is assisted by high-carbon music-wire compression springs ($k = 1.6\text{ N/mm}$, preloaded to 2.0 N) mounted around the pin body to ensure rapid, snappy retraction.
- Thermal mitigation on **production** hardware: unified extruded aluminum cooling bar (120 mm x 15 mm) tracking the actuator array, backed by a **required** non-resettable, metal-cased 85°C thermal cutoff safety fuse. Skeleton V5.1 is a prototype **without** that fuse (individual heatsinks).
### 3.5 System Safety Interlocks & Telemetry
- **Hardware Freefall Protection**:
- On system boot, the Arduino Micro configures the hardware freefall threshold (`FF_THR`) and duration (`FF_DUR`) registers on an autonomous MPU6050 accelerometer.
- The MPU6050 physical INT pin is tied to Arduino **D7** (INT6 / PE6) — **not D3 / INT0** (D3 is I2C SCL). Firmware configures INT **active-low latched** (`INT_PIN_CFG = 0xA0`) and attaches **FALLING**. V9 active-high language and breakout jumpers that leave INT active-high will miss freefall.
- Because the MPU interrupt holds priority over the 1 kHz keyboard scan loop, any $0g$ state instant-trips an isolated ISR. The Arduino bypasses all standard software state validation loops and pulls **D12** LOW in **< 10 ms**.
- D12 interfaces with a high-current **TC4420 gate driver** switching an **IRLZ44N N-Channel Power MOSFET** (low-side on Monster8 VIN-), instantly cutting the 14.8 V stepper rail. The Pi should also send **Klipper M112** on freefall SAFETY frames.
- **Battery & Thermal Management**:
- An LTC2944 gas gauge monitors a 4S Lithium battery pack (regulated via a 5V/5A TPS5430 synchronous buck module, distributed via dual-row 15A terminal blocks) over I2C.
- If capacity cross-evaluates below **5%**, the telemetry daemon blocks further motion, instantly flushes active RAM text caches to permanent `.brf` file layouts, triggers a specific structural shutdown haptic notification via a **DRV2605L driver** pulsing a **10 mm LRA motor**, and executes a graceful Linux command shutdown.
- **Boundary tracking**: **TCRT5000** paper edge on Monster8 **X-STOP `^PA14`** (`printer.cfg` — never G28 X; do not use E0-STOP) and Y-axis homing via **TCST2103** on **Y-STOP `^PA15`**. Klipper cartesian `[stepper_z]` is a **dummy** on unused EXP1 pins — not a third motor; do not attach one (`printer.cfg`).
## 4. Architectural Rules & Guardrails
1. **Protocol Isolation**: Any structural updates to serial communication variables, binary packet framing, or command enums must be edited inside the `shared/` directory *before* modifying code inside the firmware or daemon runtimes.
2. **Deterministic ISR Hygiene**: Keep all code inside `firmware-arduino/` lean. Never use the standard C++ `String` object or any mechanism that relies on dynamic allocation to ensure memory safety on the ATmega32U4.
3. **Transactional RO Write Hygiene**: Code writing down to storage must follow transactional atomic write patterns (`write -> flush -> sync`) to handle accidental power losses gracefully without impacting the integrity of the read-only filesystem.
4. **Environment Isolation**: No hardware specific paths, local configurations, or serial interface assignments should be hard-coded inside execution daemons. Keep all execution settings separated inside system parameters in `daemon-dietpi/config/`.
## 5. Pi Testing & Agent Handoff
**A code change is not complete until it is verified.** After editing runtime-affecting code, always run the appropriate clean-build, deploy, and test steps below — and fix failures before handing off. Do not stop at reporting a broken build or failed test.
### 5.1 Device Access
- Credentials: read `mobile-braille-embosser/.cursor/pi.local.env` (gitignored — never commit)
- Expected keys: `PI_HOST`, `PI_SSH_USER`, `PI_SSH_PASS`, `REMOTE_DISPLAY_URL`, `REMOTE_DISPLAY_PAIRING`
- If the file is missing, ask the user — do not guess or embed defaults in repo files
- **Browser input**: click the display to refocus if keys stop working; F/D/S/J/K/L = braille dots, arrows = D-pad, **backtick (`)** = app menu
### 5.2 Change Verification Workflow
- **Completion bar**: clean build → deploy (when runtime is affected) → test → fix loop until passing
- **When to verify on the Pi**: daemon, firmware, shared protocol, deploy configs, systemd units, or anything that changes on-device behavior — always deploy and test on the Pi
- **When local-only is OK**: docs, comments, host-side tooling not used on the Pi, or changes with no runtime effect — still run relevant local checks (lint, compile, script dry-run) when applicable
- **Clean build**: always `make clean` (or equivalent) before rebuilding after source changes — stale artifacts cause false passes
- **Deploy & test**: use **SSH** for build/deploy/service restarts; use **Browser MCP** for UI verification
- Test **one app at a time** comprehensively; when tests fail, redeploy, and retest — do not only report
- **Do not commit** unless the user explicitly asks
- Build on the Pi (**aarch64** only — never copy x86 binaries):
```bash
cd ~/mobile-braille-embosser/daemon-dietpi
make clean braillatron-ui braillatron-connectd \
BRAILLATRON_LIBLOUIS=1 BRAILLATRON_A11Y=1 BRAILLATRON_DISPLAY=1
sudo cp braillatron-ui braillatron-connectd /usr/local/bin/
sudo systemctl restart braillatron-ui braillatron-connectd braillatron-displayd
```
- Without `BRAILLATRON_LIBLOUIS=1`, braille input shows `?` / `?????`
- **Motors may be unwired** on the test unit — verify TTS, display, and emboss *logic*; do not fail solely on missing hardware
### 5.3 UI Patterns
- **LayeredBrowseList** (`daemon-dietpi/src/ui/layered_browse_list.{h,cpp}`): default for all browse UI — full launcher-style visual list, Up/Down focus, Enter select, Backspace back; apps expose via `AppSession::browse_list()` / `browse_list_active()`
- **WordBufferInput** (`daemon-dietpi/src/ui/apps/word_buffer_input.{h,cpp}`): buffer braille chords until **space**; G1 uncontracted preview while typing, G2 commit on space; **Enter** flushes buffer before app handlers; apps use `buffers_braille_words()` (exceptions: Document has its own buffer; Calculator and Morse Learning stay immediate)
- **Settings**: device toggles in `/etc/braillatron/ui.conf`; per-app config in `/etc/braillatron/*.conf` via connectd — expose under **Settings → App Settings** (`OutputHub::build_settings_menu()`)
- **Network** and **Bluetooth** live under Settings, not the launcher (`show_in_launcher() = false` on those apps)
- **Launcher**: alphabetized list; type a letter to jump to the first app whose name starts with that letter (first char of G2 translation)
- **App menu (backtick)**: **Print** at top when an app is open → `on_menu_action("print", ctx)` in `app_registry.cpp` (extensible per app; Wikipedia embosses full article)
### 5.4 Reliability
- **Never** call sync `connect->request()` from the UI thread — use `request_async()` + `mark_busy()` / `clear_busy()` so the poll loop stays responsive
- **Frozen-app watchdog**: `AppRegistry::tick_watchdog()` — 45s (`kFrozenTimeoutMs`) while busy → prompt to exit to launcher; menu must remain reachable via backtick during frozen/busy states
- **Audio playback** (Radio, YouTube, Music): mpv socket **connect test** (not just file exists), retry load; use `/usr/local/bin/yt-dlp` (apt yt-dlp is too old for YouTube); ALSA **dmix** (`deploy/os/audio/asound.aux.conf`) so TTS and mpv share output
- **Weather geocoding**: Open-Meteo expects **city + countryCode** (and region hints), not comma-joined `"City, State, Country"` strings; disambiguate US cities when state is given (`weather_backend.cpp`)
### 5.5 Apps Status & Next Targets
**Tested / patterns applied:** Contacts (address book + Search row), Document input (word buffer), Weather (multi-city wizard, °F/°C auto), Library (public sources + Worthwhile Secret), Dictionary (Kaikki SQLite on Pi), Wikipedia (visual lists + Print), YouTube (Recommended / Search / Shorts), Radio (async play + mpv fixes)
**App-specific notes:**
- Contacts `butobut` — junk from manual testing; safe to delete
- Dictionary — build ~49 MB SQLite locally (`install-dictionary-data.sh`); use `immutable=1` SQLite URI on Pi
- Worthwhile Secret — obfuscated library source; credentials in `/data/braillatron/credentials/worthwhile.ini`; never use the real site name in UI/strings
- YouTube Recommended needs cookies for personalization (else popular fallback); Search/Shorts work without cookies
- Internet Archive API identification: `grahamthetvi@icloud.com`
**Untested — good next targets (one at a time):** Calculator, Transcriber, Morse Learning, Messages, Gmail, Music, Podcasts, Spelling, LocalSend (placeholder), Document (dictation, worksheet detection, paper advance), Network and Bluetooth (now under Settings)Project Overview
[cite_start]Role: Senior XR UX / Unity Take-Home Assessment [cite: 1] for Axon. [cite_start]Hardware: Oculus Quest 1 (Targeting Android/APK [cite: 34]). [cite_start]Framework: Unity3D[cite: 50], XR Interaction Toolkit (XRI), OpenXR.
by AgentHub Crawler
=== USER INSTRUCTIONS ===
The license management system implements a hardware-locked commercial licensing solution with tiered access control and multi-stage validation.
by AgentHub Crawler
uNPU — Project 2, Frankenstein 180 nm IP-Validation SoC
Course project EE5239. A 4×4 INT8 weight-stationary systolic matrix-multiply accelerator, taken from RTL to a DRC/LVS-clean hard macro on SCL 180 nm.
by AgentHub Crawler
Sign in to leave a comment.
Holy Auramaxing — Project Spec (Master Prompt)
> App: Holy Auramaxing (one spelling in everything people see, D-059; the repo, folders and Supabase project id keep the old "holy-auramaxxxing"). Domain: not chosen yet (set `NEXT_PUBLIC_SITE_URL`). Supabase region: Mumbai (`ap-south-1`). AI coding tools re-read this file every session. Run the phase prompts in `PROMPTS.md` one at a time.
by AgentHub Crawler