🐾 Handlr ?

Guide β€Ί Modules

The Handler

The module that asks β€” daily reflection, check-in surveys, mantras, affirmations, headspace sessions, proof on demand, and the audit that notices a missed day. Rule-based today, a local AI persona later, same module.

🐾 The Handler is the voice of the game. It sets the day's prompt, asks how your head is on a cadence, hands you a mantra, sits with you through a headspace session, and notices when you skipped the one thing it required. Everything it does is an entry in your journal and an event in the log, so the stats see it.

You name it (What you call them β€” the default is "Handler"). The name is in every line it says. You also set how strict it is; every rule below is a field on /settings.

The daily rhythm

The Handler card on the dashboard shows one line at a time β€” the most important thing it wants β€” and lights the 🐾 button with due or overdue:

  1. Not locked β†’ "The kennel is quiet. When you're ready, cage up."
  2. A challenge is open β†’ "Proof. Now. Write OTTER 47 where the camera can see it…" β€” see Challenges. It outranks everything below: it has minutes on it.
  3. Check-in overdue β†’ "You've gone quiet. Check in. Now."
  4. No reflection today β†’ "Write today's reflection before the day ends."
  5. Check-in due β†’ "Good boy. Now check in."
  6. Mantra not yet recited β†’ "Recite today's mantra and mean it."
  7. Everything logged β†’ "Stay in your headspace."

What matters now

Each of those lines has a reason code, the one machine word for what the Handler wants right now. /api/v1/handler/today returns it as reason, so a Shortcut or a bot can decide whether to nag without re-deriving the order above:

Code When
unlocked / unlocked_slacking not locked (the second when a habit is slacking)
challenge a challenge is open β€” answer it now
recovery_checkin Β· recovery_reflect Β· recovery_rest a recovery day β€” the Handler eases off
checkin_overdue check-in overdue
reflect_due no reflection today
checkin_due check-in due
recite_due mantra not yet recited
habits duties done; the Handler talks about your habits
all_done everything logged

The three recovery_* codes come from your health readings, so they stay on your box: anything that leaves it is told the reason as if no health module existed.

Reflection (required)

One per local day while locked. The prompt is chosen from the library deterministically per day, so reloading never changes the question. Two ways to answer:

  • Typed β€” at least Minimum reflection length characters (default 120). Shorter is refused, and the refusal tells you how many you wrote.
  • Spoken β€” press the microphone, talk for at least Minimum spoken reflection seconds (default 30), stop, save. The recording is stored as a voice memo; an optional note goes with it. A recording with no measurable length is refused β€” a rule you can pass by sending less is not a rule. (Ogg/Opus recordings are measured exactly; other formats use the browser's reported length, cross-checked against the file's size.)

Either way: +15 XP, Good boy. Reflection logged. The due by hour (default 22:00) only changes the nag text; the day is the unit.

The microphone needs HTTPS

Browsers refuse the recorder on an insecure origin. Use your https:// address through the reverse proxy, never the raw port. See Install.

Check-in survey

While locked, every Check-in every N hours (default 4; 0 turns it off). Five scores from 1 to 10 β€” headspace Β· obedience Β· mood Β· denial Β· energy β€” plus a prompt ("What does your Handler need to know right now?") and a free line. At twice the interval it becomes overdue and jumps to the top of the Handler's list. +5 XP.

On a short leash (Mischief) the interval is halved β€” 4 hours becomes 2, never under an hour β€” and the card says so. Going overdue earns a πŸ”• Went quiet mark, once per stretch of silence, never overnight.

The scores are the raw material for headspace-over-time charts (on the roadmap) and are exported as their own CSV columns. They are prose-adjacent: they never appear on a share card or on the API's event feed (Privacy).

Mantras and affirmations

A mantra of the day (deterministic per day, like the prompt), meant to be said out loud before you log it β€” +3 XP. The whole mantra list is one fold away. Affirmations are the Handler's lines to you, one tap each, +2 XP. Both are journal entries.

Headspace sessions

A timed sit β€” meditation now, hypno scripts later. Pick minutes (at least one), optionally a script from the library, add a note after. XP = minutes, capped at 20. The duration is logged as part of the entry.

The audit: a missed reflection costs

Once per local day, at the first tick after midnight, the Handler looks at yesterday:

  • If you were locked at 20:00 yesterday, and
  • no reflection was logged for that day (voided ones do not count),

then it emits a reflection missed event and adds Penalty for a missed daily reflection (default 30 minutes) to the active clock. If there is no active lock at audit time, the event is recorded with the penalty marked not applied.

It looks exactly one day back, once. It never stacks, and the very first run only starts the clock β€” there is no retroactive penalty for days before you installed it. A missed-reflection penalty is undoable within the undo window if it was wrong.

