The secret the generated parameters a TARGET template version NEWLY declares
are minted into: <app-slug>-v<target-version-slug>.
DELIBERATELY NOT templateSecretNameFor: the mint endpoint writes a
whole new secret VERSION from the key names it is given, so minting the added
keys into the app's existing secret would rotate — and therefore break — the
keys the running workload already uses. A target-version-scoped SIBLING is
additive, leaves carried refs pointing at their original secret, and is
deterministic so a retried upgrade reuses the sibling instead of rotating it.
This is the ONE derivation both clients use (CLI template upgrade and the
webapp upgrade dialog), and they use it UNCONDITIONALLY — no "primary secret
if it does not exist yet" branch. An upgrade started in one client and
retried in the other has to land on the SAME secret, or the org accumulates
two half-populated siblings and one of the two renders refs the device
cannot resolve.
The v marker is load-bearing — without it <app>-2-0-0 is ambiguous with
an application literally named <app>-2-0-0. The app slug is TRUNCATED (not
rejected) when the version suffix leaves less than the full budget, so a long
app name degrades to a shorter deterministic name rather than failing an
upgrade half-way through.
TRUNCATION IS DISAMBIGUATED. A blind slice made two applications whose slugs
share the truncation prefix derive the SAME sibling secret — one upgrade would
write the other app's live credentials, and the "delete this leftover secret"
cleanup hint each client prints would tell one operator to delete the other
app's running secret. When (and only when) the slug does not fit, the kept head
is followed by -<8 hex> of slugFingerprint over the FULL untruncated
slug, so distinct apps get distinct siblings while the derivation stays pure
and deterministic. Names that already fit are unchanged — no existing sibling
is renamed by this.
Parameters
appName: string
targetVersion: string
Returns string
Throws
TemplateSecretNameError the app name or version slugifies to nothing
usable, or the version suffix leaves no room for a collision-safe stem.
The secret the generated parameters a TARGET template version NEWLY declares are minted into:
<app-slug>-v<target-version-slug>.DELIBERATELY NOT templateSecretNameFor: the mint endpoint writes a whole new secret VERSION from the key names it is given, so minting the added keys into the app's existing secret would rotate — and therefore break — the keys the running workload already uses. A target-version-scoped SIBLING is additive, leaves carried refs pointing at their original secret, and is deterministic so a retried upgrade reuses the sibling instead of rotating it.
This is the ONE derivation both clients use (CLI
template upgradeand the webapp upgrade dialog), and they use it UNCONDITIONALLY — no "primary secret if it does not exist yet" branch. An upgrade started in one client and retried in the other has to land on the SAME secret, or the org accumulates two half-populated siblings and one of the two renders refs the device cannot resolve.The
vmarker is load-bearing — without it<app>-2-0-0is ambiguous with an application literally named<app>-2-0-0. The app slug is TRUNCATED (not rejected) when the version suffix leaves less than the full budget, so a long app name degrades to a shorter deterministic name rather than failing an upgrade half-way through.TRUNCATION IS DISAMBIGUATED. A blind slice made two applications whose slugs share the truncation prefix derive the SAME sibling secret — one upgrade would write the other app's live credentials, and the "delete this leftover secret" cleanup hint each client prints would tell one operator to delete the other app's running secret. When (and only when) the slug does not fit, the kept head is followed by
-<8 hex>of slugFingerprint over the FULL untruncated slug, so distinct apps get distinct siblings while the derivation stays pure and deterministic. Names that already fit are unchanged — no existing sibling is renamed by this.