Skip to the lesson
CivOps AI Academy · F05One Name for Everything: a Naming Standard for Every Machine, Line, Measure and Tag
0%

F05 · Session 5 · Chapter 1

Why one name for everything

Every report, alarm, screen and AI question finds plant data by its name. If each line names the same thing differently, every one of those is built again for every line. This chapter shows what a plant's names cost today and where a single standard comes from.

25 min3 chapters≈ 90 minutes2 exercises12-question assessment · 80% passes

By the end of this chapter you can

  • Explain why a naming standard is the cheapest analytics investment a plant can make.
  • Recognise the four kinds of names one piece of equipment already has, and who uses each.
  • Turn the ISA-95 equipment hierarchy into a path that every system can use.

The same filler, three names

A bottling plant runs three lines. Each was commissioned in a different year by a different integrator. On line 1 the good-bottle count from the filler is called Filler_Cnt. On line 2 it is FIL2_COUNT_GOOD. On line 3 someone typed L3 Filler Good Bottles, with spaces. All three mean exactly the same thing.

Now the plant manager asks for one screen showing good bottles per hour on every line. Someone must find the three names, learn what each one means, check whether each counts the same way, and write three queries. When line 4 arrives, the work is repeated. When an AI agent is asked "how many good bottles did we make yesterday?", it has to guess that these three names are the same measure, and it may guess wrong.

Dashboards to build, with and without a naming standardBar chart: without a standard the count grows by 5 for every line, to 30 at six lines; with a standard it stays at 5. 0102030551 line1052 lines1553 lines2054 lines2555 lines3056 linesDashboards to build and keep, 5 per line: one name per line (red) versus one standard (green)
Built once, or built per line. With five dashboards per line, a plant with no standard keeps 30 dashboards by its sixth line. With one standard it keeps five, and each new line appears in them on the day it starts publishing.

A naming standard fixes this at the source. It is a short document, owned by the people who run the plant, that says how every machine, line, measure and tag is named. It costs nothing but an afternoon to write, and it is the part of a data platform that domain experts, not IT, are best placed to own.

The names your plant already has

No plant starts from nothing. Each piece of equipment already carries several names, each made for a different job and a different team. A standard does not throw them away; it picks one as the name the platform uses and records the others against it.

One motor, four namesA single conveyor motor has a PLC address, a P&ID equipment tag, an ISO/IEC 81346 code and a UNS path; an alias table links them. One real motorfiller infeed conveyoron bottling line 2PLC addressN7:12 (Allen-Bradley)used by the controls engineerP&ID equipment tagM-2104 on the drawingused by the process drawingsISO/IEC 81346 code=FIL.CNV1-M1used by the electrical drawingsUNS pathacme/cle/bottling/line-2/infeedused by every screen, report and AI questionAn alias table records all four, so each team keeps its own name and every system meets on the UNS path.
Four names for one motor. Controls, process drawings, electrical and the data platform each have their own. The platform uses the UNS path; an alias table keeps the rest.
Kind of nameExampleMade forWhere it belongs
PLC or device addressN7:12, DB10.DBW4, register 40001The controller's memoryOnly at the controller and the connector that reads it; never shown above it
ISA-5.1 instrument tagFIC-101, TT-2203P&IDs and instrument lists [1]An attribute of the asset, so drawings and data can be matched
ISO/IEC 81346 reference designation=FIL.CNV1-M1Function (=), product (-) and location (+) across disciplines [2]An attribute of the asset, for electrical and mechanical records
Unified Namespace pathacme/cle/bottling/line-2/filler/good_countEvery system that reads or writes plant data [3]The one name the platform, its screens and its AI agents use

What each name tells you

An ISA-5.1 tag tells an instrument technician what an instrument measures and does: in FIC-101, F is flow, I is indicating, C is controlling, and 101 is the loop number [1]. An ISO/IEC 81346 code tells an electrician what function a part serves, which product it is and where it is [2]. A device address tells the controller where a value sits in memory. None of these tells a dashboard which site, area and line a value comes from. That is what the platform's name must do.

Knowledge check

A new analyst asks why the platform does not simply use the PLC addresses as names. What is the best answer?

The backbone: the ISA-95 hierarchy

The platform's name needs an order that every plant already understands. ISA-95 (IEC 62264) provides it: enterprise, site, area, then the work centre (a line, a process cell or a storage zone) and the equipment inside it [4]. It is the same hierarchy Session 3's schema used for its tables. Written as a path, each level becomes one segment, joined by slashes, which is exactly how MQTT topics are built [5].

