attributes.queue set to support, and the judgment reads the other open tickets with the same value. Each queue is one block of a blocking relation, one of the relations, with the queue’s name as its key.
Start from the queue starter
Thetriage.against_queue starter is this judgment, ready-made. Fill it with your own paths:
POST /v1/namespaces/acme%2Fhelpdesk/judgments
- It judges only open tickets, the documents whose
kindisticketand whosestatusisopen. A ticket that is closed leaves the judgment: it is no longer judged or answered, and no longer shown to the other tickets in its queue. - It reads the ticket’s subject and the first 1,000 characters of its body, and from its queue the newest 10 other open tickets created within 14 days of the queue’s newest open ticket: when each was created, its subject, and the first 200 characters of its body. An edit past either cut changes nothing the judgment reads, so it re-judges nothing. See cut a long field.
- Each queue is its own. Tickets in
billingnever see the tickets insupport. Write the queue’s name as a short string of letters, digits,-,_and.. A ticket with no queue, or a value that is not such a string, is in no queue: it is judged with no other tickets shown, and the criteria say such a ticket repeats nothing. - The answer is yes or no. It does not name the tickets the problem repeats. Its evaluation lists every ticket it read in
related_documents, so you can see what it was compared with. - Thresholds.
repeatat 0.8 andreviewat 0.5: group a ticket aboverepeatwith the problem it repeats, and send the band between them to a person. These are starting points; post outcomes to measure and tune them. - Your own wording. Send
dry_run: trueto get the filled definition, change its question or criteria, and create from that. The same relation serves any question that depends on what else is open.
attributes.queue, listed as a reference_index job in the create response’s job_ids; the judgment’s answers are unavailable until it is done.
The context is capped at 1,500 tokens with max_tokens, which keeps each judgment standard in size. Over the cap, the oldest of the queue’s tickets are left out first, before any of the ticket’s own text is cut, and the evaluation records context_truncated: true.
What it is not
- Not everything open. It shows the newest 10 open tickets created within 14 days of the queue’s newest one. An open ticket older than that, or past the newest 10, is not shown, however much it matters. The 14 days count back from the queue’s newest open ticket, not from now, so a quiet queue still shows its last tickets. Raise
last_n(up to 254) orwindowin the definition to show more; every ticket shown is in every judgment’s context, so its size class grows with it. - Creation order, not priority. Newest means most recently created. Editing a ticket, raising its priority or reassigning it does not move it up, and the tickets shown are not the ones your team will work next. The judgment cannot tell what is ahead of this ticket in your process. Another order is not available on this relation: the tickets shown are always the newest.
- Not their answers. It reads the other tickets’ text, never their answers to this or any other judgment.
What it costs
A ticket’s own writes re-judge it, as for any judgment: a new ticket is judged within seconds, against its queue as it stands then. The cost to plan for is the other direction. Every open ticket reads the same newest few, so a change to them re-judges the whole queue:re-judgments a month = queue changes a month × open tickets per queue inside the re-judge scope
What counts as a queue change
- A write to a ticket that is open before or after it, such as a new ticket, an edit to an open one, or closing one, makes every open ticket in its queue
pendingfrom the moment the write acks. - After a quiet period, Brussle reads the queue once and compares what it shows with what it showed before. Each queue waits on its own until it has had no such write for
freshness.fanout.debounce_ms, 10 minutes by default, or untilfanout.max_wait_ms, 1 hour by default, has passed since the first write it has not yet read. So a burst of writes costs one read of the queue, and a queue that is never quiet for 10 minutes is read once an hour. - Nothing shown changed, such as a new assignee, a tag, an edit past a cut, or a closed ticket that was not among the newest shown: the open tickets are
freshagain, with no engine call and nothing counted. - Something shown changed, such as a new ticket, or one of the shown tickets closed or its subject edited: every open ticket in the queue inside the re-judge scope is re-judged. Nearly all of their contexts change, so nearly every one is billed. One whose context did not change keeps its answer and is not billed, but counts toward the rolling limit.
pending with their last answers, so in a queue written to all day they read pending much of the time. answers: "fresh_only" leaves pending answers out: list a busy queue’s answers without it.
Worked numbers
Each ticket’s context and question come to about 1,300 tokens: a standard judgment, at $0.25 per 1,000.
A is well inside the default rolling limit of 300,000 re-judgments in any 30 days. B is nearly twice it: the first 300,000 run, $75 of re-judging, and the rest are deferred until the window has room. C trades freshness for cost: the other open tickets see a new ticket up to 4 hours later, and read
pending until then, while the new ticket itself is still judged within seconds. D re-judges only the newest open tickets; the older ones keep their answers and read stale. Splitting a queue in four does not help a queue written to around the clock, since each part is still read once an hour: it helps when each part is quiet for longer.
The limits it runs under
Each is a setting infreshness.fanout, sent at create or changed later with a PATCH:
rolling_limit, 300,000 by default: the most open tickets the judgment’s queue changes may re-judge in any 30 days. Within it, a change runs on its own, at most 1,000 tickets at a time. Past it, the tickets that fit are re-judged and the rest wait: their answers readstalewithstale_reasonlimit_reached, and the events feed records onejudgment.limit_reachedwithlimitrolling_limit. They catch up on their own when older re-judgments leave the 30-day window, or at once when aPATCHraises the limit. With several queues, the queues that have spent the most of the limit wait first, so one busy queue cannot leave every other queue’s tickets stale.block_cap, 1,000 by default: the most open tickets one queue may hold. A create is refused withinvalid_requestwhen a queue already holds more, naming it indetails.key; closed tickets do not count, since they are outside Applies to. A queue that grows past the cap later waits, whatever the rolling limit: its open tickets readstale(limit_reached), and the events feed recordsjudgment.limit_reachedwithlimitblock_capand the queue inkey. It runs again once tickets are closed and the queue is back within the cap, or when aPATCHraises it.scope.created_within, 30 days by default: an open ticket created longer before the change is not re-judged. It keeps its answer and readsstalewithstale_reasonreferenced_changeduntil its own next write. If tickets stay open for weeks and their answers matter, send"scope": {"created_within": null}: the Applies to on open tickets already keeps closed ones out.
What you confirm
Withoutconfirm: true, the create returns its cost estimate and creates nothing:
replay runs the last 30 days of writes through the judgment: the open tickets’ own writes, and each queue’s tickets created in that time that are still open, re-judging the open tickets then in their queue after the quiet period. It cannot see a ticket that was closed, edited or deleted in those 30 days, so a ticket opened and closed within the month leaves no trace of the changes it made. It says so with "excludes": ["candidate_edits", "candidate_deletes"] and lower_bound: true, and its figures are “at least”. In a queue where most tickets close within days, the real figure can be several times the estimate. What bounds it is the rolling limit: fanout.cost_usd_at_limit is the most the queue changes can cost in any 30 days. Sending confirm: true agrees to both, and no queue change waits for a person after that.