TeamcenterKnowledge

Skills

TC Deployable Package

Skill tc-deployable-package. Ship a custom Teamcenter BMIDE template as a Deployment Center package whose PAYLOAD actually installs, and prove that it did. Covers the four rendering preferences a type needs and why registering one does not cover the others, the Deployment Center localization bundle's real format (wrong shape renders the raw key as the application's name), the generated-file trap that silently reverts edits at the next build, a build gate that fails when a style sheet is installed but nothing can reach it, staging into the repository, and the verification chain where the packager, the exit code and the installer log each report success on a failure. Use when building or deploying a custom template package, when a deployed capability is missing a surface, or before claiming a package installs anything.

Proven end to end on the TC2606 VM (vm2606, guest SIEMENSDC) on 2026-08-17, deploying dss4dm4 through Deployment Center into a freshly reverted tier and verifying every claim against the tier afterwards.

Read tc-bmide-project-validation first: it owns the question of whether the PROJECT is well formed. Read tc-deployment-center for operating DC itself. This skill owns the part between them, which is the part that fails silently: whether the package carries its payload, whether the payload registers anything, and how to tell.

The one rule

A deployed template that installs its data model and none of its surfaces looks exactly like a complete success. No error, no warning, no failed step. The types exist, the objects can be created, and every screen falls back to a generic default that reads as a design choice rather than a missing file.

Everything below exists because of that.

The pipeline, and where the truth lives at each step