ISA-95 levels become the pathSix levels, enterprise to measure, each turned into one path segment and joined with slashes. EnterpriseacmeSitecleAreabottlingLineline-2EquipmentfillerMeasuregood_countJoined with /acme/cle/bottling/line-2/filler/good_countSame order on every line,so a screen built for line 2works on line 7 unchanged.
From hierarchy to path. The equipment hierarchy gives the order; the path writes it down. Because every line follows the same order, anything built for one line works on the next.

This order is what makes a Unified Namespace work: a consumer can ask for acme/cle/bottling/+/filler/good_count and receive the good count from every filler in the bottling area, without knowing how many lines there are. The + is MQTT's single-level wildcard; # matches everything below a level [5]. Neither works if the levels are in a different order on each line.

6levels, always in the same order
1name per thing in the platform
0device addresses above the connector

Knowledge check

Why does the order of the levels matter as much as the words?

Knowledge check

Which of these is the platform's name for the good-bottle count on line 2?

References

  1. ISA: ANSI/ISA-5.1-2024, Instrumentation and Control Symbols and Identification (announcement). https://www.isa.org/news-press-releases/2024/october/widely-used-engineering-symbols-and-drawings-stand
  2. ISO: IEC 81346 reference designation system (ISO Online Browsing Platform). https://www.iso.org/obp/ui/en/#!iso:std:75471:en
  3. HiveMQ: Implementing a Unified Namespace with MQTT and Sparkplug. https://www.hivemq.com/blog/implementing-unified-namespace-uns-mqtt-sparkplug/
  4. ISA: ISA-95 Standard, Enterprise-Control System Integration. https://www.isa.org/standards-and-publications/isa-standards/isa-95-standard
  5. OASIS: MQTT Version 5.0 (topic names, topic filters and wildcards). https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html
  6. Eclipse Foundation: Sparkplug specification. https://sparkplug.eclipse.org/specification/

F05 · Chapter 2 · The rules

Writing the standard

A naming standard fits on one page: the levels, the allowed words, how words are joined, and where units go. This chapter writes one for a real line, then renames its tags.

30 min1 page6 rules1 vocabulary list

By the end of this chapter you can

  • Write the six rules of a naming standard: levels, case, joining, vocabulary, units and forbidden characters.
  • Build a controlled vocabulary of measures with units, from your own intent.
  • Rename a set of legacy tags to the standard, and record each old name as an alias.

Six rules on one page

A standard that people can remember beats a complete one that nobody reads. The six rules below cover almost every name a small or mid-size plant needs. Each exists because breaking it has caused a real problem.

Anatomy of a nameThe path acme/cle/bottling/line-2/filler/good_count with each segment labelled, and six rules for writing names. acmeenterprise/clesite code/bottlingarea/line-2line/fillerequipment/good_countmeasureLower case onlyMQTT topics are case sensitive: Line-2 and line-2 are two placesFixed order, no gapsevery path has all six levels, in this orderLevels in kebab-casewords joined by hyphens: line-2, press-shopMeasures in snake_casewords joined by underscores: good_count, temp_cUnit at the endtemp_c, pressure_bar, flow_l_min; counts and states need noneNothing elseno spaces or dots; + and # are MQTT wildcards
The anatomy of a name. Six segments in a fixed order, lower case, with the unit at the end of the measure.
RuleWhat it saysWhy
1. Fixed levelsenterprise / site / area / line / equipment / measure, always all six, in that orderWildcards and reused screens depend on position [1]
2. Lower caseNo capital letters anywhereMQTT topic names are case sensitive, so Line-2 and line-2 would be two different places [1]
3. JoiningWords inside a level are joined with hyphens (press-shop); words inside a measure with underscores (good_count)The measure stays one token in code, queries and spreadsheets
4. VocabularyMeasures come from a short, written list; a new word is added by review, not invented on the dayThe same measure gets the same word on every line
5. UnitsEvery physical measure ends with its unit: temp_c, pressure_bar, flow_l_minA number without a unit is a guess; unit codes follow UCUM where one exists [2]
6. ForbiddenNo spaces, dots, +, # or $ at the start+ and # are MQTT wildcards and topics starting with $ are reserved for the broker [1]

The vocabulary: measures your intent needs

Start from the intent statement you wrote in Session 2. It names the decision and the data the decision needs. Each piece of data becomes a measure, and each measure gets one word. For a supervisor deciding which line gets the next technician, from downtime by reason and open work orders, the list starts small:

