Skip to content

AAS labels the shell's asset identity "gtin" whatever scheme issued it #331

Description

@LKSNDRTMLKV

Found by the #328 identifier scan.

build_aas_from_passport takes the asset identity as a bare gtin: &str and emits it twice under a GS1 label:

// crates/dpp-aas/src/builder.rs:89
SpecificAssetId { name: "gtin".into(), value: gtin.to_owned() }
// :124
global_asset_id: format!("urn:odal-node:product:{gtin}")

The doc comment on the function already says so, and calls it pre-existing.

Why it is worth a ticket now rather than staying a documented quirk

#295 made it reachable. While every product group payload carried a mandatory gtin, the label was always true — a caller had nothing else to pass. EN 18219 schemes 2 and 3 are self-issuing and carry no GTIN, so the label is now false for exactly the passports the identifier work exists to enable.

That is the same shape as dpp-engine #376, where a GTIN was scraped out of the carrier URI and the internal UUID substituted when there was none: a scheme-1 assumption that was harmless only because scheme 1 was universal.

It matters more here than in an internal struct because an AAS Environment is an interop document. A consuming toolchain reads specificAssetIds by name; one asking for gtin and receiving did:web:acme.example.com:b:1 has been told something untrue by a document it treats as authoritative. globalAssetId carries the same value into a urn:odal-node:product: URN.

The tension to resolve, which is why this is a decision and not a patch

The parameter is deliberately not read off the passport — the unsold-goods mapper's module note records why: the asset identity is the caller's, and a file export or an AASX package assembled for a reporting authority may legitimately key on something that is not the passport's product identifier at all. So "just use product_identifier()" is not the answer; it would break the case the parameter exists for.

Options, roughly in increasing cost:

  1. Name the slot from the value. Take &ProductIdentifier where the caller has one and derive the specificAssetId name per scheme — reusing dpp_registry::{SCHEME_GTIN, SCHEME_IDENTIFICATION_LINK, SCHEME_DID}, which already state those three strings once and record all three as RegistryBasis::Assumed.
  2. Take a (name, value) pair and keep the identity fully the caller's, which makes the mislabel impossible to produce by accident but pushes the choice out.
  3. Keep &str, rename the slot to something scheme-neutral (productIdentifier) — cheapest, but silently changes a key an existing AAS consumer may match on.

Option 1 is the one that matches what dpp-registry already does for the same question on the registry wire.

Check while fixing

crates/dpp-tests/fixtures/aas/environments/*.json carry "gtin" as a specificAssetId name in all twelve environments; whichever option is taken, those goldens move with it.

Related: #328, #295, #322.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    surface/schemaMoves a JSON schema, instrument manifest or product grouptype/defectSomething published or encoded here is wrong or unbackable nowurgency/nextBlocks work already scheduled

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions