Use cases / Operations and compliance
Ticket triage and routing
Category, priority, route. Every ticket, every day, with an incident match.
- Unit
- One incoming Pylon ticket
- Ask
- Category? Priority? Engineering? Sensitive data? Then: which open incident?
- Get
- Every ticket routed. 118 matched to an incident.
Pylon · Files · 2 reducers · 6 questions · updated Sep 21, 2026
The flow
Cheap pass for every ticket. Incident pass only where engineering is needed. 758 requests for 640 tickets. Routing is a table your code applies.
Follow one record
- tickets
- Triage
- Needs engineering ≥ 0.70
- Attach open incidents
- Match incidents
- Outputs
Ticket T-2291, opened 08:41
snapshot 09:00, tenant eu-west
- T-2291We can't log in since this morning. SSO says invalid certificate. About 40 people are blocked and we have payroll to run today.
Request 51 of 640
model jev-1.13.0, attempt 1, succeeded
- account access0.77
- bug0.19
- other0.03
- how to0.01
confidence 0.72, provider reported
- P30.00
- P20.10
- P10.78
- P00.12
P1 with a chance of P0
- true0.91
a certificate problem is not a support action
- true0.02
paired with a pattern check in code
{
"model": "jev-1.13.0",
"state": {
"ticket": { "id": "T-2291", "tenant": "eu-west", "opened": "2026-09-20T08:41:00Z",
"text": "We can't log in since this morning. SSO says invalid certificate. About 40 people are blocked and we have payroll to run today." },
"policy": { "priority": "P3: cosmetic or a question. P2: a workaround exists. P1: the customer is blocked. P0: outage or data loss." }
},
"questions": {
"category": { "type": "choice", "instructions": "Which category best fits `ticket.text`?",
"criteria": { "billing": "Charges, invoices, refunds", "bug": "Something that used to work does not",
"how_to": "The customer needs to know how to do something",
"feature_request": "The customer wants a capability that does not exist",
"account_access": "Login, SSO, permissions, lockouts", "other": "None of the above" } },
"priority": { "type": "score", "instructions": "Using the definitions in `policy.priority`, how urgent is `ticket.text`?",
"criteria": ["P3 cosmetic or question", "P2 workaround exists", "P1 customer blocked", "P0 outage or data loss"] },
"needs_engineering": { "type": "noul", "instructions": "Does resolving `ticket.text` require a code or infrastructure change rather than a support action?" },
"sensitive_data": { "type": "noul", "instructions": "Does `ticket.text` contain a payment card number, a government identity number, or a password?" }
}
}
{
"model": "jev-1.13.0",
"answers": {
"category": { "choice": "account_access", "probabilities": { "account_access": 0.77, "bug": 0.19, "other": 0.03, "how_to": 0.01, "billing": 0.00, "feature_request": 0.00 }, "confidence": 0.72 },
"priority": { "expected": 2.02, "probabilities": [0.00, 0.10, 0.78, 0.12], "confidence": 0.78 },
"needs_engineering": { "probability": 0.91 },
"sensitive_data": { "probability": 0.02 }
}
}
0.91 is at or above 0.70, kept
into the engineering pass
- field
- answers.needs_engineering.probability
- comparison
- gte 0.70
- value
- 0.91
- result
- matched collection
Three incidents open at 09:00
joined on tenant, snapshot pinned by the run
- INC-0244SSO certificate rotation failed for EU tenants. Opened 07:55. Identity on-call engaged.
- INC-0231Report exports slower than 60 seconds. Opened yesterday.
- INC-0250Mobile push notifications delayed. Opened 08:30.
Request 9 of 118
model jev-1.13.0, attempt 1, succeeded
- INC-02440.89
- none0.08
- INC-02310.02
- INC-02500.01
confidence 0.86, provider reported
- true0.96
forty people and payroll today
{
"model": "jev-1.13.0",
"answers": {
"incident_match": { "choice": "INC-0244", "probabilities": { "INC-0244": 0.89, "none": 0.08, "INC-0231": 0.02, "INC-0250": 0.01 }, "confidence": 0.86 },
"blocking": { "probability": 0.96 }
}
}
One routed row
your code reads this and assigns in Pylon
- ticket
- T-2291
- category
- account access (0.77)
- priority
- P1 (2.02), P0 at 0.12
- engineering
- yes (0.91)
- incident
- INC-0244 (0.89)
- route
- Identity on-call, from routing v7: account_access + engineering
- trace
- 6 nodes, 2 attempts, incidents snapshot 09:00
What comes out
| Ticket | Category | Priority | Engineering | Incident | Route |
|---|---|---|---|---|---|
| T-2291 | account access | P1 2.02 | 0.91 | INC-0244 | Identity on-call |
| T-2288 | bug | P1 1.94 | 0.84 | INC-0231 | Reports team |
| T-2294 | billing | P2 1.21 | 0.06 | none | Billing queue |
| T-2290 | bug | P1 1.88 | 0.79 | none | Platform on-call |
| T-2287 | how to | P3 0.31 | 0.03 | none | Support tier 1 |
| T-2293 | feature request | P3 0.18 | 0.11 | none | Product inbox |
Synthetic rows in the app's Outputs layout. Priority is the expected position on your P3 to P0 scale; the distribution behind it is one click away.
Details, if you want them
whyWhy this shape
Why this shape
- Four decisions per ticket, one request. Category, priority, engineering, sensitive data.
- Your priority scale. P3 to P0, in your words, inside the state.
- Incidents are a snapshot. Matched against what was open at 09:00. The trace shows which.
- Routing in your code. Decision traced here, action audited there.
questionsThe 6 questions, verbatim
- Triage
categorycategorical, choice
Which category best fits `ticket.text`?
billingbughow tofeature requestaccount accessother - Triage
priorityordinal, score
Using the definitions in `policy.priority`, how urgent is `ticket.text`?
P3 cosmetic or questionP2 workaround existsP1 customer blockedP0 outage or data loss - Triage
needs_engineeringbinary, noul
Does resolving `ticket.text` require a code or infrastructure change rather than a support action?
- Triage
sensitive_databinary, noul
Does `ticket.text` contain a payment card number, a government identity number, or a password?
- Match incidents
incident_matchcategorical, choice
Is the problem in `ticket.text` the same problem as one of the open incidents in `incidents`?
INC-0244INC-0231INC-0250none - Match incidents
blockingbinary, noul
Is the customer described in `ticket.text` unable to work right now because of this problem?
buildHow each stage is built, as JSON
1 reducer Triage
priority is an ordinal over your own P3 to P0 definitions, so the expected value is a position on that scale. sensitive_data is a probability, not a scanner; pair it with a deterministic pattern check in code.stage definition
{
"id": "triage",
"input": "source:tickets",
"kind": "evaluate",
"model": "jev",
"name": "Triage",
"questions": {
"category": {
"criteria": {
"account_access": "Login, SSO, permissions, lockouts",
"billing": "Charges, invoices, refunds",
"bug": "Something that used to work does not",
"feature_request": "The customer wants a capability that does not exist",
"how_to": "The customer needs to know how to do something",
"other": "None of the above"
},
"instructions": "Which category best fits `ticket.text`?",
"type": "choice"
},
"needs_engineering": {
"instructions": "Does resolving `ticket.text` require a code or infrastructure change rather than a support action?",
"type": "noul"
},
"priority": {
"criteria": [
"P3 cosmetic or question",
"P2 workaround exists",
"P1 customer blocked",
"P0 outage or data loss"
],
"instructions": "Using the definitions in `policy.priority`, how urgent is `ticket.text`?",
"type": "score"
},
"sensitive_data": {
"instructions": "Does `ticket.text` contain a payment card number, a government identity number, or a password?",
"type": "noul"
}
},
"state_path": []
}2 filter Needs engineering ≥ 0.70
stage definition
{
"comparison": "gte",
"field": [
"answers",
"needs_engineering",
"probability"
],
"id": "engineering",
"input": "triage",
"kind": "filter",
"name": "Needs engineering ≥ 0.70",
"value": 0.7
}3 join Attach open incidents
stage definition
{
"id": "with_incidents",
"input": "engineering",
"kind": "join",
"left_key": [
"tenant"
],
"name": "Attach open incidents",
"right": "source:incidents",
"right_key": [
"tenant"
]
}4 reducer Match incidents
incident_match chooses among the open incidents or none; blocking asks whether the customer is stopped right now. The options here are the incidents open at 09:00. When incidents open or close, a script saves a new version of this stage.stage definition
{
"id": "match",
"input": "with_incidents",
"kind": "evaluate",
"model": "jev",
"name": "Match incidents",
"questions": {
"blocking": {
"instructions": "Is the customer described in `ticket.text` unable to work right now because of this problem?",
"type": "noul"
},
"incident_match": {
"criteria": {
"INC-0231": "Report exports slower than 60 seconds",
"INC-0244": "SSO certificate rotation failed for EU tenants",
"INC-0250": "Mobile push notifications delayed",
"none": "Not one of the open incidents"
},
"instructions": "Is the problem in `ticket.text` the same problem as one of the open incidents in `incidents`?",
"type": "choice"
}
},
"state_path": []
}5 definition The whole workflow, as saved
Saving publishes an immutable version. A run freezes this definition, the snapshot IDs and each reducer’s model profile, so the trace can always show exactly what ran. Edits create a new version; old runs keep theirs.
jevreduce.local.v1
{
"name": "Ticket triage and routing",
"schema_version": "jevreduce.local.v1",
"sources": {
"incidents": "snap_incidents_2026-09-20T09",
"routing": "snap_routing_v7",
"tickets": "snap_pylon_queue_2026-09-20T09"
},
"stages": [
{
"id": "triage",
"input": "source:tickets",
"kind": "evaluate",
"model": "jev",
"name": "Triage",
"questions": {
"category": {
"criteria": {
"account_access": "Login, SSO, permissions, lockouts",
"billing": "Charges, invoices, refunds",
"bug": "Something that used to work does not",
"feature_request": "The customer wants a capability that does not exist",
"how_to": "The customer needs to know how to do something",
"other": "None of the above"
},
"instructions": "Which category best fits `ticket.text`?",
"type": "choice"
},
"needs_engineering": {
"instructions": "Does resolving `ticket.text` require a code or infrastructure change rather than a support action?",
"type": "noul"
},
"priority": {
"criteria": [
"P3 cosmetic or question",
"P2 workaround exists",
"P1 customer blocked",
"P0 outage or data loss"
],
"instructions": "Using the definitions in `policy.priority`, how urgent is `ticket.text`?",
"type": "score"
},
"sensitive_data": {
"instructions": "Does `ticket.text` contain a payment card number, a government identity number, or a password?",
"type": "noul"
}
},
"state_path": []
},
{
"comparison": "gte",
"field": [
"answers",
"needs_engineering",
"probability"
],
"id": "engineering",
"input": "triage",
"kind": "filter",
"name": "Needs engineering ≥ 0.70",
"value": 0.7
},
{
"id": "with_incidents",
"input": "engineering",
"kind": "join",
"left_key": [
"tenant"
],
"name": "Attach open incidents",
"right": "source:incidents",
"right_key": [
"tenant"
]
},
{
"id": "match",
"input": "with_incidents",
"kind": "evaluate",
"model": "jev",
"name": "Match incidents",
"questions": {
"blocking": {
"instructions": "Is the customer described in `ticket.text` unable to work right now because of this problem?",
"type": "noul"
},
"incident_match": {
"criteria": {
"INC-0231": "Report exports slower than 60 seconds",
"INC-0244": "SSO certificate rotation failed for EU tenants",
"INC-0250": "Mobile push notifications delayed",
"none": "Not one of the open incidents"
},
"instructions": "Is the problem in `ticket.text` the same problem as one of the open incidents in `incidents`?",
"type": "choice"
}
},
"state_path": []
}
]
}limitsWhat it will not do
- Outputs, not actions. Your code assigns in Pylon.
- Incident options are a saved version. New incident, new version.
- Sensitive-data is a probability. Pair it with a pattern check.
- No deduplication. Same outage, two tickets.
- Text only. Screenshots need extraction.