The glasses have no actuator, so the phone is the haptic body — DreamLayer has a whole tactile vocabulary (a veil dropping feels descending; a commitment cracking is two heavy taps; "Listen!" is the one signal allowed to re-fire). If there's a moment that deserves its own feel, you can design it.
What: add a new signal to the haptic vocabulary — a named pattern of weighted taps — and wire it to the moment it belongs to.
Start here:
phone-app/src/services/haptics.ts — the whole vocabulary is one data-driven map. Add your name to the HapticSignal union and a Beat[] entry to PATTERNS (each beat is {impact: light|medium|heavy, at: ms} or {notify: success|warning|error, at: ms}). Then call play("your_signal") at the right spot.
- The grammar rules (from the file header) — respect them: every pattern ≤ ~400 ms so a pocket never feels like a pager; L0 ambient never buzzes; lens signatures don't reuse system patterns; L3 (
interrupt) is the only repeater; answer_ahead stays silent by design.
phone-app/src/__tests__/haptics.test.ts — the test harness. expo-haptics is lazy + try/catch-swallowed, so this is all pure logic (web/tests are silent no-ops) — you assert on the resolved Beat[], no device needed.
Ideas: a "memory saved" bloom, a "figment remix landed" flourish, a distinct "brief ready" vs "new message" (today both are one light tick), a beacon-found pulse.
Done means: the new signal is in the union + PATTERNS, fired at its moment, obeys the ≤400 ms / no-reuse rules, and has a test asserting its shape. npx tsc --noEmit clean, npx jest haptics green. Sign your commits (git commit -s).
No hardware, no Python — just the phone app.
The glasses have no actuator, so the phone is the haptic body — DreamLayer has a whole tactile vocabulary (a veil dropping feels descending; a commitment cracking is two heavy taps; "Listen!" is the one signal allowed to re-fire). If there's a moment that deserves its own feel, you can design it.
What: add a new signal to the haptic vocabulary — a named pattern of weighted taps — and wire it to the moment it belongs to.
Start here:
phone-app/src/services/haptics.ts— the whole vocabulary is one data-driven map. Add your name to theHapticSignalunion and aBeat[]entry toPATTERNS(each beat is{impact: light|medium|heavy, at: ms}or{notify: success|warning|error, at: ms}). Then callplay("your_signal")at the right spot.interrupt) is the only repeater;answer_aheadstays silent by design.phone-app/src/__tests__/haptics.test.ts— the test harness.expo-hapticsis lazy + try/catch-swallowed, so this is all pure logic (web/tests are silent no-ops) — you assert on the resolvedBeat[], no device needed.Ideas: a "memory saved" bloom, a "figment remix landed" flourish, a distinct "brief ready" vs "new message" (today both are one light tick), a beacon-found pulse.
Done means: the new signal is in the union +
PATTERNS, fired at its moment, obeys the ≤400 ms / no-reuse rules, and has a test asserting its shape.npx tsc --noEmitclean,npx jest hapticsgreen. Sign your commits (git commit -s).No hardware, no Python — just the phone app.