メインコンテンツへスキップ
見出し画像

問題管理モジュールの連携機能


    Problemのフォームには、起票元のIncidentへ戻る参照フィールドが見当たりません。Changeへつながる rfc はあるのに、Incident側にはそれらしい列が無いのです。では「このProblemはどのIncidentから来たのか」は、どこで追えるのでしょうか。Australia の PDI をデフォルト設定のまま開き、Incident・Change・Known Error・Problem Task との接続経路を実機で確かめました。

    検証環境:Australia PDI / OOTB / 2026-08-31 確認

    確認する連携先

    • Incidentから問題を起票する経路の有無

    • 問題からChangeを起票するときに引き継がれる項目

    • Known Error記事へのつながり方

    • problem_task による作業分担

    • インシデントへ回避策や対策を書き戻す仕組み

    連携の全体像

    • Problemを参照する実テーブルは duplicate_of(自己参照)と problem_task.problem の2つだけで、Incidentとの接続は名前だけが残った列に頼った作りになっている

    • Changeへの起票はUIアクションが専任し、生成した変更のIDを rfc へ書き戻す

    • Known Error記事とWorkaround/Fixの転記は、それぞれ別の仕組み(テーブルマップのリダイレクト/イベント経由のScript Action)で実装されている

    問題管理から他プロセスへつながる経路

    問題管理からの接続経路を、まず全体で見渡します。


    画像


    画像

    経路は性質の違う3種類に分かれます。

    • 参照フィールド:列に相手のsys_idを持つ。duplicate_of と problem_task.problem

    • UIアクション:ボタンを押して相手のレコードを新規作成し、参照フィールドへ書き戻す

    • 名前だけが残る列:Incidentとの接続だけがこの形。メタデータには現れないが、ACL・Business Rule・プロパティの3か所に problem_id という名前だけが残っている。クエリでは機能しない

    3番目が、この記事でいちばん詳しく確認する経路です。

    Incidentから問題を起票するボタンは用意されていない

    Incidentのフォームボタンを1つずつ確認しました。


    画像

    Create Request Create Emergency Change Create Change Request Create child incident Create Incident Task の5件は他レコードを作るボタンですが、「Create Problem」に相当するボタンは1件もありません。action_nameを problem で検索しても該当は0件でした。

    一方で sys_properties には com.snc.problem.create_from_incident.attributes というプロパティが存在します。値は次の12項目です。

    description,short_description,cmdb_ci,impact,urgency,priority,company,sys_domain,business_service,service_offering,category,subcategory

    公式説明を引用します。

    List of attributes (comma-separated) that will be copied from the incident to create a new problem

    (訳: インシデントから新しい問題を作成する際にコピーされる属性のカンマ区切りリスト)

    引用元: /sys_properties_list.do?sysparm_query=name=com.snc.problem.create_from_incident.attributes

    つまり、「Incidentから問題を起票する」という動作自体は製品として想定されています。ただしクラシックUIのフォームボタンとしては実装されていません。Agent Workspaceの関連レコード機能など、別の経路から呼ばれている可能性が高いものの、本記事の検証範囲では実体を確認できませんでした。手順書やチェックリストを作るときは、「Incidentのフォームを開いてもボタンは無い」という事実を前提にします。

    incident.problem_id という名前だけが複数の設定に残っている

    Incidentからつながる先を探すと、ボタンではなく1つの列の"痕跡"に行き当たりました。


    画像

    sys_dictionary を name=incident^element=problem_id で検索すると0件です。REST APIで sysparm_fields=problem_id を指定しても、レスポンスにキー自体が返りません。メタデータの上では、このフィールドは存在しないことになっています。

    ACLは3件、Business Ruleのスクリプト文字列にも problem_id という名前が残っていました。ここで「メタデータには無いが、実際には機能する列なのでは」という仮説を立て、クエリで確かめました。


    画像

    problem_idISNOTEMPTY で絞り込んでも、Incidentの総件数(73件)と同じ件数が返ります。絞り込みが一切効いていません。念のため実在しない架空のフィールド名(totally_fake_field_xyzISNOTEMPTY)で同じクエリを試したところ、結果はやはり73件でした。つまり problem_id は、架空のフィールド名を指定した場合とまったく同じ挙動になります。ServiceNowのクエリ解析は、辞書に無いフィールド名を含む条件をエラーにせず黙って読み飛ばし、残りの条件だけで全件を返します。

    ここで確認できたのは、一覧・REST経由のクエリ文字列(sysparm_query)を解析する層の挙動です。Business RuleやScript Actionは GlideRecord.addQuery("problem_id", ...) のように、スクリプトAPIで直接同じ列名を指定しています。これが同様に無視されるのか、それとも異なる結果になるのかは、読み取り専用の今回の調査では確認できていません。この記事でスクリプトの中身を紹介する箇所では、「そのスクリプトが書かれている」という事実と、「そのスクリプトが意図どおりに動く」という保証を分けて扱います。


    画像


    画像


    画像

    残っている痕跡は3種類です。ACL 3件(itil や problem_coordinator などのロールに読み書き範囲を与える定義)、Business Rule 1件(SNC - ITIL - Update Related Incidents のスクリプト内に addQuery("problem_id", ...) という記述)、プロパティ2件(値の文字列として problem_id を含む)です。どれも設定の中に残った記述であり、実行結果を示すものではありません。

    This is for getting 'Add' ui action functionality of incidents related list on problem.

    (訳: これはProblem上のIncidents関連リストで「Add」UIアクションの機能を得るための設定)

    引用元: /sys_properties_list.do?sysparm_query=name=com.snc.incident.link_to_task.problem

    このプロパティは、Problemフォームの「Incidents」関連リストが problem_id という名前を前提に設定されていることを示しています。ただし、一覧・REST経由のクエリでは条件として機能しないことがすでに分かっているため、この関連リストが実際に正しい行を表示できているかどうかは、今回の検証だけでは判断できません。ACL・Business Rule・プロパティのいずれも「かつてこの名前の列が実在した」ことを示す設定であり、「今も機能する列である」ことの証拠にはならない、と切り分けて考える必要があります。

    古いバージョンで実在していた参照フィールドが、辞書上は削除・非表示化された一方、それを前提にしたACLやスクリプトの記述だけが整理されずに残った状態と見るのが、もっとも無理のない説明です。手順書やチェックリストでこの列に依存した設計を見つけたら、実際にクエリが効くかどうかを自分の環境で先に確認します。

    related_incidentsの非ゼロ値は集計ではなく登録時の値と考えられる

    problem.related_incidents(件数を保持する項目)を更新する処理として、Incident側にBusiness Rule Update Problem Incident Count が存在します。条件は current.problem_id.changes()。処理は GlideAggregate で problem_id=<問題のsys_id> のIncidentを数え、related_incidents に書き込むという単純な集計です。

    ただし前節で確認したとおり、problem_id は一覧・REST経由のクエリでは条件として機能しません。current.problem_id.changes() という判定条件についても、辞書に無いフィールドへのdot-walkが安定して機能する保証は無く、実際にこのBusiness Ruleが稼働しているかどうかは今回の検証では実証できていません。

    実データでは PRB0000007 が related_incidents=2 を持ちながら、first_reported_by_task はINC0000001の1件だけを指しています。この「2」という値がどの2件のIncidentを指すのかを、Problem側から辿る手段はありません。値そのものは、Business Ruleが都度算出した最新の集計値というより、デモデータの登録時にあらかじめ設定された固定値である可能性を考慮しておくべきです。

    自社でIncidentとProblemの多対1の関係を正確に追跡したいなら、problem_id に依存する設計は避けます。辞書に定義があり実際に機能する problem.first_reported_by_task(Task型の参照フィールド)を起点にし、複数件の関連を扱う必要があるなら、独自の参照フィールドか関連テーブルを設計し直すのが確実です。

    問題からChangeを起票するときはUIアクションが項目をコピーする

    Change側には problem を参照する列がありません。接続は問題側の rfc と、2件のUIアクションが担っています。


    画像


    画像

    Create Normal Change と Create Emergency Change の2件だけで、Standard Changeを作るボタンはありません。表示条件は共通で gs.hasRole("itil,sn_change_write") && current.rfc.nil()。rfc が未設定のときだけ表示されるため、同じ問題から二重にChangeを作ることはできません。

    スクリプトの中身は2件ともほぼ同じ形です。

    var changeRequest = ChangeRequest.newNormal(); // Emergencyは newEmergency()
    changeRequest.setValue("short_description", current.short_description);
    changeRequest.setValue("description", current.description);
    changeRequest.setValue("cmdb_ci", current.cmdb_ci);
    if (changeRequest.hasValidChoice('priority', current.priority))
        changeRequest.setValue("priority", current.priority);
    changeRequest.setValue("sys_domain", current.sys_domain);
    changeRequest.setValue("company", current.company);
    changeRequest.insert();
    
    current.rfc = changeRequest.getGlideRecord().getUniqueValue();
    current.update();

    コピーは6項目、priorityだけ「Change側に有効な選択肢がある場合のみ」という条件付きです。生成した変更のsys_idを最後に rfc へ書き戻しているため、Problemのフォームから作った変更は必ず rfc 経由でたどれます。

    普段からProblemModel(prb_model)を使って独自の状態遷移を組んでいる場合でも、このUIアクションの動きは変わりません。恒久対策に構成変更が要ると分かった時点で、担当者はこの2つのボタンのどちらかを押すだけで足ります。

    Known Errorの記事はテーブルマップ経由で作られる

    原因は特定できたが恒久対策がまだ無い状態を、ServiceNowは Known Error という概念で扱います。公式説明を引用します。

    Root cause has been determined and there is a workaround but there is NO permanent fix

    (訳: 根本原因が特定され、回避策はあるが、恒久的な対策はまだ無い)

    引用元: /sys_documentation_list.do?sysparm_query=name=problem^element=known_error

    この定義を実装しているのが known_error(チェックボックス)と primary_known_error_article(記事への参照)の2項目、そして Create Known Error article というUIアクションです。


    画像

    Create Known Error article のスクリプトを見ると、GlideRecordで直接記事をinsertしていません。

    var map = new global.CSMTableMapUtil(current);
    map.findMapByName("problem_known_error_article");
    var targetURL = map.getTargetURL();
    if (targetURL) {
        action.setReturnURL(current);
        action.setRedirectURL(targetURL[0]);
    }

    テーブルマップから記事作成フォームのURLを取得してリダイレクトするだけです。記事は kb_template_known_error_article(super_class は Knowledge)に作られ、problem.knowledgebase.known_error_article プロパティが指す「Known Error」というナレッジベースに置かれます。

    Knowledge を継承するテーブルは task を継承しません。Problem・Incident・Changeがどれも task の子であるのに対し、記事だけは別の系統に属します。承認や公開範囲の考え方もtask系とは別に用意されているため、Known Error記事を運用に組み込むときはナレッジ管理側の承認フローとして扱う必要があります。

    known_errorと記事の有無は連動していない


    画像


    画像

    実データを突き合わせると、known_error=true の3件(PRB0000006/12/14)は primary_known_error_article が空欄でした。逆に記事が設定されている5件は、いずれも known_error=false です。

    known_error は担当者が「回避策はあるが恒久対策が無い」と判断したときに立てる手動フラグで、記事の作成とは別に管理されています。チェックを入れても記事が自動生成されるわけではなく、記事を作っても元のチェックが連動して立つわけでもありません。自社で運用するなら、記事を作った時点で known_error も併せて立てる手順をチェックリストに明記しておく必要があります。

    Workaround・Fixはイベント経由でIncidentの作業メモへ転記される

    回避策や対策方針が決まったら、関連するIncidentへ知らせる仕組みがあります。

    Communicate Workaround ボタンのスクリプトは、workaround_communicated_at/_by を記録して gs.eventQueue('communicate.workaround', current, current.workaround) を発行するだけです。実際に転記処理を行うのは別のScript Actionでした。


    画像


    画像

    communicate.workaround イベントには2件のScript Actionが登録されています。どちらも incident.addQuery('problem_id', current.getUniqueValue()) で対象を絞り込んだうえで、1件はプラグイン構成でさらに state=Resolved かつ close_code=Known error に絞り、もう1件は絞り込みなしで incident_state<=Resolved の全件へ書き込みます。この2件が同じ問題に対して同時に発火する条件が重なると、work_notesへ同じ内容が2回記録される作りです。前節で確認したとおり problem_id は一覧・REST側のクエリでは機能しません。addQuery によるこの絞り込み自体が意図どおりに働いているかは別途の検証が必要ですが、スクリプトの設計としては2つの独立した経路が同じイベントに登録されていることは実測できています。

    プロパティ com.snc.incident.communicate_prb_workaround_to_inc_worknotes は true です。

    When set true, all the communication from problem record will be journeled in worknotes field in related incident.

    (訳: trueに設定すると、問題レコードからのすべてのコミュニケーションが関連インシデントの作業メモに記録される)

    引用元: /sys_properties_list.do?sysparm_query=name=com.snc.incident.communicate_prb_workaround_to_inc_worknotes

    communicate.fix の方はScript Actionが1件だけで、二重書き込みは起きません。転記が重複していると相談を受けたら、対象がWorkaroundかFixか、両方のBest Practiceプラグインが有効かどうかをまず確認します。

    problem_taskはtask直下で作業を分担する

    作業を分担する仕組みは problem_task です。


    画像

    problem_task の super_class は problem ではなく task です。3階層ではなく、task を頂点とする2階層のきょうだい関係になっています。第2巻(テーブル・フィールド構成)で確認した内容と同じ結論です。

    デモデータはPTASK0010005の1件だけでした。problem_task_type=rca(Root Cause Analysis)、親は PRB0000011、担当は「Problem Task Analyst A」という problem_task_analyst ロール保持者です。assigned_to の選択肢は sys_dictionary_override で roles=problem_task_analyst に絞られており、Problem本体の assigned_to(problem_coordinator 限定)とは対象ロールが異なります。

    原因調査を複数人で並行させたい場面では、Problem本体を1人のコーディネーターが持ちながら、problem_task を切り出してアナリストへ配分する構成が想定されています。

    重複した問題はduplicate_ofで自己参照する

    似た問題が複数起票された場合の連携です。


    画像

    実データはPRB0000105→PRB0000055の1件だけでした。resolution_code=Duplicate、state=Closed です。

    重複マーク時にどの関連レコードを付け替えるかは、プロパティ problem.duplicate.records_to_move が定義しています。値は次の3テーブルです。

    incident.problem_id,sn_customerservice_case.problem,problem_task.problem

    Business Rule Cascade closure of Problem Tasks がこの値を参照し、重複マーク時に関連するIncident・Case・Problem Taskをまとめて元の問題へ付け替える設計です。辞書に無い incident.problem_id も、この移動対象リストに名指しで含まれています。設定ファイルの中では、表に見えない列であっても実在する列と同じ扱いで名前が書かれ続けている、ということです。

    CIM(継続的改善)からの連携は既存記事に譲る

    CIM(継続的改善)からも、Problemの修正記録として追跡される経路があります。プロパティ problem.fix.records の値には change_request.parent などと並んで sn_cim_register.source_id が含まれ、CIMの改善登録がProblemの対策記録として扱われることを示す形です。この経路の中身はすでに別記事で扱っているため、本記事では引き継ぎ項目の存在だけを示し、詳しい仕組みはそちらへ委ねます。

    Incidentから問題解決までの判断の流れを一枚で見る

    ここまでの経路を、実際の対応の流れに置き換えます。


    画像

    同じIncidentが繰り返し起票されたら、担当者がProblemを作成し first_reported_by_task に元のIncidentを記録します。Root Cause Analysisで原因を特定したあと、分かれ道は1つです。

    • 恒久対策がすぐ効く:Create Normal/Emergency Change で変更を起票し、rfc に紐づける

    • 回避策だけで当面をしのぐ:Create Known Error article で記事を作り、primary_known_error_article に紐づける

    どちらの道を選んでも、Resolvedへ進む段階で Communicate Workaround や Communicate Fix を押せば、関連するIncidentへ内容が自動で転記されます。担当者が個別にIncidentを開いて手動で書き込む必要はありません。

    実機で気づいたこと

    problem_stateが整数値「4」になることは実質ない

    SNC - ITIL - Update Related Incidents は problem_state.changesTo(4) で発火する設計です。実データを確認すると、24件中22件は state(101〜107)と problem_state が完全に同じ値でした。BR「Copy State to Problem State」が problem_state SAMEAS state という宣言的コピーを行うため、Madridステートモデルを使う限り problem_state は101〜107の値しか取りません。

    つまり標準ボタン(Assess/Confirm/Fix/Resolve/Complete)による通常の状態遷移では、problem_state が整数値の「4」になる場面がありません。旧来の1〜7という値の体系を前提にした条件式が、現行の状態モデルの下では事実上発火しないコードとして残っている状態です。加えてこのルールが検索条件に使う problem_id 自体、前節で確認したとおり一覧・REST側のクエリでは機能しません。二重の意味で、動いているように見えて実は発火しないルールになっている可能性があります。メジャーアップグレードのたびにこうした古い条件式が増えていないか、order順の一覧と条件式を突き合わせておく価値があります。

    記事の有無を示す2つのフラグが噛み合っていない

    known_error=true の3件と primary_known_error_article 設定済みの5件は、実データ上で1件も重なりませんでした。ボタンを押して記事を作っても手動チェックの known_error は連動せず、逆に known_error を立てても記事は自動生成されません。Known Error該当の問題を一覧するレポートを作るなら、どちらか一方の条件だけで絞り込むと漏れが出ます。両方をORで確認する運用にします。

    Workaroundの転記経路が2件重複して登録されている

    communicate.workaround イベントには、条件の異なる2件のScript Actionが独立して登録されています。片方はプラグインの組み合わせを見て対象を絞り、もう片方は絞り込みを持ちません。両方が有効な条件(state=Resolved かつ close_code=Known error)に当てはまるIncidentが対象になった場合、設計上は同じ回避策のメッセージがwork_notesに2回記録される作りです。実際に2回記録されるかどうかは、両方が根拠にしている incident.problem_id でのクエリが実行時にどう解釈されるか次第で、この記事の読み取り専用調査だけでは確定できません。運用担当は「Workaroundの転記が重複している」という問い合わせを受けたとき、まずこの2件の重複登録を疑う、という調べ方の起点として使えます。

    連携を設計するときに決めること

    ここまでの内容を、設計時の判断としてまとめました。


    画像

    最初に決めるのは、Incidentから問題への起票基準です。クラシックUIにボタンが無い以上、誰が・どのタイミングで問題を作るかを運用ルールとして明文化しておく必要があります。件数のしきい値だけで自動化するのか、担当者の判断に委ねるのかを先に決めます。

    次に、Known Error化と記事作成の運用を1つの手順にまとめます。フラグと記事が連動しない仕様を前提にすれば、チェックリスト側で両方を同時に確認する項目を作れます。

    用語

    • OOTB:Out of the Box。プラグイン追加やカスタマイズを行っていない、製品のデフォルト状態

    • PDI:Personal Developer Instance。ServiceNow が無償で提供する個人検証用インスタンス

    • Known Error:原因は特定できたが恒久対策がまだ無い状態。回避策の共有が中心になる

    • Script Action:イベントキューに積まれたイベントを受けて実行される、Business Ruleとは別系統の自動処理

    • テーブルマップ:あるテーブルのレコードから別テーブルの新規作成フォームへ、値を引き継いで遷移させる仕組み

    検証範囲とおことわり

    • 検証環境:Australia PDI(patch3)/ OOTB / 2026-08-31 確認(一部追加確認は2026-09-01)

    • 件数はすべてOOTBの定義・デモデータの数です。本番環境やカスタマイズ済み環境では異なります

    • Incidentから問題を起票する実際の操作(Agent Workspaceの関連レコード機能を含む)は行っていません。プロパティの存在確認までにとどめています

    • Known Error記事の作成フォームでの入力・保存は行っていません

    • Communicate Workaround/Fixのボタンを実際に押して、二重書き込みの発生を目視で確認する検証は行っていません

    • sys_relationship によるProblemフォームの関連リスト定義そのものは確認していません。プロパティの記述から推測しています

    • Business Rule・Script Action内の GlideRecord.addQuery("problem_id", ...) がサーバ側でどう解釈されるかは検証していません。確認できたのは一覧・REST側のクエリ文字列(sysparm_query)を解析する層の挙動だけです

    付録:自分の環境で確認するときのURL

    • Incidentの全UIアクション:/sys_ui_action_list.do?sysparm_query=table=incident^active=true^ORDERBYname

    • Problemの Create 系UIアクション:/sys_ui_action_list.do?sysparm_query=table=problem^nameLIKECreate^active=true

    • 辞書に無いことの確認:/sys_dictionary_list.do?sysparm_query=name=incident^element=problem_id

    • クエリが機能しないことの確認:/incident_list.do?sysparm_query=problem_idISNOTEMPTY(Incident全件と同じ件数が返る)

    • 該当ACL:/sys_security_acl_list.do?sysparm_query=name=incident.problem_id

    • Known Error記事の設定済み一覧:/problem_list.do?sysparm_query=primary_known_error_articleISNOTEMPTY

    • known_errorフラグの一覧:/problem_list.do?sysparm_query=known_error=true

    • 重複マークの一覧:/problem_list.do?sysparm_query=duplicate_ofISNOTEMPTY

    • Workaround/Fix転記のScript Action:/sysevent_script_action_list.do?sysparm_query=event_nameLIKEcommunicate

    • Problem Taskの一覧:/problem_task_list.do

    引用した公式説明を実機で確認する方法

    この記事で引用した説明文は、ServiceNow が製品に同梱しているフィールド・プロパティのドキュメントです。次のURLを自分のインスタンスで開くと、同じ記述が見つかります。

    • フィールドの公式説明(引用元):/sys_documentation_list.do?sysparm_query=name=problem^element=known_error

    • プロパティの公式説明(引用元):/sys_properties_list.do?sysparm_query=nameLIKEproblem^descriptionISNOTEMPTY

    関連記事

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