You've already forked incident-triage
Import UAPF package
Import UAPF package: incident-triage.uapf
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
*.uapf.tmp
|
||||||
|
.DS_Store
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
69
README.md
Normal file
69
README.md
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# lv.itsm.incident.triage
|
||||||
|
|
||||||
|
UAPF v2.5.0 package — LVRTC Incident Triage.
|
||||||
|
|
||||||
|
## Quick install (uapf-engine)
|
||||||
|
|
||||||
|
The engine reads `.uapf` ZIP archives from its `/packages` mount. Build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd uapf-packages/incident-triage
|
||||||
|
zip -rq ../incident-triage.uapf .
|
||||||
|
mv ../incident-triage.uapf /path/to/engine/packages/
|
||||||
|
docker compose restart uapf-engine
|
||||||
|
```
|
||||||
|
|
||||||
|
Or use the admin install-from-url endpoint:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://uapf-engine:4000/uapf/admin/install-from-url \
|
||||||
|
-H "Authorization: Bearer $UAPF_ENGINE_AUTH_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"sourceUrl": "https://processgit.org/AI_Sandbox/incident-triage/archive/main.zip"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
incident-triage/
|
||||||
|
manifest.json UAPF v2.5.0 manifest
|
||||||
|
uapf.yaml YAML mirror of manifest (easier diff)
|
||||||
|
algorithms/ 7 Algorithm Cards with embedded v2.5.0 tests
|
||||||
|
bpmn/ incident-triage.bpmn — 9 service tasks, linear
|
||||||
|
dmn/ 3 DMN 1.3 tables: priority, ownership, routing
|
||||||
|
resources/ guardrails.yaml, mappings.yaml
|
||||||
|
metadata/ lifecycle.yaml, ownership.yaml
|
||||||
|
docs/ overview.md (start here)
|
||||||
|
fixtures/ 3 sample signals + expected post-triage state
|
||||||
|
tests/bpmn/ Sidecar BPMN scenario tests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Algorithm Cards
|
||||||
|
|
||||||
|
| Card | Capability | Determinism |
|
||||||
|
|---|---|---|
|
||||||
|
| `algo.incident_triage.normalize_signal` | `intake.normalize@1` | deterministic |
|
||||||
|
| `algo.incident_triage.classify_incident` | `ai.classify@1` | stochastic |
|
||||||
|
| `algo.incident_triage.suggest_priority` | `ai.suggest_priority@1` | stochastic |
|
||||||
|
| `algo.incident_triage.evaluate_dmn` | `dmn.evaluate@1` | deterministic |
|
||||||
|
| `algo.incident_triage.draft_response` | `ai.draft_response@1` | stochastic |
|
||||||
|
| `algo.incident_triage.update_incident` | `incident.update@1` | deterministic, stateful |
|
||||||
|
| `algo.incident_triage.emit_event` | `event.emit@1` | deterministic, stateful |
|
||||||
|
|
||||||
|
All seven carry the v2.5.0 mandatory embedded `tests` array (≥ 2 cases each;
|
||||||
|
17 cases total across the package).
|
||||||
|
|
||||||
|
## Spec version
|
||||||
|
|
||||||
|
Tracks **`main`** of `github.com/UAPFormat/UAPF-specification`. Current
|
||||||
|
locked spec at package release: **v2.5.0** (2026-05-21).
|
||||||
|
|
||||||
|
## Source
|
||||||
|
|
||||||
|
- Workspace (OpenITSM repo): `uapf-packages/incident-triage/`
|
||||||
|
- ProcessGit (canonical): `https://processgit.org/AI_Sandbox/incident-triage`
|
||||||
|
- Engine: any uapf-engine ≥ commit aligned with UAPF v2.5.0 schemas
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT — same as the OpenITSM repository.
|
||||||
133
algorithms/classify_incident.card.yaml
Normal file
133
algorithms/classify_incident.card.yaml
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
kind: uapf.algorithm.card
|
||||||
|
id: algo.incident_triage.classify_incident
|
||||||
|
version: 1.0.0
|
||||||
|
name: Incident classifier
|
||||||
|
intent: |
|
||||||
|
Reads the normalised payload and picks one taxonomy code from a fixed
|
||||||
|
closed list. The classifier is LLM-backed at runtime (Claude via the
|
||||||
|
LLM gateway) and falls back to a deterministic keyword matcher when
|
||||||
|
the gateway is unreachable. The taxonomy code is the primary driver
|
||||||
|
for the priority and routing DMN decisions; downstream rules treat
|
||||||
|
this output as authoritative.
|
||||||
|
algorithm_kind: classifier
|
||||||
|
|
||||||
|
io:
|
||||||
|
inputs:
|
||||||
|
- id: payload
|
||||||
|
type: object
|
||||||
|
cardinality: single
|
||||||
|
documentation: |
|
||||||
|
The normalized_payload from the upstream intake.normalize step.
|
||||||
|
At minimum {title, description?, host?, severity?}.
|
||||||
|
- id: text
|
||||||
|
type: string
|
||||||
|
cardinality: single
|
||||||
|
documentation: |
|
||||||
|
Optional pre-flattened text. If absent, the host derives it from
|
||||||
|
payload.title + payload.description + payload.host.
|
||||||
|
outputs:
|
||||||
|
- id: taxonomy_code
|
||||||
|
type: string
|
||||||
|
constraints:
|
||||||
|
enum:
|
||||||
|
- network.outage.link_down
|
||||||
|
- network.degradation
|
||||||
|
- network.routing
|
||||||
|
- network.dns
|
||||||
|
- security.incident
|
||||||
|
- facility.power
|
||||||
|
- storage.capacity
|
||||||
|
- service.customer_request
|
||||||
|
- unknown.uncategorized
|
||||||
|
documentation: The chosen taxonomy code from the closed list above.
|
||||||
|
- id: confidence
|
||||||
|
type: probability
|
||||||
|
constraints:
|
||||||
|
minimum: 0
|
||||||
|
maximum: 1
|
||||||
|
documentation: Model-reported confidence; the stub fallback returns 0.75 for matched / 0.20 for unmatched.
|
||||||
|
- id: reasoning
|
||||||
|
type: string
|
||||||
|
documentation: One-sentence justification (English). Persisted with the AI decision; not shown to operator by default.
|
||||||
|
- id: label_hint
|
||||||
|
type: string
|
||||||
|
documentation: Human-friendly short label derived from the taxonomy code (e.g. "link_down").
|
||||||
|
|
||||||
|
implementation:
|
||||||
|
type: external
|
||||||
|
medium: mcp_tool
|
||||||
|
uri: uapf-ip://capability/ai.classify@1
|
||||||
|
hash: sha256:0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
runtime:
|
||||||
|
capability: ai.classify@1
|
||||||
|
note: |
|
||||||
|
Host-fulfilled UAPF-IP capability backed by the LLM gateway
|
||||||
|
(default Anthropic). When LLM_PROVIDER is unavailable, the host
|
||||||
|
falls back to a regex-driven keyword matcher that produces the
|
||||||
|
same output shape.
|
||||||
|
|
||||||
|
determinism: stochastic
|
||||||
|
side_effects: pure
|
||||||
|
complexity:
|
||||||
|
typical_latency_ms: 800
|
||||||
|
max_latency_ms: 30000
|
||||||
|
failure_mode: |
|
||||||
|
Returns taxonomy_code='unknown.uncategorized' with confidence<=0.25.
|
||||||
|
Triage continues; the DMN priority table treats unknown as P4 default.
|
||||||
|
|
||||||
|
reference:
|
||||||
|
legal: |
|
||||||
|
Latvijas Republikas Datu valsts inspekcijas vadlīnijas par
|
||||||
|
automatizētu lēmumu pieņemšanu — operators may override at any time.
|
||||||
|
standard: |
|
||||||
|
ITIL 4 — Incident Management practice; ISO/IEC 20000-1 — service
|
||||||
|
management taxonomy alignment.
|
||||||
|
|
||||||
|
limitations:
|
||||||
|
- Closed taxonomy of 9 codes — broader incident types fall to unknown.uncategorized.
|
||||||
|
- Latvian and English input supported; mixed-locale text may degrade confidence.
|
||||||
|
|
||||||
|
owners:
|
||||||
|
- type: team
|
||||||
|
id: openitsm-stewards
|
||||||
|
contact: stewards@openitsm.algomation.io
|
||||||
|
|
||||||
|
lifecycle:
|
||||||
|
status: draft
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- name: bgp-flap-network-routing
|
||||||
|
description: |
|
||||||
|
Edge router BGP session flapping — the classifier should pick
|
||||||
|
network.routing, not the broader network.outage.link_down.
|
||||||
|
inputs:
|
||||||
|
payload:
|
||||||
|
title: "BGP session flapping rtr-core-02 → AS6939"
|
||||||
|
host: "rtr-core-02.lvrtc.lv"
|
||||||
|
description: "BGP peer 198.51.100.1 toggled UP/DOWN 7 times in 12 minutes."
|
||||||
|
severity: "high"
|
||||||
|
expected_outputs:
|
||||||
|
taxonomy_code: "network.routing"
|
||||||
|
- name: customer-bandwidth-request
|
||||||
|
description: |
|
||||||
|
Latvian customer email asking for a bandwidth uplift — a
|
||||||
|
service.customer_request, not a network outage.
|
||||||
|
inputs:
|
||||||
|
payload:
|
||||||
|
title: "Klients SIA Latvija Tev: lūgums palielināt joslas platumu"
|
||||||
|
description: "Mūsu uzņēmumam nepieciešams palielināt internet pieslēguma joslas platumu no 100 Mbps uz 500 Mbps."
|
||||||
|
severity: "average"
|
||||||
|
expected_outputs:
|
||||||
|
taxonomy_code: "service.customer_request"
|
||||||
|
- name: ddos-volumetric
|
||||||
|
description: |
|
||||||
|
Volumetric UDP flood pattern — security.incident takes precedence
|
||||||
|
over generic network classifications even when the symptom is
|
||||||
|
network-shaped.
|
||||||
|
inputs:
|
||||||
|
payload:
|
||||||
|
title: "DDoS attack pattern detected on edge"
|
||||||
|
description: "Volumetric UDP flood, 4.2 Gbps inbound to 192.0.2.0/24."
|
||||||
|
severity: "critical"
|
||||||
|
expected_outputs:
|
||||||
|
taxonomy_code: "security.incident"
|
||||||
123
algorithms/draft_response.card.yaml
Normal file
123
algorithms/draft_response.card.yaml
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
kind: uapf.algorithm.card
|
||||||
|
id: algo.incident_triage.draft_response
|
||||||
|
version: 1.0.0
|
||||||
|
name: Customer response drafter
|
||||||
|
intent: |
|
||||||
|
Drafts a customer-facing incident notification in parallel Latvian
|
||||||
|
and English on behalf of LVRTC. Output is a PROPOSED AIDecision —
|
||||||
|
never auto-sent. Operator approval in the GUI is required before any
|
||||||
|
message leaves the system (guardrail approval.human_required_for
|
||||||
|
enforces this at runtime).
|
||||||
|
|
||||||
|
Tone: professional, calm, factual. Acknowledges the problem, states
|
||||||
|
that the team is investigating, gives an ETA only if known. Does NOT
|
||||||
|
promise specific resolutions. Uses proper Latvian diacritics. Bodies
|
||||||
|
capped at ~90 words each.
|
||||||
|
algorithm_kind: transformer
|
||||||
|
|
||||||
|
io:
|
||||||
|
inputs:
|
||||||
|
- id: case_id
|
||||||
|
type: string
|
||||||
|
cardinality: single
|
||||||
|
constraints:
|
||||||
|
pattern: "^[0-9a-fA-F-]{36}$"
|
||||||
|
- id: locale
|
||||||
|
type: string
|
||||||
|
constraints:
|
||||||
|
enum: [lv, en, auto]
|
||||||
|
documentation: |
|
||||||
|
'lv' or 'en' forces a single primary locale; 'auto' produces
|
||||||
|
both bodies and lets the operator choose. Default 'lv' for LVRTC.
|
||||||
|
- id: what_happened
|
||||||
|
type: string
|
||||||
|
documentation: One-line summary of the incident (used in subject + opening).
|
||||||
|
- id: eta_minutes
|
||||||
|
type: integer
|
||||||
|
cardinality: single
|
||||||
|
constraints:
|
||||||
|
minimum: 0
|
||||||
|
documentation: 'Optional. When provided, surfaced in body as \"Aptuvenais risināšanas laiks: X min\".'
|
||||||
|
outputs:
|
||||||
|
- id: subject_lv
|
||||||
|
type: string
|
||||||
|
- id: subject_en
|
||||||
|
type: string
|
||||||
|
- id: body_lv
|
||||||
|
type: string
|
||||||
|
documentation: Latvian body, proper diacritics, <=~90 words.
|
||||||
|
- id: body_en
|
||||||
|
type: string
|
||||||
|
documentation: English body, <=~90 words.
|
||||||
|
- id: locale
|
||||||
|
type: string
|
||||||
|
documentation: The locale code echoed back; informational.
|
||||||
|
|
||||||
|
implementation:
|
||||||
|
type: external
|
||||||
|
medium: mcp_tool
|
||||||
|
uri: uapf-ip://capability/ai.draft_response@1
|
||||||
|
hash: sha256:0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
runtime:
|
||||||
|
capability: ai.draft_response@1
|
||||||
|
note: |
|
||||||
|
Host-fulfilled UAPF-IP capability backed by the LLM gateway with
|
||||||
|
Anthropic as the default provider. The host enforces that the
|
||||||
|
resulting AIDecision row is PROPOSED (never AUTO_APPLIED) for
|
||||||
|
this capability. Operator approval moves it to APPROVED before
|
||||||
|
any outbound transport adapter is invoked.
|
||||||
|
|
||||||
|
determinism: stochastic
|
||||||
|
side_effects: pure
|
||||||
|
complexity:
|
||||||
|
typical_latency_ms: 1500
|
||||||
|
max_latency_ms: 60000
|
||||||
|
failure_mode: |
|
||||||
|
Returns deterministic stub drafts ("Mūsu komanda ir saņēmusi
|
||||||
|
paziņojumu...") with locale='lv' and a flag indicating LLM unavailability.
|
||||||
|
Operator can edit before approving.
|
||||||
|
|
||||||
|
reference:
|
||||||
|
legal: |
|
||||||
|
GDPR 2016/679 Article 13 — information to data subjects; LVRTC
|
||||||
|
customer-communication standards.
|
||||||
|
standard: |
|
||||||
|
ITIL 4 — Communication and Awareness practice during major incidents.
|
||||||
|
|
||||||
|
limitations:
|
||||||
|
- Cap of ~90 words per body — long incident narratives are truncated.
|
||||||
|
- Does not yet support Russian or other locales beyond lv/en.
|
||||||
|
|
||||||
|
owners:
|
||||||
|
- type: team
|
||||||
|
id: openitsm-stewards
|
||||||
|
contact: stewards@openitsm.algomation.io
|
||||||
|
|
||||||
|
lifecycle:
|
||||||
|
status: draft
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- name: link-down-with-eta
|
||||||
|
description: |
|
||||||
|
Edge link down with an ETA of 30 minutes. Both bodies should
|
||||||
|
acknowledge the outage and surface the ETA.
|
||||||
|
inputs:
|
||||||
|
case_id: "33333333-3333-3333-3333-333333333333"
|
||||||
|
locale: "auto"
|
||||||
|
what_happened: "Tīkla pārtraukums rtr-r1"
|
||||||
|
eta_minutes: 30
|
||||||
|
expected_outputs:
|
||||||
|
locale: "lv"
|
||||||
|
subject_lv: "[LVRTC] Informējam par incidentu"
|
||||||
|
subject_en: "[LVRTC] Incident notification"
|
||||||
|
- name: customer-request-no-eta
|
||||||
|
description: |
|
||||||
|
Customer-initiated request acknowledgement without an ETA.
|
||||||
|
inputs:
|
||||||
|
case_id: "44444444-4444-4444-4444-444444444444"
|
||||||
|
locale: "auto"
|
||||||
|
what_happened: "Klienta pieprasījums par joslas platumu"
|
||||||
|
expected_outputs:
|
||||||
|
locale: "lv"
|
||||||
|
subject_lv: "[LVRTC] Informējam par incidentu"
|
||||||
|
subject_en: "[LVRTC] Incident notification"
|
||||||
120
algorithms/emit_event.card.yaml
Normal file
120
algorithms/emit_event.card.yaml
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
kind: uapf.algorithm.card
|
||||||
|
id: algo.incident_triage.emit_event
|
||||||
|
version: 1.0.0
|
||||||
|
name: Case event emitter
|
||||||
|
intent: |
|
||||||
|
Appends a CaseEvent row to the case timeline. This is the canonical
|
||||||
|
way the BPMN signals "I completed a step" to the operator UI and to
|
||||||
|
the audit pipeline. Each event ends up as one row in case_events and
|
||||||
|
is also a candidate for VC signing (the VeriDocs SDK wraps a subset
|
||||||
|
of event types as Verifiable Credentials in Phase 1).
|
||||||
|
algorithm_kind: emitter
|
||||||
|
|
||||||
|
io:
|
||||||
|
inputs:
|
||||||
|
- id: case_id
|
||||||
|
type: string
|
||||||
|
cardinality: single
|
||||||
|
constraints:
|
||||||
|
pattern: "^[0-9a-fA-F-]{36}$"
|
||||||
|
- id: type
|
||||||
|
type: string
|
||||||
|
constraints:
|
||||||
|
enum:
|
||||||
|
- signal_attached
|
||||||
|
- status_changed
|
||||||
|
- triaged
|
||||||
|
- classified
|
||||||
|
- prioritized
|
||||||
|
- routed
|
||||||
|
- assigned
|
||||||
|
- ai_decision_recorded
|
||||||
|
- dmn_evaluated
|
||||||
|
- comment_added
|
||||||
|
- escalated
|
||||||
|
- resolved
|
||||||
|
- closed
|
||||||
|
documentation: Canonical event type. Used by the timeline filter pills in the operator UI.
|
||||||
|
- id: payload
|
||||||
|
type: object
|
||||||
|
documentation: |
|
||||||
|
Type-specific payload. For 'routed': {classification, priority,
|
||||||
|
ownership, group_slug}. For 'classified': {taxonomy_code,
|
||||||
|
confidence}. The schema per type is documented in the OpenITSM
|
||||||
|
case-events module.
|
||||||
|
- id: actor_label
|
||||||
|
type: string
|
||||||
|
documentation: |
|
||||||
|
Free-form actor identifier. For UAPF-driven events this is
|
||||||
|
typically 'uapf:lv.itsm.incident.triage'. For operator actions
|
||||||
|
it's 'operator:<user-slug>'.
|
||||||
|
outputs:
|
||||||
|
- id: event_id
|
||||||
|
type: string
|
||||||
|
documentation: UUID of the new CaseEvent row.
|
||||||
|
- id: recorded_at
|
||||||
|
type: string
|
||||||
|
documentation: ISO-8601 timestamp of the row insert (server clock).
|
||||||
|
|
||||||
|
implementation:
|
||||||
|
type: external
|
||||||
|
medium: mcp_tool
|
||||||
|
uri: uapf-ip://capability/event.emit@1
|
||||||
|
hash: sha256:0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
runtime:
|
||||||
|
capability: event.emit@1
|
||||||
|
note: |
|
||||||
|
Host-fulfilled UAPF-IP capability. Append-only — the host's
|
||||||
|
CaseEvent table has no UPDATE or DELETE paths exposed to UAPF
|
||||||
|
callers. The same row may later have a VC reference attached
|
||||||
|
by the VeriDocs SDK pipeline.
|
||||||
|
|
||||||
|
determinism: deterministic
|
||||||
|
side_effects: writes_state
|
||||||
|
complexity:
|
||||||
|
typical_latency_ms: 8
|
||||||
|
max_latency_ms: 2000
|
||||||
|
failure_mode: |
|
||||||
|
Throws on unknown event type or missing case_id. Caller in the
|
||||||
|
triage BPMN treats failure as soft — the case still ends in its
|
||||||
|
decided state, just without the closing 'routed' marker.
|
||||||
|
|
||||||
|
owners:
|
||||||
|
- type: team
|
||||||
|
id: openitsm-stewards
|
||||||
|
contact: stewards@openitsm.algomation.io
|
||||||
|
|
||||||
|
lifecycle:
|
||||||
|
status: draft
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- name: routed-event
|
||||||
|
description: |
|
||||||
|
Standard 'routed' event at the end of triage. Payload echoes the
|
||||||
|
classification, priority, ownership, group_slug decided upstream.
|
||||||
|
inputs:
|
||||||
|
case_id: "99999999-9999-9999-9999-999999999999"
|
||||||
|
type: "routed"
|
||||||
|
payload:
|
||||||
|
classification: "security.incident"
|
||||||
|
priority: "P1"
|
||||||
|
ownership: "lvrtc"
|
||||||
|
group_slug: "soc-l2"
|
||||||
|
actor_label: "uapf:lv.itsm.incident.triage"
|
||||||
|
expected_outputs:
|
||||||
|
recorded_at: "any-iso-timestamp"
|
||||||
|
- name: ai-decision-recorded
|
||||||
|
description: |
|
||||||
|
AI decision recording — payload carries the AIDecision row id so
|
||||||
|
operators can click through to the proposal.
|
||||||
|
inputs:
|
||||||
|
case_id: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
|
||||||
|
type: "ai_decision_recorded"
|
||||||
|
payload:
|
||||||
|
capability: "ai.draft_response"
|
||||||
|
decision_id: "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
|
||||||
|
confidence: 0.7
|
||||||
|
requires_human_approval: true
|
||||||
|
actor_label: "uapf:lv.itsm.incident.triage"
|
||||||
|
expected_outputs:
|
||||||
|
recorded_at: "any-iso-timestamp"
|
||||||
111
algorithms/evaluate_dmn.card.yaml
Normal file
111
algorithms/evaluate_dmn.card.yaml
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
kind: uapf.algorithm.card
|
||||||
|
id: algo.incident_triage.evaluate_dmn
|
||||||
|
version: 1.0.0
|
||||||
|
name: DMN decision evaluator
|
||||||
|
intent: |
|
||||||
|
Wraps a DMN 1.3 decision-table evaluation as a callable UAPF-IP
|
||||||
|
capability. The triage BPMN invokes the three DMN tables in this
|
||||||
|
package (priority, ownership, routing) natively via businessRuleTask;
|
||||||
|
this card describes the dmn.evaluate@1 capability for cases where the
|
||||||
|
same evaluation is needed outside the BPMN runtime (operator manual
|
||||||
|
re-evaluation, batch backfill, regression testing).
|
||||||
|
|
||||||
|
Engine-internal DMN evaluation and this capability call return the
|
||||||
|
same output for the same input — that property is the only thing
|
||||||
|
this card asserts.
|
||||||
|
algorithm_kind: rule_table
|
||||||
|
|
||||||
|
io:
|
||||||
|
inputs:
|
||||||
|
- id: package_id
|
||||||
|
type: string
|
||||||
|
documentation: UAPF package id whose dmn/ cornerstone holds the table.
|
||||||
|
- id: decision_id
|
||||||
|
type: string
|
||||||
|
constraints:
|
||||||
|
enum: [priority, ownership, routing]
|
||||||
|
documentation: Which DMN decision to evaluate in this package.
|
||||||
|
- id: inputs
|
||||||
|
type: object
|
||||||
|
documentation: |
|
||||||
|
Decision-input columns as a flat object. For priority:
|
||||||
|
{severity, service_tier, ai_suggested_priority, classification}.
|
||||||
|
For ownership: {classification, host_domain, source}.
|
||||||
|
For routing: {classification, priority, ownership}.
|
||||||
|
outputs:
|
||||||
|
- id: output
|
||||||
|
type: object
|
||||||
|
documentation: |
|
||||||
|
Object with the decision-output columns. priority -> {priority}.
|
||||||
|
ownership -> {ownership}. routing -> {group_slug}.
|
||||||
|
- id: hit_rule_ids
|
||||||
|
type: array
|
||||||
|
documentation: Rule ids that matched (FIRST hit-policy produces 1; ANY may produce N).
|
||||||
|
- id: hit_policy
|
||||||
|
type: string
|
||||||
|
constraints:
|
||||||
|
enum: [FIRST, UNIQUE, ANY, PRIORITY, OUTPUT_ORDER, COLLECT, RULE_ORDER]
|
||||||
|
|
||||||
|
implementation:
|
||||||
|
type: external
|
||||||
|
medium: mcp_tool
|
||||||
|
uri: uapf-ip://capability/dmn.evaluate@1
|
||||||
|
hash: sha256:0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
runtime:
|
||||||
|
capability: dmn.evaluate@1
|
||||||
|
note: |
|
||||||
|
Host-fulfilled UAPF-IP capability. The OpenITSM host reads the
|
||||||
|
DMN file from the package's dmn/ cornerstone and applies the
|
||||||
|
DMN 1.3 hit-policy semantics. Same decision artifact, same
|
||||||
|
output as the in-process engine evaluation.
|
||||||
|
|
||||||
|
determinism: deterministic
|
||||||
|
side_effects: pure
|
||||||
|
complexity:
|
||||||
|
typical_latency_ms: 5
|
||||||
|
max_latency_ms: 5000
|
||||||
|
failure_mode: |
|
||||||
|
Throws if the requested package_id is not loaded by the runtime, or
|
||||||
|
if the named decision_id is not present in that package's dmn/
|
||||||
|
directory. Triage callers fall back to safe defaults (P4, lvrtc,
|
||||||
|
helpdesk-l1) so the case still completes.
|
||||||
|
|
||||||
|
owners:
|
||||||
|
- type: team
|
||||||
|
id: openitsm-stewards
|
||||||
|
contact: stewards@openitsm.algomation.io
|
||||||
|
|
||||||
|
lifecycle:
|
||||||
|
status: draft
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- name: priority-critical-tier1
|
||||||
|
description: |
|
||||||
|
The priority table should rule P1 for a critical+tier_1 input
|
||||||
|
regardless of AI suggestion.
|
||||||
|
inputs:
|
||||||
|
package_id: "lv.itsm.incident.triage"
|
||||||
|
decision_id: "priority"
|
||||||
|
inputs:
|
||||||
|
severity: "critical"
|
||||||
|
service_tier: "tier_1"
|
||||||
|
ai_suggested_priority: "P3"
|
||||||
|
classification: "network.outage.link_down"
|
||||||
|
expected_outputs:
|
||||||
|
output:
|
||||||
|
priority: "P1"
|
||||||
|
hit_policy: "FIRST"
|
||||||
|
- name: routing-security-to-soc
|
||||||
|
description: |
|
||||||
|
Routing of a security.incident at P1 should land on soc-l2.
|
||||||
|
inputs:
|
||||||
|
package_id: "lv.itsm.incident.triage"
|
||||||
|
decision_id: "routing"
|
||||||
|
inputs:
|
||||||
|
classification: "security.incident"
|
||||||
|
priority: "P1"
|
||||||
|
ownership: "lvrtc"
|
||||||
|
expected_outputs:
|
||||||
|
output:
|
||||||
|
group_slug: "soc-l2"
|
||||||
|
hit_policy: "FIRST"
|
||||||
91
algorithms/normalize_signal.card.yaml
Normal file
91
algorithms/normalize_signal.card.yaml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
kind: uapf.algorithm.card
|
||||||
|
id: algo.incident_triage.normalize_signal
|
||||||
|
version: 1.0.0
|
||||||
|
name: Signal normalizer
|
||||||
|
intent: |
|
||||||
|
Reads a freshly-received Signal row by id and folds the
|
||||||
|
source-specific payload (Zabbix event, IMAP email, Jira DC issue,
|
||||||
|
manual entry) into a single normalised shape with the fields
|
||||||
|
downstream cards expect: title, description, host, severity, source
|
||||||
|
hint, optional contact metadata, and a content-hash for dedupe.
|
||||||
|
Idempotent; safe to re-run.
|
||||||
|
algorithm_kind: transformer
|
||||||
|
|
||||||
|
io:
|
||||||
|
inputs:
|
||||||
|
- id: signal_id
|
||||||
|
type: string
|
||||||
|
cardinality: single
|
||||||
|
constraints:
|
||||||
|
pattern: "^[0-9a-fA-F-]{36}$"
|
||||||
|
documentation: UUID of the Signal row to normalise.
|
||||||
|
outputs:
|
||||||
|
- id: normalized_payload
|
||||||
|
type: object
|
||||||
|
documentation: |
|
||||||
|
Adapter-agnostic dictionary. Stable keys: title, description,
|
||||||
|
host, severity (one of disaster|high|critical|average|warning|low|info),
|
||||||
|
source, source_event_id, optional received_at, optional contact_email.
|
||||||
|
- id: dedupe_hash
|
||||||
|
type: string
|
||||||
|
documentation: SHA-256 hex over (source, source_event_id, host) used to suppress repeat signals.
|
||||||
|
- id: source_kind
|
||||||
|
type: string
|
||||||
|
documentation: One of zabbix|email|jira_dc|jira_cloud|manual|cti.
|
||||||
|
|
||||||
|
implementation:
|
||||||
|
type: external
|
||||||
|
medium: mcp_tool
|
||||||
|
uri: uapf-ip://capability/intake.normalize@1
|
||||||
|
hash: sha256:0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
runtime:
|
||||||
|
capability: intake.normalize@1
|
||||||
|
note: |
|
||||||
|
Host-fulfilled UAPF-IP capability. The OpenITSM host's
|
||||||
|
intake.normalize handler implements one normaliser per source.
|
||||||
|
Hash is a placeholder until the runtime publishes the
|
||||||
|
implementation hash.
|
||||||
|
|
||||||
|
determinism: deterministic
|
||||||
|
side_effects: pure
|
||||||
|
complexity:
|
||||||
|
typical_latency_ms: 30
|
||||||
|
max_latency_ms: 2000
|
||||||
|
failure_mode: |
|
||||||
|
Returns source_kind='unknown' with whatever raw_payload was available
|
||||||
|
on the signal row. Triage continues with best-effort classification.
|
||||||
|
|
||||||
|
owners:
|
||||||
|
- type: team
|
||||||
|
id: openitsm-stewards
|
||||||
|
contact: stewards@openitsm.algomation.io
|
||||||
|
|
||||||
|
lifecycle:
|
||||||
|
status: draft
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- name: zabbix-link-down
|
||||||
|
description: |
|
||||||
|
Zabbix event for a transport-link outage on an edge router.
|
||||||
|
Title, host and severity are normalised from the raw event shape.
|
||||||
|
inputs:
|
||||||
|
signal_id: "11111111-1111-1111-1111-111111111111"
|
||||||
|
expected_outputs:
|
||||||
|
source_kind: "zabbix"
|
||||||
|
normalized_payload:
|
||||||
|
title: "Link down on edge router rtr-r1"
|
||||||
|
host: "rtr-r1.lvrtc.lv"
|
||||||
|
severity: "high"
|
||||||
|
source: "zabbix"
|
||||||
|
- name: email-customer-lv
|
||||||
|
description: |
|
||||||
|
Customer-facing Latvian-language email about a bandwidth uplift
|
||||||
|
request. Subject becomes title; body becomes description.
|
||||||
|
inputs:
|
||||||
|
signal_id: "22222222-2222-2222-2222-222222222222"
|
||||||
|
expected_outputs:
|
||||||
|
source_kind: "email"
|
||||||
|
normalized_payload:
|
||||||
|
title: "Klients SIA Latvija Tev: lūgums palielināt joslas platumu"
|
||||||
|
severity: "average"
|
||||||
|
source: "email"
|
||||||
98
algorithms/suggest_priority.card.yaml
Normal file
98
algorithms/suggest_priority.card.yaml
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
kind: uapf.algorithm.card
|
||||||
|
id: algo.incident_triage.suggest_priority
|
||||||
|
version: 1.0.0
|
||||||
|
name: Priority suggester
|
||||||
|
intent: |
|
||||||
|
Reads the classified incident plus its service-tier and reported
|
||||||
|
severity and proposes a priority on the P1..P4 scale. This output is
|
||||||
|
a SOFT suggestion only — the priority DMN table makes the binding
|
||||||
|
decision, with this suggestion as one of its four input columns.
|
||||||
|
Separating "AI suggestion" from "binding decision" keeps the AI
|
||||||
|
contestable and the auditor's job tractable.
|
||||||
|
algorithm_kind: classifier
|
||||||
|
|
||||||
|
io:
|
||||||
|
inputs:
|
||||||
|
- id: severity
|
||||||
|
type: string
|
||||||
|
constraints:
|
||||||
|
enum: [disaster, critical, high, average, warning, low, info]
|
||||||
|
documentation: Source-reported severity (Zabbix verbatim; normalised for other adapters).
|
||||||
|
- id: service_tier
|
||||||
|
type: string
|
||||||
|
constraints:
|
||||||
|
enum: [tier_1, tier_2, best_effort]
|
||||||
|
documentation: Service tier of the affected service (from the connection or host catalog).
|
||||||
|
- id: classification
|
||||||
|
type: string
|
||||||
|
documentation: |
|
||||||
|
Taxonomy code from ai.classify@1. The suggester applies a fixed
|
||||||
|
elevation for security.incident regardless of severity.
|
||||||
|
outputs:
|
||||||
|
- id: priority
|
||||||
|
type: string
|
||||||
|
constraints:
|
||||||
|
enum: [P1, P2, P3, P4]
|
||||||
|
- id: reason
|
||||||
|
type: string
|
||||||
|
documentation: One-sentence justification (English). Visible to operator.
|
||||||
|
|
||||||
|
implementation:
|
||||||
|
type: external
|
||||||
|
medium: mcp_tool
|
||||||
|
uri: uapf-ip://capability/ai.suggest_priority@1
|
||||||
|
hash: sha256:0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
runtime:
|
||||||
|
capability: ai.suggest_priority@1
|
||||||
|
note: |
|
||||||
|
Host-fulfilled UAPF-IP capability. The OpenITSM host can answer
|
||||||
|
via either the LLM gateway or a deterministic rule. The DMN
|
||||||
|
priority table downstream applies a binding decision on top.
|
||||||
|
|
||||||
|
determinism: stochastic
|
||||||
|
side_effects: pure
|
||||||
|
complexity:
|
||||||
|
typical_latency_ms: 600
|
||||||
|
max_latency_ms: 30000
|
||||||
|
failure_mode: |
|
||||||
|
Returns priority='P4' with reason='LLM unavailable, defaulted'. The
|
||||||
|
binding DMN can still raise the priority based on severity x tier.
|
||||||
|
|
||||||
|
owners:
|
||||||
|
- type: team
|
||||||
|
id: openitsm-stewards
|
||||||
|
contact: stewards@openitsm.algomation.io
|
||||||
|
|
||||||
|
lifecycle:
|
||||||
|
status: draft
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- name: disaster-on-tier1-is-p1
|
||||||
|
description: |
|
||||||
|
Disaster severity on a tier_1 service is always P1 regardless of
|
||||||
|
classification.
|
||||||
|
inputs:
|
||||||
|
severity: "disaster"
|
||||||
|
service_tier: "tier_1"
|
||||||
|
classification: "network.outage.link_down"
|
||||||
|
expected_outputs:
|
||||||
|
priority: "P1"
|
||||||
|
- name: security-incident-elevates
|
||||||
|
description: |
|
||||||
|
Security incidents elevate to P1 regardless of severity field.
|
||||||
|
inputs:
|
||||||
|
severity: "average"
|
||||||
|
service_tier: "tier_2"
|
||||||
|
classification: "security.incident"
|
||||||
|
expected_outputs:
|
||||||
|
priority: "P1"
|
||||||
|
- name: customer-request-low
|
||||||
|
description: |
|
||||||
|
A customer service request on best_effort tier is P4 unless
|
||||||
|
escalated by an operator.
|
||||||
|
inputs:
|
||||||
|
severity: "info"
|
||||||
|
service_tier: "best_effort"
|
||||||
|
classification: "service.customer_request"
|
||||||
|
expected_outputs:
|
||||||
|
priority: "P4"
|
||||||
122
algorithms/update_incident.card.yaml
Normal file
122
algorithms/update_incident.card.yaml
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
kind: uapf.algorithm.card
|
||||||
|
id: algo.incident_triage.update_incident
|
||||||
|
version: 1.0.0
|
||||||
|
name: Incident updater
|
||||||
|
intent: |
|
||||||
|
Applies a patch to the Case row (priority, ownership, assigned_group_id,
|
||||||
|
taxonomy_code) and optionally transitions the FSM (open -> triaged,
|
||||||
|
triaged -> in_progress, etc). Every transition emits a CaseEvent so
|
||||||
|
the timeline reflects the change. Refuses illegal transitions per the
|
||||||
|
state machine in OpenITSM's services/incident.py module — the engine
|
||||||
|
treats the resulting error as a hard failure.
|
||||||
|
algorithm_kind: emitter
|
||||||
|
|
||||||
|
io:
|
||||||
|
inputs:
|
||||||
|
- id: case_id
|
||||||
|
type: string
|
||||||
|
cardinality: single
|
||||||
|
constraints:
|
||||||
|
pattern: "^[0-9a-fA-F-]{36}$"
|
||||||
|
- id: patch
|
||||||
|
type: object
|
||||||
|
documentation: |
|
||||||
|
Subset of writable case fields. Allowed keys: priority,
|
||||||
|
ownership, assigned_group_id, taxonomy_code, sla_breached,
|
||||||
|
operator_notes. Unknown keys are rejected.
|
||||||
|
- id: status
|
||||||
|
type: string
|
||||||
|
constraints:
|
||||||
|
enum: [open, triaged, in_progress, waiting_customer, waiting_third_party, resolved, closed, cancelled]
|
||||||
|
documentation: |
|
||||||
|
Optional target status. If absent, only field updates are applied.
|
||||||
|
If present, an FSM transition is attempted; illegal transitions
|
||||||
|
raise.
|
||||||
|
- id: reason
|
||||||
|
type: string
|
||||||
|
documentation: Human-readable reason recorded on the CaseEvent.
|
||||||
|
outputs:
|
||||||
|
- id: case_id
|
||||||
|
type: string
|
||||||
|
- id: new_status
|
||||||
|
type: string
|
||||||
|
documentation: The case status after the call (unchanged if status input was absent).
|
||||||
|
- id: success
|
||||||
|
type: boolean
|
||||||
|
- id: event_ids
|
||||||
|
type: array
|
||||||
|
documentation: CaseEvent row ids emitted by this call.
|
||||||
|
|
||||||
|
implementation:
|
||||||
|
type: external
|
||||||
|
medium: mcp_tool
|
||||||
|
uri: uapf-ip://capability/incident.update@1
|
||||||
|
hash: sha256:0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
runtime:
|
||||||
|
capability: incident.update@1
|
||||||
|
note: |
|
||||||
|
Host-fulfilled UAPF-IP capability. The OpenITSM host validates
|
||||||
|
the patch against the writable-field allowlist and runs FSM
|
||||||
|
transitions through services/incident.transition_case. All
|
||||||
|
mutations happen in a single DB transaction with the emitted
|
||||||
|
CaseEvent rows.
|
||||||
|
|
||||||
|
determinism: deterministic
|
||||||
|
side_effects: writes_state
|
||||||
|
complexity:
|
||||||
|
typical_latency_ms: 25
|
||||||
|
max_latency_ms: 5000
|
||||||
|
failure_mode: |
|
||||||
|
Illegal FSM transition or unknown patch key throws and the entire
|
||||||
|
call is rolled back. Triage callers do NOT proceed past this step on
|
||||||
|
failure — the case stays at its prior status.
|
||||||
|
|
||||||
|
reference:
|
||||||
|
legal: |
|
||||||
|
Latvian National Standard for ITSM (LVS EN ISO/IEC 20000-1).
|
||||||
|
standard: |
|
||||||
|
ITIL 4 — Incident Management state machine.
|
||||||
|
|
||||||
|
owners:
|
||||||
|
- type: team
|
||||||
|
id: openitsm-stewards
|
||||||
|
contact: stewards@openitsm.algomation.io
|
||||||
|
|
||||||
|
lifecycle:
|
||||||
|
status: draft
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- name: open-to-triaged-with-priority
|
||||||
|
description: |
|
||||||
|
Open case gets a priority + assigned group and transitions to triaged.
|
||||||
|
inputs:
|
||||||
|
case_id: "55555555-5555-5555-5555-555555555555"
|
||||||
|
patch:
|
||||||
|
priority: "P1"
|
||||||
|
ownership: "lvrtc"
|
||||||
|
assigned_group_id: "66666666-6666-6666-6666-666666666666"
|
||||||
|
status: "triaged"
|
||||||
|
reason: "Auto-triaged by lv.itsm.incident.triage v1.0.0"
|
||||||
|
expected_outputs:
|
||||||
|
success: true
|
||||||
|
new_status: "triaged"
|
||||||
|
- name: patch-only-no-transition
|
||||||
|
description: |
|
||||||
|
Patch without a status input updates fields but leaves the FSM
|
||||||
|
state alone.
|
||||||
|
inputs:
|
||||||
|
case_id: "77777777-7777-7777-7777-777777777777"
|
||||||
|
patch:
|
||||||
|
operator_notes: "Customer called to follow up"
|
||||||
|
reason: "Operator note added"
|
||||||
|
expected_outputs:
|
||||||
|
success: true
|
||||||
|
- name: illegal-transition-throws
|
||||||
|
description: |
|
||||||
|
Closed cases cannot return to in_progress; the capability fails.
|
||||||
|
inputs:
|
||||||
|
case_id: "88888888-8888-8888-8888-888888888888"
|
||||||
|
status: "in_progress"
|
||||||
|
reason: "Attempting to reopen a closed case"
|
||||||
|
expected_outputs:
|
||||||
|
success: false
|
||||||
274
bpmn/incident-triage.bpmn
Normal file
274
bpmn/incident-triage.bpmn
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn:definitions
|
||||||
|
xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
|
||||||
|
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
|
||||||
|
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
|
||||||
|
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
|
||||||
|
xmlns:uapf="https://uapf.dev/bpmn-ext/v1"
|
||||||
|
xmlns:uapf24="https://uapf.dev/bpmn/v2.4"
|
||||||
|
id="Definitions_IncidentTriage"
|
||||||
|
targetNamespace="https://uapf.dev/processes/lv.itsm.incident.triage"
|
||||||
|
exporter="openitsm-uapf-generator" exporterVersion="1.0.0">
|
||||||
|
<bpmn:process id="Process_IncidentTriage" name="Incident Triage" isExecutable="true">
|
||||||
|
<bpmn:documentation>
|
||||||
|
Linear UAPF process invoked by OpenITSM intake. Each step is a host-fulfilled
|
||||||
|
UAPF-IP capability call governed by an Algorithm Card under algorithms/.
|
||||||
|
The three dmn.evaluate@1 invocations read priority.dmn / ownership.dmn /
|
||||||
|
routing.dmn from the package's dmn/ cornerstone.
|
||||||
|
</bpmn:documentation>
|
||||||
|
<bpmn:startEvent id="Start" name="Signal received">
|
||||||
|
<bpmn:outgoing>Flow_01</bpmn:outgoing>
|
||||||
|
</bpmn:startEvent>
|
||||||
|
<bpmn:serviceTask id="Task_NormalizeSignal"
|
||||||
|
name="Normalize signal"
|
||||||
|
uapf:capability="intake.normalize@1"
|
||||||
|
uapf24:algorithmCardRef="algo.incident_triage.normalize_signal">
|
||||||
|
<bpmn:documentation>Reads the freshly-received Signal row and folds the source-specific payload (Zabbix / IMAP / Jira / manual) into a uniform shape downstream cards expect.</bpmn:documentation>
|
||||||
|
<bpmn:incoming>Flow_01</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_02</bpmn:outgoing>
|
||||||
|
<bpmn:ioSpecification>
|
||||||
|
<bpmn:dataInput id="Task_NormalizeSignal_in_signal_id" name="signal_id : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_NormalizeSignal_out_normalized_payload" name="normalized_payload : object"/>
|
||||||
|
<bpmn:dataOutput id="Task_NormalizeSignal_out_dedupe_hash" name="dedupe_hash : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_NormalizeSignal_out_source_kind" name="source_kind : string"/>
|
||||||
|
<bpmn:inputSet>
|
||||||
|
<bpmn:dataInputRefs>Task_NormalizeSignal_in_signal_id</bpmn:dataInputRefs>
|
||||||
|
</bpmn:inputSet>
|
||||||
|
<bpmn:outputSet>
|
||||||
|
<bpmn:dataOutputRefs>Task_NormalizeSignal_out_normalized_payload</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_NormalizeSignal_out_dedupe_hash</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_NormalizeSignal_out_source_kind</bpmn:dataOutputRefs>
|
||||||
|
</bpmn:outputSet>
|
||||||
|
</bpmn:ioSpecification>
|
||||||
|
</bpmn:serviceTask>
|
||||||
|
<bpmn:serviceTask id="Task_ClassifyIncident"
|
||||||
|
name="Classify incident"
|
||||||
|
uapf:capability="ai.classify@1"
|
||||||
|
uapf24:algorithmCardRef="algo.incident_triage.classify_incident">
|
||||||
|
<bpmn:documentation>Picks one taxonomy code from a closed list. LLM-backed at runtime with deterministic regex fallback.</bpmn:documentation>
|
||||||
|
<bpmn:incoming>Flow_02</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_03</bpmn:outgoing>
|
||||||
|
<bpmn:ioSpecification>
|
||||||
|
<bpmn:dataInput id="Task_ClassifyIncident_in_payload" name="payload : object"/>
|
||||||
|
<bpmn:dataInput id="Task_ClassifyIncident_in_text" name="text : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_ClassifyIncident_out_taxonomy_code" name="taxonomy_code : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_ClassifyIncident_out_confidence" name="confidence : number"/>
|
||||||
|
<bpmn:dataOutput id="Task_ClassifyIncident_out_reasoning" name="reasoning : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_ClassifyIncident_out_label_hint" name="label_hint : string"/>
|
||||||
|
<bpmn:inputSet>
|
||||||
|
<bpmn:dataInputRefs>Task_ClassifyIncident_in_payload</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_ClassifyIncident_in_text</bpmn:dataInputRefs>
|
||||||
|
</bpmn:inputSet>
|
||||||
|
<bpmn:outputSet>
|
||||||
|
<bpmn:dataOutputRefs>Task_ClassifyIncident_out_taxonomy_code</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_ClassifyIncident_out_confidence</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_ClassifyIncident_out_reasoning</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_ClassifyIncident_out_label_hint</bpmn:dataOutputRefs>
|
||||||
|
</bpmn:outputSet>
|
||||||
|
</bpmn:ioSpecification>
|
||||||
|
</bpmn:serviceTask>
|
||||||
|
<bpmn:serviceTask id="Task_SuggestPriority"
|
||||||
|
name="Suggest priority"
|
||||||
|
uapf:capability="ai.suggest_priority@1"
|
||||||
|
uapf24:algorithmCardRef="algo.incident_triage.suggest_priority">
|
||||||
|
<bpmn:documentation>Soft P1..P4 suggestion from severity x service_tier x classification. The downstream DMN makes the binding decision.</bpmn:documentation>
|
||||||
|
<bpmn:incoming>Flow_03</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_04</bpmn:outgoing>
|
||||||
|
<bpmn:ioSpecification>
|
||||||
|
<bpmn:dataInput id="Task_SuggestPriority_in_severity" name="severity : string"/>
|
||||||
|
<bpmn:dataInput id="Task_SuggestPriority_in_service_tier" name="service_tier : string"/>
|
||||||
|
<bpmn:dataInput id="Task_SuggestPriority_in_classification" name="classification : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_SuggestPriority_out_priority" name="priority : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_SuggestPriority_out_reason" name="reason : string"/>
|
||||||
|
<bpmn:inputSet>
|
||||||
|
<bpmn:dataInputRefs>Task_SuggestPriority_in_severity</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_SuggestPriority_in_service_tier</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_SuggestPriority_in_classification</bpmn:dataInputRefs>
|
||||||
|
</bpmn:inputSet>
|
||||||
|
<bpmn:outputSet>
|
||||||
|
<bpmn:dataOutputRefs>Task_SuggestPriority_out_priority</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_SuggestPriority_out_reason</bpmn:dataOutputRefs>
|
||||||
|
</bpmn:outputSet>
|
||||||
|
</bpmn:ioSpecification>
|
||||||
|
</bpmn:serviceTask>
|
||||||
|
<bpmn:serviceTask id="Task_EvaluatePriorityDmn"
|
||||||
|
name="Evaluate priority DMN"
|
||||||
|
uapf:capability="dmn.evaluate@1"
|
||||||
|
uapf24:algorithmCardRef="algo.incident_triage.evaluate_dmn">
|
||||||
|
<bpmn:documentation>Binding priority decision: FIRST-hit DMN over severity, service_tier, ai_suggested_priority, classification.</bpmn:documentation>
|
||||||
|
<bpmn:incoming>Flow_04</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_05</bpmn:outgoing>
|
||||||
|
<bpmn:ioSpecification>
|
||||||
|
<bpmn:dataInput id="Task_EvaluatePriorityDmn_in_package_id" name="package_id : string"/>
|
||||||
|
<bpmn:dataInput id="Task_EvaluatePriorityDmn_in_decision_id" name="decision_id : string"/>
|
||||||
|
<bpmn:dataInput id="Task_EvaluatePriorityDmn_in_inputs" name="inputs : object"/>
|
||||||
|
<bpmn:dataOutput id="Task_EvaluatePriorityDmn_out_output" name="output : object"/>
|
||||||
|
<bpmn:dataOutput id="Task_EvaluatePriorityDmn_out_hit_rule_ids" name="hit_rule_ids : array"/>
|
||||||
|
<bpmn:dataOutput id="Task_EvaluatePriorityDmn_out_hit_policy" name="hit_policy : string"/>
|
||||||
|
<bpmn:inputSet>
|
||||||
|
<bpmn:dataInputRefs>Task_EvaluatePriorityDmn_in_package_id</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_EvaluatePriorityDmn_in_decision_id</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_EvaluatePriorityDmn_in_inputs</bpmn:dataInputRefs>
|
||||||
|
</bpmn:inputSet>
|
||||||
|
<bpmn:outputSet>
|
||||||
|
<bpmn:dataOutputRefs>Task_EvaluatePriorityDmn_out_output</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_EvaluatePriorityDmn_out_hit_rule_ids</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_EvaluatePriorityDmn_out_hit_policy</bpmn:dataOutputRefs>
|
||||||
|
</bpmn:outputSet>
|
||||||
|
</bpmn:ioSpecification>
|
||||||
|
</bpmn:serviceTask>
|
||||||
|
<bpmn:serviceTask id="Task_EvaluateOwnershipDmn"
|
||||||
|
name="Evaluate ownership DMN"
|
||||||
|
uapf:capability="dmn.evaluate@1"
|
||||||
|
uapf24:algorithmCardRef="algo.incident_triage.evaluate_dmn">
|
||||||
|
<bpmn:documentation>Binding ownership decision: stay inside LVRTC or hand off externally based on classification + host_domain + source.</bpmn:documentation>
|
||||||
|
<bpmn:incoming>Flow_05</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_06</bpmn:outgoing>
|
||||||
|
<bpmn:ioSpecification>
|
||||||
|
<bpmn:dataInput id="Task_EvaluateOwnershipDmn_in_package_id" name="package_id : string"/>
|
||||||
|
<bpmn:dataInput id="Task_EvaluateOwnershipDmn_in_decision_id" name="decision_id : string"/>
|
||||||
|
<bpmn:dataInput id="Task_EvaluateOwnershipDmn_in_inputs" name="inputs : object"/>
|
||||||
|
<bpmn:dataOutput id="Task_EvaluateOwnershipDmn_out_output" name="output : object"/>
|
||||||
|
<bpmn:dataOutput id="Task_EvaluateOwnershipDmn_out_hit_rule_ids" name="hit_rule_ids : array"/>
|
||||||
|
<bpmn:dataOutput id="Task_EvaluateOwnershipDmn_out_hit_policy" name="hit_policy : string"/>
|
||||||
|
<bpmn:inputSet>
|
||||||
|
<bpmn:dataInputRefs>Task_EvaluateOwnershipDmn_in_package_id</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_EvaluateOwnershipDmn_in_decision_id</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_EvaluateOwnershipDmn_in_inputs</bpmn:dataInputRefs>
|
||||||
|
</bpmn:inputSet>
|
||||||
|
<bpmn:outputSet>
|
||||||
|
<bpmn:dataOutputRefs>Task_EvaluateOwnershipDmn_out_output</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_EvaluateOwnershipDmn_out_hit_rule_ids</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_EvaluateOwnershipDmn_out_hit_policy</bpmn:dataOutputRefs>
|
||||||
|
</bpmn:outputSet>
|
||||||
|
</bpmn:ioSpecification>
|
||||||
|
</bpmn:serviceTask>
|
||||||
|
<bpmn:serviceTask id="Task_EvaluateRoutingDmn"
|
||||||
|
name="Evaluate routing DMN"
|
||||||
|
uapf:capability="dmn.evaluate@1"
|
||||||
|
uapf24:algorithmCardRef="algo.incident_triage.evaluate_dmn">
|
||||||
|
<bpmn:documentation>Picks the expert group (helpdesk-l1, noc-l1/l2, soc-l2, facility-l2, platform-l2, external-handoff) from classification + priority + ownership.</bpmn:documentation>
|
||||||
|
<bpmn:incoming>Flow_06</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_07</bpmn:outgoing>
|
||||||
|
<bpmn:ioSpecification>
|
||||||
|
<bpmn:dataInput id="Task_EvaluateRoutingDmn_in_package_id" name="package_id : string"/>
|
||||||
|
<bpmn:dataInput id="Task_EvaluateRoutingDmn_in_decision_id" name="decision_id : string"/>
|
||||||
|
<bpmn:dataInput id="Task_EvaluateRoutingDmn_in_inputs" name="inputs : object"/>
|
||||||
|
<bpmn:dataOutput id="Task_EvaluateRoutingDmn_out_output" name="output : object"/>
|
||||||
|
<bpmn:dataOutput id="Task_EvaluateRoutingDmn_out_hit_rule_ids" name="hit_rule_ids : array"/>
|
||||||
|
<bpmn:dataOutput id="Task_EvaluateRoutingDmn_out_hit_policy" name="hit_policy : string"/>
|
||||||
|
<bpmn:inputSet>
|
||||||
|
<bpmn:dataInputRefs>Task_EvaluateRoutingDmn_in_package_id</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_EvaluateRoutingDmn_in_decision_id</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_EvaluateRoutingDmn_in_inputs</bpmn:dataInputRefs>
|
||||||
|
</bpmn:inputSet>
|
||||||
|
<bpmn:outputSet>
|
||||||
|
<bpmn:dataOutputRefs>Task_EvaluateRoutingDmn_out_output</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_EvaluateRoutingDmn_out_hit_rule_ids</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_EvaluateRoutingDmn_out_hit_policy</bpmn:dataOutputRefs>
|
||||||
|
</bpmn:outputSet>
|
||||||
|
</bpmn:ioSpecification>
|
||||||
|
</bpmn:serviceTask>
|
||||||
|
<bpmn:serviceTask id="Task_UpdateIncident"
|
||||||
|
name="Update incident state"
|
||||||
|
uapf:capability="incident.update@1"
|
||||||
|
uapf24:algorithmCardRef="algo.incident_triage.update_incident">
|
||||||
|
<bpmn:documentation>Applies the decided priority + ownership + assigned_group_id and transitions open -> triaged. All mutations in one DB transaction.</bpmn:documentation>
|
||||||
|
<bpmn:incoming>Flow_07</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_08</bpmn:outgoing>
|
||||||
|
<bpmn:ioSpecification>
|
||||||
|
<bpmn:dataInput id="Task_UpdateIncident_in_case_id" name="case_id : string"/>
|
||||||
|
<bpmn:dataInput id="Task_UpdateIncident_in_patch" name="patch : object"/>
|
||||||
|
<bpmn:dataInput id="Task_UpdateIncident_in_status" name="status : string"/>
|
||||||
|
<bpmn:dataInput id="Task_UpdateIncident_in_reason" name="reason : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_UpdateIncident_out_case_id" name="case_id : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_UpdateIncident_out_new_status" name="new_status : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_UpdateIncident_out_success" name="success : boolean"/>
|
||||||
|
<bpmn:dataOutput id="Task_UpdateIncident_out_event_ids" name="event_ids : array"/>
|
||||||
|
<bpmn:inputSet>
|
||||||
|
<bpmn:dataInputRefs>Task_UpdateIncident_in_case_id</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_UpdateIncident_in_patch</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_UpdateIncident_in_status</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_UpdateIncident_in_reason</bpmn:dataInputRefs>
|
||||||
|
</bpmn:inputSet>
|
||||||
|
<bpmn:outputSet>
|
||||||
|
<bpmn:dataOutputRefs>Task_UpdateIncident_out_case_id</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_UpdateIncident_out_new_status</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_UpdateIncident_out_success</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_UpdateIncident_out_event_ids</bpmn:dataOutputRefs>
|
||||||
|
</bpmn:outputSet>
|
||||||
|
</bpmn:ioSpecification>
|
||||||
|
</bpmn:serviceTask>
|
||||||
|
<bpmn:serviceTask id="Task_DraftResponse"
|
||||||
|
name="Draft customer response"
|
||||||
|
uapf:capability="ai.draft_response@1"
|
||||||
|
uapf24:algorithmCardRef="algo.incident_triage.draft_response">
|
||||||
|
<bpmn:documentation>Drafts a parallel Latvian + English customer notification. Produces an AIDecision row with requires_human_approval=true. Operator must approve before any outbound transport adapter runs.</bpmn:documentation>
|
||||||
|
<bpmn:incoming>Flow_08</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_09</bpmn:outgoing>
|
||||||
|
<bpmn:ioSpecification>
|
||||||
|
<bpmn:dataInput id="Task_DraftResponse_in_case_id" name="case_id : string"/>
|
||||||
|
<bpmn:dataInput id="Task_DraftResponse_in_locale" name="locale : string"/>
|
||||||
|
<bpmn:dataInput id="Task_DraftResponse_in_what_happened" name="what_happened : string"/>
|
||||||
|
<bpmn:dataInput id="Task_DraftResponse_in_eta_minutes" name="eta_minutes : integer"/>
|
||||||
|
<bpmn:dataOutput id="Task_DraftResponse_out_subject_lv" name="subject_lv : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_DraftResponse_out_subject_en" name="subject_en : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_DraftResponse_out_body_lv" name="body_lv : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_DraftResponse_out_body_en" name="body_en : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_DraftResponse_out_locale" name="locale : string"/>
|
||||||
|
<bpmn:inputSet>
|
||||||
|
<bpmn:dataInputRefs>Task_DraftResponse_in_case_id</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_DraftResponse_in_locale</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_DraftResponse_in_what_happened</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_DraftResponse_in_eta_minutes</bpmn:dataInputRefs>
|
||||||
|
</bpmn:inputSet>
|
||||||
|
<bpmn:outputSet>
|
||||||
|
<bpmn:dataOutputRefs>Task_DraftResponse_out_subject_lv</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_DraftResponse_out_subject_en</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_DraftResponse_out_body_lv</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_DraftResponse_out_body_en</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_DraftResponse_out_locale</bpmn:dataOutputRefs>
|
||||||
|
</bpmn:outputSet>
|
||||||
|
</bpmn:ioSpecification>
|
||||||
|
</bpmn:serviceTask>
|
||||||
|
<bpmn:serviceTask id="Task_EmitEvent"
|
||||||
|
name="Emit routed event"
|
||||||
|
uapf:capability="event.emit@1"
|
||||||
|
uapf24:algorithmCardRef="algo.incident_triage.emit_event">
|
||||||
|
<bpmn:documentation>Emits the closing 'routed' CaseEvent. Payload echoes classification, priority, ownership, group_slug for the timeline.</bpmn:documentation>
|
||||||
|
<bpmn:incoming>Flow_09</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_10</bpmn:outgoing>
|
||||||
|
<bpmn:ioSpecification>
|
||||||
|
<bpmn:dataInput id="Task_EmitEvent_in_case_id" name="case_id : string"/>
|
||||||
|
<bpmn:dataInput id="Task_EmitEvent_in_type" name="type : string"/>
|
||||||
|
<bpmn:dataInput id="Task_EmitEvent_in_payload" name="payload : object"/>
|
||||||
|
<bpmn:dataInput id="Task_EmitEvent_in_actor_label" name="actor_label : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_EmitEvent_out_event_id" name="event_id : string"/>
|
||||||
|
<bpmn:dataOutput id="Task_EmitEvent_out_recorded_at" name="recorded_at : string"/>
|
||||||
|
<bpmn:inputSet>
|
||||||
|
<bpmn:dataInputRefs>Task_EmitEvent_in_case_id</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_EmitEvent_in_type</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_EmitEvent_in_payload</bpmn:dataInputRefs>
|
||||||
|
<bpmn:dataInputRefs>Task_EmitEvent_in_actor_label</bpmn:dataInputRefs>
|
||||||
|
</bpmn:inputSet>
|
||||||
|
<bpmn:outputSet>
|
||||||
|
<bpmn:dataOutputRefs>Task_EmitEvent_out_event_id</bpmn:dataOutputRefs>
|
||||||
|
<bpmn:dataOutputRefs>Task_EmitEvent_out_recorded_at</bpmn:dataOutputRefs>
|
||||||
|
</bpmn:outputSet>
|
||||||
|
</bpmn:ioSpecification>
|
||||||
|
</bpmn:serviceTask>
|
||||||
|
<bpmn:endEvent id="End" name="Triage complete">
|
||||||
|
<bpmn:incoming>Flow_10</bpmn:incoming>
|
||||||
|
</bpmn:endEvent>
|
||||||
|
<bpmn:sequenceFlow id="Flow_01" sourceRef="Start" targetRef="Task_NormalizeSignal"/>
|
||||||
|
<bpmn:sequenceFlow id="Flow_02" sourceRef="Task_NormalizeSignal" targetRef="Task_ClassifyIncident"/>
|
||||||
|
<bpmn:sequenceFlow id="Flow_03" sourceRef="Task_ClassifyIncident" targetRef="Task_SuggestPriority"/>
|
||||||
|
<bpmn:sequenceFlow id="Flow_04" sourceRef="Task_SuggestPriority" targetRef="Task_EvaluatePriorityDmn"/>
|
||||||
|
<bpmn:sequenceFlow id="Flow_05" sourceRef="Task_EvaluatePriorityDmn" targetRef="Task_EvaluateOwnershipDmn"/>
|
||||||
|
<bpmn:sequenceFlow id="Flow_06" sourceRef="Task_EvaluateOwnershipDmn" targetRef="Task_EvaluateRoutingDmn"/>
|
||||||
|
<bpmn:sequenceFlow id="Flow_07" sourceRef="Task_EvaluateRoutingDmn" targetRef="Task_UpdateIncident"/>
|
||||||
|
<bpmn:sequenceFlow id="Flow_08" sourceRef="Task_UpdateIncident" targetRef="Task_DraftResponse"/>
|
||||||
|
<bpmn:sequenceFlow id="Flow_09" sourceRef="Task_DraftResponse" targetRef="Task_EmitEvent"/>
|
||||||
|
<bpmn:sequenceFlow id="Flow_10" sourceRef="Task_EmitEvent" targetRef="End"/>
|
||||||
|
</bpmn:process>
|
||||||
|
</bpmn:definitions>
|
||||||
142
dmn/ownership.dmn
Normal file
142
dmn/ownership.dmn
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<dmn:definitions
|
||||||
|
xmlns:dmn="https://www.omg.org/spec/DMN/20191111/MODEL/"
|
||||||
|
xmlns:feel="https://www.omg.org/spec/DMN/20191111/FEEL/"
|
||||||
|
xmlns:dmndi="https://www.omg.org/spec/DMN/20191111/DMNDI/"
|
||||||
|
xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"
|
||||||
|
id="DMN_Ownership"
|
||||||
|
name="Incident ownership"
|
||||||
|
namespace="https://uapf.dev/dmn/lv.itsm.incident.triage/ownership"
|
||||||
|
exporter="openitsm-uapf-generator"
|
||||||
|
exporterVersion="1.0.0">
|
||||||
|
<dmn:description>
|
||||||
|
Determine whether LVRTC owns this incident or it should be transferred.
|
||||||
|
</dmn:description>
|
||||||
|
<dmn:decision id="ownership" name="Incident ownership">
|
||||||
|
<dmn:variable
|
||||||
|
id="var_ownership"
|
||||||
|
name="ownership_result"
|
||||||
|
typeRef="Any"/>
|
||||||
|
<dmn:decisionTable id="DecisionTable_ownership" hitPolicy="FIRST">
|
||||||
|
<dmn:input id="input_ownership_0" label="classification">
|
||||||
|
<dmn:inputExpression id="inputExpr_ownership_0" typeRef="string">
|
||||||
|
<dmn:text>classification</dmn:text>
|
||||||
|
</dmn:inputExpression>
|
||||||
|
</dmn:input>
|
||||||
|
<dmn:input id="input_ownership_1" label="host_domain">
|
||||||
|
<dmn:inputExpression id="inputExpr_ownership_1" typeRef="string">
|
||||||
|
<dmn:text>host_domain</dmn:text>
|
||||||
|
</dmn:inputExpression>
|
||||||
|
</dmn:input>
|
||||||
|
<dmn:input id="input_ownership_2" label="source">
|
||||||
|
<dmn:inputExpression id="inputExpr_ownership_2" typeRef="string">
|
||||||
|
<dmn:text>source</dmn:text>
|
||||||
|
</dmn:inputExpression>
|
||||||
|
</dmn:input>
|
||||||
|
<dmn:output id="output_ownership_0" label="ownership" typeRef="string"/>
|
||||||
|
<dmn:output id="output_ownership_1" label="reason" typeRef="string"/>
|
||||||
|
<dmn:rule id="rule_ownership_1">
|
||||||
|
<dmn:inputEntry id="ie_ownership_1_0">
|
||||||
|
<dmn:text>"security.incident"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_1_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_1_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_1_0">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_1_1">
|
||||||
|
<dmn:text>"Security incidents owned by LVRTC SOC"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_ownership_2">
|
||||||
|
<dmn:inputEntry id="ie_ownership_2_0">
|
||||||
|
<dmn:text>"facility.power"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_2_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_2_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_2_0">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_2_1">
|
||||||
|
<dmn:text>"Facility / power is LVRTC's"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_ownership_3">
|
||||||
|
<dmn:inputEntry id="ie_ownership_3_0">
|
||||||
|
<dmn:text>"service.customer_request"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_3_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_3_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_3_0">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_3_1">
|
||||||
|
<dmn:text>"Customer requests are LVRTC's intake"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_ownership_4">
|
||||||
|
<dmn:inputEntry id="ie_ownership_4_0">
|
||||||
|
<dmn:text>"unknown.uncategorized"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_4_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_4_2">
|
||||||
|
<dmn:text>"phone"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_4_0">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_4_1">
|
||||||
|
<dmn:text>"Phone intake stays with LVRTC L1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_ownership_5">
|
||||||
|
<dmn:inputEntry id="ie_ownership_5_0">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_5_1">
|
||||||
|
<dmn:text>"lvrtc.lv"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_5_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_5_0">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_5_1">
|
||||||
|
<dmn:text>"Anything on lvrtc.lv hosts is ours"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_ownership_6">
|
||||||
|
<dmn:inputEntry id="ie_ownership_6_0">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_6_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_ownership_6_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_6_0">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_ownership_6_1">
|
||||||
|
<dmn:text>"Default: LVRTC owns until escalation transfers"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
</dmn:decisionTable>
|
||||||
|
</dmn:decision>
|
||||||
|
</dmn:definitions>
|
||||||
326
dmn/priority.dmn
Normal file
326
dmn/priority.dmn
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<dmn:definitions
|
||||||
|
xmlns:dmn="https://www.omg.org/spec/DMN/20191111/MODEL/"
|
||||||
|
xmlns:feel="https://www.omg.org/spec/DMN/20191111/FEEL/"
|
||||||
|
xmlns:dmndi="https://www.omg.org/spec/DMN/20191111/DMNDI/"
|
||||||
|
xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"
|
||||||
|
id="DMN_Priority"
|
||||||
|
name="Incident priority"
|
||||||
|
namespace="https://uapf.dev/dmn/lv.itsm.incident.triage/priority"
|
||||||
|
exporter="openitsm-uapf-generator"
|
||||||
|
exporterVersion="1.0.0">
|
||||||
|
<dmn:description>
|
||||||
|
Determine the final P1..P4 priority from severity, service tier, and AI
|
||||||
|
suggestion. FIRST matching rule wins.
|
||||||
|
</dmn:description>
|
||||||
|
<dmn:decision id="priority" name="Incident priority">
|
||||||
|
<dmn:variable
|
||||||
|
id="var_priority"
|
||||||
|
name="priority_result"
|
||||||
|
typeRef="Any"/>
|
||||||
|
<dmn:decisionTable id="DecisionTable_priority" hitPolicy="FIRST">
|
||||||
|
<dmn:input id="input_priority_0" label="severity">
|
||||||
|
<dmn:inputExpression id="inputExpr_priority_0" typeRef="string">
|
||||||
|
<dmn:text>severity</dmn:text>
|
||||||
|
</dmn:inputExpression>
|
||||||
|
</dmn:input>
|
||||||
|
<dmn:input id="input_priority_1" label="service_tier">
|
||||||
|
<dmn:inputExpression id="inputExpr_priority_1" typeRef="string">
|
||||||
|
<dmn:text>service_tier</dmn:text>
|
||||||
|
</dmn:inputExpression>
|
||||||
|
</dmn:input>
|
||||||
|
<dmn:input id="input_priority_2" label="ai_suggested_priority">
|
||||||
|
<dmn:inputExpression id="inputExpr_priority_2" typeRef="string">
|
||||||
|
<dmn:text>ai_suggested_priority</dmn:text>
|
||||||
|
</dmn:inputExpression>
|
||||||
|
</dmn:input>
|
||||||
|
<dmn:input id="input_priority_3" label="classification">
|
||||||
|
<dmn:inputExpression id="inputExpr_priority_3" typeRef="string">
|
||||||
|
<dmn:text>classification</dmn:text>
|
||||||
|
</dmn:inputExpression>
|
||||||
|
</dmn:input>
|
||||||
|
<dmn:output id="output_priority_0" label="priority" typeRef="string"/>
|
||||||
|
<dmn:output id="output_priority_1" label="reason" typeRef="string"/>
|
||||||
|
<dmn:rule id="rule_priority_1">
|
||||||
|
<dmn:inputEntry id="ie_priority_1_0">
|
||||||
|
<dmn:text>"disaster"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_1_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_1_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_1_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_1_0">
|
||||||
|
<dmn:text>"P1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_1_1">
|
||||||
|
<dmn:text>"Disaster severity always overrides"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_2">
|
||||||
|
<dmn:inputEntry id="ie_priority_2_0">
|
||||||
|
<dmn:text>"critical"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_2_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_2_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_2_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_2_0">
|
||||||
|
<dmn:text>"P1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_2_1">
|
||||||
|
<dmn:text>"Critical severity always overrides"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_3">
|
||||||
|
<dmn:inputEntry id="ie_priority_3_0">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_3_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_3_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_3_3">
|
||||||
|
<dmn:text>"security.incident"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_3_0">
|
||||||
|
<dmn:text>"P1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_3_1">
|
||||||
|
<dmn:text>"Security incidents are always P1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_4">
|
||||||
|
<dmn:inputEntry id="ie_priority_4_0">
|
||||||
|
<dmn:text>"high"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_4_1">
|
||||||
|
<dmn:text>"tier_1"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_4_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_4_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_4_0">
|
||||||
|
<dmn:text>"P1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_4_1">
|
||||||
|
<dmn:text>"High on tier_1 service"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_5">
|
||||||
|
<dmn:inputEntry id="ie_priority_5_0">
|
||||||
|
<dmn:text>"high"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_5_1">
|
||||||
|
<dmn:text>"tier_2"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_5_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_5_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_5_0">
|
||||||
|
<dmn:text>"P2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_5_1">
|
||||||
|
<dmn:text>"High on tier_2 service"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_6">
|
||||||
|
<dmn:inputEntry id="ie_priority_6_0">
|
||||||
|
<dmn:text>"high"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_6_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_6_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_6_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_6_0">
|
||||||
|
<dmn:text>"P2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_6_1">
|
||||||
|
<dmn:text>"High severity, lower tier"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_7">
|
||||||
|
<dmn:inputEntry id="ie_priority_7_0">
|
||||||
|
<dmn:text>"average"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_7_1">
|
||||||
|
<dmn:text>"tier_1"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_7_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_7_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_7_0">
|
||||||
|
<dmn:text>"P2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_7_1">
|
||||||
|
<dmn:text>"Average on tier_1 service"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_8">
|
||||||
|
<dmn:inputEntry id="ie_priority_8_0">
|
||||||
|
<dmn:text>"average"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_8_1">
|
||||||
|
<dmn:text>"tier_2"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_8_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_8_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_8_0">
|
||||||
|
<dmn:text>"P3"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_8_1">
|
||||||
|
<dmn:text>"Average on tier_2 service"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_9">
|
||||||
|
<dmn:inputEntry id="ie_priority_9_0">
|
||||||
|
<dmn:text>"warning"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_9_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_9_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_9_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_9_0">
|
||||||
|
<dmn:text>"P3"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_9_1">
|
||||||
|
<dmn:text>"Warning severity"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_10">
|
||||||
|
<dmn:inputEntry id="ie_priority_10_0">
|
||||||
|
<dmn:text>"information"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_10_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_10_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_10_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_10_0">
|
||||||
|
<dmn:text>"P4"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_10_1">
|
||||||
|
<dmn:text>"Informational"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_11">
|
||||||
|
<dmn:inputEntry id="ie_priority_11_0">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_11_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_11_2">
|
||||||
|
<dmn:text>"P1"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_11_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_11_0">
|
||||||
|
<dmn:text>"P1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_11_1">
|
||||||
|
<dmn:text>"Fallback: trust AI suggestion P1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_12">
|
||||||
|
<dmn:inputEntry id="ie_priority_12_0">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_12_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_12_2">
|
||||||
|
<dmn:text>"P2"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_12_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_12_0">
|
||||||
|
<dmn:text>"P2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_12_1">
|
||||||
|
<dmn:text>"Fallback: trust AI suggestion P2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_13">
|
||||||
|
<dmn:inputEntry id="ie_priority_13_0">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_13_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_13_2">
|
||||||
|
<dmn:text>"P3"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_13_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_13_0">
|
||||||
|
<dmn:text>"P3"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_13_1">
|
||||||
|
<dmn:text>"Fallback: trust AI suggestion P3"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_priority_14">
|
||||||
|
<dmn:inputEntry id="ie_priority_14_0">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_14_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_14_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_priority_14_3">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_14_0">
|
||||||
|
<dmn:text>"P4"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_priority_14_1">
|
||||||
|
<dmn:text>"Default when nothing else matches"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
</dmn:decisionTable>
|
||||||
|
</dmn:decision>
|
||||||
|
</dmn:definitions>
|
||||||
278
dmn/routing.dmn
Normal file
278
dmn/routing.dmn
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<dmn:definitions
|
||||||
|
xmlns:dmn="https://www.omg.org/spec/DMN/20191111/MODEL/"
|
||||||
|
xmlns:feel="https://www.omg.org/spec/DMN/20191111/FEEL/"
|
||||||
|
xmlns:dmndi="https://www.omg.org/spec/DMN/20191111/DMNDI/"
|
||||||
|
xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"
|
||||||
|
id="DMN_Routing"
|
||||||
|
name="Incident routing"
|
||||||
|
namespace="https://uapf.dev/dmn/lv.itsm.incident.triage/routing"
|
||||||
|
exporter="openitsm-uapf-generator"
|
||||||
|
exporterVersion="1.0.0">
|
||||||
|
<dmn:description>
|
||||||
|
Route to an expert group slug based on classification + priority. FIRST hit.
|
||||||
|
</dmn:description>
|
||||||
|
<dmn:decision id="routing" name="Incident routing">
|
||||||
|
<dmn:variable
|
||||||
|
id="var_routing"
|
||||||
|
name="routing_result"
|
||||||
|
typeRef="Any"/>
|
||||||
|
<dmn:decisionTable id="DecisionTable_routing" hitPolicy="FIRST">
|
||||||
|
<dmn:input id="input_routing_0" label="classification">
|
||||||
|
<dmn:inputExpression id="inputExpr_routing_0" typeRef="string">
|
||||||
|
<dmn:text>classification</dmn:text>
|
||||||
|
</dmn:inputExpression>
|
||||||
|
</dmn:input>
|
||||||
|
<dmn:input id="input_routing_1" label="priority">
|
||||||
|
<dmn:inputExpression id="inputExpr_routing_1" typeRef="string">
|
||||||
|
<dmn:text>priority</dmn:text>
|
||||||
|
</dmn:inputExpression>
|
||||||
|
</dmn:input>
|
||||||
|
<dmn:input id="input_routing_2" label="ownership">
|
||||||
|
<dmn:inputExpression id="inputExpr_routing_2" typeRef="string">
|
||||||
|
<dmn:text>ownership</dmn:text>
|
||||||
|
</dmn:inputExpression>
|
||||||
|
</dmn:input>
|
||||||
|
<dmn:output id="output_routing_0" label="group_slug" typeRef="string"/>
|
||||||
|
<dmn:output id="output_routing_1" label="reason" typeRef="string"/>
|
||||||
|
<dmn:rule id="rule_routing_1">
|
||||||
|
<dmn:inputEntry id="ie_routing_1_0">
|
||||||
|
<dmn:text>"security.incident"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_1_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_1_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_1_0">
|
||||||
|
<dmn:text>"soc-l2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_1_1">
|
||||||
|
<dmn:text>"Security goes to SOC L2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_2">
|
||||||
|
<dmn:inputEntry id="ie_routing_2_0">
|
||||||
|
<dmn:text>"network.outage.link_down"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_2_1">
|
||||||
|
<dmn:text>"P1"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_2_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_2_0">
|
||||||
|
<dmn:text>"noc-l2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_2_1">
|
||||||
|
<dmn:text>"Network P1 to NOC L2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_3">
|
||||||
|
<dmn:inputEntry id="ie_routing_3_0">
|
||||||
|
<dmn:text>"network.outage.link_down"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_3_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_3_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_3_0">
|
||||||
|
<dmn:text>"noc-l1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_3_1">
|
||||||
|
<dmn:text>"Network non-P1 to NOC L1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_4">
|
||||||
|
<dmn:inputEntry id="ie_routing_4_0">
|
||||||
|
<dmn:text>"network.degradation"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_4_1">
|
||||||
|
<dmn:text>"P1"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_4_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_4_0">
|
||||||
|
<dmn:text>"noc-l2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_4_1">
|
||||||
|
<dmn:text>"Network degradation P1 to NOC L2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_5">
|
||||||
|
<dmn:inputEntry id="ie_routing_5_0">
|
||||||
|
<dmn:text>"network.degradation"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_5_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_5_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_5_0">
|
||||||
|
<dmn:text>"noc-l1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_5_1">
|
||||||
|
<dmn:text>"Network degradation lower to NOC L1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_6">
|
||||||
|
<dmn:inputEntry id="ie_routing_6_0">
|
||||||
|
<dmn:text>"network.routing"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_6_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_6_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_6_0">
|
||||||
|
<dmn:text>"noc-l2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_6_1">
|
||||||
|
<dmn:text>"Routing issues need L2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_7">
|
||||||
|
<dmn:inputEntry id="ie_routing_7_0">
|
||||||
|
<dmn:text>"network.dns"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_7_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_7_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_7_0">
|
||||||
|
<dmn:text>"noc-l2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_7_1">
|
||||||
|
<dmn:text>"DNS issues to NOC L2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_8">
|
||||||
|
<dmn:inputEntry id="ie_routing_8_0">
|
||||||
|
<dmn:text>"facility.power"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_8_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_8_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_8_0">
|
||||||
|
<dmn:text>"facility-l2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_8_1">
|
||||||
|
<dmn:text>"Power to facility ops"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_9">
|
||||||
|
<dmn:inputEntry id="ie_routing_9_0">
|
||||||
|
<dmn:text>"storage.capacity"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_9_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_9_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_9_0">
|
||||||
|
<dmn:text>"platform-l2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_9_1">
|
||||||
|
<dmn:text>"Storage to platform ops"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_10">
|
||||||
|
<dmn:inputEntry id="ie_routing_10_0">
|
||||||
|
<dmn:text>"service.customer_request"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_10_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_10_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_10_0">
|
||||||
|
<dmn:text>"helpdesk-l1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_10_1">
|
||||||
|
<dmn:text>"Customer requests to L1 helpdesk"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_11">
|
||||||
|
<dmn:inputEntry id="ie_routing_11_0">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_11_1">
|
||||||
|
<dmn:text>"P1"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_11_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_11_0">
|
||||||
|
<dmn:text>"noc-l2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_11_1">
|
||||||
|
<dmn:text>"Default P1: NOC L2"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_12">
|
||||||
|
<dmn:inputEntry id="ie_routing_12_0">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_12_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_12_2">
|
||||||
|
<dmn:text>"lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_12_0">
|
||||||
|
<dmn:text>"helpdesk-l1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_12_1">
|
||||||
|
<dmn:text>"Default: L1 helpdesk triages"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_13">
|
||||||
|
<dmn:inputEntry id="ie_routing_13_0">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_13_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_13_2">
|
||||||
|
<dmn:text>"not_lvrtc"</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_13_0">
|
||||||
|
<dmn:text>"external-handoff"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_13_1">
|
||||||
|
<dmn:text>"Not ours - external handoff"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
<dmn:rule id="rule_routing_14">
|
||||||
|
<dmn:inputEntry id="ie_routing_14_0">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_14_1">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:inputEntry id="ie_routing_14_2">
|
||||||
|
<dmn:text>-</dmn:text>
|
||||||
|
</dmn:inputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_14_0">
|
||||||
|
<dmn:text>"helpdesk-l1"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
<dmn:outputEntry id="oe_routing_14_1">
|
||||||
|
<dmn:text>"Final default"</dmn:text>
|
||||||
|
</dmn:outputEntry>
|
||||||
|
</dmn:rule>
|
||||||
|
</dmn:decisionTable>
|
||||||
|
</dmn:decision>
|
||||||
|
</dmn:definitions>
|
||||||
49
docs/host-lookup-tables.md
Normal file
49
docs/host-lookup-tables.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# Host lookup tables
|
||||||
|
|
||||||
|
This package expects the OpenITSM host to maintain three deployment-specific
|
||||||
|
lookup tables. They are NOT part of the package (the package only defines the
|
||||||
|
abstract triage process); each host deployment populates them.
|
||||||
|
|
||||||
|
## Expert groups
|
||||||
|
|
||||||
|
The routing DMN resolves to one of these `group_slug` values. The host MUST
|
||||||
|
have a matching `expert_groups` row for each:
|
||||||
|
|
||||||
|
| slug | name |
|
||||||
|
|-------------------|-------------------|
|
||||||
|
| `helpdesk-l1` | L1 helpdesk |
|
||||||
|
| `noc-l1` | Network Ops L1 |
|
||||||
|
| `noc-l2` | Network Ops L2 |
|
||||||
|
| `soc-l2` | Security Ops L2 |
|
||||||
|
| `facility-l2` | Facility & Power L2 |
|
||||||
|
| `platform-l2` | Platform Ops L2 |
|
||||||
|
| `external-handoff`| External handoff |
|
||||||
|
|
||||||
|
## Service tiers
|
||||||
|
|
||||||
|
The priority DMN consumes these tier codes. Hosts MUST have a matching
|
||||||
|
`service_tiers` row.
|
||||||
|
|
||||||
|
| code | name | first_response | resolution |
|
||||||
|
|---------------|-------------------------------|----------------|------------|
|
||||||
|
| `tier_1` | Tier 1 (mission-critical) | 15 min | 240 min |
|
||||||
|
| `tier_2` | Tier 2 (standard) | 60 min | 480 min |
|
||||||
|
| `best_effort` | Best effort (non-SLA) | — (no SLA) | — |
|
||||||
|
|
||||||
|
## Taxonomy
|
||||||
|
|
||||||
|
The closed list of taxonomy codes `ai.classify@1` can emit, mirrored in the
|
||||||
|
classify_incident Algorithm Card's `io.outputs.taxonomy_code.constraints.enum`
|
||||||
|
and consumed as input to the priority + routing DMN.
|
||||||
|
|
||||||
|
| code | LV | EN |
|
||||||
|
|-------------------------------|--------------------------|---------------------|
|
||||||
|
| `network.outage.link_down` | Saites pārtraukums | Link down |
|
||||||
|
| `network.degradation` | Tīkla degradācija | Network degradation |
|
||||||
|
| `network.routing` | Maršrutēšana | Routing |
|
||||||
|
| `network.dns` | DNS | DNS |
|
||||||
|
| `security.incident` | Drošības incidents | Security incident |
|
||||||
|
| `facility.power` | Elektroapgāde | Power / facility |
|
||||||
|
| `storage.capacity` | Diska vieta | Storage capacity |
|
||||||
|
| `service.customer_request` | Klienta pieprasījums | Customer request |
|
||||||
|
| `unknown.uncategorized` | Neklasificēts | Uncategorized |
|
||||||
60
docs/overview.md
Normal file
60
docs/overview.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# `lv.itsm.incident.triage` — overview
|
||||||
|
|
||||||
|
Level-4 UAPF process for triaging IT-infrastructure incidents at LVRTC.
|
||||||
|
|
||||||
|
## What it does
|
||||||
|
|
||||||
|
A new Signal lands in OpenITSM (Zabbix webhook, IMAP poll, Jira DC webhook,
|
||||||
|
manual entry). The host opens a Case and starts a session of this package
|
||||||
|
against the UAPF engine. The engine then drives the linear flow defined in
|
||||||
|
`bpmn/incident-triage.bpmn`, calling back to OpenITSM at every step:
|
||||||
|
|
||||||
|
1. **Normalize** the source-specific payload to a uniform shape.
|
||||||
|
2. **Classify** into one of nine taxonomy codes (LLM + regex fallback).
|
||||||
|
3. **Suggest** a soft P1..P4 priority.
|
||||||
|
4. **Evaluate** the three DMN tables in order: priority (binding),
|
||||||
|
ownership (LVRTC vs external), routing (which expert group).
|
||||||
|
5. **Update** the case with the decided priority + group + status=triaged.
|
||||||
|
6. **Draft** a parallel Latvian + English customer notification — flagged
|
||||||
|
PROPOSED, requires operator approval before send.
|
||||||
|
7. **Emit** the closing `routed` CaseEvent.
|
||||||
|
|
||||||
|
## Why the split
|
||||||
|
|
||||||
|
Classification, priority suggestion, and customer-response drafting are
|
||||||
|
the AI steps. Everything *binding* — the actual priority, who handles it,
|
||||||
|
which group — lives in versioned DMN, not in Python. That keeps the AI
|
||||||
|
contestable and the auditor's job tractable: an evaluator can read
|
||||||
|
`dmn/priority.dmn` and know exactly what priority an incident *will*
|
||||||
|
receive, given its severity and tier, without running anything.
|
||||||
|
|
||||||
|
## Cornerstones
|
||||||
|
|
||||||
|
- **bpmn/** — `incident-triage.bpmn` — 1 process, 9 service tasks, linear.
|
||||||
|
- **dmn/** — `priority.dmn` (14 rules), `ownership.dmn` (6 rules),
|
||||||
|
`routing.dmn` (14 rules), all FIRST hit-policy.
|
||||||
|
- **algorithms/** — 7 algorithm cards, each with embedded v2.5.0 tests.
|
||||||
|
- **resources/** — guardrails (PII, approval gating, timeouts, retention)
|
||||||
|
and host mappings (expert groups, service tiers, taxonomy).
|
||||||
|
- **metadata/** — lifecycle + ownership.
|
||||||
|
|
||||||
|
## Versioning
|
||||||
|
|
||||||
|
This package targets **UAPF v2.5.0** (track main, refreshed on every
|
||||||
|
schema release). Breaking changes follow the spec's CHANGELOG.
|
||||||
|
|
||||||
|
## Host requirements
|
||||||
|
|
||||||
|
OpenITSM must implement and advertise (via `/uapf/host/manifest`) the
|
||||||
|
seven UAPF-IP capabilities listed in `requires_capabilities`:
|
||||||
|
|
||||||
|
- `intake.normalize@1`
|
||||||
|
- `ai.classify@1`
|
||||||
|
- `ai.suggest_priority@1`
|
||||||
|
- `ai.draft_response@1`
|
||||||
|
- `dmn.evaluate@1`
|
||||||
|
- `incident.update@1`
|
||||||
|
- `event.emit@1`
|
||||||
|
|
||||||
|
The first six are intent-bearing (each governed by its own Algorithm
|
||||||
|
Card); `event.emit` is an append-only timeline writer.
|
||||||
16
fixtures/signal-email-customer-lv.json
Normal file
16
fixtures/signal-email-customer-lv.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"source": "email",
|
||||||
|
"external_id": "MSG-2026-05-25-001",
|
||||||
|
"raw_payload": {
|
||||||
|
"subject": "Klients SIA Latvija Tev: lūgums palielināt joslas platumu",
|
||||||
|
"from": "ivars.berzins@klients-latvija.lv",
|
||||||
|
"to": "atbalsts@lvrtc.lv",
|
||||||
|
"body": "Labdien, mūsu uzņēmumam nepieciešams palielināt internet pieslēguma joslas platumu no 100 Mbps uz 500 Mbps. Lūdzu, informējiet par procedūru un izmaksām. Ar cieņu, Ivars Bērziņš"
|
||||||
|
},
|
||||||
|
"expected_after_triage": {
|
||||||
|
"taxonomy_code": "service.customer_request",
|
||||||
|
"priority": "P3",
|
||||||
|
"ownership": "lvrtc",
|
||||||
|
"group_slug": "helpdesk-l1"
|
||||||
|
}
|
||||||
|
}
|
||||||
17
fixtures/signal-zabbix-ddos.json
Normal file
17
fixtures/signal-zabbix-ddos.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"source": "zabbix",
|
||||||
|
"external_id": "ZBX-EVT-9374",
|
||||||
|
"raw_payload": {
|
||||||
|
"title": "DDoS attack pattern detected on edge",
|
||||||
|
"host": "rtr-r3.lvrtc.lv",
|
||||||
|
"severity": "critical",
|
||||||
|
"body": "Volumetric UDP flood, 4.2 Gbps inbound to 192.0.2.0/24. Source: 12 ASNs, predominantly AS197207. Auto-mitigation engaged.",
|
||||||
|
"tags": ["security", "ddos"]
|
||||||
|
},
|
||||||
|
"expected_after_triage": {
|
||||||
|
"taxonomy_code": "security.incident",
|
||||||
|
"priority": "P1",
|
||||||
|
"ownership": "lvrtc",
|
||||||
|
"group_slug": "soc-l2"
|
||||||
|
}
|
||||||
|
}
|
||||||
18
fixtures/signal-zabbix-link-down.json
Normal file
18
fixtures/signal-zabbix-link-down.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"source": "zabbix",
|
||||||
|
"external_id": "ZBX-EVT-9342",
|
||||||
|
"raw_payload": {
|
||||||
|
"title": "Link down on edge router rtr-r1",
|
||||||
|
"host": "rtr-r1.lvrtc.lv",
|
||||||
|
"severity": "high",
|
||||||
|
"body": "Interface ge-0/0/3 went DOWN at 09:14:02 UTC. BGP session to upstream provider AS6939 also flapping.",
|
||||||
|
"event_id": "9342",
|
||||||
|
"tags": ["network", "edge"]
|
||||||
|
},
|
||||||
|
"expected_after_triage": {
|
||||||
|
"taxonomy_code": "network.routing",
|
||||||
|
"priority": "P1",
|
||||||
|
"ownership": "lvrtc",
|
||||||
|
"group_slug": "noc-l2"
|
||||||
|
}
|
||||||
|
}
|
||||||
63
manifest.json
Normal file
63
manifest.json
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"kind": "uapf.package",
|
||||||
|
"id": "lv.itsm.incident.triage",
|
||||||
|
"name": "LVRTC Incident Triage",
|
||||||
|
"description": "Level-4 UAPF process for triaging IT-infrastructure incidents at LVRTC.\n\nSix BPMN service tasks invoke the UAPF-IP capabilities intake.normalize@1,\nai.classify@1, ai.suggest_priority@1, ai.draft_response@1,\nincident.update@1 and event.emit@1. Three DMN decision tables encode the\ndeterministic rules previously hidden inside the host: priority maps\nseverity x service-tier x AI-suggestion x classification onto P1-P4;\nownership decides whether the case stays inside LVRTC or hands off to an\nexternal partner; routing picks the expert group (helpdesk-l1, noc-l1/l2,\nsoc-l2, facility-l2, platform-l2, external-handoff).\n\nClassification, priority suggestion and customer response drafting are AI\nsteps; the rules that decide *what* the AI proposes versus *who* handles\nit live in versioned DMN, not Python. Drafted customer responses are\nproduced in both Latvian and English and require human approval before\nsending (governed by Algorithm Card algo.incident_triage.draft_response).\n\nv1.0.0 targets UAPF v2.5.0: algorithm cards carry embedded `tests`\narrays (>=2 per card) per chapter 13.16; BPMN service tasks carry\nuapf24:algorithmCardRef attributes; resource targets are dispatch\nendpoints only.\n",
|
||||||
|
"level": 4,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"requires_capabilities": [
|
||||||
|
"intake.normalize@1+",
|
||||||
|
"ai.classify@1+",
|
||||||
|
"ai.suggest_priority@1+",
|
||||||
|
"ai.draft_response@1+",
|
||||||
|
"dmn.evaluate@1+",
|
||||||
|
"incident.update@1+",
|
||||||
|
"event.emit@1+"
|
||||||
|
],
|
||||||
|
"profiles_supported": [
|
||||||
|
"uapf-ip-orchestrated"
|
||||||
|
],
|
||||||
|
"guardrails": "resources/guardrails.yaml",
|
||||||
|
"includes": [],
|
||||||
|
"dependencies": {},
|
||||||
|
"cornerstones": {
|
||||||
|
"bpmn": true,
|
||||||
|
"dmn": true,
|
||||||
|
"cmmn": false,
|
||||||
|
"resources": true
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"bpmn": "bpmn",
|
||||||
|
"dmn": "dmn",
|
||||||
|
"resources": "resources",
|
||||||
|
"metadata": "metadata"
|
||||||
|
},
|
||||||
|
"exposure": {
|
||||||
|
"mcp": {
|
||||||
|
"enabled": true,
|
||||||
|
"runnable": true,
|
||||||
|
"exposedEntrypoints": [
|
||||||
|
"Process_IncidentTriage"
|
||||||
|
],
|
||||||
|
"exposedArtifacts": [
|
||||||
|
"manifest",
|
||||||
|
"bpmn",
|
||||||
|
"dmn",
|
||||||
|
"docs"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"owners": [
|
||||||
|
{
|
||||||
|
"type": "team",
|
||||||
|
"id": "lvrtc",
|
||||||
|
"contact": "incident-mgmt@lvrtc.lv"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "team",
|
||||||
|
"id": "openitsm-stewards",
|
||||||
|
"contact": "stewards@openitsm.algomation.io"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lifecycle": "draft"
|
||||||
|
}
|
||||||
16
metadata/lifecycle.yaml
Normal file
16
metadata/lifecycle.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
kind: uapf.metadata.lifecycle
|
||||||
|
status: draft
|
||||||
|
created: "2026-06-01T00:00:00Z"
|
||||||
|
lastModified: "2026-06-01T00:00:00Z"
|
||||||
|
changeHistory:
|
||||||
|
- version: "1.0.0"
|
||||||
|
date: "2026-06-01"
|
||||||
|
summary: |
|
||||||
|
Initial release. Six BPMN service tasks invoke UAPF-IP capabilities
|
||||||
|
(intake.normalize, ai.classify, ai.suggest_priority, ai.draft_response,
|
||||||
|
incident.update, event.emit). Three DMN decision tables encode the
|
||||||
|
priority / ownership / routing rules previously hidden in the
|
||||||
|
OpenITSM host's inline triage runner. Seven algorithm cards (the
|
||||||
|
six service-task cards plus dmn.evaluate as a host-fulfilled
|
||||||
|
capability for governance) carry embedded tests per UAPF v2.5.0.
|
||||||
|
author: "openitsm-stewards"
|
||||||
19
metadata/ownership.yaml
Normal file
19
metadata/ownership.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
kind: uapf.metadata.ownership
|
||||||
|
owners:
|
||||||
|
- type: team
|
||||||
|
id: lvrtc
|
||||||
|
name: VAS Latvijas Valsts Radio un Televizijas Centrs
|
||||||
|
contact: incident-mgmt@lvrtc.lv
|
||||||
|
role: owner
|
||||||
|
- type: team
|
||||||
|
id: openitsm-stewards
|
||||||
|
name: OpenITSM Package Stewards
|
||||||
|
contact: stewards@openitsm.algomation.io
|
||||||
|
role: maintainer
|
||||||
|
approvers:
|
||||||
|
- lvrtc-incident-board
|
||||||
|
- openitsm-stewards
|
||||||
|
escalation:
|
||||||
|
level_1:
|
||||||
|
team: lvrtc-incident-board
|
||||||
|
contact: incident-board@lvrtc.lv
|
||||||
15
processgit.mcp.yaml
Normal file
15
processgit.mcp.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Hints for ProcessGit's MCP indexer about this package.
|
||||||
|
kind: processgit.mcp.hints
|
||||||
|
package_id: lv.itsm.incident.triage
|
||||||
|
description: LVRTC incident triage — UAPF v2.5.0 package
|
||||||
|
tags:
|
||||||
|
- itsm
|
||||||
|
- incident-management
|
||||||
|
- lvrtc
|
||||||
|
- openitsm
|
||||||
|
- critical-infrastructure
|
||||||
|
- nis2
|
||||||
|
locale_primary: lv
|
||||||
|
locales:
|
||||||
|
- lv
|
||||||
|
- en
|
||||||
37
resources/guardrails.yaml
Normal file
37
resources/guardrails.yaml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
kind: uapf.resources.guardrails
|
||||||
|
|
||||||
|
# Applied by the UAPF runtime to every UAPF-IP capability invocation
|
||||||
|
# governed by this package. Cross-cutting safety rails — enforced regardless
|
||||||
|
# of which Algorithm Card the runtime is dispatching.
|
||||||
|
|
||||||
|
pii:
|
||||||
|
redact_in_payloads: true
|
||||||
|
forbidden_in_drafts:
|
||||||
|
- personas_kods
|
||||||
|
- magnetic_stripe
|
||||||
|
- iban
|
||||||
|
allowed_in_drafts:
|
||||||
|
- case_number
|
||||||
|
- host_domain
|
||||||
|
- approximate_eta
|
||||||
|
|
||||||
|
approval:
|
||||||
|
human_required_for:
|
||||||
|
- ai.draft_response # outbound customer text always reviewed
|
||||||
|
- incident.update # write actions never auto-applied
|
||||||
|
auto_applied:
|
||||||
|
- intake.normalize
|
||||||
|
- ai.classify
|
||||||
|
- ai.suggest_priority
|
||||||
|
- dmn.evaluate
|
||||||
|
- event.emit
|
||||||
|
|
||||||
|
timeouts:
|
||||||
|
capability_default_ms: 30000
|
||||||
|
llm_default_ms: 45000
|
||||||
|
dmn_default_ms: 5000
|
||||||
|
|
||||||
|
retention:
|
||||||
|
algorithm_outputs_days: 365
|
||||||
|
audit_events_days: 2557 # 7 years (Latvian state-archive default)
|
||||||
|
signed_artifacts: indefinite
|
||||||
194
resources/mappings.yaml
Normal file
194
resources/mappings.yaml
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
kind: uapf.resources.mapping
|
||||||
|
|
||||||
|
# Host-readable contract for the seven capability-backed service tasks in
|
||||||
|
# this package. Algorithm Card references live on the BPMN service tasks
|
||||||
|
# themselves (uapf24:algorithmCardRef attribute) per UAPF v2.4.0+. The
|
||||||
|
# targets below are dispatch endpoints only.
|
||||||
|
|
||||||
|
targets:
|
||||||
|
- id: agent.intake_normalizer
|
||||||
|
type: system_api
|
||||||
|
name: Signal normalizer
|
||||||
|
description: Host capability intake.normalize@1, governed by the normalize_signal Algorithm Card.
|
||||||
|
capabilities:
|
||||||
|
- capability.intake.normalize
|
||||||
|
|
||||||
|
- id: agent.classifier
|
||||||
|
type: ai_agent
|
||||||
|
name: Incident taxonomy classifier
|
||||||
|
description: Host capability ai.classify@1 (LLM-backed), governed by the classify_incident Algorithm Card.
|
||||||
|
capabilities:
|
||||||
|
- capability.ai.classify
|
||||||
|
|
||||||
|
- id: agent.priority_suggester
|
||||||
|
type: ai_agent
|
||||||
|
name: Priority suggester
|
||||||
|
description: Host capability ai.suggest_priority@1, governed by the suggest_priority Algorithm Card.
|
||||||
|
capabilities:
|
||||||
|
- capability.ai.suggest_priority
|
||||||
|
|
||||||
|
- id: agent.dmn_evaluator
|
||||||
|
type: system_api
|
||||||
|
name: DMN decision evaluator
|
||||||
|
description: Host capability dmn.evaluate@1, governed by the evaluate_dmn Algorithm Card. Invoked three times in the BPMN with different decision_id input.
|
||||||
|
capabilities:
|
||||||
|
- capability.dmn.evaluate
|
||||||
|
|
||||||
|
- id: agent.response_drafter
|
||||||
|
type: ai_agent
|
||||||
|
name: Customer response drafter
|
||||||
|
description: Host capability ai.draft_response@1, governed by the draft_response Algorithm Card. Requires human approval before send.
|
||||||
|
capabilities:
|
||||||
|
- capability.ai.draft_response
|
||||||
|
|
||||||
|
- id: agent.incident_updater
|
||||||
|
type: system_api
|
||||||
|
name: Incident state writer
|
||||||
|
description: Host capability incident.update@1, governed by the update_incident Algorithm Card. Applies field patches and FSM transitions.
|
||||||
|
capabilities:
|
||||||
|
- capability.incident.update
|
||||||
|
|
||||||
|
- id: agent.event_emitter
|
||||||
|
type: system_api
|
||||||
|
name: Case event emitter
|
||||||
|
description: Host capability event.emit@1, governed by the emit_event Algorithm Card. Append-only timeline writer.
|
||||||
|
capabilities:
|
||||||
|
- capability.event.emit
|
||||||
|
|
||||||
|
bindings:
|
||||||
|
- source: { type: bpmn.serviceTask, ref: Task_NormalizeSignal }
|
||||||
|
targetId: agent.intake_normalizer
|
||||||
|
mode: autonomous
|
||||||
|
contract:
|
||||||
|
input:
|
||||||
|
- { name: signal_id, type: string, required: true }
|
||||||
|
output:
|
||||||
|
- { name: normalized_payload, type: object }
|
||||||
|
- { name: dedupe_hash, type: string }
|
||||||
|
- { name: source_kind, type: string }
|
||||||
|
timeout: "5s"
|
||||||
|
requiredCapabilities: [capability.intake.normalize]
|
||||||
|
|
||||||
|
- source: { type: bpmn.serviceTask, ref: Task_ClassifyIncident }
|
||||||
|
targetId: agent.classifier
|
||||||
|
mode: autonomous
|
||||||
|
contract:
|
||||||
|
input:
|
||||||
|
- { name: payload, type: object, required: true }
|
||||||
|
- { name: text, type: string }
|
||||||
|
output:
|
||||||
|
- { name: taxonomy_code, type: string }
|
||||||
|
- { name: confidence, type: number, description: "0.0-1.0 model confidence" }
|
||||||
|
- { name: reasoning, type: string }
|
||||||
|
- { name: label_hint, type: string }
|
||||||
|
timeout: "30s"
|
||||||
|
requiredCapabilities: [capability.ai.classify]
|
||||||
|
|
||||||
|
- source: { type: bpmn.serviceTask, ref: Task_SuggestPriority }
|
||||||
|
targetId: agent.priority_suggester
|
||||||
|
mode: autonomous
|
||||||
|
contract:
|
||||||
|
input:
|
||||||
|
- { name: severity, type: string, required: true }
|
||||||
|
- { name: service_tier, type: string, required: true }
|
||||||
|
- { name: classification, type: string, required: true }
|
||||||
|
output:
|
||||||
|
- { name: priority, type: string }
|
||||||
|
- { name: reason, type: string }
|
||||||
|
timeout: "30s"
|
||||||
|
requiredCapabilities: [capability.ai.suggest_priority]
|
||||||
|
|
||||||
|
- source: { type: bpmn.serviceTask, ref: Task_EvaluatePriorityDmn }
|
||||||
|
targetId: agent.dmn_evaluator
|
||||||
|
mode: autonomous
|
||||||
|
contract:
|
||||||
|
input:
|
||||||
|
- { name: package_id, type: string, required: true }
|
||||||
|
- { name: decision_id, type: string, required: true }
|
||||||
|
- { name: inputs, type: object, required: true }
|
||||||
|
output:
|
||||||
|
- { name: output, type: object }
|
||||||
|
- { name: hit_rule_ids, type: array }
|
||||||
|
- { name: hit_policy, type: string }
|
||||||
|
timeout: "5s"
|
||||||
|
requiredCapabilities: [capability.dmn.evaluate]
|
||||||
|
|
||||||
|
- source: { type: bpmn.serviceTask, ref: Task_EvaluateOwnershipDmn }
|
||||||
|
targetId: agent.dmn_evaluator
|
||||||
|
mode: autonomous
|
||||||
|
contract:
|
||||||
|
input:
|
||||||
|
- { name: package_id, type: string, required: true }
|
||||||
|
- { name: decision_id, type: string, required: true }
|
||||||
|
- { name: inputs, type: object, required: true }
|
||||||
|
output:
|
||||||
|
- { name: output, type: object }
|
||||||
|
- { name: hit_rule_ids, type: array }
|
||||||
|
- { name: hit_policy, type: string }
|
||||||
|
timeout: "5s"
|
||||||
|
requiredCapabilities: [capability.dmn.evaluate]
|
||||||
|
|
||||||
|
- source: { type: bpmn.serviceTask, ref: Task_EvaluateRoutingDmn }
|
||||||
|
targetId: agent.dmn_evaluator
|
||||||
|
mode: autonomous
|
||||||
|
contract:
|
||||||
|
input:
|
||||||
|
- { name: package_id, type: string, required: true }
|
||||||
|
- { name: decision_id, type: string, required: true }
|
||||||
|
- { name: inputs, type: object, required: true }
|
||||||
|
output:
|
||||||
|
- { name: output, type: object }
|
||||||
|
- { name: hit_rule_ids, type: array }
|
||||||
|
- { name: hit_policy, type: string }
|
||||||
|
timeout: "5s"
|
||||||
|
requiredCapabilities: [capability.dmn.evaluate]
|
||||||
|
|
||||||
|
- source: { type: bpmn.serviceTask, ref: Task_UpdateIncident }
|
||||||
|
targetId: agent.incident_updater
|
||||||
|
mode: autonomous
|
||||||
|
contract:
|
||||||
|
input:
|
||||||
|
- { name: case_id, type: string, required: true }
|
||||||
|
- { name: patch, type: object, required: true }
|
||||||
|
- { name: status, type: string }
|
||||||
|
- { name: reason, type: string }
|
||||||
|
output:
|
||||||
|
- { name: case_id, type: string }
|
||||||
|
- { name: new_status, type: string }
|
||||||
|
- { name: success, type: boolean }
|
||||||
|
- { name: event_ids, type: array }
|
||||||
|
timeout: "10s"
|
||||||
|
requiredCapabilities: [capability.incident.update]
|
||||||
|
|
||||||
|
- source: { type: bpmn.serviceTask, ref: Task_DraftResponse }
|
||||||
|
targetId: agent.response_drafter
|
||||||
|
mode: supervised
|
||||||
|
contract:
|
||||||
|
input:
|
||||||
|
- { name: case_id, type: string, required: true }
|
||||||
|
- { name: locale, type: string }
|
||||||
|
- { name: what_happened, type: string, required: true }
|
||||||
|
- { name: eta_minutes, type: number }
|
||||||
|
output:
|
||||||
|
- { name: subject_lv, type: string }
|
||||||
|
- { name: subject_en, type: string }
|
||||||
|
- { name: body_lv, type: string }
|
||||||
|
- { name: body_en, type: string }
|
||||||
|
- { name: locale, type: string }
|
||||||
|
timeout: "60s"
|
||||||
|
requiredCapabilities: [capability.ai.draft_response]
|
||||||
|
|
||||||
|
- source: { type: bpmn.serviceTask, ref: Task_EmitEvent }
|
||||||
|
targetId: agent.event_emitter
|
||||||
|
mode: autonomous
|
||||||
|
contract:
|
||||||
|
input:
|
||||||
|
- { name: case_id, type: string, required: true }
|
||||||
|
- { name: type, type: string, required: true }
|
||||||
|
- { name: payload, type: object }
|
||||||
|
- { name: actor_label, type: string }
|
||||||
|
output:
|
||||||
|
- { name: event_id, type: string }
|
||||||
|
- { name: recorded_at, type: string }
|
||||||
|
timeout: "5s"
|
||||||
|
requiredCapabilities: [capability.event.emit]
|
||||||
35
tests/bpmn/triage-link-down.test.yaml
Normal file
35
tests/bpmn/triage-link-down.test.yaml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
kind: uapf.test.bpmn
|
||||||
|
target: bpmn/incident-triage.bpmn
|
||||||
|
process_id: Process_IncidentTriage
|
||||||
|
name: triage-link-down
|
||||||
|
description: |
|
||||||
|
End-to-end happy path: a Zabbix link-down event arrives, classifies as
|
||||||
|
network.routing, gets prioritised P1 by the priority DMN, owned by LVRTC,
|
||||||
|
routed to noc-l2, the case transitions to triaged, a Latvian customer
|
||||||
|
draft is proposed, and a 'routed' event is emitted.
|
||||||
|
|
||||||
|
input:
|
||||||
|
signal_id: "11111111-1111-1111-1111-111111111111"
|
||||||
|
payload:
|
||||||
|
title: "Link down on edge router rtr-r1"
|
||||||
|
host: "rtr-r1.lvrtc.lv"
|
||||||
|
severity: "high"
|
||||||
|
description: "BGP session also flapping"
|
||||||
|
|
||||||
|
expected_steps_completed:
|
||||||
|
- Task_NormalizeSignal
|
||||||
|
- Task_ClassifyIncident
|
||||||
|
- Task_SuggestPriority
|
||||||
|
- Task_EvaluatePriorityDmn
|
||||||
|
- Task_EvaluateOwnershipDmn
|
||||||
|
- Task_EvaluateRoutingDmn
|
||||||
|
- Task_UpdateIncident
|
||||||
|
- Task_DraftResponse
|
||||||
|
- Task_EmitEvent
|
||||||
|
|
||||||
|
expected_outputs:
|
||||||
|
taxonomy_code: "network.routing"
|
||||||
|
priority: "P1"
|
||||||
|
ownership: "lvrtc"
|
||||||
|
group_slug: "noc-l2"
|
||||||
|
new_status: "triaged"
|
||||||
79
uapf.yaml
Normal file
79
uapf.yaml
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
kind: uapf.package
|
||||||
|
id: lv.itsm.incident.triage
|
||||||
|
name: LVRTC Incident Triage
|
||||||
|
description: |
|
||||||
|
Level-4 UAPF process for triaging IT-infrastructure incidents at LVRTC.
|
||||||
|
|
||||||
|
Six BPMN service tasks invoke the UAPF-IP capabilities intake.normalize@1,
|
||||||
|
ai.classify@1, ai.suggest_priority@1, ai.draft_response@1,
|
||||||
|
incident.update@1 and event.emit@1. Three DMN decision tables encode the
|
||||||
|
deterministic rules previously hidden inside the host: priority maps
|
||||||
|
severity x service-tier x AI-suggestion x classification onto P1-P4;
|
||||||
|
ownership decides whether the case stays inside LVRTC or hands off to an
|
||||||
|
external partner; routing picks the expert group (helpdesk-l1, noc-l1/l2,
|
||||||
|
soc-l2, facility-l2, platform-l2, external-handoff).
|
||||||
|
|
||||||
|
Classification, priority suggestion and customer response drafting are AI
|
||||||
|
steps; the rules that decide *what* the AI proposes versus *who* handles
|
||||||
|
it live in versioned DMN, not Python. Drafted customer responses are
|
||||||
|
produced in both Latvian and English and require human approval before
|
||||||
|
sending (governed by Algorithm Card algo.incident_triage.draft_response).
|
||||||
|
|
||||||
|
v1.0.0 targets UAPF v2.5.0: algorithm cards carry embedded `tests`
|
||||||
|
arrays (>=2 per card) per chapter 13.16; BPMN service tasks carry
|
||||||
|
uapf24:algorithmCardRef attributes; resource targets are dispatch
|
||||||
|
endpoints only.
|
||||||
|
|
||||||
|
level: 4
|
||||||
|
version: "1.0.0"
|
||||||
|
|
||||||
|
requires_capabilities:
|
||||||
|
- intake.normalize@1+
|
||||||
|
- ai.classify@1+
|
||||||
|
- ai.suggest_priority@1+
|
||||||
|
- ai.draft_response@1+
|
||||||
|
- dmn.evaluate@1+
|
||||||
|
- incident.update@1+
|
||||||
|
- event.emit@1+
|
||||||
|
|
||||||
|
profiles_supported:
|
||||||
|
- uapf-ip-orchestrated
|
||||||
|
|
||||||
|
guardrails: resources/guardrails.yaml
|
||||||
|
includes: []
|
||||||
|
dependencies: {}
|
||||||
|
|
||||||
|
cornerstones:
|
||||||
|
bpmn: true
|
||||||
|
dmn: true
|
||||||
|
cmmn: false
|
||||||
|
resources: true
|
||||||
|
|
||||||
|
paths:
|
||||||
|
bpmn: bpmn
|
||||||
|
dmn: dmn
|
||||||
|
resources: resources
|
||||||
|
metadata: metadata
|
||||||
|
|
||||||
|
|
||||||
|
exposure:
|
||||||
|
mcp:
|
||||||
|
enabled: true
|
||||||
|
runnable: true
|
||||||
|
exposedEntrypoints:
|
||||||
|
- "Process_IncidentTriage"
|
||||||
|
exposedArtifacts:
|
||||||
|
- manifest
|
||||||
|
- bpmn
|
||||||
|
- dmn
|
||||||
|
- docs
|
||||||
|
|
||||||
|
owners:
|
||||||
|
- type: team
|
||||||
|
id: lvrtc
|
||||||
|
contact: incident-mgmt@lvrtc.lv
|
||||||
|
- type: team
|
||||||
|
id: openitsm-stewards
|
||||||
|
contact: stewards@openitsm.algomation.io
|
||||||
|
|
||||||
|
lifecycle: draft
|
||||||
Reference in New Issue
Block a user