Spec 005 — Attention gating
Status: Draft Related: PRD FR-13..FR-15, Wiki: attention-gating
Goal
In group chats especially, the bot should speak only when wanted. Adopt Cortex R4's five-level ladder.
Modes
| Mode | Behavior |
|---|---|
always |
Respond to every message. Default for 1:1 DMs. |
mentions-only |
Respond only if @picortex appears or message is a direct reply to a bot message. Default for groups. |
discriminate |
Run LLM classifier on message; respond iff should_respond == true. |
discriminate-quiet |
Same as discriminate but if should_respond == false, also skip reactions/typing indicators. |
silent |
Record only; never respond. Useful for eavesdropping / training data. |
Rule-first pipeline
Before the LLM discriminator runs, hard rules evaluate in order:
- Slash command (
/picortex <x>) → always respond (mode-independent). - Direct reply to a bot message → always respond.
@picortexmention → respond.- Admin override message from Jacob's DM → respond (even in
silentmode). - Non-text payload (image, voice memo) → depends on mode;
alwaysresponds, others skip.
If no rule fires and mode is discriminate, run the LLM classifier. If mode is mentions-only and no rule fired, skip.
LLM discriminator
- Prompt lives at
$CHAT_HOME/.picortex/prompts/discriminator.md, git-tracked inside the chat's home. - Default template seeded on provisioning (from
/usr/local/share/picortex/discriminator.default.md). - Prompt receives: last N=6 messages (user+bot), the new message, chat metadata.
- Response must be JSON:
{"should_respond": bool, "reason": "..."}. - Model: default
claude-3-5-haikuvia Anthropic API (cheap + fast). - Failure: if the model returns invalid JSON or times out (> 5 s), fail-open (respond) for 1:1, fail-closed (skip) for groups.
Cost budget: < $0.001 per classification.
Configuration UI
In chat settings panel (Spec 007):
- Current mode (radio)
- "Edit discriminator prompt" → opens file-browser on
.picortex/prompts/discriminator.md - "Test discriminator" → run on recent N messages and show decisions
- "Version history" →
git logon the chat's home repo
Admin commands
Parsed from message body:
/picortex attention always|mentions-only|discriminate|discriminate-quiet|silent/picortex attention show— print current mode + prompt path- Only accepted from the chat owner (Jacob's phone number).
Schema
CREATE TABLE chat_config (
chat_id TEXT PRIMARY KEY,
attention_mode TEXT NOT NULL DEFAULT 'mentions-only',
discriminator_model TEXT DEFAULT 'claude-3-5-haiku',
discriminator_threshold REAL DEFAULT 0.5,
updated_at INTEGER NOT NULL
);
Testing
- Unit: rule pipeline (mention detection, slash command parsing).
- Integration: discriminator prompt harness with golden tests.
- E2E: linq-sim group; toggle modes; assert responses vs non-responses.
Open questions
- OQ1: How to expose "why did you respond / not respond" to Jacob? (Debug panel showing discriminator reason.)
- OQ2: Per-user attention overrides inside a group? (v0.2.)