On a plant floor the highest-stakes configuration items aren't servers — they're PLCs, SCADA historians, and the production lines they control. When a controller fails, the question isn't "which IT service degrades?" — it's "which line stops, and how much product per hour?" And a change to a controller can't ship whenever risk looks low; it has to land inside a planned maintenance window or it takes the line down mid-shift. A generic ITSM models IT dependencies and business hours; it can't see OT at all. This overlay extends the CMDB into operational technology.
The problem — and the money
The buyer is the plant's OT / reliability lead who lives between IT change control and production uptime. A minute of unplanned line downtime is measured in thousands of dollars of lost product; a controller patched outside its maintenance window is exactly how that happens. A vanilla ITSM auto- approves a low-risk change to a "device" it doesn't know drives a line. The payoff is two concrete answers: a failing PLC's blast radius reaches its production LINE (not a vague "device impacted"), and a controller change scheduled outside its line's maintenance window is routed to CAB regardless of a low risk score. That's why this overlay exists — it points the CMDB at the plant, not just the data center.
This is the ITSM suite + the manufacturing overlay. The six base skills — core, cmdb-blast-radius, change-management and the rest — are unchanged. The overlay only adds: three columns, one table, one weighted edge kind, and two gate changes. Same bucket, one copy of the rows.
What manufacturing adds
A small, additive diff on top of the suite (skill: itsm/manufacturing → the
itsm/overlays/manufacturing contract):
- Three columns on the
itsm/corecismaster —ci_class(IT | OT),site, andplant_line— added withALTER TABLE … ADD COLUMNover the pg wire. A column-add, never a second copy. - One table —
maintenance_windows(keywindow_id): planned OT downtime per production line (plant_line,ci_id,window_start,window_end,production_impact). - One edge kind —
controls(OT controller → production line) inserted into the suite'sci_edges. Unlikedepends_on, it is already impact-directional, so it is copied into the reverseimpactstable without flipping — a failing PLC reaches the lines it drives. - One rollup change — cmdb-blast-radius adds an
ot_impactrollup (impacted plant lines) alongsideimpacted_services. - One gate change — change-management gains a maintenance-window floor: a change on an OT CI
scheduled outside its line's maintenance window routes to
cab_reviewregardless of low risk.
Apply the diff — the ALTER, the window table, the OT topology, and the graph:
In the itsm bucket, apply the manufacturing overlay: ALTER cis ADD ci_class, site, plant_line; create maintenance_windows; add OT CIs (plc-line1 20, line-1 21, scada-historian 22 on plant-a / line-1); add a controls edge plc-line1->line-1; build the reverse impacts (controls unflipped) and re-CREATE GRAPH cmdb_impact; seed a maintenance window for line-1.
data_pg→data_table_create→data_table_upsertAdded ci_class/site/plant_line to cis (ALTER over pg — the master, not a copy). Created maintenance_windows. Seeded plc-line1 (OT controller), line-1 (production_line) and scada-historian on plant-a/line-1; inserted the controls edge; rebuilt impacts (controls copied unflipped) and re-created cmdb_impact; seeded the 2026-09-06 02:00-04:00 window for line-1.
export BUCKET=itsm # the SAME bucket the ITSM suite built — the overlay only ADDs
# 1) OT column-adds on the itsm/core cis master — ALTER over the pg wire, never a second copy
dodil data pg -b "$BUCKET" "ALTER TABLE cis ADD COLUMN ci_class VARCHAR"
dodil data pg -b "$BUCKET" "ALTER TABLE cis ADD COLUMN site VARCHAR"
dodil data pg -b "$BUCKET" "ALTER TABLE cis ADD COLUMN plant_line VARCHAR"
# 2) planned OT downtime per production line
dodil data table create maintenance_windows -b "$BUCKET" --merge-key window_id \
--columns-json '[{"name":"window_id","type":"string","nullable":false},{"name":"plant_line","type":"string","nullable":true},{"name":"ci_id","type":"long","nullable":true},{"name":"window_start","type":"string","nullable":true},{"name":"window_end","type":"string","nullable":true},{"name":"production_impact","type":"boolean","nullable":true}]'
# 3) OT CIs + the controls edge (partial merge onto cis; ci_edges/impacts owned by core + cmdb-blast-radius)
dodil data table upsert cis -b "$BUCKET" --merge --row '{"id":20,"name":"plc-line1","ci_type":"plc","ci_class":"OT","site":"plant-a","plant_line":"line-1"}'
dodil data table upsert cis -b "$BUCKET" --merge --row '{"id":21,"name":"line-1","ci_type":"production_line","ci_class":"OT","site":"plant-a","plant_line":"line-1"}'
dodil data table upsert ci_edges -b "$BUCKET" --row '{"src":20,"dst":21,"rel":"controls"}'
# 4) rebuild the TYPED reverse impacts — depends_on/runs_on/part_of FLIP; controls stays (already impact-directional)
dodil data pg -b "$BUCKET" "INSERT INTO impacts (src, dst) SELECT dst, src FROM ci_edges WHERE rel IN ('depends_on','runs_on','part_of')"
dodil data pg -b "$BUCKET" "INSERT INTO impacts (src, dst) SELECT src, dst FROM ci_edges WHERE rel = 'controls'"
dodil data pg -b "$BUCKET" "DROP GRAPH IF EXISTS cmdb_impact"
dodil data pg -b "$BUCKET" "CREATE GRAPH cmdb_impact NODES (cis KEY id) EDGES (impacts SRC src DST dst)"
# 5) seed a maintenance window for line-1
dodil data table upsert maintenance_windows -b "$BUCKET" --row '{"window_id":"mw-line1-1","plant_line":"line-1","ci_id":20,"window_start":"2026-09-06T02:00:00Z","window_end":"2026-09-06T04:00:00Z","production_impact":false}'Now the payoff — the OT blast radius reaching a line, and the maintenance-window floor:
In itsm, traverse the blast radius from plc-line1 (CI 20) and show it reaches the production line, rolled up to impacted plant lines. Then compute the change verdict for two OT changes on plc-line1 — one scheduled inside line-1's maintenance window, one outside.
data_pg→data_boltgraph_khop from plc-line1 (20) reaches line-1 (21) at hop 1 — 1 impacted plant line. CHG6001 (scheduled 02:30-03:00, inside the 02:00-04:00 window) = auto_approve; CHG6002 (scheduled 2026-09-07 14:00, outside any window) = cab_review — held despite low risk and the model's auto_approve.
# OT blast radius — a failing PLC reaches the production LINE (graph_khop returns column `node`)
dodil data pg -b "$BUCKET" "
SELECT k.node AS ci_id, c.name, c.ci_class, c.plant_line, k.hop_distance
FROM graph_khop('cmdb_impact', 20, 5) k JOIN cis c ON c.id = k.node ORDER BY k.hop_distance"
# 21 | line-1 | OT | line-1 | 1 <- the PLC's blast reaches its production line
# ot_impact rollup — distinct plant lines a failing OT CI takes down
dodil data pg -b "$BUCKET" "SELECT count(DISTINCT c.plant_line) AS impacted_plant_lines
FROM graph_khop('cmdb_impact', 20, 5) k JOIN cis c ON c.id = k.node WHERE c.ci_type = 'production_line'"
# 1
# the MAINTENANCE-WINDOW FLOOR — an OT change scheduled OUTSIDE its line's window -> cab_review
dodil data pg -b "$BUCKET" "
SELECT ch.number, ci.ci_class, cc.window_start AS scheduled, ch.gate_verdict AS model_says,
CASE WHEN ci.ci_class = 'OT' AND NOT EXISTS (
SELECT 1 FROM maintenance_windows mw
WHERE mw.plant_line = ci.plant_line
AND cc.window_start >= mw.window_start AND cc.window_end <= mw.window_end)
THEN 'cab_review' ELSE ch.gate_verdict END AS final_verdict
FROM changes ch JOIN cis ci ON ci.id = ch.ci_id JOIN change_calendar cc ON cc.change_id = ch.id
WHERE ch.ci_id = 20 ORDER BY ch.id"
# CHG6001 | OT | 2026-09-06T02:30 | auto_approve | auto_approve (inside the window)
# CHG6002 | OT | 2026-09-07T14:00 | auto_approve | cab_review (outside — held despite low risk)The blast-radius traversal is unchanged from the base skill — the overlay only adds the controls rel to
impact_rels so OT dependencies propagate. The change gate is unchanged too; only the deterministic floor
gains the maintenance-window clause.
Scaffold it — the one-shot
With the DODIL MCP connected, one prompt composes the suite and this overlay:
Scaffold an ITSM for my manufacturing plant — the ITSM suite plus the manufacturing overlay.
Base: the full itsm suite (core masters + CMDB blast-radius graph + sla / incident / problem /
change management) on one bucket.
Then apply the manufacturing overlay on the SAME bucket:
1. ALTER cis ADD ci_class, site, plant_line (pg wire — the master, not a copy).
2. Create maintenance_windows (key window_id) — planned OT downtime per line.
3. Add the OT controls edge to ci_edges and to impact_rels; rebuild the reverse impacts (controls stays
unflipped — it is already impact-directional) and re-CREATE GRAPH cmdb_impact so a failing PLC reaches
its production lines. Add an ot_impact rollup alongside impacted_services.
4. Add a maintenance-window floor to change-management: an OT change scheduled outside its line's window
routes to cab_review regardless of low risk.
Seed the plant demo above and show the OT blast reaching a line + the window floor holding a change.Verify
Every result below was live-validated on 2026-09-02 (org IHDIASH, throwaway bucket, torn down after):
# columns land (nullable, over the pg wire)
dodil data pg -b "$BUCKET" "ALTER TABLE cis ADD COLUMN ci_class VARCHAR" # + site, plant_line
# OT blast: plc-line1 (20) reaches line-1 (21) at hop 1
dodil data pg -b "$BUCKET" "SELECT k.node, c.name FROM graph_khop('cmdb_impact', 20, 5) k
JOIN cis c ON c.id = k.node"
# Bolt confirms the same typed traversal
dodil data bolt -b "$BUCKET" -g cmdb_impact "MATCH (f)-[*1..5]->(a) WHERE id(f)=20 RETURN a"
# the window floor: CHG6002 (outside any window) = cab_review despite low risk / model auto_approveThe ALTER-adds, the maintenance_windows table, the OT blast radius reaching a production line (graph_khop
- Bolt), the
ot_impactrollup, and the maintenance-window floor are proven live. Theot_impactprecompute and the change-advisor readingmaintenance_windowsreuse the image-mode engine pattern proven in the base cmdb-blast-radius and change-management skills.
Connect your tools
Everything the overlay wrote lives in the one DataK3 bucket, reachable by your own stack — a plant OT
dashboard reads maintenance_windows over the Postgres wire; an MES / historian integration walks the OT
controls graph over Bolt to chart a PLC's line impact. data connect itsm prints the endpoints. Full,
live-validated walkthrough: Connect your tools.
Composes
This page is not a fork of the ITSM — it is a composition:
- Base: the six ITSM suite skills (
itsm/core,itsm/cmdb-blast-radius,itsm/change-management, …) — the system of record, unchanged. - Overlay:
itsm/overlays/manufacturing— the additive diff above (the OT columns, themaintenance_windowstable, thecontrolsedge, theot_impactrollup, the maintenance-window floor).
Read the base to learn the mechanics; this overlay is the small, industry-specific diff on top.