Back to list
groeimetai

sla-management

by groeimetai

🤖 AI-powered ServiceNow development with 400+ MCP tools. Works with Claude, GPT, Gemini, Ollama & 75+ providers. Deploy widgets, manage incidents, automate workflows - all through natural language. Open-source Build Agent alternative.

42🍴 9📅 Jan 23, 2026

SKILL.md


name: sla-management description: This skill should be used when the user asks to "create SLA", "service level agreement", "SLA definition", "SLA workflow", "task SLA", "breach", "response time", "resolution time", or any ServiceNow SLA Management development. license: Apache-2.0 compatibility: Designed for Snow-Code and ServiceNow development metadata: author: groeimetai version: "1.0.0" category: servicenow tools:

  • snow_sla_definition_create
  • snow_query_table
  • snow_find_artifact
  • snow_execute_script_with_output

SLA Management for ServiceNow

SLA (Service Level Agreement) Management tracks and ensures service commitments are met.

SLA Components

ComponentTablePurpose
SLA Definitioncontract_slaSLA rules and conditions
Task SLAtask_slaSLA instance on a task
SLA Workflowwf_workflowSLA breach notifications
SLA Schedulecmn_scheduleBusiness hours definition

SLA Flow

Task Created
    ↓
SLA Definition Conditions Match
    ↓
Task SLA Record Created
    ↓
Timer Starts (based on schedule)
    ↓
SLA Stages: In Progress → Breached (if not met)
    ↓
Task Resolved/Closed
    ↓
SLA Achieved or Breached

SLA Definition (ES5)

Create SLA Definition

// Create SLA Definition (ES5 ONLY!)
var sla = new GlideRecord('contract_sla');
sla.initialize();

// Basic info
sla.setValue('name', 'P1 Incident Response Time');
sla.setValue('type', 'SLA');  // SLA, OLA, UC
sla.setValue('table', 'incident');

// Target duration
sla.setValue('duration_type', 'response');  // response or resolution
sla.setValue('duration', 'PT15M');  // 15 minutes (ISO 8601)

// Conditions - when SLA attaches
sla.setValue('start_condition', 'priority=1^active=true');
sla.setValue('stop_condition', 'work_notes.changesTo()');
sla.setValue('pause_condition', 'state=3');  // Pause when On Hold
sla.setValue('cancel_condition', 'state=8');  // Cancel when Cancelled

// Schedule (business hours)
sla.setValue('schedule', getScheduleSysId('8-5 M-F'));

// Enable
sla.setValue('active', true);

sla.insert();

SLA Conditions Explained

// Start Condition: When SLA timer begins
// Example: P1 incidents when created
var startCondition = 'priority=1^active=true^sys_created_onRELATIVEGT@minute@ago@0';

// Stop Condition: When SLA is achieved
// Example: When work notes are added (response) or resolved (resolution)
var responseStop = 'work_notes.changes()';
var resolutionStop = 'state=6^ORstate=7';  // Resolved or Closed

// Pause Condition: Timer pauses
// Example: On Hold or Awaiting User Info
var pauseCondition = 'state=3^ORstate=-5';

// Cancel Condition: SLA cancelled without breach
// Example: Incident cancelled or duplicate
var cancelCondition = 'state=8^ORclose_code=Duplicate';

Task SLA Operations (ES5)

Query Task SLAs

// Find SLAs for an incident (ES5 ONLY!)
var incidentSysId = 'incident_sys_id';

var taskSla = new GlideRecord('task_sla');
taskSla.addQuery('task', incidentSysId);
taskSla.query();

while (taskSla.next()) {
    gs.info('SLA: ' + taskSla.sla.getDisplayValue() +
            ' | Stage: ' + taskSla.stage.getDisplayValue() +
            ' | Breached: ' + taskSla.getValue('has_breached') +
            ' | Planned End: ' + taskSla.getValue('planned_end_time'));
}

