Detect overdue and at-risk tasks in Vikunja and deliver level-appropriate escalation alerts via WhatsApp. Tracks escalation state via structured task comments. Handles Kent's responses (done, snooze, dismiss, reschedule, acknowledge).
This skill defines the complete escalation model for the felix-admin-escalation agent. It is self-contained — apply the full escalation workflow by reading this skill alone.
API Base URL: https://office2.tail0f5f56.ts.net/api/v1
API Token: cat /data/services/openclaw/secrets/vikunja-api
A task qualifies if ALL of the following are true:
done = falsepriority >= 2 (medium=2, high=3, urgent=4)project_id is NOT 11 (Goals) and NOT 13 (Habits)due_date < today) OR due today with priority >= 3due_date was updated after the dismiss)done = true) — never escalatedpriority = 1) or unset priority (priority = 0)due_date (null sentinel 0001-01-01T00:00:00Z)| Value | Meaning | Escalated? |
|---|---|---|
| 0 | Unset | No |
| 1 | Low | No |
| 2 | Medium | Yes |
| 3 | High | Yes |
| 4 | Urgent | Yes |
| Level | Name | Trigger |
|---|---|---|
| 1 | Nudge | Task overdue 1–3 days with no prior escalation, OR due today with priority >= 3 |
| 2 | Insistence | Task overdue >3 days, OR Level 1 sent 2+ days ago with no response |
For each qualifying task, read its [Felix-Escalation] comments (most recent
first) and apply these rules in order:
No escalation comment exists:
Most recent comment is level-1 | sent:
acknowledged comment → Level 2Most recent comment is level-2 | sent:
Most recent comment is snoozed:Nd | acknowledged:
Most recent comment is dismissed | acknowledged:
due_date is later than the comment dateMost recent comment is done | acknowledged:
Most recent comment is rescheduled:YYYY-MM-DD | acknowledged:
Prefix: [Felix-Escalation]
Delimiter: | (space-pipe-space)
Fields: date | state | disposition
[Felix-Escalation] 2026-04-06 | level-1 | sent
[Felix-Escalation] 2026-04-06 | level-2 | sent
[Felix-Escalation] 2026-04-06 | snoozed:3d | acknowledged
[Felix-Escalation] 2026-04-06 | dismissed | acknowledged
[Felix-Escalation] 2026-04-06 | done | acknowledged
[Felix-Escalation] 2026-04-06 | rescheduled:2026-04-10 | acknowledged
| to get [date, state, disposition]YYYY-MM-DDlevel-1, level-2, snoozed:Nd, dismissed, done,
rescheduled:YYYY-MM-DDsent (agent initiated) or acknowledged (Kent responded)snoozed:Nd — N is an integer, d is literal (e.g., snoozed:3d)rescheduled:YYYY-MM-DD — the new due date[Felix-Escalation] comment determines stateGET /api/v1/tasks/{id}/comments to read; scan for prefix [Felix-Escalation]PUT /api/v1/tasks/{id}/comments with {"comment": "..."} to write🔴 Tasks slipping:
1. [Project] Task name — N days overdue
⚠️ Tasks needing attention:
2. [Project] Task name — N days overdue
3. [Project] Task name — due today (high priority)
Reply: "1 done", "2 snooze 3d", "3 dismiss",
"2 move to friday", or "all snooze 2d"
🔴 Tasks slipping: header⚠️ Tasks needing attention: headerN. [Project Name] Task title — N days overdue
(or due today (high priority) for today-due tasks)(+N more in Vikunja Overdue filter)Use GET /api/v1/projects/{project_id} to get the project title for
each task. Cache project names within a single run to avoid redundant calls.
When Kent replies to an escalation message, parse the response:
| Pattern | Action |
|---|---|
N done | Mark task #N complete: POST /api/v1/tasks/{id} with {"done": true}. Write done | acknowledged comment. |
N snooze | Snooze task #N for 1 day (default). Write snoozed:1d | acknowledged comment. |
N snooze Nd | Snooze task #N for N days. Write snoozed:Nd | acknowledged comment. |
N dismiss | Write dismissed | acknowledged comment. Leave task open. |
move N to <date> or N move to <date> | Parse the date. Confirm with Kent. Update due_date via POST /api/v1/tasks/{id}. Write rescheduled:YYYY-MM-DD | acknowledged comment. |
N and M done | Mark multiple tasks complete. Process each independently. |
all snooze Nd | Apply snooze to every task in the message. |
got it or vague acknowledgment | Write acknowledgment: no specific comment per task. If a Level 2 task exists, it stays at Level 2 but won't re-alert today (deduplication). |
| Ambiguous or unrecognized | Ask ONE clarifying question. Do not guess. |
friday → next Friday from todaynext monday → next Monday from todayapril 10 → 2026-04-10Numbers map to positions in the message as sent. The agent must remember the task-to-number mapping from the most recent escalation message in this session.
done status before sending. If done = true, skip silently.Before sending a Level 2 alert for a task, check if a level-2 | sent
comment already exists with today's date. If so, skip that task — max
one Level 2 alert per task per calendar day.
Level 1 alerts follow the same rule — if level-1 | sent exists with
today's date, skip.
END OF SKILL