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