Check SLA Status

// SLA Status Helper (ES5 ONLY!)
var SLAHelper = Class.create();
SLAHelper.prototype = {
    initialize: function() {},

    /**
     * Get SLA status for a task
     * @param {string} taskSysId - Task sys_id
     * @returns {Array} - Array of SLA status objects
     */
    getSLAStatus: function(taskSysId) {
        var slaStatuses = [];

        var taskSla = new GlideRecord('task_sla');
        taskSla.addQuery('task', taskSysId);
        taskSla.addQuery('active', true);
        taskSla.query();

        while (taskSla.next()) {
            var now = new GlideDateTime();
            var plannedEnd = new GlideDateTime(taskSla.getValue('planned_end_time'));
            var timeLeft = GlideDateTime.subtract(now, plannedEnd);

            slaStatuses.push({
                name: taskSla.sla.getDisplayValue(),
                stage: taskSla.stage.getDisplayValue(),
                hasBreached: taskSla.getValue('has_breached') === 'true',
                percentageComplete: taskSla.getValue('percentage'),
                plannedEnd: taskSla.getValue('planned_end_time'),
                timeLeft: this._formatDuration(timeLeft),
                isAtRisk: this._isAtRisk(taskSla)
            });
        }

        return slaStatuses;
    },

    /**
     * Check if any SLA is at risk (>75% elapsed)
     */
    _isAtRisk: function(taskSla) {
        var percentage = parseFloat(taskSla.getValue('percentage'));
        return percentage >= 75 && taskSla.getValue('has_breached') !== 'true';
    },

    _formatDuration: function(duration) {
        var totalSeconds = duration.getNumericValue() / 1000;
        var hours = Math.floor(totalSeconds / 3600);
        var minutes = Math.floor((totalSeconds % 3600) / 60);
        return hours + 'h ' + minutes + 'm';
    },

    type: 'SLAHelper'
};

Pause/Resume SLA

// Pause SLAs when incident goes On Hold (ES5 ONLY!)
// Business Rule: after, update, incident

(function executeRule(current, previous) {
    // Check if state changed to On Hold
    if (current.state.changesTo('3')) {
        pauseIncidentSLAs(current.getUniqueValue());
    }

    // Check if state changed from On Hold
    if (previous.state == '3' && current.state != '3') {
        resumeIncidentSLAs(current.getUniqueValue());
    }
})(current, previous);

function pauseIncidentSLAs(incidentId) {
    var taskSla = new GlideRecord('task_sla');
    taskSla.addQuery('task', incidentId);
    taskSla.addQuery('active', true);
    taskSla.addQuery('stage', '!=', 'breached');
    taskSla.query();

    while (taskSla.next()) {
        var slaDef = new GlideRecord('contract_sla');
        if (slaDef.get(taskSla.getValue('sla'))) {
            // Only pause if SLA has pause condition
            if (slaDef.getValue('pause_condition')) {
                taskSla.pause = true;
                taskSla.pause_time = new GlideDateTime();
                taskSla.update();
            }
        }
    }
}

SLA Workflows

Breach Notification Script (ES5)

// SLA Workflow Activity: Send breach notification (ES5 ONLY!)
(function executeActivity() {
    var taskSla = current;
    var task = taskSla.task.getRefRecord();

    // Get escalation recipients
    var recipients = [];

    // Add assigned user
    if (task.assigned_to) {
        recipients.push(task.assigned_to.getValue('email'));
    }

    // Add assignment group manager
    if (task.assignment_group) {
        var group = task.assignment_group.getRefRecord();
        if (group.manager) {
            recipients.push(group.manager.email);
        }
    }

    // Send notification
    if (recipients.length > 0) {
        gs.eventQueue('sla.breach.notification', task, recipients.join(','), taskSla.sla.getDisplayValue());
    }
})();

SLA Escalation Rules