Catching up

A day the audit marked blank stays open for seven days, and while any is open a πŸ—’ Catch up card sits at the top of the Handler page (the home card says Blank pages Β· N to catch up). It lists the days and asks one question; one entry answers every page on it, however many β€” at least Minimum reflection length.

It is cheaper than staying silent, and never free:

  • each πŸ“„ Blank page mark (2) becomes a πŸ“ Late page (1) for the rest of its week (Mischief);
  • it earns no XP, and the penalty the audit added stays added;
  • the days stay blank β€” on the calendar, in the heatmap and in your streaks. The entry is filed on the day you wrote it, as a catch-up, and the log says which days it answered.

What it buys is the Handler letting go of those pages: it stops asking for them. A reflection cannot be backdated into a day that is already marked blank β€” the catch-up is the one way back. Undo a catch-up (within the undo window) and its pages are open again.

Challenges: proof on demand

Off until you switch it on. Then, while you are locked, your Handler asks for proof at a moment you did not choose: a word and a number β€” say OTTER 47 β€” and a few minutes to send a photo with it in frame and your cage in the shot. Write it on paper, on another screen, on your skin; anywhere the camera can read it.

  • It arrives as the Handler's top line on the dashboard and the Handler page (with the answer form right there), as reason: challenge on /api/v1/handler/today with the word and the deadline, and β€” if you use the chat bot with reminders on β€” as a message that makes your phone ring.
  • Answer with 🎯 Here it is: a verification photo, captioned with the word, +10 XP. The word rides onto the photo's stamped export as proof Β· OTTER 47, so the picture carries the question it answered.
  • Miss it and it costs what a missed reflection costs (Penalty for a missed daily reflection or challenge, default 30 minutes), stamped at the deadline, undoable within the undo window if it was wrong. With Mischief on, silence is a πŸ‘» Ghosted mark.
  • Can't right now? Say so (πŸ™‹ I can't right now). The same minutes go on β€” but it is a πŸ™‹ Owned up mark, not Ghosted. Honesty is the cheaper move, never a free one.

When none is asked: outside your asking hours, while you are not locked, while one is already open, while you are paused (the safeword) or out for hygiene, on a recovery day, and past twice your daily number. A moment that falls on any of these is skipped, not saved for later.

When a miss costs nothing: if you said the safeword, or opened a hygiene window, while the challenge stood β€” the miss is still written, saying why it was held back (no penalty β€” paused). Out for hygiene is no mark at all; a pause is a mark with no weight. Nothing passes silently.

πŸ”΄ Handlr does not read the word in your photo. It records that you answered in time and keeps the word beside the picture, for you β€” and anyone you show it to β€” to check. A model on your own box that looks for it is on the roadmap (local vision verification).

Why it works this way

These are choices, and each has a reason:

  • The word is the proof, not the camera. A page can ask the browser for the camera, but any browser may ignore it and every desktop does, so "camera only" would be a rule you could pass by picking a file β€” a ritual, not a control. A photo taken before the challenge cannot show a word minted for it. So the answer form takes a photo from anywhere (on a phone, the camera is the first thing it offers), and there is no "did it earlier" time field: an answer is stamped when it arrives.
  • A word and two digits (from a list of 64 words, digits 2–9): fast to write by hand, easy to read in a dim photo, no 0/O or 1/I to argue about, 4,096 possibilities. A photo's own timestamp is not used: photos lose it on purpose when they are re-saved.
  • Off by default. A new way to lose time on the clock should never arrive with an upgrade.
  • Truly random timing. The wait to the next challenge is drawn fresh every time, averaging your number per day across your asking hours. Any other spacing would let a challenge you just answered tell you how long you are safe. The price: some days bring fewer than your number, some more β€” never more than twice it.
  • Ten minutes to answer by default: enough to find a pen in another room, short enough that it is a test of now.
  • The missed-reflection penalty, not a new one. A challenge is the same kind of duty β€” asked, not optional β€” so it costs the same through the same setting. One number to tune.
  • No time off for answering. Proof is the price of the lock, not a bargain; time off would make you want to be asked. You get XP.
  • The same marks as training. Ghosted and Owned up already mean "left to run out" and "said you couldn't"; a challenge is weighed the way training is, so the ledger stays one idea.
  • None on a recovery day. The Handler's own line on those days is "Nothing more is being asked of you today." A surprise demand would make it a liar.
  • Ringing in the chat room, not a quiet notice. A notice does not notify, and an ask with minutes on it that reaches nobody is not an ask. It follows your !remind switch, because it is a reminder in all but name.