MeasureMeaningUnitType
stateMachine state: running, idle, down, changeover (one fixed list)nonetext from a list
down_reasonWhy the machine is down, from the plant's reason listnonetext from a list
good_countGood units since the start of the shiftunitswhole number
reject_countRejected units since the start of the shiftunitswhole number
speed_bpmCurrent speed in bottles per minute1/minnumber
temp_cTemperature in degrees CelsiusCelnumber
pressure_barPressure in barbarnumber

Counts and states carry no unit suffix because they have no physical unit. A state should use a fixed list of values, written in the standard. PackML's machine states are a published model to borrow from if your equipment supports it [3].

Time, and where it lives

A measure's name never contains a time or a date. Each value carries its own timestamp, stored in UTC and written in ISO 8601 form (for example 2026-10-04T13:05:00Z) [4]. Shift and day boundaries are computed from the timestamp and the plant's time zone, never baked into a name such as count_shift_b.

Knowledge check

A line lead proposes the measure name Temp for an oven. What does the standard change?

Writing it down

The standard is a file in the platform's repository, so it is versioned, reviewed and visible to every person and agent who works on the platform. A short Markdown file is enough. Here is a complete one for the bottling plant:

docs/naming-standard.md
# Naming standard (version 1)
Owner: operations engineering. Changes by pull request, reviewed by the area owner.

## Path
enterprise/site/area/line/equipment/measure   (all six, in this order)
Example: acme/cle/bottling/line-2/filler/good_count

## Characters
Lower case a-z and digits 0-9 only.
Levels: words joined by hyphens (press-shop, line-2).
Measures: words joined by underscores (good_count).
Never: spaces, dots, + # or a leading $.

## Units
Physical measures end with the unit: temp_c, pressure_bar, flow_l_min, speed_bpm.
Counts and states have no unit.

## Vocabulary (add a word only by review)
state, down_reason, good_count, reject_count, speed_bpm, temp_c, pressure_bar

## Codes
Sites: cle = Cleveland. Areas: bottling, packaging, utilities.
Lines: line-1 ... line-9. Equipment: filler, capper, labeller, pasteuriser, palletiser.

## Aliases
Every legacy tag is recorded in the alias table with its standard name.

Renaming the legacy tags

With the standard written, each existing tag gets its standard name. Nothing in the control system is renamed: the PLC keeps its addresses and the SCADA keeps its tags. The connector, or the template in your SCADA, maps each old name onto the new one, and the alias table records the pair [5].

Renaming tags to one standardFive tag names from three lines, such as Filler_Cnt and FIL2_COUNT_GOOD, mapped onto standard paths ending good_count and temp_c. Before: what each line called itAfter: one standardLine 1Filler_Cntacme/cle/bottling/line-1/filler/good_countLine 2FIL2_COUNT_GOODacme/cle/bottling/line-2/filler/good_countLine 3L3 Filler Good Bottlesacme/cle/bottling/line-3/filler/good_countLine 1TT101_PVacme/cle/bottling/line-1/pasteuriser/temp_cLine 2Past2Tempacme/cle/bottling/line-2/pasteuriser/temp_cThe same question now has the same answer on every line: subscribe to …/+/filler/good_count.
Five legacy tags, one standard. The old names stay in the alias table, so anyone searching by an old name still finds the measure.
  1. Export the tag list from the SCADA or historian as a spreadsheet (name, description, unit, address).
  2. Add a column for the standard name. Fill it level by level: site, area, line, equipment, then the measure from the vocabulary.
  3. Where no vocabulary word fits, write the proposed word in a separate column. These go to review, not straight into the standard.
  4. Where two tags turn out to be the same measure, keep one and mark the other as a duplicate.
  5. Save the finished list as the alias table: legacy name, standard name, unit, source system.
Exercise · Write your standard and rename 20 tags35 minutes

You need: A spreadsheet, your Session 2 intent statement, a list of 20 real tag names from one line (or the sample list in the steps)

Work on paper or in a spreadsheet. Nothing here touches the plant. If you cannot export real tags yet, use these: Filler_Cnt, FIL2_COUNT_GOOD, Past2Temp, TT101_PV, CAP_SPD, Line1Down, L1_DOWN_RSN, PAL_CNT, Oven Temp, OVN_TMP_F.

Outcome: A one-page naming standard and a 20-row alias table, every standard name following the six rules.

Knowledge check

