TMF v5.0 is an open standard. That makes it a great compile target: anyone implementing the standard speaks the same shape. DOIL takes advantage of that.
The interesting move is what the compiler does when the target is a TMF API set: it emits signal-flow bindings, not vendor commands.
What "signal flow" means here
A TMF v5.0 signal flow is a series of typed events that move between subsystems:
- CRM emits subscriber-lifecycle events (TMF629, TMF620).
- Service quality emits performance signals (TMF628).
- Event management raises trouble tickets (TMF688, TMF621).
- Resource inventory holds the topology (TMF639).
The DarkNOC registry already lists 132 of these APIs. The DOIL compiler doesn't implement them — it emits bindings against them. Whatever speaks the standard on the other end is fine.
A DOIL fragment, two ways
Same intent, different target:
agent ChurnCatcher
triggers do
on_event :subscriber_at_risk
end
tools do
crm_lookup
retention_offer safety: true
end
def execute
offer = retention_offer.for(subscriber)
apply(offer) if approved?(offer)
end
endCompiled with --target=twin, this runs against crm-sim (the TMF v5.0 signal source in the constellation).
Compiled with --target=runtime, the bindings switch to live TMF APIs — whichever implementations the runtime is configured to call.
Same DOIL. Same intent. Two targets. Zero vendor names anywhere in the source.
Why vendor-neutral matters
Most operational code rots because the vendor changes. A new OEM ships, a new BSS lands, and last year's scripts become artefacts. Targeting the standard instead of the implementation moves the rot from the agent code to the binding layer — and the binding layer is generated, so it's cheap to regenerate.
The agent stays. The binding swaps. The Reality Twin loop doesn't notice.
Next read: Composite indexes in DOIL — how the Cockpit consumes the language.