# Osysharp.WorkQueues — the inbox: queues, who holds what, and the time promised on it

> `Osysharp.WorkQueues` is the inbox of an app: named queues, who holds each item, how it is handed on, and the service levels promised on it — over any kind of item.

<!-- id: agent-kit-work-queues · area: agent · stability: preview · html: https://osysharp.com/reference/agent/kit-work-queues/ -->

> **You are here:** [Building with agents](https://osysharp.com/reference/agent/guide/) › [The kits](https://osysharp.com/reference/agent/guide-kits/) › WorkQueues

## Summary        {#summary}
`Osysharp.WorkQueues` is the inbox of an app: named queues, who holds each item, how it is handed on, and the service levels promised on it — over any kind of item.

It is not an agents kit. It is where people already do their work, and that is why requests from agents land in it: an approval from an agent is one more item in the place a person already looks.

|  |  |
|---|---|
| Package | `Osysharp.WorkQueues`, version 1.0.0 |
| You add it with | `use Osysharp.WorkQueues;` in the app's manifest. |
| It also uses | `Identity`, `Organizations`, `Organizations.ServicePlans`, `Presence`, `ServiceHours`, `Workflow` — parts of the platform's own library |
| Its own test app | The smallest correct consumer, with TWO kinds of work so the kit's generality is proven here and not only by the helpdesk — `kits/work-queues/tests` |

## Description    {#description}

### What do you get without writing anything?   {#free}
- The inbox screens: Mine, Unassigned, At risk, each queue.
- Routing: who is given an item, by rules, round robin or load.
- Clocks in business hours, paused while waiting, with a warning before a promise is broken.
- Restricted queues, seen only by their members.

### When do you need it?   {#when}
From [shape 2](https://osysharp.com/reference/agent/guide-approvals/) on: it is the inbox [HumanRequests](https://osysharp.com/reference/agent/kit-human-requests/) puts its requests in.

### What does it expose?   {#exposes}
The tables below are generated from the kit itself, not written by hand: `osy kits Osysharp.WorkQueues --surface` lists each of
them with the code of the kit's own test app that uses it, and the tests that show it working.

**Settings** — one line in the app, each field with a default.

| You write | It says |
|---|---|
| `app.Inbox = new InboxSetup { AgentsHandOn, DefaultQueue, AccountRouting, KeepHolderOnEscalation, Routing, Views, Words, Links }` | How the app's inbox works. |

**Types you derive from** — your app writes a class of its own.

| Type | What it is |
|---|---|
| `WorkItem` | Anything a team works through a queue. |
| `InboxLinks` | The kinds of link the app's items may have — `app.Inbox = new InboxSetup { Links = new DeskLinks() }`, overriding `Kinds`. |
| `InboxRouting` | Where an item goes and what it needs, said in the app's own terms. |
| `InboxViews` | The app's own filters for saved views — a view whose `AppFilter` is "tag:refund" shows the items `Narrow` names. |

**Policies you answer** — each is a question the kit asks your app: `policy Name => …;`

| Policy | The question | Until the app says otherwise |
|---|---|---|
| `WorksInbox` | Works items: takes them, responds, moves them within their queues, sees the inbox. | nothing: the app must answer it |
| `LeadsInbox` | Also moves other people's work, manages queue members, availability and skills. | nothing: the app must answer it |
| `AdministersInbox` | Also changes queues, SLA policies, hours, routing rules and shared views, and sees restricted queues. | nothing: the app must answer it |

**Functions you call**, those its own tests show most first.

| Function | What it does | Tests that show it |
|---|---|---|
| `When(DateTime at)` | An instant as a person reads it on the trail — "Mon 8 Jun 06:00 UTC", in their language. | 109 |
| `MoveTo(WorkItem item, Queue queue, Principal? by, bool asLead)` | `item` moves to `queue`; its holder keeps it only when they may hold it there. | 109 |
| `Clocks(WorkItem item)` | The promises on `item` — the newest clock of each metric. | 106 |
| `AtRisk(WorkItem item, SlaMetric metric)` | `metric`'s clock went at risk — recorded once, and the app is told. | 105 |
| `Breached(WorkItem item, SlaMetric metric)` | `metric`'s promise ran out. | 105 |
| `Words(SlaMetric metric)` | The app's word for `metric` ("first response", "feedback due"). | 105 |
| `Paused(Handling h)` | Is the item paused on the requester, or held — every clock stopped? | 104 |
| `Refill(Principal? person, WorkItem? except = …, DateTime? at = …)` | `person`'s load dropped, or they are back: pull the pooled items they may be given, oldest-due first — each is routed by its own run, which gives it to whoever is free (them, unless somebody was wa… | 102 |
| `Met(WorkItem item, SlaMetric metric)` | `metric`'s clock is met — on time, or late. | 96 |
| `LoadOf(Principal person)` | How many items `person` holds that need them. | 93 |
| `MoveDue(WorkItem item, DateTime due, string why)` | Move the item's absolute due date (an extension the law allows, a deadline agreed again), saying why — recorded on the item's trail; its resolution clock is retargeted to the new instant. | 77 |
| `InboxStepWords(InboxStep happened)` | What a step of the trail says to whoever is reading — "Arrived in Billing — rule “Billing words”.", "Ines took it.", "Moved to Billing by Rahul." The one place the trail is put into words: the trai… | 65 |
| `OnDuty(Principal person, DateTime now)` | How a person stands for routing at `now`: available, on their hours, not away. | 60 |
| `PolicyMatching(WorkPriority priority, OrganizationTier? tier, Queue? queue, string channel, string segment, string kind, bool vip)` | The policy an item with these attributes is promised by — THE rule `PolicyFor` applies, and what the settings' "which policy applies?" tester asks without an item. | 54 |
| `TrailOf(WorkItem item)` | The trail of `item`, oldest first — "why is this here". | 38 |
| `TakeWork(WorkItem item, Guid? expected = …)` | Take `item`. | 36 |
| `TrailWords(List<Guid> ids)` | The steps `ids` said for the reader — what a trail on screen fetches for the steps it has not said yet. | 28 |
| `Responded(WorkItem item, DateTime? at = …)` | We gave the requester a response. | 21 |
| `MyAccounts()` | The organisations whose account team the viewer is on, each with its open, at-risk, offered and waiting work — the viewer's own reads, a fixed handful of statements however many accounts and items. | 20 |
| `Link(WorkItem from, WorkItem to, string key)` | Link `from` to `to` as `key` says — "#1043 duplicates #1042" is `Link(dup, original, "duplicate")`. | 19 |
| `LinkWork(Guid itemId, Guid otherId, string key, bool back = …)` | A person links `itemId` to `otherId` — `back`: the other item is the one that says it ("Duplicated by #1043" makes #1043 the duplicate). | 16 |
| `GoAway(DateTime? until = …, Principal? cover = …, string reason = …)` | Go away now — until `until` (none: until you come back), with `cover` taking your work. | 16 |
| `InitialsOf(string name)` | "Ines Moreau" → "IM". | 16 |
| `ComeBack()` | You are back: every live absence of yours ends, an availability marked away is available again, and you are given work again. | 13 |
| `AppFilteredBy(Guid id)` | `AppFiltered` for the saved view `id` — none when there is no such view, or it has no app filter. | 12 |
| `UnlinkWork(Guid linkId)` | A person removes a link. | 12 |
| `Rows(BuiltInView view)` | The items of a built-in view, as the viewer may read them — one read. | 12 |
| `MyPresence()` | The viewer's own standing: their status, hours, any time away and its cover, and their load. | 11 |
| `TrailLines(WorkItem item)` | `item`'s trail — every change of holder or queue, oldest first — said for the reader, in their language: "Arrived in Billing — rule “Billing words”.", "Offered to Ines (account owner) …", "Given to… | 11 |
| `CancelWork(WorkItem item, string reason)` | Cancelled — a duplicate, withdrawn. | 11 |
| `RowOf(WorkItem w, List<SlaClock> clocks, List<RoutingOffer> offers, Func<Guid, string> whoFor)` | One item as its list line reads it — from the item, ITS clocks (the governing one: the soonest still running and not yet missed; the missed one: the earliest still owed) and ITS live offer. | 11 |
| `InboxNav(InboxCounts c, List<Queue> queues, List<InboxView> views, string prefix, bool accounts = …, bool lead = …)` | The inbox's rows for a shell's nav — the built-in views with their counts, then the queues (lower levels first), then the saved views. | 11 |
| `WaitOn(WorkItem item, WaitFor reason, DateTime? at = …)` | The item waits on someone: the requester (every clock pauses), somebody else (resolution runs, unless the policy pauses it), or nobody — held by agreement (every clock pauses). | 10 |
| `HandWorkTo(WorkItem item, Principal person, Guid? expected = …)` | Hand `item` to `person` — who must be able to hold it. | 9 |
| `WorkDone(WorkItem item, DateTime? at = …)` | It is done — solved, approved, decided. | 7 |
| `Counts()` | Every count the rail shows — ONE grouped read of the items (queue × phase × held-by-me × held × offered × promise), as the viewer may read them, summed here; and one read of the queues' names. | 6 |
| `RequesterWrote(WorkItem item, DateTime? at = …)` | The requester wrote. | 5 |
| `MoveWork(WorkItem item, Queue queue)` | Move `item` to `queue`. | 5 |
| `Prioritise(WorkItem item, WorkPriority priority)` | Change how urgent the item is: the policy is chosen again, and every clock still running is retargeted to the new promise, keeping the time already used. | 4 |
| `ItemLinksOf(Guid itemId)` | `item`'s links, from both sides, each said in the reader's language — grouped by kind in the app's order, then newest first. | 4 |
| `ReleaseWork(WorkItem item)` | Give `item` back to its queue. | 3 |
| `MarkAway(Principal person, DateTime? until = …, Principal? cover = …, string reason = …)` | A lead marks `person` away now. | 3 |
| `HasPromise(WorkItem item)` | Is `item` promised anything at all — by a policy, or by an absolute due date? | 3 |
| `EscalateWork(WorkItem item, string why)` | Escalate `item` to the next level — the queue its queue `EscalatesTo` — saying `why`. | 2 |
| `LinkedTo(WorkItem item, string key)` | The item `item` links to as `key` says — the problem an incident is of — or null. | 2 |
| `NeedsOf(WorkItem item)` | The skills `item` needs, by name — "Billing (required), Spanish". | 2 |
| `WhichPolicy(WorkPriority priority, Guid? tier, Guid? queue, string channel, string kind, bool vip)` | "Which policy applies to an item like this?" — the settings' tester, as a sentence: the policy, what it promises, and the hours it counts in; or that nothing is promised. | 2 |
| `RowsIn(Queue queue)` | The items waiting in `queue` — worked or waiting — as the viewer may read them. | 2 |
| `RowsOf(InboxView view)` | The items of a saved view, as the viewer may read them — one read, then the app's own filter. | 2 |
| `Eligible(WorkItem item)` | The people who may hold `item` — its queue's active members, and its organisation's account team where the queue is not restricted — less anybody missing a skill it requires; each with their load, … | 1 |
| `TeamRows()` | Everybody who works a queue: their load against their capacity, what of it is at risk, whether they are on, and who covers for them while away. | 1 |
| `ResumeWork(WorkItem item, DateTime? at = …)` | The wait is over — the item is worked again, and a response is owed. | 1 |
| `ReopenWork(WorkItem item, DateTime? at = …)` | It was done, and is not — the resolution clock runs again from where it stopped. | 1 |
| `TakeMany(List<WorkItem> items)` | Take every item that can be taken; say why for the rest. | 1 |
| `MoveMany(List<WorkItem> items, Queue queue)` | Move every item that can be moved to `queue`; say why for the rest. | 1 |
| `AddressWork(WorkItem item, Principal to)` | For a kit whose items are put to people by name: give `item` to `to` from inside a run — a request that went unanswered goes on to the next person. | 1 |
| `LinkedFrom(WorkItem item, string key)` | The items that link to `item` as `key` says — a problem's incidents, an original's duplicates. | 1 |
| `AcceptOffer(WorkItem item)` | Take the item offered to you — the same as `TakeWork` on it. | 1 |
| `DeclineOffer(WorkItem item)` | Say no to the item offered to you: it falls through to the next step at once. | 1 |
| `Ordered(List<WorkRow> rows, WorkSort sort)` | Order a list's rows. | 1 |
| `LampFor(Handling h, SlaState sla)` | The lamp an item is drawn with — see the head of this file. | 1 |
| `DueTone(Handling h, SlaState sla, DateTime? due, TimeSpan? budget, DateTime now)` | The band a countdown is in: past (red), in its last quarter or at risk (amber), or fine (ink) — and no colour at all for a clock the team does not owe. | 1 |
| `Countdown(DateTime due, DateTime now)` | A countdown read at a glance: "0:42", "3h", "2d" — "−0:05" once it is past. | 1 |
| `IsInboxEvent(Event e)` | Whether `e` is one of the inbox's own events. | 0 |
| `InboxTime(Event e)` | When `e` happened — a promise's moment as its clock reached it (an imported item's breach is dated at its own minute, not the night it was found), else when it was raised. | 0 |
| `InboxNotice(Event e)` | What `e` says to the person it names — the one offered it, the cover handed it, the holder or a lead told of a promise — in their language: "Offered to you.", "Handed to you — Ines is away until Mo… | 0 |

**Screens and components you mount** — each is one line in a page of yours.

| Component | What it draws |
|---|---|
| `AssignControl(item, opened)` | Who has it, and handing it on — the item's holder as a chip that opens the hand-to menu, plus Take / Release. |
| `CandidateRow(c, onPick, disabled)` | One person in the hand-to menu: who, their languages, whether they are on, and a meter of their load against what the inbox gives them — amber at capacity. |
| `LoadMeter(percent, full)` | A thin meter — load against capacity — amber when full. |
| `ItemClocks(item, opened)` | The item's promises — a chip per metric for an item's head: "first response · 0:42", "next response · 3h", "resolution · 2d", each with a meter that shortens as the time goes — amber in its last quarter, red once missed; a paused one says so; a met one says so with a check that draws itself. |
| `ClockChip(c, word, left)` | One promise as a chip — see `ItemClocks`. |
| `WhyHere(item, opened)` | Why this is here — the item's trail in sentences, oldest first: where it arrived and by which rule, who it was offered to and why that fell through, who was given it and why, every hand-on, move and escalation, with when. |
| `TrailStep(step, sentence, latest, now)` | One step of an item's trail — its sentence for the reader (`TrailLines`), or, for a step recorded after the trail opened, fetched as it appears. |
| `ItemSeats(item, activity)` | Who else is on this item, and what they are doing — "Rahul — replying" — for the item's header. |
| `WorkItemHead(item, opened)` | An item's head — its reference and title, who else is on it, who has it (and handing it on), where it waits, how urgent it is, and its promises. |
| `HeadFact(label, value, tone)` | One fact of an item's head — what it is and what it holds, with a lamp in its tone when it has one. |
| `ItemLinks(item, hrefOf, shortcut, empty, titled, opened, onAct)` | The item's links — every link it has, from its side ("Duplicate of #1042", "Caused #1057"), each opening the other item, each removable by whoever works the inbox; and "Link…", which asks which way and finds the other item by its reference or the words of its title. |
| `LinkLine(link, back, said, hrefOf, onRemove, onAct)` | One link from an item's side — the words, the other item (its reference, title and where it stands), opening it; and, for a kind people choose, removing it. |
| `WorkLine(row, href, mark, picked, now, onPick, compact)` | One item in the list — two lines: what it is and how long is left, then who it is for and who has it. |
| `PickMark(on, onToggle, label)` | A row's pick box — a command, not a binding: whether it is ticked follows from the list's selection, and pressing it changes the selection. |
| `WorkList(view, hrefOf, open, title, whoFor, more, onMore, titled, onShown, whoMatches)` | The inbox's list — one view of the work (a built-in view, a queue, or a saved view, named by `view`), live, ordered, filterable, and worked from the keyboard: J/K move, X picks, Enter opens, T takes; with a pick, the bulk bar hands, moves, re-prioritises and escalates them all, and says why for any it could not. |
| `WorkListView(view, hrefOf, open, title, whoFor, more, onMore, titled, onShown, whoMatches)` | One view's list — `WorkList`'s body, mounted afresh for each view. |
| `WorkLamp(handling, sla)` | An item's lamp. |
| `SlaChip(row, now)` | The countdown on a row — what is left of the promise the team owes, in tabular mono: ink while there is time, amber in its last quarter, red once it is past. |
| `HolderMark(row, now)` | Who has it, at the end of a row: their initials — or, while it is offered to somebody first, "→ Ines · 12:00", the offer counting down to when it falls through. |
| `InboxPanes(view, hrefOf, open, title, whoFor, more, onMore, listW, headerNamesView, onShown, whoMatches, pageOpen, pageWide)` | The list, and what is open beside it — `view`'s `WorkList` and, beside it on a wide screen, the slot: the open item, or `InboxOverview` when nothing is open. |
| `InboxOverview(view, title, noun)` | No item selected — the pane beside the list when no item is open: the view's name, what it holds (late, at risk, nobody on it, waiting — from the rail's own grouped read, live), and the keys that work the list. |
| `OverviewFigure(n, word, tone, last)` | One figure of the overview — a count in mono, and its word under it. |
| `KeyLine(keys, what, also)` | One line of a keyboard lesson — the key, spelled by the platform for the reader's keyboard (⌘ on a Mac), and what it does. |
| `MyStatus()` | My status — the switch in the shell's corner: Available (give me work), Busy (nothing new), Offline, or Away until a time with a colleague covering. |
| `TeamLoad()` | The team's load, for a lead — each person's work against their capacity, what of it is at risk, whether they are on, away and who covers; the busiest first. |
| `StandingMark(status, away, onHours)` | A person's standing as a lamp. |
| `MyAccountsPanel(prefix)` | My accounts — the organisations whose account team the viewer is on: tier, open, at risk, offered to them first, waiting; the busiest first. |
| `AccountFigure(n, word, tone)` | A count and its word, in mono — "3 open". |
| `InboxShell(chrome, prefix)` | The inbox in the app's sidebar — the floor's `SidebarShell`, with the inbox's rows (views, queues, saved views and their live counts) above the app's own nav. |
| `QueueSettings()` | Queues — where work waits: each queue's name, whether it is restricted, its level and the level above it, how it hands work out, its timers and hours, what happens to a member's work when they go away — and who works it. |
| `SlaPolicySettings()` | Sla policies — what an item is promised: each policy's conditions (the most specific match wins), its three targets, the hours they count in, when a clock goes at risk, and what each clock does when it is at risk or breached. |
| `BusinessHoursSettings()` | Business hours — the calendars promises count in: each one's zone and weekly hours, and the holidays its clocks stop for. |
| `RoutingRuleSettings(appAction, appActionHint)` | Routing rules — in order, where an arriving item goes and what it needs: conditions (words in the title, channel, organisation, tier, VIP, language, segment, kind) and a closed set of actions (a queue, a priority, a skill, a person), plus the app's own action in the app's own words — `appAction: "Tag it", appActionHint: "refund"` for a helpdesk whose `InboxRouting.Act` tags. |
| `SkillSettings()` | Skills and languages — what work can need, and who holds it (with a level). |
| `SharedViewSettings(appFilter, appFilterHint)` | Shared views — views the whole team sees in the rail: a name and what it keeps (queue, holder, priority floor, tier, at risk, waiting, done, language, kind, and the app's own filter in the app's own words — `appFilter: "Tagged"`). |
| `WorkItemView(item, opened)` | An item's screen — its head (`WorkItemHead`: who has it, where it waits, its promises) and, under it, what the item IS as the owner of its kind draws it (`WorkItemDetail`). |

**Slots you can fill** — a place on the kit's screens where your app, or another kit, adds a section.

| Slot | What goes there |
|---|---|
| `WorkItemDetail(T item)` | What an item is, drawn by whoever owns its kind — the place on an item's screen, under its head, where a kit (or the app) shows one kind of item: an approval's amount and steps, a proposal's change… |
| `WorkBulkAction(string kind, List<Guid> ids, Action<string> done)` | A change to many items at once, added by whoever owns their kind — a place on the list's bulk bar, drawn while something is picked. |

**Pages it brings** — routes the kit serves by itself.

| Route | Page |
|---|---|
| `/settings/queues` | `QueuesSettings` |
| `/settings/routing` | `RoutingSettings` |
| `/settings/skills` | `SkillsSettings` |
| `/settings/views` | `ViewSettings` |
| `/settings/sla` | `SlaSettings` |
| `/settings/hours` | `HoursSettings` |

**Events your app can hear** — `[On] void Heard(EventName e) { … }`

| Event | When |
|---|---|
| `ItemArrived` | It arrived and its promise was chosen — by `Policy` (its name), or by a due date it carries. |
| `ItemQueued` | It landed in a queue — the default one, the one its account falls through to, or the one a routing rule named. |
| `ItemRouted` | A routing rule placed it in a queue — `Step.Rule` names the rule, `Step.To` the queue. |
| `HolderChanged` | Who holds it changed — somebody took it, was given it or handed it on, or let it go. |
| `ItemMoved` | It moved to another queue — by somebody, or falling through to the queue that serves its account. |
| `ItemEscalated` | It was escalated a level. |
| `ItemOffered` | It was offered to `To` — it is theirs if they take it in time. |
| `OfferFellThrough` | An offer fell through — declined, not taken in time, or its person went away. |
| `OfferWithdrawn` | Somebody else took it while it was offered: the offer to `About` is withdrawn. |
| `RoutingSkipped` | Routing passed somebody over — away, at capacity, or not allowed to hold it — or a rule named somebody who may not. |
| `ItemPooled` | Nobody was free: it waits in the queue's pool, for a speaker of `Language` when it waits for one. |
| `PickupOverdue` | Nobody picked it up within its queue's pickup time — the leads should know. |
| `PriorityChanged` | Its priority changed — by somebody, or by its promise (`Metric` at its `Moment`). |
| `DueMoved` | Its due date moved, and why. |
| `ItemCancelled` | It was cancelled, and why. |
| `ItemReopened` | It was reopened — by the team, or because its requester wrote back. |
| `PromiseAtRisk` | A promise on it is at risk — `Metric`'s clock reached its at-risk point at `At`. |
| `PromiseBreached` | A promise on it was missed — `Metric`'s clock ran out at `At` (an imported item's, at its own minute). |
| `PromiseMet` | A promise on it was kept — on time, or `Late`. |
| `PromiseToldToHolder` | Its policy says to tell whoever holds it that a promise is at risk or missed — `Holder`, named `About` at the time. |
| `PromiseToldToLeads` | Its policy says to tell the leads that a promise is at risk or missed — whom only the app knows. |
| `ItemLinked` | It was linked to `Other` (as it was named) — the link's kind by its key; `Back`: this is the item the link names ("Duplicated by #1043" rather than "Duplicate of #1042"). |
| `ItemUnlinked` | A link of it was removed. |

## What to read next   {#read-next}
- [Osysharp.HumanRequests — something put to a person, and their answer coming back](https://osysharp.com/reference/agent/kit-human-requests/) — something put to a person, and their answer coming back
- [Osysharp.Agents.HumanRequests — an agent's proposals and questions, in the inbox of the person they are for](https://osysharp.com/reference/agent/kit-agents-human-requests/) — an agent's proposals and questions, in the inbox of the person they are for
- [Shape 2 — work done for people, with approvals](https://osysharp.com/reference/agent/guide-approvals/) — Shape 2 — work done for people, with approvals

## Go deeper   {#see-also}
- [The WorkQueues kit — queues, who holds what, and the service levels promised on any item](https://osysharp.com/reference/workflow/inbox-kit/) — the kit: queues, holding, routing, clocks
- [Workflow.Inbox&lt;T&gt; (what is waiting for me)](https://osysharp.com/reference/workflow/inbox/) — work waiting for a person
- [ServiceHours (SLA-accrual windows)](https://osysharp.com/reference/workflow/service-hours/) — business hours