OVN_TMP_F holds an oven temperature in degrees Fahrenheit. The standard says temperatures are in Celsius. What is the right standard entry?

Knowledge check

Why is the standard kept as a file in the repository rather than in a shared drive?

References

  1. OASIS: MQTT Version 5.0, section 4.7 Topic Names and Topic Filters. https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html
  2. The Unified Code for Units of Measure (UCUM). https://ucum.org/
  3. OMAC: PackML, the packaging machine language state model. https://www.omac.org/packml
  4. ISO: ISO 8601 Date and time format. https://www.iso.org/iso-8601-date-and-time-format.html
  5. Inductive Automation: Ignition user manual (tags, user-defined types and reference tags). https://www.docs.inductiveautomation.com/

F05 · Chapter 3 · Enforcement

Keeping every name true

A standard that relies on memory decays within a year. This chapter makes the machine enforce it: templates that stamp out correct names, a database that refuses bad ones, a CI check on every change, and an owner for every branch of the tree.

25 min4 layers of enforcement1 CI check≈ 30 minutes hands-on

By the end of this chapter you can

  • Use templates and aliases so correct names are the default, not an effort.
  • Make the database and CI refuse a name that breaks the standard.
  • Run a simple governance loop for new words, new levels and renames.

Make the right name the easy name

People do not break naming standards on purpose. They break them at 2 a.m. during a changeover, when typing a new tag by hand is faster than looking up the rule. The answer is to make sure nobody types names by hand. In a SCADA such as Ignition, a user-defined type (UDT) is a template: define a Filler once with its members (state, good count, reject count, speed), and every filler you create from it has exactly those members with exactly those names [1]. A parameter maps each instance onto its controller's addresses, which is aliasing done by the template.

Aliasing device addresses to one nameAddresses from three controller brands map into one Filler template and one standard path. Allen-Bradley PLCFiller1:I.Data[4]Siemens S7 PLCDB10.DBW4Modbus TCP controllerregister 40001, ×0.1Template: Fillerstate · good_countreject_count · speed_bpmunits and limits built inOne name per filler…/line-2/filler/good_countthe address stays belowDevice addresses change with hardware. The name never does: only the alias is updated.
Aliasing through a template. Three controller brands, three address formats, one Filler template and one name per filler. Swap a PLC and only the address parameter changes.

The same idea works without a SCADA. CESMII's Smart Manufacturing Profiles and the OPC UA information models are published, reusable definitions of a type of equipment and its attributes, so different vendors' machines can present the same structure [2] [3]. Whatever tool you use, the pattern is the same: one type, many instances, names generated from the type.

Make the database refuse a bad name

The platform's database is the last line of defence. Session 3's schema has a table for the measures the platform knows about. A CHECK constraint on that table makes PostgreSQL refuse any row whose path breaks the standard, whoever or whatever tries to insert it [4]. A constraint cannot be forgotten, and an AI agent that writes a bad name gets an error instead of silently creating an island.

A migration: the database checks every name
-- Every measure path must follow the naming standard (docs/naming-standard.md).
alter table measures
  add constraint measures_path_follows_standard check (
    path ~ '^[a-z0-9]+(-[a-z0-9]+)*(/[a-z0-9]+(-[a-z0-9]+)*){4}/[a-z][a-z0-9]*(_[a-z0-9]+)*$'
  );

Read the pattern left to right: one level of lower-case words joined by hyphens, then exactly four more such levels after a slash, then a slash and a measure of lower-case words joined by underscores. It is exactly rules 1, 2, 3 and 6 of the standard. Rule 4 (vocabulary) is checked against the list in the next step, and rule 5 (units) by the vocabulary itself, because every word in the list already carries its unit.

Check every change in CI

The database catches names at the moment they are written. CI catches them earlier, in the pull request, before anything reaches the live platform. A short test reads the vocabulary from the standard, then checks every name in the seed data, the synthetic data generator from Session 4 and any configuration file. Branch protection (Session 1) means a failing check blocks the merge [5].

The name check in CIA pull request runs a CI name check; names that match pass and the merge is allowed; bad names fail with a message and the merge is blocked. Pull requestadds 40 assetsCI: name checkevery name vs the rulePass: merge allowedall 40 names match the standardFail: merge blocked✗ Filler_Cnt: upper case, no path✗ …/line-2/filler/temp: no unitfix the names, push againThe rule lives in the repository and is checked by a machine on every change, not remembered by people.
The name check in CI. The rule lives in the repository; a machine checks it on every pull request and names the exact name that broke it.
A CI check your agent can write
// test/names.test.mjs — every name in the seed data follows the standard.
import { readFileSync } from "node:fs";
import assert from "node:assert/strict";

