TeamcenterKnowledge

Skills

Cameo TC Element Authoring

Skill cameo-tc-element-authoring. Author SysML in Cameo so it actually lands in Teamcenter through the HCL connector. Covers the element-type landing matrix (what each Cameo type becomes in TC), the three gates that decide whether something exports at all (a port needs a part-property occurrence, a connector needs factory ends plus propertyPath, an object flow needs CallBehaviorAction endpoints), the direction rules that make Allocate and Verify work or silently fail, the "set only at creation" class of traps where editing an existing element is ignored with no error, the two relations that never export despite 330 declared rules each, and the verification discipline (server-side reads only, because the headless Check-In never stamps TC ids back into the model). Use for any Cameo model that must reach Teamcenter, any "the export succeeded but nothing is there" investigation, and before writing modeling guidance for other people.

EXERCISED 2026-08-17 on vm2606 (https://siemensdc/tc, TC 2606, user ed) across 21 incremental Check-Ins of model CSA_ProbeManual (item 007106), driving the HCL Cameo Connector headlessly. Every row below was verified by a server-side SOA read, never by the connector's return value. Mapping reference: MAGICDRAW_BHMIntegrationDefinition_TC2506.xml.

Companion detail, with the failed attempts kept: Capital_TC_Integration/docs/CAMEO_ELEMENT_LANDING_MATRIX.md and Capital_TC_Integration/docs/CAMEO_CONNECTOR_DEFECTS.md.

The landing matrix

Cameo Teamcenter notes
Block Fnd0LogicalBlock seg0Kind = the applied stereotype name
Part property (composite, «PartProperty») Fnd0LogicalBOMLine child this is the decomposition
ProxyPort typed by an interface block Fnd0LogicIntrfce only via a part occurrence, see Gate 1
Connector Fnd0LogicConn endpoints on the OCCURRENCE, see Gate 2
Interface Block Seg0Interface
Signal (bare UML metaclass) Seg0IntfSpec no stereotype needed
Flow property on an interface block Seg0ItemFlow via Seg0ExchangeAllocation
Item Flow («ItemFlow» InformationFlow) Seg0ItemFlowExchanges via Seg0Implements
Activity Functionality no stereotype needed
Activity Parameter Node Network_Port GDELine occurrence under the Functionality
Object Flow Network only from CBA pins, see Gate 3
Value property + «TC_Parameter_Stereotype» Att0MeasurableAttribute* value rides a tagged value
Requirement Requirement subtypes are extends, they behave the same
Package Uml0Package contents become BOM children
Diagram Seg0Diagram attached via Fnd0Diagram_Attaches
Project Uml0MLModel
mdzip Mdw0MDModel
Action / OpaqueAction nothing the mapping declares no Action rule at all

Gate 1: a port needs a part-property occurrence

A ProxyPort on a block produces no TC object until something owns that block through a part property. This is the GBVR (grandchild) behaviour in the mapping.

Symptom: ports exist in the model, carry no TC id, and are absent from Teamcenter, while the blocks around them landed fine.

Fix: give the ports' blocks a parent block with composite part properties. The ports then appear with no edit to the ports themselves:

ProbeSystem
  Fnd0LogicalBOMLine -> Alpha rev
      GDELine -> Fnd0LogicIntrfce      <- the port, now real

Use ProxyPort. Bare Port and Full Port are declared in the mapping but are bad practice on this stack and have caused trouble before. ⚠ Measured 2026-08-28 (ZZCOV probe, vm2606): all three port kinds DO export as Fnd0LogicIntrfce, discriminated by seg0Kind (empty / FullPort / ProxyPort), so the convention is about downstream consumers keying on ProxyPort, not about the export failing.

Gate 2: connector ends come from the factory, and need propertyPath

conn = f.createConnectorInstance()      # ALREADY supplies exactly 2 ends
conn.setName("AlphaToBeta")
conn.setOwner(owningBlock)
ends = list(conn.getEnd())              # do NOT add your own

def wire(en, port, part):
    en.setRole(port)
    en.setPartWithPort(part)
    StereotypesHelper.addStereotype(en, nce)          # NestedConnectorEnd
    StereotypesHelper.setStereotypePropertyValue(en, nce, "propertyPath", [part])

wire(ends[0], portA, partA)
wire(ends[1], portB, partB)

Adding your own ends produces a 4-end connector that silently fails to serialise. saveProject returns true and the connector is then simply absent from the .mdzip. This is a strong suspect for any unexplained Export Failed: The given value is invalid.

Endpoints live on the connector's occurrence, never on the item:

getProperties(<connector BOMLine>, ["fnd0bl_connected_end1", "fnd0bl_connected_end2"])

Gate 3: an object flow needs CallBehaviorAction endpoints

An ObjectFlow exports only when its source and target pins sit on a CallBehaviorAction whose behavior is an Activity that itself exports.

Measured, four shapes:

shape result
ActivityParameterNode to ActivityParameterNode does not land
pins on plain OpaqueActions does not land
ActivityParameterNode pair drawn on a real SysML Activity Diagram does not land
pins on CallBehaviorActions with an exported behavior necessary, NOT sufficient - see Gate 3b

The diagram theory is refuted, not untested: the flow was placed on an activity diagram that the connector's own filter accepted (its diagram count rose) and no Network appeared. The name is irrelevant; a flow named from birth lands fine.

Gate 3b: BOTH end nodes need a non-null getSyncElement()

This is the gate that Gate 3 above misses, and it is the one that fails silently. Gate 3 is necessary and NOT sufficient: pins can sit on perfectly good CallBehaviorActions whose behaviors export, and the flow still produces no Network, with no fault and no error in the publish result.

EXERCISED 2026-08-26 on vm2606, read off the shipped jar and then proven by fixing it.

From CameoTCIntPlugin.jar, com.hcl.cameotc.integration.service.relationMgmt.CameoElementsRelations .prepareForObjectFlow (decompiled with the JRE's own javap):

ActivityNode src = flow.getSource();
ActivityNode tgt = flow.getTarget();
if (src == null || tgt == null) { valid = false; return valid; }
Element s = src.getSyncElement();
Element t = tgt.getSyncElement();
if (t == null || s == null) { valid = false; return valid; }   // <-- THE GATE

The exclusion reason recorded is the literal resource key Validation_for_ObjFlow. Its message in Resources_en_US.properties is:

Object Flow should have Input and Output Pin at ends.

That message is MISLEADING and cost this workspace days. The failing flows all had a correct uml:OutputPin at source and uml:InputPin at target. The rule does not test the metaclass of the ends at all; it tests whether each end node carries a syncElement.

What syncElement is. Element.getSyncElement() / setSyncElement(Element) are public on com.nomagic.uml2.ext.magicdraw.classes.mdkernel.Element. On a pin it is the link to the Parameter on the called behavior that the pin mirrors. MagicDraw sets it when IT generates the pins by synchronising a CallBehaviorAction against its behavior's parameters. A pin created programmatically with EF.createInputPinInstance() / createOutputPinInstance() and merely added to the action has syncElement == null, so every object flow authored from Jython fails this gate unless you set it yourself.

The fix, and it needs no re-authoring:

# for each end node of the flow
beh = pin.getOwner().getBehavior()          # the called Activity
param = next(p for p in beh.getOwnedParameter() if p.getName() == pin.getName())
pin.setSyncElement(param)                   # <-- this is the whole fix

Create the matching Parameter (plus its ActivityParameterNode) first if the behavior does not have one. Then save, deep sync, Publish.

Measured result. In 007916 Confirm and Geolocate, 19 of 20 pins had a null syncElement, including the six flows that had ALREADY crossed - so all nine flows in that file were being excluded on every publish. The six only looked healthy because they already carried TC uids from an earlier pass and did not need re-creating. After setting syncElement on all 20 pins and one Publish, the tier's Network count went 55 to 59. The same fix on 007913 Fly and Navigate took it 59 to 65. Ten nets that had never existed, recovered without re-authoring a single flow.

A published model can LOSE this. Those six had crossed originally, yet their pins read null afterwards. Publish rewrites the local file from Teamcenter, and syncElement does not survive the round trip. So re-check it before every publish, not once.

syncElement is NOT serialised in the .mdzip under any name the offline auditor can see, so this cannot be checked with mdzip_audit.py or any XMI parse. It takes a live Cameo and one call per pin. Do not conclude from a clean offline audit that the flows will export.

The one shape this does not rescue

A flow whose end is an ActivityParameterNode owned by the parent Activity (a delegation of a sub-function's output to the parent's own output parameter) is not a function-to-function link. Binding its syncElement to its Parameter makes it pass the gate, and the publish then fails anyway. Treat delegation flows as out of scope for Network until someone proves otherwise.

Gate 3c: the endpoint functions must be PACKAGE members, not nested Activities

EXERCISED 2026-08-26 on vm2606, by controlled experiment. An ObjectFlow whose endpoint behaviors are Activities owned by another Activity produces no Network. Move the same Activities so a Package owns them, change nothing else, and the flows export.

This is a THIRD independent condition. Gate 3 (pins on CallBehaviorActions), Gate 3b (syncElement on both end nodes) and Gate 3c all have to hold. Each one fails silently and the publish still returns ok: true.

How it was isolated, because the result is only worth what the method is. The JPO MSP-2 reference architecture had 8 functions nested inside a parent Activity MSP2-FN-ROOT, wired with 13 object flows. Everything else was already right and verified server-side: all 23 Parameters crossed as Network_Port, all 9 functions as Functionality, both new Signals as Seg0IntfSpec, all 13 flows passed Gate 3 and Gate 3b. Zero Networks, across THREE publishes.

Eliminated first, each by measurement rather than argument:

candidate how it was killed
syncElement null set on all 26 end nodes and re-read; still zero
same-publish ordering (Parameters had no TC uid yet) 2nd publish, no model change; still zero
endpoint functions not allocated 8 Seg0Allocate created and READ BACK off 007239/A;1 in Teamcenter; still zero
flow-owning parent not allocated 9th Seg0Allocate added; still zero
endpoints performed by the SAME block falsified from the wildfire control: GeodeticFix, TerrainModel and ProbeQualityMetric all have producer and consumer on one block (Geolocation Solver) and all three ARE Networks

Then the minimal test. Two functions either side of ONE flow (MSP2-FN-3 -> MSP2-FN-1, carrying SIG-TIMING-REF) were re-homed from the Activity into the package. One publish:

Network nFound 65 -> 66      the single new item is 007987-SIG-TIMING-REF

Exactly the one flow whose BOTH endpoints moved. The other 12, still nested, did not appear. Moving the remaining 6 functions and publishing again took it 66 -> 78, all 13 verified individually by uid as object_type = Network.

The rule: a function that must carry object flows has to be owned by a Package. Use composition or an allocation relation to express the decomposition, not Activity nesting. Element ids are stable across the re-home, so existing Teamcenter items are preserved: the 8 MSP-2 functions kept items 007256-007265.

Nesting is legal SysML and looks tidier in the containment tree, which is why this is worth writing down. Nothing in Cameo, in the deep-sync report, or in the publish result objects to it. The only symptom is a Network that never appears.

Direction decides Allocate and Verify

The mapping is fully cross-product and permits far more than the connector delivers. Direction, not declaration, is what works.

relation working direction wrong direction
Allocate client = Block, supplier = Activity (structure to behavior) Activity to Block aborts the entire Check-In
Verify Requirement to Requirement Activity to Requirement produces nothing
Derive Requirement to Requirement, either way
Satisfy client = Block, supplier = Requirement

⚠ The wrong-direction Allocate fails with a message that misdescribes the cause:

Relating an object of type "System Block Revision" to an object of type "Function Revision"
is not allowed, because the "Allocate" relation is not supported between these two objects.

That pair IS permitted: createRelations with exactly those revision types succeeds, and the working direction produces that same pair. Worse, the failure then blocks every subsequent Check-In of that model, not just its own element. If check-ins start failing after an allocation edit, delete the Allocate first and re-push before debugging anything else.

Set only at creation

A whole class of traps: the element exports correctly when created right, and editing it afterwards is silently ignored.

  • Item flow source/target. Set informationSource / informationTarget to Blocks when you create the InformationFlow. Editing them later leaves seg0Source / seg0Target empty forever. Delete and recreate instead. Measured on both sides, see the section below.
  • Connector ends. As above.
  • Object flow endpoints. As above.
  • Package contents. Create the element inside the package. Do not move an existing one in.

This is not a blanket "edits never propagate": renaming propagates, and re-pointing a Verify abstraction propagates. It bites structural and REF-behaviour links.

When something structural does not appear, delete the element and author it correctly from scratch before concluding the capability is missing. That single move settled two "defects" that were not defects.

Item flows: the ends, and how to read them back

EXERCISED 2026-08-24 on vm2606, both halves, across two models and 130 objects. This is the one rule in this file with a controlled comparison behind it rather than a single observation.

In Cameo, the ends are CHILD ELEMENTS carrying xmi:idref, not attributes. A regex looking for informationSource='...' on the opening tag finds nothing and reads as "no ends set":

<packagedElement xmi:type='uml:InformationFlow' xmi:id='...' name='Fuel From Main Tank'>
    <conveyed           xmi:idref='...'/>   <!-- uml:Signal -->
    <informationSource  xmi:idref='...'/>   <!-- uml:Class, the BLOCK, not the port -->
    <informationTarget  xmi:idref='...'/>   <!-- uml:Class, the BLOCK, not the port -->
    <realizingConnector xmi:idref='...'/>
</packagedElement>

The measured contrast, which is what makes the Blocks rule a fact rather than a preference:

model what the ends point at seg0Source seg0Target Seg0HasExchangeItem
IFFS_Exercise (007146) uml:Class 9 / 9 9 / 9 9 / 9
SENTINEL-W, before re-author uml:Port 0 / 121 0 / 121 121 / 121

Port ends do not fail to publish. They publish a Seg0ItemFlowExchanges object that conveys its Signal correctly and does not say what it connects. That is a narrower and more dangerous defect than "it did not land": the object count is right, the conveyed item is right, and only the endpoints are missing, so anything checking presence rather than content scores it as a success.

Reading one back, and the casing trap

The properties are on the Seg0ItemFlowExchanges object itself. Plain getProperties, no GRM traversal. ⚠ The type mixes naming conventions, and a wrong-case name returns EMPTY exactly like a genuine absence:

property case holds
seg0Source lower the source Block, e.g. 007123-FuelPressureSensor
seg0Target lower the target Block, e.g. 007119-FuelControlUnit
Seg0HasExchangeItem CAPITAL S the conveyed Signal, e.g. 007199-FuelPressureSignal
object_string derived <source>-<target>

Asking for seg0HasExchangeItem returns nothing on a healthy object, which is how one investigation concluded the conveyed Signal had not crossed when all 121 of them carried it. Same family as the malformed-preference-probe trap: a bad name and a real absence are the same result.

⚠⚠ Active Workspace's "External Connections" table is NOT the flow direction, and it disagrees with seg0Source/seg0Target BY DESIGN. EXERCISED 2026-08-28 on connector 007204 (IFFS_Exercise), prompted by Chris's manual AWC check after "the seg0 check regularly gives incorrect results": the Interfaces page's External Connections table showed Source System = 007119-FuelControlUnit / Source Port = dataIn / Target System = 007123-FuelPressureSensor, the exact REVERSE of the exchange's seg0Source/seg0Target. Reading the connector OCCURRENCE settled it: that table renders the connector's ENDS under "Source"/"Target" column headers (fnd0bl_connected_end1 = dataIn.1 on FuelControlUnit, end2 = dataOut.1 on FuelPressureSensor). End order is creation order and carries no flow semantics: an INPUT port sitting in the "Source Port" column is the giveaway. The flow direction lives on the Seg0ItemFlowExchanges object, which the SAME page's Exchange Items grid shows correctly, so one AWC page can display both vocabularies disagreeing. Anyone comparing the External Connections columns against seg0Source/seg0Target will see them "wrong" roughly half the time. Two different property pairs share one column name; neither is broken.

Reachable from the connector as Fnd0LogicConnRevision -> Seg0Implements -> the Seg0ItemFlowExchanges, which is how the forward transform collects carriers.

★ The one-property acceptance check

object_string is DERIVED from source and target. Populated on all 9 good ones (007123-FuelPressureSensor-007119-FuelControlUnit), empty on all 121 bad ones.

After a publish, read object_string on the item-flow objects. Non-empty means both endpoints landed; empty means they did not. One property, one glance, and a partial write cannot fake it.

THIS CHECK IS SPECIFIC TO Seg0ItemFlowExchanges AND MUST NOT BE GENERALISED. object_string is DERIVED from source and target only on that type. Everywhere else it is the ordinary id-plus-name display string, which is non-empty on every healthy object and says nothing whatsoever about wiring:

type object_string usable as a wiring check
Seg0ItemFlowExchanges 007123-FuelPressureSensor-007119-FuelControlUnit yes, it is derived
Network 007919-ThermalAnomaly no, id + name
NetworkRevision 007919/A;1-ThermalAnomaly no, id + rev + name

Applying it to a Network would report every net as correctly wired, always. Caught by the Wildfire session on 2026-08-24 immediately after this entry was first written without the caveat.

⚠ It also does NOT cover the conveyed item: the 121 broken flows have Seg0HasExchangeItem populated and object_string empty. Check both if you care about both.

The functional layer: Networks are ITEMS, and carry no endpoints

EXERCISED 2026-08-24 on vm2606, and this is the counterpart to the item-flow rule above: the two layers store their connectivity in completely different places.

An object flow between CallBehaviorAction pins lands as a Network (item) / NetworkRevision, whose item-level type is PSConnectionRevision. It carries no endpoints. Four routes tried, all negative, each with the instrument proven working on other objects in the same session:

route result
seg0Source / seg0Target on the NetworkRevision, any casing absent from the type, not merely empty
expandGRMRelationsForPrimary / ForSecondary from the NetworkRevision only NetworkRevision Master
connection occurrences in the owning model's BOM the 4 found are BLOCK connectors, no Networks
connection occurrences in the Functionality's own BOM its pins are there, 0 connections

Do not go looking for the wiring on the Network. It is a named net, nothing more.

The connectivity IS recoverable, by joining function pins on their SIGNAL. A Network_Port occurrence under a Functionality carries a durable signalUids (plus a readable signalRefs), so two pins on two different Functionalities that share a signal uid are the two ends of that net. Measured on 007912 (Detect Ignition): 88 Logical Port occurrences, 39 carrying a signal uid, 11 distinct signals, 11 of 11 spanning two or more different parent functions, 0 orphans - and the reconstructed net names match the Network item names one for one.

⇒ Join on the uid, never the name. The names coincide here (VnirFrame the pin, VnirFrame the Network, 007854-VnirFrame the signal) which makes name-matching look sufficient, and signal names are documented elsewhere in this workspace as NOT unique across items.

Parameters: structure and value have different carriers

Setting a SysML default value creates the parameter and an Att0MeasureValue* with a real att0DateMeasured and an empty value. That reads like partial success and is not.

The value carrier is the stereotype tagged value:

TC_Parameter_Stereotype.Measurement  ->  att1Value    direction Both

Set Measurement and both att1Value and the MeasureValue's att0Value populate.

Still broken and not fixable from Cameo: att0AttrDefRev self-binds to a datatype-shaped default definition (e.g. Double (each)) with att0Uom empty. ObjectId is mapped TcToTool only, so the real definition must be bound Teamcenter-side. See tc-parameters-units.

Relations: what works and what does not

Confirmed working: Seg0Satisfy, Seg0Derive, IAV0Verify (req to req only), Seg0Allocate (structure to behavior), Att0HasParamValue, Seg0Implements, Seg0HasExchangeItem, Seg0ExchangeAllocation, Fnd0Diagram_Attaches, Item Flow::seg0Source / seg0Target, Flow Property::seg0ExchangeItem.

Confirmed NOT working: Seg0Refine and FND_TraceLink. 330 declared rules each. Four configurations apiece (both directions, shared pair, and a brand-new pair carrying no other relation), with three controls: a positive instrument control in every call, a fresh-element control, and a cardinality control. They simply do not come across.

⇒ For refine and trace links, author TC-side with createRelations. That works, and the relation survives a later Cameo Check-In (proven with Allocate) because the connector does not clobber relations it did not create.

Seg0Specializes (Generalization): EXERCISED 2026-08-28 on vm2606 (ZZCOV probe). A block-to- block Generalization crosses as a Seg0Specializes GRM relation, child REVISION -> parent ITEM. No reference property is compiled on either revision (both casings return dropped-name), so read it with expandGRMRelationsForPrimary (relationName filter member, expItemRev required) and carry a known-good relation in the same call as the instrument control.

Also from the same probe: a flow property typed by an in-model «ValueType» DataType allocates and resolves seg0ExchangeItem exactly like a Signal-typed one, while a BARE uml:DataType flow property allocates nothing even though the DataType itself lands as a Seg0IntfSpec. The signal-typing rule is about in-model-ness plus stereotype family, not metaclass.

Jython authoring traps

  • An InformationFlow cannot be owned by a Class. setOwner(block) throws IllegalArgumentException: can not find container for. Own it in a Package.
  • Activity uses getNode(), not getOwnedNode().
  • Own a Satisfy or Allocate Abstraction after the getClient() / getSupplier() writes: those writes re-home it.
  • The Requirement stereotype's own ownedAttribute is only [base_Class]. Id and Text are inherited from AbstractRequirement; setStereotypePropertyValue still finds them.
  • Keep Jython pure ASCII.
  • Wrap every model modification in a named session so a failure rolls back cleanly.
  • For a stereotype sourced from a used project, do not call setStereotypePropertyValue in the same session as the addStereotype: the entire stereotype application is silently discarded. Apply the stereotype in one session, set the tagged values in a second. This can turn a stamped «TC_Parameter_Stereotype» back into an unstamped one, which aborts the next push. (Relayed 2026-08-28 from the "Library palettes for functions and performers" session, root-caused and exercised there; not re-run here.)

The working order, and why each step is where it is

Check-Out  ->  author  ->  save  ->  mark for Deep Sync  ->  Check-In  ->  verify server-side

Both of the middle steps were learned by getting them wrong on a live model in one sitting.

Author AFTER the Check-Out, never before. A Check-Out pulls from Teamcenter and discards local edits. Eleven allocations and nine parameter values authored before a Check-Out were silently gone afterwards: the file shrank, the counts read zero, no warning of any kind. This is the same family as the long-standing "Synchronize pulls, it does not push" trap.

Correction: an earlier version of this note also named Put Model as a pull. It is not. There are three distinct pushes/pulls, and conflating them costs a duplicate item or a discarded edit: Put Model sends a NEW model and always mints a new TC item (the correct mode for a model that does not yet exist, the wrong one for a model that does, where it silently creates a duplicate); Publish updates an EXISTING checked-out model in place; Synchronize is the one that pulls. Both Put Model and Publish can optionally preserve the checkout. See "Re-publishing a model as NEW" below for the Put Model path in full.

Mark for Deep Sync AFTER the save and BEFORE the Check-In. A Check-In with nothing marked reports success and lands EMPTY containers, which in an update overwrites what was already there. Measured: a model reading 182 occurrences in Teamcenter dropped to 1 after a clean, error-free Check-In. Marking all 5,334 elements and re-pushing restored it to 185. Nothing warned, and the run that destroyed the content looked exactly like the run that restored it.

⇒ A clean Check-In is not evidence. Re-read the occurrence count server-side after every push.

Re-publishing a model as NEW (stripping Teamcenter identity)

When a model's Check-In is broken and you want a clean item rather than a repair, strip its TC identity and use Put Model, which is a different code path from the Check-In/update path:

  1. Unmark Deep Sync on everything (CameoUtil.stopSharing(id), walked recursively).
  2. Remove the Teamcenter identity. Removing the Teamcenter profile is the intended route, but it is an attached read-only module: ModelElementsManager.removeElement raises ReadOnlyElementException, and ModulesService.detachModulesOnTask wants a ModuleUsage, not the IAttachedProject that ProjectUtilities.getAllAttachedProjects returns. The route that worked was removing the stereotype APPLICATIONS instead (StereotypesHelper.removeStereotype for TC_Object_Stereotype, Teamcenter_Data, TC_CheckIn_CheckOut_Stereotype, TC_Share_Unshare_Stereotype, TC_Parameter_Stereotype). Skip read-only elements: those live in the UML/SysML/ISO profiles and carry no model identity.
  3. Save.
  4. Mark for Deep Sync.
  5. Put Model.

This costs you the parameter stamps. TC_Parameter_Stereotype goes with the strip, so parameters do not export at all on the fresh push and must be re-applied afterwards. Measured: parameters: 0 on the first read of the new model.

Note com.nomagic.magicdraw.core.ProjectUtilities is the class that resolves; com.nomagic.magicdraw.core.project.ProjectUtilities does not exist.

After a Put Model the project is not checked out, so the next push needs a Check-Out.

Correction, 2026-08-28: this note previously said headless Check-Out remains blocked. It is not. cameo_ops_checkout (route="import", CameoProgressBarServiceImpl.importProject(...) with flags[0]=true) was EXERCISED 2026-08-20 and re-verified 2026-08-24 on vm2606 (ZZP00_Containers / 000518), with the server-side checked_out flip read over an independent SOA session and an untouched-item control. ⚠ The vendor's own checkout() on its own STAGES A FILE AND RESERVES NOTHING while returning a plausible response with a staging path; that call is the trap this correction replaces. (Source: the cameo-mcp session and the "Another Headless Cameo" session; operational detail in RECIPES.md and cameo-mcp/docs/STATUS.md.)

Verifying: server-side only

The headless Check-In path does not write TC ids back into the model. The GUI path does. Measured in one read on one model: three GUI-created elements carried Teamcenter_Data.itemid + stableTcId, and eight headless-created elements carried nothing while all eleven existed in Teamcenter.

⇒ Walking the model for stamps to decide what landed under-reports. It is not a valid test.

Identity is still maintained server-side (keyed on cifContainerIdentifier, the Cameo element id), so re-pushing updates in place rather than duplicating. Across 21 pushes nothing forked.

Other verification notes:

  • exportRequirements returns a JsonObject describing what it intended to send, on paths that create nothing. It is not evidence.
  • The Check-In path writes no payload to the connector log. Input JSON of Export is the Put Model / export path only. Do not read its absence as proof of anything.
  • Seg0ItemFlowExchanges has an empty object_string, so tc_query_by_type reports 0 for it however many exist. Dereference Seg0Implements from the connector instead.
  • A flow property's result is a GRM relation on the interface revision (Seg0ExchangeAllocation), not BOM structure. A BOM expand finds nothing and reads as failure.
  • For relations whose GRM primary is WorkspaceObject (Derive, Refine), no reference property is compiled on either endpoint. Use expandGRMRelationsForPrimary with an explicit relationName filter, and always include a known-good relation in the same call as a positive control.
  • The connector stamps the PARAMETER, not the ActivityParameterNode. The landing matrix line "ActivityParameterNode -> Network_Port" is true about the MAPPING and false about which element carries the Teamcenter identity. processActivityParameterNode fetches the node, then calls setID(parameter.getID()), so the TC object is keyed on the Parameter. EXERCISED 2026-08-26 on vm2606: a stereotype scan of the 23 ActivityParameterNodes on the MSP-2 functions returned 0 crossed while the 23 Parameters returned 23 of 23, and the Network_Ports existed the whole time. ⇒ Verify the Parameter. Scanning the node reads as a total failure of the port layer.
  • Allocate relations carry NO tcuid and NO TC_Object_Stereotype. They become GRM relations, not items, so they never receive the stereotypes an item gets. Their absence from a stereotype scan is not evidence they failed: 0 of 16 in one file, 15 of which were confirmed present on the tier. ⇒ Read Seg0Allocate off the BLOCK REVISION (not the item, not the Activity), and put a deliberately fake property name in the same call as a control, because tc_get_properties silently drops unresolvable attribute names and an absent property is otherwise indistinguishable from an empty one. EXERCISED 2026-08-26: reading Seg0Allocate on 007239/A;1-MSP2-LB-ROOT returned all 9 function revisions, with fnd0ThisIsAFakeControlProperty dropped from the same response, proving the read discriminates.

A minimal model that exercises everything

Package Sensors
  Block  System            parts: a : Alpha (composite), b : Beta (composite)
                           value property rate : Real + «TC_Parameter_Stereotype» Measurement
  Block  Alpha             ProxyPort out : Link
  Block  Beta              ProxyPort in  : ~Link
  InterfaceBlock Link      flow property sig : DataSignal («FlowProperty», direction out)
  Signal DataSignal
  Connector on System      out@a <-> in@b, both ends «NestedConnectorEnd» with propertyPath
  ItemFlow                 conveyed DataSignal, realizing the connector,
                           source = Alpha, target = Beta   (BLOCKS, at creation)
  Activity Acquire         ActivityParameterNodes typed by DataSignal
                           CallBehaviorAction -> Activity Sample (with pins)
                           CallBehaviorAction -> Activity Publish (with pins)
                           ObjectFlow between the CBA pins
  Requirement R1, R2       Derive R2->R1, Verify R2->R1
  Satisfy                  System -> R1
  Allocate                 Alpha -> Sample          (structure to behavior)

Related skills

cameo-connector-config (environments and release switching), cameo-headless-automation (driving Cameo through the bridge), tc-parameters-units, tc-relations-traceability, tc-query-discovery, diagnose-silent-failure.

Task-ordered cookbook over these mechanics, with the test-model roster and the peer-session findings ledger: RECIPES.md in this skill folder.


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