TeamcenterKnowledge

Skills

TC Relations Traceability

Skill tc-relations-traceability. Create and verify Teamcenter relations (GRM) over SOA. createRelations shapes, the revision-uid rule, direction enforcement, the verified relation-type atlas for architecture/allocation/verification/reliability, and the one-call reference-property read that beats GRM traversal. Use when linking TC objects or proving a traceability claim.

An orphan item is not a deliverable. Author relation-structured sets.

The operation

Core-2006-03-DataManagement/createRelations

{"input":[{"clientId":"r1",
           "relationType":"Seg0Allocate",
           "primaryObject":{"uid":"<uid>","type":"<Type>"},
           "secondaryObject":{"uid":"<uid>","type":"<Type>"}}]}

The XSD also marks userData (a ModelObject) required; in practice the JSON REST binding accepts the call without it. Add userData as NULLTAG if a call is faulting.

Two rules that cause most failures

  1. Relations must use REVISION uids, not Item uids. GRM rules are declared at the revision level (p=Fnd0LogicalBlockRevision, s=FunctionalityRevision). createRelations on item-level uids will not match the rule. One documented exception: Mq0ElementToFailureModeRel takes the Mq0FailureMode item-level uid as secondary.
  2. Direction is strictly enforced, not just the type pair. Reversing a relation is explicitly rejected with a clear "not allowed" fault. GRM primary and secondary order is real.

A rejection can be informative rather than a bug. Seg0Allocate between Fnd0LogicConnRevision and FunctionalityRevision is refused with "Allocate relation is not supported between these two objects", confirming the GRM table's silence on that pair was correct: Seg0Allocate's real declared pairs from a connector are to NetworkRevision/PSConnectionRevision.

Verified relation atlas

Architecture and allocation

Purpose Relation Primary Secondary
Functional/logical decomposition Seg0Realize FunctionalityRevision FunctionalityRevision (self-referential; same for Fnd0LogicalBlockRevision)
Allocation Seg0Allocate Fnd0LogicalBlockRevision FunctionalityRevision
Connector realization Seg0Allocate Fnd0LogicConnRevision NetworkRevision
Interface contract Seg0Implements Fnd0LogicConnRevision Seg0IntfSpec
Port typed by transport Seg0Implements Fnd0LogicIntrfce (the PORT object, not a revision) Seg0InterfaceRevision
Generic cross-domain trace FND_TraceLink almost anything almost anything

Seg0Implements carries a second, different arrow, and it is the one that closes port-to-protocol. EXERCISED live on vm2606 (TC 2606) 2026-08-09, 11 relations created and each read back by an independent getProperties after the write:

{"input":[{"clientId":"p1","relationType":"Seg0Implements",
 "primaryObject":{"uid":"<port uid>","type":"Fnd0LogicIntrfce"},
 "secondaryObject":{"uid":"<interface REVISION uid>","type":"Seg0InterfaceRevision"},
 "userData":{"uid":"AAAAAAAAAAAAAA","type":"unknownType"}}]}

Note the asymmetry, which is easy to get wrong: the port side anchors on the plain object (a Fnd0LogicIntrfce, className GeneralDesignElement, which has no revision), while the interface side anchors on the revision per the usual Seg0Interface rule. Reach the revision via the item's revision_list.

Two facts about Fnd0LogicIntrfce worth having before you plan a port write:

  • A port has NO item_id. Its identity is uid plus type. Anything keying ports by id is keying on something that is not there; anything keying them by name is worse, because port names collide freely (25 Aircraft ports held five duplicated names plus p1 five times).
  • Seg0Implements and fnd0Direction are both present-and-empty on a port landed by the HCL connector, on 25 of 25 measured. Present-and-empty is a different finding from absent, and only a read with a known-good control attribute (object_name) distinguishes them. The Cameo model's port-to- InterfaceBlock typing does not appear to survive the crossing, so this relation is currently the repair, not the readout.

Seg0Realize is the practical decomposition relation for functional and logical structure. BOM occurrence child-add is a separate, harder path (see tc-bom-structure), and BOM is for physical product structure anyway.

FND_TraceLink is foundation-level and broadly permissive. It worked Signal -> Fnd0LogicalBlock, HRN_Cable Revision -> SignalRevision, and Fnd0LogicConnRevision -> SignalRevision, in some cases without a declared GRM row backing it.

Verification lifecycle

Every arrow below was created live and read back:

Requirement          <--Seg0Derive--   IAV0VerifReqmt      (what and how to verify)
Requirement          <--Seg0Satisfy--  IAV0TestCase        (how it WILL be verified)
Crt0VldnContract     --IAV0VerificationTL-->  IAV0SimulRequest   (simulation path)
Crt0VldnContract     --IAV0VerificationTL-->  IAV0TestRequest    (physical-test path)
IAV0TestRequest      --IAV0VerificationTL-->  IAV0TestProcedur
IAV0TestProcedur     --IAV0VerificationTL-->  IAV0TestEvent      (execution)

Both request paths can coexist on one contract: it is a multi-value reference property. IAV0VerifAssmForm is where the verification method and result are literally recorded; it is a Form and needs a different attach pattern.

Reliability

Purpose Relation Primary Secondary
Element to failure mode Mq0ElementToFailureModeRel Fnd0SEBlockRevision family (FunctionalityRevision or Fnd0LogicalBlockRevision) Mq0FailureMode item uid
Function to failure condition Fha0AnalyzedByFCRel FunctionalityRevision only Fha0FailureCndnRevision
Analysis to what it assesses TC_CAE_Source CAEAnalysisRevision any assessed ItemRevision family

