THE FORWARD TRANSFORM
One Read, Four Tools
Explained from the beginning, with nothing assumed. An architect draws a system once. Teamcenter keeps the master copy. From that one master copy, three completely different engineering tools each get the drawing they need — and none of them holds a second copy of anything.
The idea in one picture
Start with the problem in the plainest terms. A fuel system is one thing, but four different people need four different pictures of it. The architect wants boxes and lines. The electrical engineer wants wires and connectors. The fluid engineer wants pipes, pumps and valves. The reliability engineer wants to know how it breaks. Traditionally each of them draws their own picture, and the four pictures drift apart the moment anyone changes anything.
The forward transform removes the drift by removing the copies. There is one master description in Teamcenter. Every downstream picture is generated from it.
The rule that decides where each part goes
The interesting question is step 3: when the sorter reads Teamcenter, how does it know that a pump belongs on the fuel drawing and the electrical drawing, but a pressure sensor belongs only on the electrical one?
The answer is the part's ports — its plugs. Every plug is typed by an interface: fuel, electrical, or signal. A part reaches a tool when it has a plug of that kind. Nobody maintains a list; the design itself already says it.
Here is the rule actually running, against the live Teamcenter tier, with no model file involved at all:
$ node bin/route-from-tc.mjs --item 041908
ROUTING DERIVED FROM TEAMCENTER 041908 (no Cameo model read)
CheckValve fluid -> nx-diagramming
ElectricBoostPump electrical+fluid+signal -> capital, nx-diagramming, software
Engine fluid -> nx-diagramming
FlopTube fluid -> nx-diagramming
FuelControlUnit electrical+signal -> capital, software
FuelFilter fluid -> nx-diagramming
FuelPressureRegulator fluid -> nx-diagramming
FuelPressureSensor signal -> capital, software
FuelQuantitySensor signal -> capital, software
HeaderTank fluid -> nx-diagramming
MainFuelTank fluid -> nx-diagramming
ports typed via Seg0Implements: 22 untyped: 7
The seven untyped ports are correct and expected: they are activity parameter pins on the functions (BoostFuelPressure, StoreAndCollectFuel …), not block ports. An audit that reported them as failures would be lying.
Where the typing lives, and the mistake worth recording
A port in Teamcenter is a first-class object of type Fnd0LogicIntrfce — display name "Logical Port", 792 of them on this tier. Its typing link to an interface is the relation Seg0Implements.
GDELine whose tag equals its own BOM-line uid, and concluding there was no object behind it. An occurrence is a port's usage; the object is separate — exactly as a component's occurrence differs from its revision. Check a type by name before declaring something absent.Two API traps sit behind that link and both fail quietly:
| Trap | What happens |
|---|---|
Seg0Implements looks like a property | It appears in the type's property list, but it is a GRM relation. setProperties on it returns HTTP 200, no error, and changes nothing. Use Core-2006-03-DataManagement/createRelations. |
| Resolving a port BOM line to its object | Only bl_line_object works. awb0UnderlyingObject, bl_rev_object and bl_item all return nothing — which reads like "no object exists". |
bin/link-port-interfaces.mjs populated all 22 block ports of item 041908 against their interface revisions (FuelInterface, ControlDataInterface, PowerInterface), dry-run by default, every write re-read to confirm. That is why the routing above works from Teamcenter alone.
What actually comes out
Three generators consume the same exchange bundle. They are deterministic, dependency-free, and contain no LLM — the same input produces byte-identical output every time.
| Generator | Produces | Consumed by |
|---|---|---|
capital-import-xml.mjs | Capital Systems Architect project XML | Capital: Files → Import Project & Generate Diagrams |
nx-schematic-spec.mjs | an NX build spec, then a real .prt + PDF | NX Schematic Designer |
made-import-json.mjs | a MADE API 2.0.0 payload | MADe: Integration → Import New Project |
The whole engine is covered by 606 assertions across 29 suites in npm test, all passing as of 1 August 2026.
What this page does not claim
The forward direction is proven end to end on a real model. Two things are genuinely incomplete and are documented rather than glossed:
- Function allocation does not travel. The bundle carries the functions but
allocationsis empty, so MADe synthesizes interface functions instead of landing the real ones. See the MADe page for exactly what that looks like in the product. - The port typing has not been wired into the bundle yet. It exists in Teamcenter and
route-from-tc.mjsreads it, but a live read through the occurrence path still returnsinterfaceId: null. See the status board. - Every port arrives twice, and that breaks the propagation graph. A Cameo push files each block under two parents, so the occurrence read returns 44 port rows for 29 real ports and only 11 of the 44 flows end up carrying a connection. MADe's validation reports 55 errors as a result — measured and explained here.
The full, itemised done-and-not-done list is on its own page, because a documentation site that only lists successes is not worth reading.