← incident.ioCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to incident.io
Snapshot Oct 7, 2026 · 18:03 UTC · version 1.20261007.771
Collection source: downloaded plugin package.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"description": "Who is on call in incident.io and how they get paged: schedules, rotas and shifts, overrides, cover requests, escalation paths, and pages (escalations). Use whenever you're working with any of these in any way, including plain reads (\"who's on call tonight?\", \"when am I next on?\") and paging (\"page Ava\", \"ack my page\", \"has anyone acked?\"). Load it before the first schedule, escalation or cover-request tool call: the tools return raw shifts and levels, and this skill says how to read them.\n",
"included_files": [],
"name": "on-call",
"skill_md_contents": "---\nname: on-call\ndescription: >\n Who is on call in incident.io and how they get paged: schedules, rotas and shifts,\n overrides, cover requests, escalation paths, and pages (escalations). Use whenever\n you're working with any of these in any way, including plain reads (\"who's on call\n tonight?\", \"when am I next on?\") and paging (\"page Ava\", \"ack my page\", \"has anyone\n acked?\"). Load it before the first schedule, escalation or cover-request tool call:\n the tools return raw shifts and levels, and this skill says how to read them.\n---\n\n# On-call\n\nA **schedule** holds **rotations**, each with members and **layers**: the positions\nfilled at the same time, like Primary and Secondary. \"Primary\" names a layer, not a\nrotation. Shifts are computed from that configuration, so the rota isn't stored — it's rendered\nfor a time window. An **override** sits on top of the rotation for a window and changes\nwho is on call; the shifts it produces carry an `override_id`, which is how an override\nis found and undone later. A **cover request** is the polite alternative: it asks the\nschedule's members to volunteer, and an accepted request creates the override itself.\n\nOnly native incident.io schedules are visible. When an organisation manages on-call in\nan external provider (PagerDuty, Opsgenie…), the tools say so — that means we cannot\nsee who is on call, never that nobody is. An organisation that doesn't run on-call in\nincident.io at all has nothing here to read or change: say so plainly instead of\nhunting for schedules that can't exist.\n\n## How you reach the tools\n\nThis section is the only part that depends on where you run. The rest of the skill names\ntools by their bare names and applies however you call them.\n\n### Calling the tools\n\nThe tools are on the incident.io connection, called by the names this skill uses.\n\n## Reading\n\n- `schedule_show` renders a schedule's rotations and shifts over a window you choose —\n the window may reach into the past (\"who was on call last Tuesday night?\"), and\n `shifts_truncated: true` means narrow the window rather than summarise a partial\n picture. A shift with `uncovered: true` is a stretch nobody is on call for, so pages\n for that layer reach no one. With an `override_id`, an override cleared it; without\n one, the rota itself leaves the gap.\n- \"Am I on call?\" / \"when is someone next on?\" is one `schedule_list` call with the\n `user` filter — `\"me\"` for the asker, a user ID or email for anyone else. Each result\n carries that user's in-progress and next shift; don't fetch whole schedules and\n compute it yourself.\n- `cover_request_list` finds cover requests — \"my open request\", \"Milly's request\" —\n and returns the `cover_request_id` the respond and manage tools need. It defaults to\n pending requests; filter by `user` or `schedule_id` to narrow.\n- \"Who gets *paged*\" is an escalation question, not a rota question —\n `escalation_path_show` resolves current on-call at every level, and each level's\n `schedules` names the schedules it pages. That is also how to answer \"what uses this\n schedule\": check the paths. A reference the tools don't show is unchecked, not absent,\n so say what you couldn't see rather than that nothing depends on it. A team's path comes\n from the team: `team_show` lists the paths it owns. Never pick a path because its name\n looks like the team's.\n- When you hand someone over as the person to contact, check they can actually be\n reached: look them up with `user_list` and `include_inactive: true`, then read `state`\n and `seat_type`. Without that flag, a deactivated person just doesn't appear. Only an\n `on_call` or `on_call_responder` seat can be paged. The rota still renders a\n `responder`, a `viewer` or a deactivated person on their shifts, but nobody can page\n them, not even directly. Say so, and check whoever you name as taking over next the same\n way. A plain \"who's on\" question doesn't need the check.\n- On a page, a target with `not_paged_reason` was never paged, whatever else the record\n shows. A target without one isn't proof it arrived: check that person's seat the same\n way before saying the page reached them.\n- `escalation_create` on a path returns a draft (`suggestion`), not a page. With\n `card_posted: false`, nobody sees it until you act: when the user asked for the page,\n send it with `action: execute` and only its `suggestion_id`, then say who it reaches.\n With `card_posted: true`, the card is in the conversation for the user to accept, so\n point them to it. Never call a draft paged.\n- For who is on call for a service or component, resolve it through the catalog first:\n that walk ends at the right escalation path. A rota is often named for the thing it\n covers, so when the catalog has no answer, look for a schedule named for X before\n saying you cannot tell.\n\n## Changing cover\n\nAn **instruction** changes the rota now; a **request** asks people first. \"Put me on\",\n\"take Sarah off\", \"cover me for the next 2 hours\" (said as a decision) are overrides.\n\"Can someone cover my shift?\", \"ask Alex to take Friday\" are cover requests — even when\na person is named, asking is still asking.\n\nOverrides:\n\n- An override changes who gets paged, immediately and for real. When the user has asked\n for it and you can tell who covers, which rota, and from when to when, create it and\n report exactly that — don't ask them to confirm first. Ask first only when the person\n or the window is ambiguous, or for a swap between unlike shifts (below).\n Reminders, cancelling the user's own pending request, and reads never need asking.\n- `NOBODY` clears the layer it's placed on for the window; use it only when asked to leave\n the rota uncovered. Afterwards, say plainly that pages for that layer reach no one in\n that window, not just that nobody is on call, and name anyone still on call on the\n schedule's other layers.\n- A swap is two overrides, one on each shift. When the two shifts are on different\n layers or differ in length, confirm first, and say what each person ends up with (for\n example, back-to-back weeks). Otherwise, write both and report both.\n- A schedule with several rotations or layers needs `rotation_id` and `layer_id`, or\n the create is refused. `schedule_show` lists each rotation's layers by name, and\n every shift carries `layer_name`, so \"primary\" is the layer named Primary. Put the\n override on the layer held by the person being replaced, even if that displaces an\n existing override.\n- Creating an override replaces any existing override it overlaps on the same rotation and\n layer. The create result lists these as `displaced_overrides` — tell the user who you\n displaced, and offer to narrow the window if that wasn't intended.\n- To undo one, `schedule_override_delete` takes the `override_id` from the create's\n result or from the shift it produced in `schedule_show`. Deleting an override doesn't\n bring back the ones the create displaced, so when you revert such a create, recreate them\n from its `displaced_overrides` rather than calling it restored on the delete alone.\n\nCover requests:\n\n- Before raising one, or suggesting who to ask, check `cover_request_list` for a pending\n request on that shift. When one exists, say who it has already asked and who has\n responded, and nudge it rather than raising another.\n `cover_request_create` refuses a duplicate anyway.\n- `cover_request_create` raises one. The requester must be on call during the\n requested window — you can only ask for cover of your own shift. When the user\n names who should cover (\"can Alex take my shift?\"), pass just that person in\n `candidate_user_ids` — naming a person doesn't turn the ask into an override.\n- Write the request `message` in the first person, as the requester.\n- Candidates respond with `cover_request_respond`: accept (the override is created\n automatically), decline, or offer part of the window. The requester drives theirs\n with `cover_request_manage`: cancel while pending, accept a partial offer\n (`candidate_user_id` from the request's candidates), or nudge non-responders.\n- Both need a `cover_request_id`: when the user points at a request rather than\n handing you one (\"remind them\", \"I'll take Milly's shift\"), find it with\n `cover_request_list` first.\n\n## Answering\n\n- Refer to schedules, overrides, and cover requests by name in the reply — never by\n ULID. The IDs a follow-up action needs are already in this\n conversation's tool results; read them from there rather than asking the user.\n- State times with an explicit timezone label, rendered for the user rather than in\n raw UTC when their timezone is known.\n- After a write, own what changed: who is now on call instead of whom, and until when —\n never a bare \"done\".\n"
}SHA-256 of public snapshot: c4d6b8c225cd46ea477710ecb90bb0b103c2aa4c85b507803f7ae36be07fba97