Four tools with complete schemas and descriptions. Tool naming follows verb_noun pattern (rlaif_info, rlaif_log, rlaif_negative, rlaif_positive). Descriptions are detailed (194 - 392 chars, within baseline range) and explain what each tool does, when to use it, and return structure. Parameters have types and descriptions. However, descriptions lack explicit guidance on error recovery, and the two action tools (negative/positive) do not document confirmation/dry-run patterns despite being irreversible. Output schemas are documented in description text but not in formal JSON Schema. Error handling is minimal, no guidance on what to do if device is offline or rate-limited.
Report rlaif device + server state across both channels. Does not trigger any device. Returns: {negative?: {channel, device: {name, online, paused, api_max_intensity, api_max_duration_s}, config: {allow, max_intensity, max_duration_s, bucket_capacity, refill_seconds}, rate_limit: {tokens_available, next_refill_at}}, positive?: {channel, device: {name, online, actuators}, config: {...}, rate_limit: {...}}}. A channel block is omitted when that channel is not configured.
Return up to `limit` most recent rlaif operations from both channels' logs, newest first (default limit 10, max 200 entries retained per channel). Returns: {entries: [{op_id, timestamp, channel, requested: {intensity, duration_s}, actual: {intensity, duration_s}, clamped, rate_limited, high_intensity, device_response, reason?, error?}], retained: int}.
Give the user negative stimulus (shock). Parameters: - intensity: 1–100. The server clamps this to the configured cap (default 25, hard ceiling 50). - duration_s: 1–15 seconds. Clamped to the configured cap (default 2s, hard ceiling 5s). - reason: optional short string explaining why this is being fired. Returns: {op_id, timestamp, channel: "negative", requested, actual, clamped, rate_limited, high_intensity, device_response, reason?, error?}.
Give the user positive stimulus (vibration). Parameters: - intensity: 1–100. The server clamps this to the configured cap (default 75, hard ceiling 100). - duration_s: 1–60 seconds. Clamped to the configured cap (default 5s, hard ceiling 30s). - reason: optional short string explaining why this is being fired. Returns: {op_id, timestamp, channel: "positive", requested, actual, clamped, rate_limited, high_intensity, device_response, reason?, error?}.
Irreversible tools (rlaif_negative, rlaif_positive) lack confirmation/dry-run pattern. Agents can fire stimuli without explicit user approval, risking unintended harm.
Error handling is implicit. Descriptions mention clamping and rate-limiting but do not guide LLM on recovery actions (e.g., 'If rate_limited=true, wait N seconds before retry').
Output schemas documented only in description text, not in formal JSON Schema. LLMs cannot parse unstructured descriptions reliably to extract response structure.
Parameter 'reason' on rlaif_negative and rlaif_positive is optional but lacks guidance on when to include it. Should clarify: 'Include to log the agent's rationale for audit/debugging.'
Inferred effective spec: 2026-07-28+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2026-07-28+ | v2 |
rlaif_log's 'limit' parameter lacks explicit bounds validation guidance. Description says 'max 200' but does not state what happens if limit > 200 (clamped? error?).