Design consequence: the relation property lands only on the PRIMARY object, and the assessed element is usually created by an earlier architecture task, not by the reliability task. A reliability completion check therefore needs the touched assessed-element uid too. createRelations reports it in ServiceData.updated, so a runner harvesting all uids seen in tool results (not just brand-new creates) covers it naturally.

Requirements

IMAN_specification is a real relation name, but it is not always the containment relation. On production Requirement data it points at a FullText dataset (the requirement's rich-content body), not at a parent spec. Spec to requirement containment is the BOM/occurrence structure, not a GRM relation. Confirm what a relation type actually connects on THIS instance, by inspecting a real production object, before using it structurally.

Verifying a relation: the one-call read

Every GRM relation declared against a specific business-object type pair compiles into a same-named reference property on the primary object.

getProperties(revisionUid, attributes: ["Seg0Allocate"])

returns the allocated Function's uid and display name directly. No GRM traversal, no relation-object walk. This held for every one of roughly 15 relations tested across three cracking rounds. It is one call instead of two.

The exception you must plan around

Relations whose GRM primary type is the maximally generic WorkspaceObject do not expose this way, on either endpoint, under any name. Seg0Satisfy and Seg0Derive are both like this. They create successfully and read back as nothing.

Fallback: createRelations returns the relation object's own uid (type ImanRelation). getProperties on that uid returns a human-readable confirmation naming both endpoints, for example "039244/-/ESP-BCU Brew Controller ECU -> 039241/-/ESP-FN-1 Control Brew Temperature". This requires the authoring pipeline to capture and carry that relation uid.

Any new domain crack that leans on a WorkspaceObject-primary relation should assume it will hit this gap and either pick a type-specific alternative or plan the relation-uid capture first. An honest "cannot verify yet" beats a check that silently fails on correct work.

Reading a Seg0 relation: the db lane, and a fake-property control

EXERCISED 2026-08-12 on vm2606 (TC 2606) and saber2506 (TC 2506).

Two things will make a correct read look like an empty one.

1. The ui lane can be empty while db holds the uid. Measured on a real Fnd0LogicConnRevision:

Seg0Implements   ui:[""]   db:["gQJAAEBhp$kOEC"]      <- the uid is ONLY in db
  -> Seg0ItemFlowExchanges
       Seg0HasExchangeItem  ui:["001360-ZX5_Sig"]  db:["Q4DAAEBhp$kOEC"]

A reader gating on ui reports "no item flow" with an HTTP 200 and no error. Worse, that intermediate Seg0ItemFlowExchanges object has object_string empty in both lanes, so a reader keying on the display string sees nothing even in the right lane. Chase the db uid and dereference it.

2. Ask for a property you know does not exist, in the same call. This is what turns an empty result into information:

Response shape Means
{"ui":[], "db":[]} the property exists on this type and is genuinely unpopulated
omitted from the response entirely the property does not exist on this type

Without the fake-property control those two are indistinguishable, and "absent" gets reported as "empty": the scope-error family the workspace CLAUDE.md documents. Measured with Seg0NotARealProperty alongside the real ones.

Read the REVISION, not the item. On the item, a real-but-unpopulated relation and a fake name are both omitted, so an item-level read discriminates nothing.

It differs by release, so label the release

2606 (vm2606) 2506 (saber2506)
Seg0Implements on the revision returned returned
Seg0Allocate on Fnd0LogicalBlockRevision returned (empty) omitted, not a property of the type
Seg0Realize returned omitted

So on 2506 a getProperties-based allocation read is impossible by construction, and its absence from a read is not evidence about the data. Any "confirmed readable" note must carry the release it was confirmed on: an unlabelled one travels, and the next reader applies it to the tier where it is false.

Do not default to GRM traversal for verification

expandGRMRelationsForPrimary / ForSecondary do work on some instances (proven 2026-07-28 on saber2506, and they are how the Cameo signal-to-carrier chain was read) with body:

{"primaryObjects":[{"uid":"<uid>"}],
 "pref":{"expItemRev":false,"returnRelations":true,
         "info":[{"relationTypeName":"","otherSideObjectTypes":[]}]}}

But whereReferenced, whereReferencedByRelationName, and getRelatedObjects have faulted on multiple unrelated instances. Treat any GRM-traversal fault on a new instance as expected-until-proven-otherwise, not as a struct mistake to debug. The reliable set on every instance tested: getProperties, executeSavedQuery, createRelations, deleteRelations, deleteObjects.

Also: Core-2007-01-DataManagement/loadObjects with a bare {"uids":[...]} faults 214086 "invalid syntax". Use getProperties.

Do not prove absence with the rich client

Impact Analysis at rule "All" and the Details tab both showed nothing for a pin that demonstrably had a Seg0Implements relation, which SOA returned immediately. An empty relation panel means the view is not configured to traverse that relation, not that the relation is absent.

Bidirectionality

A trace link in one direction is necessary but not sufficient to describe a requirement as "traced" in a report. Confirm the link is queryable from the end you are claiming coverage from, before writing coverage language.

Related skills

tc-object-authoring, tc-verify-and-cleanup, tc-query-discovery.


Generated from skills/tc-relations-traceability/SKILL.md in the tc-automation-skills library, which is the canonical copy and also serves as the agent skill set for Teamcenter work.