Four repositories. One physical world. A walk through the roadside contract that OpenITS is trying to keep.
The four GitHub repos are a cut in the code. The world they describe is older than any of them. We start at the intersection.
Every later idea — YANG, adapters, JetStream, DMZs — exists because of a locked metal box at an intersection.
A city or state Department of Transportation does not run a traffic app. It runs field infrastructure. The cabinet is the place those devices share: power, a local network, and usually a single unfriendly path back to the Traffic Management Center.
The DOT did not buy a stack. They bought an Econolite controller in 2014, cameras in 2019, a sign in 2021. Those boxes will outlive any one software vendor.
Same metal box. Two ownership models. The left column is what you bought. The right column is what a consumer can actually use.
Notice: Econolite and McCain are the same kind of device. Without a vendor-neutral layer they still cannot share an ATMS.
Your ATMS speaks Econolite downtown and McCain in the suburbs, plus a third dashboard for the cameras. A mode change exists only in one dialect. A neighbor has no subject to subscribe to.
Devices still speak their native dialects inside the box. What exits is a versioned vocabulary. Consumers subscribe. A peer DOT is allowed a slice, not a seat on the control plane.
ITS is just IoT with traffic lights.
IoT usually assumes you own the devices and pick the protocol. Here the devices are already installed, already mixed by vendor, and already legally entangled with signal timing. The software does not get to invent the world. It has to describe one.
A city buys Econolite downtown and McCain in the suburbs, plus cameras from a third vendor. What specifically goes wrong if each vendor’s software owns “the intersection”? Which of those problems is political rather than technical?
Technical: even two signal controllers — same function — do not share a language. The ATMS is not “one extra adapter per device type.” It is one extra dialect per vendor of the same type, plus another for every camera and sign. The fix is not a single server the ATMS calls. It is a bus: a collector publishes typed events, and many consumers subscribe.
Political: a neighboring agency is not merely “off the network.” You could VPN them in. You still would not, because that would put a foreign operator on your control plane. Sharing occupancy on a corridor without sharing the ability to change a timing plan is a boundary — later, the DMZ — not a connectivity problem.
The GitHub split is where the thing that changes, who may change it, and how often, actually differ. A monorepo looks tidy. Then a YANG revision waits on a cert rotation.
Must means the contract or the mapping cannot stay true without it. Smell means the split has failed.
Pick a change.
“Obsolete except as a local sandbox to POC a dashboard.” That treats Grafana as the product and the hops as scenery.
cabinet-sim injects CloudEvents once. Every leafnode, cross-domain source, and DMZ subject transform is the real mechanism. The demo is allowed to lie about devices. It is not allowed to lie about the transport.
Demo is the real system, shrunk.
Collector is the real translator and is not what the demo runs at the roadside. Infra is the real bus factory; the demo only borrows its renderer. Models is the real contract; the demo is one commit behind a signal-control rewrite. Treating the demo as source of truth is how you learn a frozen snapshot.
A vendor adds a pedestrian-wait OID. Which repo must change, which may, and which changing would be a smell? Why is “just update the demo, that’s where the dashboards are” the wrong reflex?
Must: collector, always — that is who polls the OID. Models, if “pedestrian wait” is not already in the contract. May: demo, only if you are showing that event on the tour and the pin is new enough to have the type. Smell: infra. Streams and certs do not care which OID you polled.
The demo is not obsolete. It is the wrong job. Dashboards there are how you see federation and WAN-cut, not where a new roadside fact enters the system. Putting the OID in the demo teaches a frozen, faked device and never teaches an adapter.
Why YANG, why many small modules, why everything else in openits-models is generated. The collector is not allowed to invent the vocabulary.
module 03 · not yet written