@bsv/dpp-profiles 0.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE +58 -0
  2. package/README.md +64 -0
  3. package/dist/applicability.d.ts +96 -0
  4. package/dist/applicability.d.ts.map +1 -0
  5. package/dist/applicability.js +181 -0
  6. package/dist/applicability.js.map +1 -0
  7. package/dist/combinations.d.ts +30 -0
  8. package/dist/combinations.d.ts.map +1 -0
  9. package/dist/combinations.js +103 -0
  10. package/dist/combinations.js.map +1 -0
  11. package/dist/evidence-shapes.d.ts +198 -0
  12. package/dist/evidence-shapes.d.ts.map +1 -0
  13. package/dist/evidence-shapes.js +123 -0
  14. package/dist/evidence-shapes.js.map +1 -0
  15. package/dist/gs1-epc-binary.d.ts +81 -0
  16. package/dist/gs1-epc-binary.d.ts.map +1 -0
  17. package/dist/gs1-epc-binary.js +252 -0
  18. package/dist/gs1-epc-binary.js.map +1 -0
  19. package/dist/gs1-resolution.d.ts +392 -0
  20. package/dist/gs1-resolution.d.ts.map +1 -0
  21. package/dist/gs1-resolution.js +696 -0
  22. package/dist/gs1-resolution.js.map +1 -0
  23. package/dist/identifiers.d.ts +57 -0
  24. package/dist/identifiers.d.ts.map +1 -0
  25. package/dist/identifiers.js +117 -0
  26. package/dist/identifiers.js.map +1 -0
  27. package/dist/index.d.ts +235 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +124 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/manifest-v2.d.ts +87 -0
  32. package/dist/manifest-v2.d.ts.map +1 -0
  33. package/dist/manifest-v2.js +31 -0
  34. package/dist/manifest-v2.js.map +1 -0
  35. package/dist/mapping.d.ts +84 -0
  36. package/dist/mapping.d.ts.map +1 -0
  37. package/dist/mapping.js +88 -0
  38. package/dist/mapping.js.map +1 -0
  39. package/dist/projections.d.ts +233 -0
  40. package/dist/projections.d.ts.map +1 -0
  41. package/dist/projections.js +466 -0
  42. package/dist/projections.js.map +1 -0
  43. package/frozen.json +42 -0
  44. package/generated/consumer/battery-v2.json +2248 -0
  45. package/generated/consumer/battery-v3.json +4354 -0
  46. package/generated/consumer/general-v1.json +9 -0
  47. package/generated/consumer/general-v2.json +714 -0
  48. package/generated/consumer/textile-v1.json +101 -0
  49. package/generated/consumer/textile-v2.json +1033 -0
  50. package/generated/consumer/textile-v3.json +2011 -0
  51. package/generated/index.json +86 -0
  52. package/generated/mapping/battery@2.md +116 -0
  53. package/generated/mapping/battery@3.md +130 -0
  54. package/generated/mapping/general@2.md +50 -0
  55. package/generated/mapping/textile@2.md +61 -0
  56. package/generated/mapping/textile@3.md +73 -0
  57. package/generated/payload-schema/battery@2.public.schema.json +609 -0
  58. package/generated/payload-schema/battery@2.restricted.schema.json +377 -0
  59. package/generated/payload-schema/battery@3.public.schema.json +1364 -0
  60. package/generated/payload-schema/battery@3.restricted.schema.json +1097 -0
  61. package/generated/payload-schema/general@1.public.schema.json +37 -0
  62. package/generated/payload-schema/general@1.restricted.schema.json +9 -0
  63. package/generated/payload-schema/general@2.public.schema.json +352 -0
  64. package/generated/payload-schema/general@2.restricted.schema.json +52 -0
  65. package/generated/payload-schema/textile@1.public.schema.json +82 -0
  66. package/generated/payload-schema/textile@1.restricted.schema.json +22 -0
  67. package/generated/payload-schema/textile@2.public.schema.json +464 -0
  68. package/generated/payload-schema/textile@2.restricted.schema.json +78 -0
  69. package/generated/payload-schema/textile@3.public.schema.json +1299 -0
  70. package/generated/payload-schema/textile@3.restricted.schema.json +78 -0
  71. package/manifests/battery@2.json +4047 -0
  72. package/manifests/battery@3.json +6164 -0
  73. package/manifests/exchange/untp-0.7.0-jose@1.json +191 -0
  74. package/manifests/exchange/vc-di-ecdsa-rdfc-2019@1.json +74 -0
  75. package/manifests/exchange/vsc-draft-compat@0.1.0.json +64 -0
  76. package/manifests/general@1.json +148 -0
  77. package/manifests/general@2.json +1266 -0
  78. package/manifests/interoperability/epcis-json@1.json +69 -0
  79. package/manifests/interoperability/epcis-vsc@1.json +64 -0
  80. package/manifests/interoperability/gs1-digital-link@1.json +71 -0
  81. package/manifests/operator/federated-operators@1.json +54 -0
  82. package/manifests/operator/single-operator@1.json +52 -0
  83. package/manifests/textile@1.json +383 -0
  84. package/manifests/textile@2.json +1682 -0
  85. package/manifests/textile@3.json +2763 -0
  86. package/package.json +59 -0
  87. package/schemas/exchange-profile.schema.json +134 -0
  88. package/schemas/gs1/NOTICE.md +11 -0
  89. package/schemas/gs1/resolver-description-file-schema-1.2.0.json +124 -0
  90. package/schemas/gs1/resolver-linkset-context-1.2.1.jsonld +39 -0
  91. package/schemas/gs1/resolver-linkset-schema-1.2.1.json +96 -0
  92. package/schemas/interoperability-profile.schema.json +347 -0
  93. package/schemas/operator-profile.schema.json +108 -0
  94. package/schemas/product-identity.schema.json +45 -0
  95. package/schemas/profile-manifest-v2.schema.json +1087 -0
  96. package/schemas/profile-manifest.schema.json +291 -0