Setting Meaning Default
handler.challenges_per_day About how many a day while locked (0 = off, at most 12) 0
handler.challenge_minutes Minutes to answer one (2–120) 10
handler.challenge_from_hour Asked from this hour… 9
handler.challenge_until_hour …until this hour (wraps midnight: 14 β†’ 2 is fine; the same hour = all day) 21

The journal

The Handler page ends with the journal: the last forty entries of every kind, with prompt, body, scores, duration and the voice player where there is a memo. The Log page shows the same things as events with an excerpt.

The library: your Handler's voice

Settings β†’ 🐾 Handler holds the prompt library, one table, five kinds:

Kind Used for Seeded with
reflection the daily prompt 12
checkin the check-in question 4
mantra mantra of the day 8
affirmation the affirmation buttons 8
meditation headspace scripts 3

Each line has a weight (probability in the daily draw; 0 never draws) and an enabled switch. A line tagged lapse:<mark> (lapse:zoomies, lapse:blank_page, … or lapse:any) is a lapse question: it is never drawn on an ordinary day, only asked about a lapse (Mischief). A set of them is seeded once; edit them like the rest. Add your own; rewrite the seeded ones; disable what does not land. The register is yours: firm, gentle, explicit, clinical β€” the mechanics do not care.

Or wear somebody else's: a persona is a playset that is a whole Handler β€” a name, a temperament, the lines in one voice. Collared under one, its lines replace these for every kind it wrote, and its name and temperament are your Handler's; your own settings are never overwritten and are back the moment you release yourself. See Personas.

A prompt written for one day

Somebody you have allowed to write a prompt (Consent) writes it for one later day, never today β€” a reflection, a check-in or a mantra. On that day it goes first β€” ahead of the library and ahead of a running event's lines β€” but only while their permission is still live, they are still the one holding it (a pack's next Handler does not inherit the last one's prompts), and you are not paused. That is checked every time the page is drawn, so a revoke or the safeword takes it off the page at once and a resume brings it back; the prompt itself is never edited or deleted. It is not part of your library, and you cannot rewrite it β€” to take it away, revoke their permission or pause. While a hidden lock is running, a prompt somebody else wrote is not shown at all (they may be able to see the clock you chose not to), and it is back the moment the lock ends.

Settings

Key Meaning Default
handler.name What you call them (a persona you're collared under names them instead) Handler
handler.strictness How strict they are: warm, firm or strict β€” what Mischief weighs and asks, and your AI Handler's voice (a persona's own while you wear it) firm
handler.reflection_min_chars Minimum typed reflection 120
handler.reflection_due_hour Due-by hour for the nag text β€” and the chat bot's reflection reminder comes four hours before it 22
handler.checkin_hours Check-in cadence while locked (0 = off) 4
handler.missed_penalty_minutes Cost of a missed daily reflection β€” and of a missed challenge 30
handler.voice_min_seconds Minimum spoken reflection (0 = no minimum) 30
handler.challenge* The four challenge settings off

What the Handler never does

It never leaves the box, never reads anything that is not in your log, never posts, and only ever acts by writing events through the same doors you use. Your AI Handler inherits exactly those limits: a model on your own computer, acting as ai only under what you grant on Consent, capped per day, every action an event β€” and this page's rule-based line always stands beside whatever it says.

Lines from others

The card under the Handler's own line shows what somebody else said to you today: your AI Handler (πŸ€– Your AI Handler said) and, with packs, a Handler (πŸ—£ Sir (Handler) said, or πŸ€– Byte (AI Handler) said when the one who signed says it is an AI). Each is today's latest, and each stands only while its voice may speak β€” the grant to say a line still live, and nothing paused: revoke it, or say the safeword, and the line leaves this page (it stays in your log).

πŸ”’ While your lock is hidden, a line that talks about time shows as a line about time β€” hidden with your timer. It is theirs and is kept word for word; tap to reveal shows it on this page only. Your AI never gets that far: a line of its own about a hidden clock is dropped before it is kept β€” and a line it wrote knowing your hidden clock (you granted it) shows as a line written knowing your hidden clock, whatever it says, until the lock is no longer hidden.

The Handler and your habits

Since 0.11.0 the Handler reads the habits board. Once the day's duties are done β€” reflection written, check-in made, mantra said β€” its line turns to the work: praise for a habit on a run, a stern word for one you are slacking on. When you are not locked it still speaks: Not locked β€” but you're still my pup. The Handler page carries an On your habits card with every verdict, and the same sentence it says is the one written into your log as a Consistency rewarded or A word from your Handler event. See Habits β†’ Praise and a talking-to for how it judges.

This page is docs/handler.md in the repo. Spotted a mistake? Tell us how to report it β†’