awc/xrt/*.xml, awc/prefs/*.xml     <- SOURCE. Edit here.
        |  build_package
project/install/<template>/...     <- GENERATED. Never edit.
        |  bmide_generate_package.bat  (on the tier, inside tc_Vanilla_Env.bat)
output/wntx64/packaging/full_update/<template>_all_<ver>/
        |  copy, unzipped
C:\apps\DC\repository\software\<kit>
        |  Deployment Center
C:\apps\PLM\tc_root\install\<template>\   + rows in the database

★★ The last arrow is the only one that matters and the only one nothing checks. Every step before it can succeed while the payload is empty.

★★★ Never edit a generated file

Hit here on 2026-08-17 and it silently reverted five preference registrations. project/install/<template>/data/<prefix>_preferences.xml is produced by the build from awc/prefs/<prefix>_stylesheet_registration.xml. Editing the generated copy works, survives testing, and disappears at the next regeneration.

Count before and after every build. That is what caught it:

prefs: 7      <- before
prefs: 2      <- after regenerating

Reading the file did not catch it; the file looked right until the build ran. Grep for the file name in the generator before editing anything under a directory a build writes to. If the generator copies it, the file you want is upstream.

The registration set: FOUR preferences, not one

A type's surfaces are registered separately and independently. Registering one does not cover the others, and there is no error when one is absent.

preference drives
AWC_<Type>.SUMMARYRENDERING the tabbed summary
AWC_<Type>.showObjectLocation.SUMMARYRENDERING the LOCATION tab row (Details, Relations, ...)
AWC_<Type>.INFORENDERING the information panel
AWC_<Type>.CREATERENDERING the create/Add dialog

Do not read "OOTB types register all four" as a rule. Measured across the whole 2606 tier: of 591 types carrying a plain SUMMARYRENDERING, 378 also have INFORENDERING, 240 also have showObjectLocation, and only 171 (29%) have all three. Absence is the majority case.

★ That number was originally reported here as "three unrelated OOTB types each register all three", from a sample drawn out of the set of files carrying AwRelationsSublocation, which by construction already have showObjectLocation. Selecting on the property being measured turned a minority pattern into an apparent universal. If a base rate matters, count the whole population.

★★★ A style sheet that nothing can reach ships inert

The defect that motivated this skill. Three create panels were authored, added to the install manifest, and installed as datasets with no registering preference. The Add dialog then falls back to a generic skeleton: two empty sections and none of the type's properties. Nothing errors, and the utility reports success.

It survived every screen test because the tier and the package disagreed and only the tier was ever looked at: the registrations existed there, set by hand during earlier testing. An exported site preference list is what finally showed it, by counting.

Gate the build. A sheet is reachable two ways and both are legitimate:

  • a preference names it (<value>Dm0CriterionCreate</value>), or
  • another sheet injects it (<inject type="dataset" src="..."/>)

Anything else is dead payload. Fail the build, do not warn.

unreachable = [ds for ds in manifest_entries
               if f"<value>{ds}</value>" not in prefs
               and f'src="{ds}"' not in all_installed_sheets]

Run it against known-bad input, every time. Controls that caught real problems: clean copy passes; one registration dropped fails and names the sheet; one inject broken fails and names the sheet.

The Deployment Center localization bundle

Wrong shape here renders the raw key as the application's name in DC's picker.

<localization name="<packageId>">
    <property name="displayName" value="Decision Management"/>
    <property name="description" value="..."/>
</localization>

★★ The keys are RELATIVE. The descriptor asks for ${packageId}.displayName; the packageId half comes from the <localization name> attribute and only the remainder is the property name. Right shape plus fully-qualified keys parses and resolves nothing.

The file NAME is a decoy and is not wrong. The descriptor references ${packageId}Bundle.xml while the file on disk is <packageId>DCBundle_<locale>.xml. That reads like a mismatch and is exactly what Siemens ships: acistoprt_translator, acrobatlauncher and activeworkspacebom all do it. Check the media before "fixing" it.

★★★ A verifier for this already existed and passed. It checked that every ${packageId}.X in the descriptor had a matching entry in the bundle, comparing the generator's output against the generator's own idea of a key. It confirmed self-consistency and could not detect a wrong format by construction. Assert the SHAPE first, against a shipped file, then the contents.

Reading a generated kit

<template>_all_<ver>/
    media_teamcenter_<template>.xml     <- what DC identifies the kit by
    artifacts/
        <template>_install.zip          <- THE PAYLOAD IS IN HERE
        <template>_template.zip
        <template>_icons.zip
        <template>_project_tc<rel>.zip
    dc_contributions/packages/...
    tem_contributions/...

Listing loose files in the kit reports zero style sheets on a correct kit. The payload is zipped. Open <template>_install.zip and read the entries, and read the preference file's contents out of the archive rather than off disk.

Staging

Kits must be unzipped and sit in a software directory. On this VM:

C:\apps\DC\repository\software\<kit>

DC_RepoService scans it, and that service is Manual and Stopped after a revert. A kit that does not appear is that service not running at least as often as it is a bad kit.

★★★ Verification: three reporters that lie

1. The packaging utility. bmide_generate_package.bat reporting success says nothing about whether the package is viable. Established the hard way, more than once. Never assert viability from it.

2. The exit code. preferences_manager prints General Fault Exception and Fatal error detected at startup and then exits 1 while completing successfully. Control: the environment batch alone exits 0 and prints nothing, and the export that exited 1 wrote a correct 6.5 MB file holding 10541 preferences. Consequence: package post-install steps need failonerror="false" to work at all, which equally means a genuine failure there is invisible.

3. The installer log. install_xml_stylesheet_datasets -replace logs a per-dataset line when it CREATES and no line at all when it REPLACES. Success and no-op are indistinguishable. It also adds a dataset VERSION per run rather than overwriting.

Verify by effect, from a fresh process.

preferences_manager -u=... -p=... -g=dba -mode=export -scope=SITE -out_file=<f>

then count AWC_<Prefix>* in the output. SOA preference reads are cached per session and hand back the old value on the connection that wrote it.

The acceptance test, written BEFORE the deploy

State it in advance so it cannot be rationalised afterwards. The one used here:

  1. exported preferences show N of N registrations
  2. all M style sheet datasets created, named in the deploy log
  3. the data model is present, checked with a fabricated type as a control
  4. the surfaces render

Checks 1 to 3 are headless. Check 4 needs eyes or a headless browser.

Deploy into a reverted tier. The revert wipes hand-installed work, which is what makes it an experiment rather than a demonstration. Anything present afterwards came from the package.

★★ The install probe

When a surface does not appear and the log cannot tell you whether your file reached the renderer, install a deliberately ugly marker alongside the change:

<section title="INSTALL PROBE - delete me">
  <property name="item_id"/>
</section>

Three outcomes, one look: marker and fix (done); marker only (installs land, the change is wrong); neither (installs are not reaching the renderer, and every earlier "fix" was untested).

This should be the FIRST move, not the fourth. Three attempts were reported as installed here purely on the strength of a log that cannot distinguish success from no-op.

XRT traps that only a deploy will find

★★ A top-level <inject> may need to be a BARE child of <rendering>. <content><inject src="RelationsSummary"/></content> does not render; <inject src="RelationsSummary"/> does. Both forms exist OOTB and the wrapper works for other injects in the same file, which is what makes this expensive: the wrapper looks proven by the working tabs beside it.

★★ A copied visibleWhen does not carry the context that made it true. ActiveWorkspace:Location == com.siemens.splm.clientfx.tcui.xrt.showObjectLocation, lifted from two OOTB sheets that use it for exactly this purpose, is FALSE in a type summary sheet, because that sheet renders nested inside the location's own Details page rather than as the location.

★★ An absent tab, a gated-off tab, and a tab pointing at the wrong kind of view are identical on screen. Do not iterate on guesses. Find a type that already does what you want, read its style sheet, and copy the mechanism. Two calls spent reading Uml0ModelRevSummary beat two deploys spent guessing.

Client-owned views are asked for, not authored. A pageNameToken names a LOCATION view and belongs in the location sheet. Inside a type summary, contribute the panel instead (<inject type="dataset" src="RelationsSummary"/>, an htmlPanel bound to Rv1RelationsBrowser). 243 sheets on this tier inject that one.

⚠ Injecting another template's dataset creates an undeclared dependency. It resolves on a tier where that template is installed and points at nothing where it is not. Declare it, or record it as open. Do not invent the guid.

★★★ The deploy leaves services stopped, the pool manager among them

Measured on the 2026-08-17 dss4dm4 deploy: the deployment stopped seven services and started five. Stopped and never restarted:

Server Manager   (Teamcenter Server Manager TCDB_PoolA)
actionmgrd

Found because a parallel SSO effort hit the same gap from the other side: their deploy restarted some services but not the pool manager, so tcserver spawns kept using pre-deploy configuration and rejected every login. Nothing they tried worked until the pool manager was restarted by hand.

Restart the Server Manager explicitly after any deploy that changes the data model or the configuration, and check the service list rather than assuming the deploy left the tier as it found it. A stopped actionmgrd is quieter and will surface later as workflow actions simply not firing.

★ The reason this is easy to miss: Server Manager replaces dead or missing tcservers quickly enough that a pool census still reads its normal size, so health-check numbers look fine while the processes behind them are wrong. Count what the pool is made of, not how big it is.

And do not let the timing evidence overclaim. On that tier, 12 tcserver processes started before the deploy and none crashed, while 17 started after and 6 crashed. That looks like proof of stale state and is not: the pre-deploy processes never loaded the new type model, so "a stale pool manager" and "the new model crashes tcserver" predict exactly the same pattern. The pre-deploy set is not a control. The discriminating test is to restart the pool manager and re-run the same workload.

Icons are NOT packaged by default

project/icons/master_icon.xml generates as an empty <TcBusinessDataIncludes/>, so <template>_icons.zip ships with one entry and no icons. AWC type icons live in aws2\stage\out\darsi_repo\image\ (plus two other bundle paths) as type<TypeName>48.svg, and unlike style sheets they are not read from the database per render: shipping them means contributing into the client bundle and rebuilding the client, which is the multi-GB DARSI build. Budget for it separately or state plainly that the capability ships without icons.

Provenance

Mark every claim here EXERCISED or DERIVED. Everything above was exercised on vm2606 on 2026-08-17 except the icon delivery route, which is DERIVED from where the tier keeps its icons and has not been performed.

Related skills

tc-bmide-project-validation, tc-deployment-center, tc-awc-stylesheets, tc-awc-custom-tab, tc-vm-operations, diagnose-silent-failure.


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