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:
- exported preferences show N of N registrations
- all M style sheet datasets created, named in the deploy log
- the data model is present, checked with a fabricated type as a control
- 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.