@@ -0,0 +1,69 @@
1
+ {
2
+ "manifestVersion": "1",
3
+ "id": "epcis-json",
4
+ "version": "1",
5
+ "profile": "epcis-json@1",
6
+ "kind": "interoperability",
7
+ "role": "source-exchange",
8
+ "status": "current",
9
+ "title": "EPCIS 2.0.1 JSON and JSON-LD source exchange",
10
+ "description": "Bounded import, standard query consumption, exact-byte retention, idempotent and conflict-aware re-arrival, and original-byte export of EPCIS 2.0.1 documents, as spec/epcis-interoperability.md defines. A source is validated against the pinned schema and retained with its findings; it is never repaired, coerced or reordered, and importing it never publishes a credential or touches a native token. Not an EPCIS repository, not a capture interface, and not a claim of GS1 conformance.",
11
+ "specification": "spec/epcis-interoperability.md",
12
+ "standards": [
13
+ { "id": "epcis", "name": "GS1 EPCIS", "version": "2.0.1", "uri": "https://ref.gs1.org/standards/epcis/2.0.1/", "scope": "The JSON and JSON-LD bindings of EPCISDocument and EPCISQueryDocument, the five event types, event identity and error declarations, and the REST query binding's events query, pagination and headers." },
14
+ { "id": "cbv", "name": "GS1 Core Business Vocabulary", "version": "2.0.0", "uri": "https://ref.gs1.org/standards/cbv/", "scope": "Business step, disposition, business transaction and source or destination type values as the JSON binding carries them; no other vocabulary is interpreted." },
15
+ { "id": "gs1-digital-link-uri-syntax", "name": "GS1 Digital Link URI syntax", "version": "1.7.0", "uri": "https://ref.gs1.org/standards/digital-link/uri-syntax/1.7.0/", "scope": "The reading of claimed-GS1 identifiers that appear as HTTPS Digital Link URIs; the grammar is applied, never used to rewrite an identifier." },
16
+ { "id": "jcs", "name": "JSON Canonicalization Scheme", "version": "RFC 8785", "uri": "https://www.rfc-editor.org/rfc/rfc8785", "scope": "The canonical form the event-body digest and inline context digests are taken over." }
17
+ ],
18
+ "artefacts": [
19
+ { "id": "epcis-json-schema", "kind": "json-schema", "uri": "https://ref.gs1.org/standards/epcis/2.0.1/epcis-json-schema.json", "version": "2.0.1", "digest": "0f46ff694efffd8d8ce840a33dfde84228add11b516b8b258f3200740ae210af", "byteLength": 55680, "retrieval": "pinned", "carried": "packages/vsc/artifacts/epcis/epcis-json-schema-2.0.1.json", "notes": "Every source document is validated against these exact bytes; a document the schema rejects is retained with failed findings, never repaired." },
20
+ { "id": "epcis-context", "kind": "jsonld-context", "uri": "https://ref.gs1.org/standards/epcis/2.0.1/epcis-context.jsonld", "version": "2.0.1", "digest": "5056c65f991425b1d3a35e35edf4f7d0c7ff56cf688c2912b930f93494713737", "byteLength": 20690, "retrieval": "pinned", "carried": "packages/vsc/artifacts/epcis/epcis-context-2.0.1.jsonld", "notes": "The one context IRI this profile pins; its digest enters every event-body digest of a document that declares it." },
21
+ { "id": "epcis-query-schema", "kind": "json-schema", "uri": "https://ref.gs1.org/standards/epcis/2.0.1/query-schema.json", "version": "2.0.1", "digest": "4b5583c9a0a715324594617f3cf6744f4f930568484f7df8fb7aa81819355341", "byteLength": 27229, "retrieval": "pinned", "carried": "packages/vsc/artifacts/epcis/query-schema-2.0.1.json", "notes": "The shape of a named query body; the pull connector expresses its bounded query through the standard parameters and this schema names them." },
22
+ { "id": "epcis-openapi", "kind": "openapi", "uri": "https://ref.gs1.org/standards/epcis/2.0.1/openapi.json", "version": "2.0.1", "digest": "3d33792c520d7a7a1d080382d956730bb07021c7dd1cc17229fce27b784d66fc", "byteLength": 351201, "retrieval": "pinned", "licence": "Apache-2.0 as its info block declares", "notes": "Pinned by digest and not carried: the pull connector consumes GET /events with MATCH_anyEPC, eventType, GE_eventTime, LT_eventTime, GE_recordTime, EQ_eventID, perPage and nextPageToken, the Link rel=next header, GS1-EPCIS-Version and GS1-CBV-Version, and GS1-Next-Page-Token-Expires, exactly as this artefact defines them." }
23
+ ],
24
+ "inputs": [
25
+ { "id": "epcis-document-json", "mediaType": "application/json", "format": "EPCISDocument", "notes": "The JSON binding; the document declares its @context." },
26
+ { "id": "epcis-document-jsonld", "mediaType": "application/ld+json", "format": "EPCISDocument" },
27
+ { "id": "epcis-query-document-json", "mediaType": "application/json", "format": "EPCISQueryDocument", "notes": "One page of a standard query result, from a file or from the pull connector." },
28
+ { "id": "epcis-query-document-jsonld", "mediaType": "application/ld+json", "format": "EPCISQueryDocument" }
29
+ ],
30
+ "outputs": [
31
+ { "id": "original-bytes", "mediaType": "application/octet-stream", "format": "the exact received bytes, served under the received media type", "notes": "Export returns the retained bytes and never a re-serialisation." },
32
+ { "id": "import-record", "mediaType": "application/json", "format": "epcis-import@1 (contracts/epcis-import.schema.json)", "notes": "Per-event pointers, identities, validation and mapping findings, conflicts and publication references." }
33
+ ],
34
+ "dependencies": [
35
+ { "name": "ajv", "version": "8.20.0", "licence": "MIT", "use": "Validation of a source against the pinned schema, formats asserted, nothing coerced." },
36
+ { "name": "ajv-formats", "version": "3.0.1", "licence": "MIT", "use": "The uri and date-time formats the schema names." }
37
+ ],
38
+ "limits": {
39
+ "maxDocumentBytes": 2097152,
40
+ "maxEventsPerPage": 100,
41
+ "maxJsonDepth": 64,
42
+ "maxContextDocuments": 16,
43
+ "maxContextBytes": 1048576,
44
+ "fetchTimeoutMs": 10000,
45
+ "maxPullPages": 10,
46
+ "maxPullBytes": 20971520,
47
+ "maxPullSeconds": 60
48
+ },
49
+ "mappingLimits": [
50
+ { "id": "unpinned-context", "outcome": "unsupported", "reason": "A context IRI this profile has not pinned is preserved as declared; no claim that depends on its terms can pass." },
51
+ { "id": "extension-event-type", "outcome": "unsupported", "reason": "An event whose type is not one of the five is retained with its pointer and identity and is not interpreted." },
52
+ { "id": "alternative-jsonld-terms", "outcome": "transformed", "reason": "Two JSON-LD spellings of one meaning digest differently; equivalence across terms or sources is not promised and never inferred." },
53
+ { "id": "timestamp-only-polling", "outcome": "transformed", "reason": "A pull bounded by record time cannot discover every retrospective error declaration; completeness is declared per query, never assumed." }
54
+ ],
55
+ "unsupported": [
56
+ { "id": "xml-binding", "reason": "The XML binding is not read; a source in XML is refused by media type." },
57
+ { "id": "soap-and-as2", "reason": "No SOAP or AS2 transport." },
58
+ { "id": "subscriptions", "reason": "No subscription or push delivery; retrieval is a bounded pull or a file import." },
59
+ { "id": "capture-interface", "reason": "This profile imports and retains; it does not operate a capture endpoint or an EPCIS repository." },
60
+ { "id": "complete-history", "reason": "No import or pull asserts complete history; each result declares its query, cutoff and limits." },
61
+ { "id": "automatic-native-operations", "reason": "An import never issues, updates, transfers or retires a native passport state and never publishes a credential; those are separately authorised operations." },
62
+ { "id": "recursive-crawl", "reason": "Retrieval of further identifiers requires explicit caller or configured scope; there is no repository crawler." }
63
+ ],
64
+ "sourceRefs": [
65
+ { "id": "epcis-2.0.1", "name": "GS1 EPCIS 2.0.1", "reference": "https://ref.gs1.org/standards/epcis/2.0.1/", "version": "2.0.1", "attribution": "GS1 AISBL", "use": "The document, event and query contracts this profile reads." },
66
+ { "id": "cbv-2.0.0", "name": "GS1 Core Business Vocabulary 2.0.0", "reference": "https://ref.gs1.org/standards/cbv/", "version": "2.0.0", "attribution": "GS1 AISBL", "use": "The vocabulary values the JSON binding carries." },
67
+ { "id": "rfc-8785", "name": "JSON Canonicalization Scheme", "reference": "https://www.rfc-editor.org/rfc/rfc8785", "attribution": "IETF", "use": "Canonical form for digests." }
68
+ ]
69
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "manifestVersion": "1",
3
+ "id": "epcis-vsc",
4
+ "version": "1",
5
+ "profile": "epcis-vsc@1",
6
+ "kind": "interoperability",
7
+ "role": "mapping",
8
+ "status": "current",
9
+ "title": "EPCIS event to VSC SEAL mapping with explicit outcomes",
10
+ "description": "The bounded projection of one retained EPCIS 2.0.1 event into the existing vsc-draft-compat@0.1.0 SEAL, as packages/vsc mapEpcisEventWithReport implements it and spec/epcis-interoperability.md section 3 defines it. Every mapping returns one of lossless, transformed, unsupported or insufficient-data with its losses or missing inputs named; the source event is retained in the signed round-trip extension and the exact source bytes and pointer are named in the signed source reference urn:bsv:dpp:epcis-source:1. Mapping never issues: issuance needs the actual issuer, key, role, jurisdiction, status and custody evidence and the complete SEAL must pass the VSC profile unchanged.",
11
+ "specification": "spec/epcis-interoperability.md",
12
+ "standards": [
13
+ { "id": "epcis", "name": "GS1 EPCIS", "version": "2.0.1", "uri": "https://ref.gs1.org/standards/epcis/2.0.1/", "scope": "The five event types and their identifier, time, place, step, disposition and action members." },
14
+ { "id": "cbv", "name": "GS1 Core Business Vocabulary", "version": "2.0.0", "uri": "https://ref.gs1.org/standards/cbv/", "scope": "Business steps and dispositions carried as the JSON binding spells them; a disposition the VSC custody model does not name is unsupported, never substituted." },
15
+ { "id": "vsc-draft-compat", "name": "VSC draft compatibility profile", "version": "0.1.0", "uri": "spec/vsc-profile.md", "scope": "The SEAL structure, custody state model and correction rules the mapped credential must satisfy unchanged." }
16
+ ],
17
+ "artefacts": [
18
+ { "id": "epcis-json-schema", "kind": "json-schema", "uri": "https://ref.gs1.org/standards/epcis/2.0.1/epcis-json-schema.json", "version": "2.0.1", "digest": "0f46ff694efffd8d8ce840a33dfde84228add11b516b8b258f3200740ae210af", "byteLength": 55680, "retrieval": "pinned", "carried": "packages/vsc/artifacts/epcis/epcis-json-schema-2.0.1.json" },
19
+ { "id": "epcis-context", "kind": "jsonld-context", "uri": "https://ref.gs1.org/standards/epcis/2.0.1/epcis-context.jsonld", "version": "2.0.1", "digest": "5056c65f991425b1d3a35e35edf4f7d0c7ff56cf688c2912b930f93494713737", "byteLength": 20690, "retrieval": "pinned", "carried": "packages/vsc/artifacts/epcis/epcis-context-2.0.1.jsonld" },
20
+ { "id": "owned-seal-schema", "kind": "json-schema", "uri": "urn:bsv:vsc:schema:0.1.0", "version": "0.1.0", "digest": "839123ea6a2ca459c62143a9a38ece281a7b91e719dca057b28baf4d53106d15", "retrieval": "owned", "carried": "packages/vsc/artifacts/seal-0.1.0.schema.json", "notes": "The mapped SEAL validates against the owned schema before it is returned." },
21
+ { "id": "owned-context", "kind": "jsonld-context", "uri": "urn:bsv:vsc:context:0.1.0", "version": "0.1.0", "digest": "3c74b79c50ebb151086c8bbe05222d0177a9d20c6f7b725b4e3a60645274cccc", "retrieval": "owned", "carried": "packages/vsc/artifacts/context-0.1.0.jsonld" }
22
+ ],
23
+ "inputs": [
24
+ { "id": "retained-event", "mediaType": "application/json", "format": "one event of a retained EPCISDocument or EPCISQueryDocument, with its pointer, source digest and pinned context digests" },
25
+ { "id": "mapping-options", "mediaType": "application/json", "format": "issuer DID, assertion method, actor role, jurisdiction, issuance time, credential status entry, custody chain and, for a TransformationEvent, the explicit action decision", "notes": "Every option is the signing issuer's own evidence, never read from the event." }
26
+ ],
27
+ "outputs": [
28
+ { "id": "mapping-report", "mediaType": "application/json", "format": "mapping outcome, missing inputs, unmapped semantics, preserved members and the unsigned SEAL when one exists" },
29
+ { "id": "unsigned-seal", "mediaType": "application/vc+ld+json", "format": "vsc-seal-json-v1 without proof, carrying the round-trip extension urn:bsv:vsc:vocab:epcis-roundtrip:0.1.0 and the source reference urn:bsv:dpp:epcis-source:1", "notes": "Issuance, status, authority, custody evaluation and anchoring are separate steps under the VSC profile and the registry contract." }
30
+ ],
31
+ "dependencies": [],
32
+ "limits": {
33
+ "maxProductIdentifiers": 256,
34
+ "extensionVocabularies": "urn:bsv:vsc:vocab:epcis-roundtrip:0.1.0, urn:bsv:dpp:epcis-source:1"
35
+ },
36
+ "mappingLimits": [
37
+ { "id": "multi-product-event", "outcome": "transformed", "reason": "Several product identifiers are carried in what.productIdentifiers, but linear custody continuity and subject scope are evaluated per identifier by the VSC profile; a multi-product event is not a custody step for any one product." },
38
+ { "id": "transformation-action-decision", "outcome": "transformed", "reason": "A TransformationEvent carries no action; the action in the SEAL is the caller's explicit decision, not a source fact. Without the decision the mapping is unsupported." },
39
+ { "id": "custody-state-unnamed", "outcome": "unsupported", "reason": "A disposition outside the VSC custody model (for example in_progress, sellable_accessible, damaged) has no custody state; the event stays evidence only." },
40
+ { "id": "maintenance-observation", "outcome": "unsupported", "reason": "An observation with no custody transition (an inspection, a repair, a sensor reading) is retained; the VSC profile's Q-state rules are not changed to admit it." },
41
+ { "id": "sensor-elements", "outcome": "transformed", "reason": "Sensor reports, their units and metadata are retained in the round-trip extension only; the event vector carries no measurement." },
42
+ { "id": "source-destination-parties", "outcome": "transformed", "reason": "Owning and possessing party lists are retained, never projected into who: the SEAL's actor is the signing issuer and a named party is not attributed with the event." },
43
+ { "id": "business-transactions", "outcome": "transformed", "reason": "Business transaction references are retained in the round-trip extension only." },
44
+ { "id": "quantities", "outcome": "transformed", "reason": "Quantity lists and their units are retained; the SEAL's single quantity is not populated from a list." },
45
+ { "id": "persistent-disposition", "outcome": "transformed", "reason": "Set and unset persistent dispositions are retained, not evaluated." },
46
+ { "id": "instance-lot-master-data", "outcome": "transformed", "reason": "ILMD is retained under its own keys without interpretation." },
47
+ { "id": "certification-info", "outcome": "transformed", "reason": "A certificationInfo reference is retained; it is not certification evidence until separately verified." },
48
+ { "id": "error-declaration", "outcome": "transformed", "reason": "An EPCIS error declaration is retained and reported; it is not a VSC correctionOf and grants no correction authority." },
49
+ { "id": "transformation-id", "outcome": "transformed", "reason": "The transformation identifier linking stages is retained in the extension; the VSC chain does not carry it." },
50
+ { "id": "event-level-context", "outcome": "transformed", "reason": "An event-level @context is retained; only the document-level pinned context enters the digest and the mapping." },
51
+ { "id": "extension-members", "outcome": "transformed", "reason": "Members outside the five event types' schema are retained verbatim under extension:<name> and never interpreted." },
52
+ { "id": "insufficient-event-vector", "outcome": "insufficient-data", "reason": "Missing eventTime, eventTimeZoneOffset, bizStep, disposition, recordTime (with no recordedAt) or product identifiers are never fabricated." }
53
+ ],
54
+ "unsupported": [
55
+ { "id": "automatic-issuance", "reason": "A mapping result is not a credential; issuing the SEAL is a separately authorised operation with its own issuer, status, authority and custody inputs." },
56
+ { "id": "native-token-operations", "reason": "No mapped event invokes Issue, Update, Transfer or Retire; shipping, receiving or owning-party fields never establish token authority or acceptance." },
57
+ { "id": "vsc-correction-from-error-declaration", "reason": "A VSC correction requires the existing issuer or delegation, chain and reason evidence; an EPCIS error declaration alone does not create one." },
58
+ { "id": "reporter-attribution", "reason": "A SEAL signed by this service attests to receipt and mapping of a report; it does not assert that the service performed the physical event and the source reporter is named only in the retained extension." }
59
+ ],
60
+ "sourceRefs": [
61
+ { "id": "epcis-2.0.1", "name": "GS1 EPCIS 2.0.1", "reference": "https://ref.gs1.org/standards/epcis/2.0.1/", "version": "2.0.1", "attribution": "GS1 AISBL", "use": "The event members mapped or retained." },
62
+ { "id": "vsc-core", "name": "VSC Core draft", "reference": "https://w3c-cg.github.io/vsc/specs/vsc-core.html", "version": "c279de3debcd6eab94a77034584d1750f5d65e6a", "attribution": "Verifiable Supply Chain Community Group", "use": "The SEAL and custody rules the mapped credential must satisfy." }
63
+ ]
64
+ }
@@ -0,0 +1,71 @@
1
+ {
2
+ "manifestVersion": "1",
3
+ "id": "gs1-digital-link",
4
+ "version": "1",
5
+ "profile": "gs1-digital-link@1",
6
+ "kind": "interoperability",
7
+ "role": "discovery",
8
+ "status": "proposed",
9
+ "title": "GS1 Digital Link discovery for primary key 01, with a hosted GS1-Conformant Resolver and a replaceable discovery client",
10
+ "description": "How a passport identified by a GS1 Digital Link URI is resolved to its passport and evidence services: the URI grammar for the GTIN and its three key qualifiers, decompression of the EPC binary form, resolution records with authorised links at each granularity, the linkset a GS1-Conformant Resolver 1.2.1 returns and the selection a discovery client makes over it. The profile claims the resolver standard's clauses for one supported primary key; it does not claim allocation authority for any GTIN, host any other primary key, or decode the general GS1 Digital Link compression. A link inherited from the model level is model information under a serialised request, never an item passport.",
11
+ "specification": "spec/gs1-discovery.md",
12
+ "standards": [
13
+ { "id": "gs1-uri-syntax", "name": "GS1 Digital Link: URI Syntax", "version": "1.7.0", "uri": "https://ref.gs1.org/standards/digital-link/uri-syntax/1.7.0/", "scope": "Primary key 01 with key qualifiers 22, 10 and 21 in that order, data attributes in the query string, percent-encoding, and the special compressed form." },
14
+ { "id": "gs1-resolver", "name": "GS1-Conformant Resolver", "version": "1.2.1", "uri": "https://ref.gs1.org/standards/resolver/1.2.1/", "scope": "Sections 2.2 to 2.14 and 3 for one supported primary key: decompression, validation and error differentiation, link attributes, the default link, the granular-identifier hierarchy of 2.5.9 and 2.5.10, redirection, requested link types, matching by media type, language and context, the linkset in application/linkset+json, query forwarding, trailing slashes, the GS1 vocabulary namespace and the resolver description file." },
15
+ { "id": "gs1-epc-binary-compression", "name": "GS1 Digital Link URI: Compression Technical Standard for EPC binary strings", "version": "1.0.0", "uri": "https://ref.gs1.org/standards/digital-link/compression/1.0.0/", "scope": "Sections 4.1 and 4.2: the eh (hexadecimal) and ex (URI-safe base 64) compression strings and their decoding to an uncompressed URI under the given stem." },
16
+ { "id": "gs1-tds", "name": "GS1 EPC Tag Data Standard", "version": "current at implementation", "uri": "https://ref.gs1.org/standards/tds/", "scope": "The SGTIN-96 and SGTIN-198 schemes: headers 30 and 36, the filter value, the seven-row partition table, the integer and seven-bit-character serials, and the pure-identity EPC URI." }
17
+ ],
18
+ "artefacts": [
19
+ { "id": "resolver-linkset-schema", "kind": "json-schema", "uri": "https://ref.gs1.org/standards/resolver/1.2.1/linkset-schema", "version": "1.2.1", "digest": "d2e23510f17558c29f9d1baf9e112a70df42efd6557a49dc9a317048973669f2", "byteLength": 4696, "retrieval": "pinned", "carried": "schemas/gs1/resolver-linkset-schema-1.2.1.json", "licence": "GS1 published standards artefact; see schemas/gs1/NOTICE.md", "notes": "Every linkset this profile produces validates against it. The schema admits a link relation key only as a lower-case token or an http(s) IRI of letters, digits, dots and slashes, which is why the owned evidence-package relation is spelled without a hyphen." },
20
+ { "id": "resolver-description-file-schema", "kind": "json-schema", "uri": "https://ref.gs1.org/standards/resolver/1.2.0/description-file-schema", "version": "1.2.0", "digest": "99d505c7aa2004cde3277651e8db0e019eab61d2746b2631ddab3fec8a13617e", "byteLength": 3593, "retrieval": "pinned", "carried": "schemas/gs1/resolver-description-file-schema-1.2.0.json", "licence": "GS1 published standards artefact; see schemas/gs1/NOTICE.md", "notes": "The resolver description file at /.well-known/gs1resolver validates against it; the 1.2.1 standard points at the 1.2.0 schema." },
21
+ { "id": "resolver-linkset-context", "kind": "jsonld-context", "uri": "https://ref.gs1.org/standards/resolver/1.2.1/linkset-context", "version": "1.2.1", "digest": "05792d010165fa6f28cc9cc3463cc1668f522ac75c26abe5b2877ec4a37b1312", "byteLength": 838, "retrieval": "pinned", "carried": "schemas/gs1/resolver-linkset-context-1.2.1.jsonld", "licence": "GS1 published standards artefact; see schemas/gs1/NOTICE.md", "notes": "Named in the Link header beside a JSON linkset and in the description file. It maps gs1: to http://gs1.org/voc/ while the resolver standard's text expands gs1: to https://ref.gs1.org/voc/; the reference code writes the latter and reads both." },
22
+ { "id": "gs1-uri-syntax-specification", "kind": "specification", "uri": "https://ref.gs1.org/standards/digital-link/uri-syntax/1.7.0/", "version": "1.7.0", "retrieval": "not-retrieved", "notes": "Read at implementation; the grammar implemented is stated in the specification document, and no conformance claim rests on a text that was not pinned." },
23
+ { "id": "gs1-resolver-specification", "kind": "specification", "uri": "https://ref.gs1.org/standards/resolver/1.2.1/", "version": "1.2.1", "retrieval": "not-retrieved", "notes": "Read at implementation as HTML; the clauses implemented are listed in the specification document." },
24
+ { "id": "gs1-epc-binary-compression-specification", "kind": "specification", "uri": "https://ref.gs1.org/standards/digital-link/compression/1.0.0/", "version": "1.0.0", "retrieval": "not-retrieved", "notes": "Read at implementation as PDF; its two worked examples are the independent decompression vectors." },
25
+ { "id": "gs1-application-identifiers", "kind": "vocabulary", "uri": "https://ref.gs1.org/ai/GS1_Application_Identifiers.jsonld", "version": "current at implementation", "retrieval": "not-retrieved", "notes": "The complete AI grammar. The reference code validates the AIs it states with certainty and carries any other data attribute unvalidated, so a new AI is never refused for being unknown." }
26
+ ],
27
+ "inputs": [
28
+ { "id": "uncompressed-uri", "mediaType": "text/uri-list", "format": "GS1 Digital Link URI, uncompressed, primary key 01", "notes": "Optional qualifiers 22, 10, 21 in that order; data attributes and linkType in the query; one trailing slash tolerated." },
29
+ { "id": "compressed-epc-uri", "mediaType": "text/uri-list", "format": "GS1 Digital Link URI, special compressed form carrying an EPC binary string (eh or ex)", "notes": "SGTIN-96 and SGTIN-198 only." },
30
+ { "id": "resolution-record", "mediaType": "application/json", "format": "ResolutionRecord", "notes": "A key, its qualifiers, an established passport binding where one exists, authorised links with disclosure and a configuration revision; validated at ingestion by resolutionRecordProblems." },
31
+ { "id": "linkset", "mediaType": "application/linkset+json", "format": "RFC 9264 linkset as the GS1 resolver schema shapes it", "notes": "What the discovery client reads from this or any other GS1-Conformant Resolver." }
32
+ ],
33
+ "outputs": [
34
+ { "id": "linkset", "mediaType": "application/linkset+json", "format": "RFC 9264 linkset, anchored at each matched record's uncompressed URI, validating against the pinned schema" },
35
+ { "id": "resolver-description", "mediaType": "application/json", "format": "GS1 resolver description file, validating against the pinned schema" },
36
+ { "id": "resolution-outcome", "mediaType": "application/json", "format": "redirect, multiple-choices, not-found, linkset or no-records, with every matched record's anchor and granularity" },
37
+ { "id": "selected-link", "mediaType": "application/json", "format": "The discovery client's selection: one link, its anchor and the anchor's scope, or ambiguous, or not-found with the relations available" }
38
+ ],
39
+ "dependencies": [],
40
+ "limits": {
41
+ "primaryKeys": "01",
42
+ "qualifierValueMaxLength": 20,
43
+ "epcSchemes": "sgtin-96, sgtin-198",
44
+ "trailingSlashesTolerated": 1,
45
+ "linkRelationKeyGrammar": "lower-case token or http(s) IRI of letters, digits, dots and slashes, per the pinned linkset schema"
46
+ },
47
+ "mappingLimits": [
48
+ { "id": "model-fact-under-item-request", "outcome": "transformed", "reason": "A link registered at the model or lot level answers a serialised request with its own anchor and granularity; it is broader information and is never returned as an item fact." },
49
+ { "id": "unknown-data-attribute", "outcome": "transformed", "reason": "A data attribute whose AI the reference code does not know is carried with validated false; its value is preserved, not interpreted." },
50
+ { "id": "key-equivalence-is-not-binding", "outcome": "insufficient-data", "reason": "Two URIs with one key tuple name one entity; binding a signed credential or passport to that entity needs the evidence the specification names, which a resolver record does not supply." }
51
+ ],
52
+ "unsupported": [
53
+ { "id": "other-primary-keys", "reason": "SSCC (00), GLN (414, 415, 417), GRAI (8003), GIAI (8004), ITIP (8006), GDTI (253), GCN (255), GINC (401), GSIN (402), CPID (8010), GMN (8013), GSRN (8017, 8018) are refused as unsupported primary keys; the description file declares 01 only." },
54
+ { "id": "third-party-serialised-extension", "reason": "AI 235 is a GTIN qualifier this profile does not host; it is refused by name rather than read as a serial." },
55
+ { "id": "general-digital-link-compression", "reason": "The general compression algorithm of GS1 Digital Link 1.1 is optional for a conformant resolver and is not decoded; only the EPC binary form (eh, ex) is." },
56
+ { "id": "other-epc-schemes", "reason": "EPC headers other than SGTIN-96 (30) and SGTIN-198 (36) are refused with the header named; SSCC, SGLN, GRAI, GIAI, GSRN, GDTI, CPI, SGCN, ITIP and GID are outside the declared scope." },
57
+ { "id": "allocation-authority", "reason": "A valid check digit, a decodable EPC, a matching DID or a URL under a host proves nothing about who GS1 allocated a number to; link administration needs scoped operator authority over the configured namespace." },
58
+ { "id": "target-url-templates", "reason": "Links are stored as complete target URLs; RFC 6570 templating of targets from the request is not implemented." },
59
+ { "id": "pattern-based-redirection", "reason": "Redirection of whole prefixes to another resolver (gs1:handledBy) is a deployment's configuration, not part of this profile's reference code." },
60
+ { "id": "context-value-lists", "reason": "The context keyword is matched against values a link declares; no external list of context values is fetched." },
61
+ { "id": "html-linkset-page", "reason": "The reference code produces the JSON linkset; a human-readable page for text/html requests is the hosting route's presentation, reusing the existing passport page." }
62
+ ],
63
+ "sourceRefs": [
64
+ { "id": "gs1-uri-syntax", "name": "GS1 Digital Link: URI Syntax 1.7.0", "reference": "https://ref.gs1.org/standards/digital-link/uri-syntax/1.7.0/", "version": "1.7.0", "attribution": "GS1 AISBL", "use": "The grammar of the request URI." },
65
+ { "id": "gs1-resolver", "name": "GS1-Conformant Resolver 1.2.1", "reference": "https://ref.gs1.org/standards/resolver/1.2.1/", "version": "1.2.1", "attribution": "GS1 AISBL", "use": "Resolver behaviour, linkset shape, description file." },
66
+ { "id": "gs1-epc-binary-compression", "name": "GS1 Digital Link URI: Compression Technical Standard for EPC binary strings 1.0.0", "reference": "https://ref.gs1.org/standards/digital-link/compression/1.0.0/", "version": "1.0.0", "attribution": "GS1 AISBL", "use": "Decompression of the eh and ex forms; its worked examples are the independent vectors." },
67
+ { "id": "gs1-tds", "name": "GS1 EPC Tag Data Standard", "reference": "https://ref.gs1.org/standards/tds/", "attribution": "GS1 AISBL", "use": "SGTIN-96 and SGTIN-198 decoding." },
68
+ { "id": "rfc-9264", "name": "Linkset: Media Types and a Link Relation Type for Link Sets", "reference": "https://www.rfc-editor.org/rfc/rfc9264", "attribution": "IETF", "use": "The linkset document." },
69
+ { "id": "rfc-8615", "name": "Well-Known Uniform Resource Identifiers", "reference": "https://www.rfc-editor.org/rfc/rfc8615", "attribution": "IETF", "use": "The /.well-known/gs1resolver location." }
70
+ ]
71
+ }
@@ -0,0 +1,54 @@
1
+ {
2
+ "manifestVersion": "1",
3
+ "id": "federated-operators",
4
+ "version": 1,
5
+ "profile": "federated-operators@1",
6
+ "kind": "operator",
7
+ "status": "proposed",
8
+ "title": "Independently administered operators serving the same evidence",
9
+ "description": "Two or more operators with separate administrations, credentials, databases and processes, synchronising both rails under one published admission policy. Two URLs over one database do not qualify, and two processes under one administration prove only the mechanism.",
10
+ "roles": ["overlay"],
11
+ "admission": {
12
+ "topics": ["tm_dpp", "tm_attestation"],
13
+ "nativeRules": "As single-operator@1; every operator enforces the same native rules and the shared, documented admission policy.",
14
+ "idempotent": true,
15
+ "ownerConsent": "deployment-choice"
16
+ },
17
+ "publisherPolicy": {
18
+ "separateFromOperatorIdentity": true,
19
+ "keySet": "A bounded set of authorised publisher keys with a policy version, activation and retirement times, shared by every operator and preserved as historical authorisation evidence.",
20
+ "historicalAuthorisation": "A state's publisher signature is checked against the key authorised at its time; a retired key still authenticates the states it signed while active.",
21
+ "handover": "A signed authorisation record under the selected governance and custody policy, with the old key's evidence preserved; the token spending key, if it must move, moves only through the authorised custody or transfer mechanism, never by editing an allowlist."
22
+ },
23
+ "discovery": { "mode": "ship-slap", "notes": "Or a declared static-peer profile when SHIP and SLAP are not used; either way discovery says where evidence may be found and never authorises a publisher or trusts a returned history." },
24
+ "synchronisation": {
25
+ "mode": "gasp",
26
+ "genesisFirst": true,
27
+ "deduplication": "By transaction and output identity for states, by outpoint and claim digest for anchors; replay creates no duplicate.",
28
+ "proofUpdates": "Proof updates are ingested and validated separately from replaying held outputs; a refuted proof returns to pending.",
29
+ "checkpoints": "Persist synchronisation checkpoints with the peer, source and accepted-chain context.",
30
+ "bounds": "Bound peers, requests and backfill work explicitly.",
31
+ "reorganisation": "An accepted-chain reorganisation evicts and recovers under the same exact evidence rules on every operator."
32
+ },
33
+ "retention": {
34
+ "spentStates": "Every operator retains spent passport states.",
35
+ "anchorLeaves": "Every operator retains independent anchor leaves.",
36
+ "bytes": "Every operator holds the bytes it admitted; stopping one leaves the others able to serve complete, verifiable retained evidence."
37
+ },
38
+ "capabilities": {
39
+ "document": "contracts/capabilities.schema.json",
40
+ "mustDeclare": ["roles", "topics", "services", "publisherPolicy with policyVersion", "synchronisation.profile federated-operators@1 with discovery, gasp and peers", "limits"]
41
+ },
42
+ "acceptance": [
43
+ { "id": "two-operators-sync", "exercise": "Operator A issues on both rails; operator B, with its own keys, database and process, synchronises both and serves byte-identical evidence.", "evidence": "proposed local exercise with two processes and two databases", "independence": "local" },
44
+ { "id": "partition-recovery", "exercise": "B recovers after a partition and converges without duplicates.", "evidence": "proposed local exercise", "independence": "local" },
45
+ { "id": "proof-repair", "exercise": "A refuted proof on one operator is repaired and converges on the other.", "evidence": "proposed local exercise", "independence": "local" },
46
+ { "id": "operator-loss", "exercise": "A stops; B serves complete retained evidence that a reader verifies from bytes and headers.", "evidence": "proposed local exercise", "independence": "local" },
47
+ { "id": "publisher-rotation", "exercise": "A publisher key is rotated and handed over under a signed authorisation; historical states still verify under the retired key; an unauthorised third publisher is refused.", "evidence": "proposed local exercise", "independence": "local" },
48
+ { "id": "malicious-peer", "exercise": "A stale or malicious peer's history is detected by local verification, not by counting peers.", "evidence": "proposed local exercise", "independence": "local" },
49
+ { "id": "independently-administered", "exercise": "Two organisations, separate credentials and databases, run the exercises above and observe the same results.", "evidence": "not yet run; a local federation is not this", "independence": "independently-administered" }
50
+ ],
51
+ "unsupported": [
52
+ { "id": "claim-before-observation", "reason": "This profile cannot be claimed by a deployment until the independently administered exercise has been observed." }
53
+ ]
54
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "manifestVersion": "1",
3
+ "id": "single-operator",
4
+ "version": 1,
5
+ "profile": "single-operator@1",
6
+ "kind": "operator",
7
+ "status": "current",
8
+ "title": "One operator, one index",
9
+ "description": "The reference node as deployed today: one administration, one database, discovery and peer synchronisation off, every native rule enforced. A basic deployment that says exactly what it is.",
10
+ "roles": ["overlay"],
11
+ "admission": {
12
+ "topics": ["tm_dpp", "tm_attestation", "tm_uora_dpp"],
13
+ "nativeRules": "tm_dpp admits a state on the record model's rules, the configured publisher key and the selected custody policy; tm_attestation admits an anchor on its exact script, framed signature and derived key, optionally restricted to named anchoring services; tm_uora_dpp serves the historical format only.",
14
+ "idempotent": true,
15
+ "ownerConsent": "deployment-choice"
16
+ },
17
+ "publisherPolicy": {
18
+ "separateFromOperatorIdentity": true,
19
+ "keySet": "Publisher identity keys are configured explicitly (SERVICE_IDENTITY_KEY, ANCHOR_SERVICE_KEYS), never derived from the operator's own key, and named in the capability document.",
20
+ "historicalAuthorisation": "A state's publisher signature is verified against a key that was authorised at the state's time; the current allowlist alone is not authority for a historical state.",
21
+ "handover": "A publisher handover is a signed authorisation record under the selected governance policy with the old key's evidence preserved; it never moves a token spending key, which only the custody mechanism can move."
22
+ },
23
+ "discovery": { "mode": "none", "notes": "No SHIP or SLAP advertisement; clients pin the host." },
24
+ "synchronisation": {
25
+ "mode": "none",
26
+ "genesisFirst": true,
27
+ "deduplication": "Admission of a held outpoint is a no-op; an anchor is deduplicated by outpoint and digest.",
28
+ "proofUpdates": "Proofs arrive through POST /arc-ingest, are validated against the header source before storage and never replay held outputs.",
29
+ "checkpoints": "Not applicable without peers.",
30
+ "bounds": "Request body 8 MiB, lookup 500 outputs, anchor page 100 default and 500 maximum.",
31
+ "reorganisation": "A proof the header source refutes returns the state to pending until repaired."
32
+ },
33
+ "retention": {
34
+ "spentStates": "Spent passport states are retained as history through coinsToRetain.",
35
+ "anchorLeaves": "Anchor outputs are retained and indexed; eviction follows the engine's rules.",
36
+ "bytes": "Every admitted transaction's BEEF is stored once per transaction."
37
+ },
38
+ "capabilities": {
39
+ "document": "contracts/capabilities.schema.json",
40
+ "mustDeclare": ["roles", "topics", "services", "publisherPolicy", "synchronisation.profile single-operator@1", "limits", "unsupported ship-slap-discovery and gasp-synchronisation"]
41
+ },
42
+ "acceptance": [
43
+ { "id": "single-admission", "exercise": "Admit the pinned chain and anchor fixtures over HTTP and serve them back byte-identical.", "evidence": "packages/overlay-topics/test/http.test.ts, attestationHttp.test.ts", "independence": "local" },
44
+ { "id": "single-replay", "exercise": "Re-announce every admitted output and observe no duplicate index entry.", "evidence": "packages/overlay-topics/test/engineStorage.test.ts", "independence": "local" },
45
+ { "id": "single-capabilities", "exercise": "Serve a capability document that validates against the schema and says discovery and synchronisation are off.", "evidence": "proposed: GET /capabilities on the reference node", "independence": "local" }
46
+ ],
47
+ "unsupported": [
48
+ { "id": "independent-replication", "reason": "One administration cannot claim independently replicated evidence." },
49
+ { "id": "ship-slap", "reason": "Advertising needs a funded wallet the reference node does not hold." },
50
+ { "id": "gasp", "reason": "Peer synchronisation is off." }
51
+ ]
52
+ }