const standard = readFileSync("docs/naming-standard.md", "utf8");
const vocabulary = standard.split("## Vocabulary")[1].split("\n")[1].split(",").map((w) => w.trim());
const PATH = /^[a-z0-9]+(-[a-z0-9]+)*(\/[a-z0-9]+(-[a-z0-9]+)*){4}\/[a-z][a-z0-9]*(_[a-z0-9]+)*$/;

const seed = JSON.parse(readFileSync("db/seed/measures.json", "utf8"));
for (const { path } of seed) {
  assert.match(path, PATH, `${path}: breaks the naming standard`);
  const measure = path.split("/").pop();
  assert.ok(vocabulary.includes(measure), `${path}: "${measure}" is not in the vocabulary`);
}
console.log(`${seed.length} names follow the standard`);

The file names above (db/seed/measures.json) are examples: your agent will use the paths in your own repository. What matters is that the test reads the standard itself, so the document and the check can never disagree.

Knowledge check

An AI agent adds 40 new measures in a pull request. One is named Filler_Speed. What stops it reaching the live platform?

An owner for every branch

A standard also needs people. Give each area of the tree an owner: the person who decides what a new measure in bottling is called, or whether packaging gets a new line code. Changes follow one loop, through a pull request, so every decision has a reviewer and a date.

Naming governance loopFive steps around the standard: propose, review by the area owner, add to the vocabulary, CI checks it, publish. The namingstandard1 · Proposea new measure or level, in a pullrequest2 · Reviewthe namespace owner for that area3 · Addto the vocabulary list in the standard4 · CheckCI accepts the new word from now on5 · Publishscreens and agents can use it
The governance loop. A new word is proposed, reviewed by the area owner, added to the vocabulary, accepted by CI from then on, and published to every screen and agent.

Renames never break anything

Sooner or later a name will be wrong: a line is renumbered, an area is split. Never rename in place. Add the new name, record the old one as an alias, move consumers across, and only then retire the old name. Consumers keep working throughout, and the history is never orphaned.

ChangeHowWho approves
New measure wordPull request adding it to the vocabularyArea owner
New line or equipment codePull request adding the code; templates create the namesArea owner
New level or new rulePull request changing the standard; version number goes upPlant engineering lead and IT
RenameAdd new name, alias the old, move consumers, retire the oldArea owner; announce to everyone who consumes it
Exercise · Make CI enforce your standard30 minutes

You need: Your platform repository, your AI coding agent (Claude Code or similar), GitHub

Do this on a branch of your own platform. Your agent writes the code; you check that it does what the standard says.

Outcome: The naming standard is in the repository, the database refuses bad paths, and CI blocks any pull request that adds a bad name.

Knowledge check

Line 2 is renumbered to line 5. What is the safe way to change its names?

References

  1. Inductive Automation: Ignition user manual (user-defined types). https://www.docs.inductiveautomation.com/
  2. CESMII: Smart Manufacturing Profiles (GitHub). https://github.com/cesmii/SMProfiles
  3. OPC Foundation: OPC Unified Architecture. https://opcfoundation.org/about/opc-technologies/opc-ua/
  4. PostgreSQL Documentation: Constraints (check constraints). https://www.postgresql.org/docs/current/ddl-constraints.html
  5. GitHub Docs: About protected branches. https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches

Chapter 4 · 12 questions · 80% passes

Final assessment

Twelve questions across the element. Score 80% (10 of 12) to pass. Your LMS records your score and each answer; you can review the chapters and try again.

15 min12 questions≈ 15 minutesRetake allowed

Choose one answer for each question, then submit. You will see the right answer and why for every question.

1. Why is a naming standard called the cheapest analytics investment a plant can make?
2. Which name should never appear above the connector that reads the controller?
3. In the ISA-5.1 tag FIC-101, what does the F stand for?
4. What gives the platform's path its order of levels?
5. Why must every name be lower case?
6. Which measure name follows the standard for a pressure in bar?
7. Why are + and # forbidden inside names?
8. Where does a value's time belong?
9. A legacy tag Past2Temp is renamed. What happens to the old name?
10. What does an Ignition user-defined type (UDT) do for naming?
11. An AI agent inserts a measure named Filler_Speed directly into the database. What should stop it?
12. Line 2 is renumbered as line 5. What is the safe order of work?