// SLA Escalation Script Include (ES5 ONLY!)
var SLAEscalation = Class.create();
SLAEscalation.prototype = {
    initialize: function() {},

    /**
     * Escalate breached SLA
     */
    escalateBreached: function(taskSlaSysId) {
        var taskSla = new GlideRecord('task_sla');
        if (!taskSla.get(taskSlaSysId)) {
            return false;
        }

        var task = taskSla.task.getRefRecord();

        // Increase priority
        var currentPriority = parseInt(task.getValue('priority'), 10);
        if (currentPriority > 1) {
            task.setValue('priority', currentPriority - 1);
        }

        // Set escalation flag
        task.setValue('escalation', 1);

        // Add work note
        task.work_notes = 'SLA Breached: ' + taskSla.sla.getDisplayValue() +
                         '\nAutomatic escalation applied.';

        task.update();

        // Notify on-call
        this._notifyOnCall(task);

        return true;
    },

    _notifyOnCall: function(task) {
        // Get on-call schedule
        var oncall = new OnCallRotation();
        var onCallUser = oncall.getOnCallUser(task.assignment_group);

        if (onCallUser) {
            gs.eventQueue('sla.oncall.notification', task, onCallUser.sys_id, '');
        }
    },

    type: 'SLAEscalation'
};

SLA Reports

SLA Compliance Query (ES5)

// Calculate SLA compliance rate (ES5 ONLY!)
function getSLAComplianceRate(slaName, startDate, endDate) {
    var ga = new GlideAggregate('task_sla');
    ga.addQuery('sla.name', slaName);
    ga.addQuery('end_time', '>=', startDate);
    ga.addQuery('end_time', '<=', endDate);
    ga.addQuery('active', false);  // Completed SLAs only
    ga.addAggregate('COUNT');
    ga.addAggregate('COUNT', 'has_breached');
    ga.groupBy('has_breached');
    ga.query();

    var total = 0;
    var breached = 0;

    while (ga.next()) {
        var count = parseInt(ga.getAggregate('COUNT'), 10);
        total += count;
        if (ga.getValue('has_breached') === 'true') {
            breached = count;
        }
    }

    if (total === 0) {
        return { compliance: 100, total: 0, breached: 0 };
    }

    var achieved = total - breached;
    var compliance = Math.round((achieved / total) * 100 * 10) / 10;

    return {
        compliance: compliance,
        total: total,
        achieved: achieved,
        breached: breached
    };
}

// Usage
var stats = getSLAComplianceRate('P1 Incident Response',
    gs.beginningOfThisMonth(),
    gs.endOfThisMonth());
gs.info('P1 Response SLA Compliance: ' + stats.compliance + '%');

MCP Tool Integration

Available Tools

ToolPurpose
snow_find_artifactFind SLA definitions
snow_query_tableQuery task_sla records
snow_execute_script_with_outputTest SLA scripts
snow_create_business_ruleCreate SLA triggers

Example Workflow

// 1. Find existing SLAs
await snow_find_artifact({
    type: 'contract_sla',
    name: 'P1'
});

// 2. Query SLA breaches
await snow_query_table({
    table: 'task_sla',
    query: 'has_breached=true^end_time>=javascript:gs.beginningOfThisMonth()',
    fields: 'sla,task,end_time,business_duration'
});

// 3. Check SLA compliance
await snow_execute_script_with_output({
    script: 'var stats = getSLAComplianceRate("P1 Response", gs.beginningOfThisMonth(), gs.endOfThisMonth()); gs.info(JSON.stringify(stats));'
});

Best Practices

  1. Clear Names - "P1 Incident Response 15min"
  2. Business Hours - Use appropriate schedules
  3. Pause Conditions - Pause for external waits
  4. Escalation - Notify before breach
  5. Metrics - Track compliance rates
  6. Testing - Test with various scenarios
  7. Documentation - Document SLA terms
  8. ES5 Only - No modern JavaScript syntax

Score

Total Score

75/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon