Crate boundaries: split AAS and the trust layer out of core - #74
Open
LKSNDRTMLKV wants to merge 37 commits into
Open
Crate boundaries: split AAS and the trust layer out of core#74LKSNDRTMLKV wants to merge 37 commits into
LKSNDRTMLKV wants to merge 37 commits into
Conversation
* docs: pin transfer-of-responsibility articles * fix: tier lintResult above the public view * chore: gate all features in test, lint and doc * refactor: share one canonical content hasher * docs: add product lineage design proposal * fix: protect lineage edges from field patches * docs: correct registry status and pin seal requirements * docs: remove stale unpublished-registry claims * docs: scope the public-tier invariant to content * docs: record open-issue fixes in the changelog
* docs: pin registry rules to the official journal text * chore(release): bump workspace to 0.10.0
24 commits of redundancy cleanup across every crate, plus the version bump (0.10.0 -> 0.11.0) and CHANGELOG entry the 5 breaking changes require. Full detail in CHANGELOG.md [0.11.0]. Codacy-reviewed: 2 genuine perf findings fixed, 1 pre-existing wasm32 validation-gap note reviewed and declined (documented, not a regression), 4 informational comments needed no action.
* fix(rules): cite Art. 8 and Art. 10(5) correctly * feat(rules): select Art. 8 phase by market date * feat(domain): add battery schema v2.1.0 * feat(plugins): derive Art. 8 phase by date * refactor(calc): select rulesets by law date * chore(build): run plugin tests in check gate
* refactor(domain): model access as an Art. 77(2) lattice * fix(domain): redact lintResult from the public view
* fix(rules): cite Art. 8 and Art. 10(5) correctly * feat(rules): select Art. 8 phase by market date * feat(domain): add battery schema v2.1.0 * feat(plugins): derive Art. 8 phase by date * refactor(calc): select rulesets by law date * chore(build): run plugin tests in check gate * fix(domain): preserve carbon class label verbatim
Seven files asserted an "EU Electronics DPP adopted 18 March 2026" that no instrument supports. Two of them — the electronics v1.0.0 and v1.1.0 schema descriptions, which ship to crates.io — extended it into a fabricated timeline naming AI servers, high-end PCBs and foldable phones with a 1 January 2027 second phase. Replaced with the real basis: Reg. (EU) 2023/1670 and 2023/1669, in force 2025-06-20, with dates left to the sector manifest rather than restated. cfb.rs described the battery carbon-footprint delegated act as adopted in March 2025. It has not been adopted; it was due February 2025 and has slipped. The module now says so and warns against mistaking (EU) 2025/606 (recycling efficiency) for it. smartphone.rs gains a precision note only: the 2023/1669 method is in Annex IV point 5 and the class boundaries in Annex II Table 4, and the enacted index runs 1,00-5,00 against this heuristic's 0-10. The existing Annex IV citations were correct and are unchanged. No behaviour change. Full gate green.
The embedded ECHA snapshot held 30 CAS numbers against an official list of 253 at the 2026-02-04 revision. Callers had no machine-readable way to know how partial it was, so a finding set produced from a 12 percent snapshot was indistinguishable from one produced against the full list. Adds ECHA_CANDIDATE_LIST_AS_OF, ECHA_CANDIDATE_LIST_OFFICIAL_COUNT and candidate_list_provenance(), so a caller can record what a passport was actually checked against rather than inferring completeness. Adds the two substances from the 2026-02-04 revision, n-Hexane and BPAF, whose SCIP notification deadline is 2026-08-04. The snapshot is now 32 of 253 — still partial, and a test asserts it reports itself so. Corrects the update cadence in the module docs: additions do not follow the stated June/December rhythm, the most recent being February 2026. Classification semantics are unchanged and were already correct — an absent CAS yields NotInEmbeddedList, meaning unknown to this snapshot, never cleared. A test now guards that against a well-meaning rename.
Adding a sector currently ships a silently degraded AAS mapping. The dispatch in aas::sectors ends in a deliberate catch-all that renders an unmodelled SectorData variant as a generic key-value submodel with no semantic IDs. The fallback is right for forward compatibility, but it means a missing builder produces no build error and no test failure — just lower-fidelity interop output on a surface the EN 1822x work depends on. Two tests close the gap without removing the fallback: every catalog sector must appear in the AAS case table, and no sector may resolve to the generic builder. The coverage test found battery absent from a table whose own docs claim it feeds every sector. Battery is exercised by battery_end_to_end.rs, so it is listed as covered elsewhere rather than duplicated here.
RegulatoryStatus conflated two independent questions: which legal instrument a sector derives from, and whether its obligations bind yet. Five of eleven sectors are not ESPR sectors — battery, toy, detergent, construction and electronics each derive from their own instrument — and the catalog had no way to say so. Adds Regime as a separate axis and a Watch status for sectors tracked with no DPP instrument at all. Watch is never determinable, inheriting the safe answer from the existing matches!(InForce) rather than a new branch. Tightens the InForce doc comment, which read "legally in force, or has a firm adopted applicability date". That trailing clause invited marking a sector in-force on the strength of a future date. InForce now means obligations are determinable now. Documents dppAppliesFrom as the passport-obligation date, explicitly not the determination gate. Gating determinations on it would suppress valid findings: battery's passport is required from 2027-02-18, but its Art. 9 mercury and cadmium prohibitions have applied since 2008 and are determinable today. A regression test guards this. Breaking: SectorDescriptor gains a required `regime` field.
dpp-calc shipped only a non-regulatory six-factor heuristic on a 0-10 scale, while the index actually displayed on the energy label for smartphones and slate tablets has applied since 2025-06-20. Adds it, extracted from the primary text: the Annex IV point 5 formula R = SDD*0,25 + SF*0,15 + ST*0,15 + SSP*0,15 + SSU*0,15 + SRI*0,15, all six parameters scored 1-5 across ten priority parts, both weight sets (rigid and foldable), and the Annex II Table 4 class boundaries. R runs 1,00-5,00. Shipped alongside the heuristic rather than replacing it. The receipt model identifies a ruleset by id and version, so changing the heuristic's semantics in place would invalidate every receipt already issued against it. The heuristic also covers product categories this regulation does not. The resolver is deliberately untouched: smartphone-tablet would now have two candidate rulesets active on the same date, and picking between them by row order is not a decision to make silently. Twelve tests, including both weight sets summing to 1, every class boundary driven through the calculator, and a guard that the two scales stay distinguishable.
Updates the requirements on [jsonschema](https://github.com/Stranger6667/jsonschema) to permit the latest version. - [Release notes](https://github.com/Stranger6667/jsonschema/releases) - [Changelog](https://github.com/Stranger6667/jsonschema/blob/master/CHANGELOG.md) - [Commits](Stranger6667/jsonschema@cli-v0.46.0...ruby-v0.48.1) --- updated-dependencies: - dependency-name: jsonschema dependency-version: 0.48.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [criterion](https://github.com/criterion-rs/criterion.rs) to permit the latest version. - [Release notes](https://github.com/criterion-rs/criterion.rs/releases) - [Changelog](https://github.com/criterion-rs/criterion.rs/blob/master/CHANGELOG.md) - [Commits](criterion-rs/criterion.rs@0.5.0...criterion-v0.8.2) --- updated-dependencies: - dependency-name: criterion dependency-version: 0.8.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* docs: refresh READMEs for the access lattice * chore(release): date 0.11.0 and log its changes * docs: correct ESPR citations against the OJ text * docs: retire access-tier vocabulary and refresh dpp-calc * docs: correct the CI coverage note on plugin tests
Updates the requirements on [base64](https://github.com/marshallpierce/rust-base64) to permit the latest version. - [Changelog](https://github.com/marshallpierce/rust-base64/blob/master/RELEASE-NOTES.md) - [Commits](marshallpierce/rust-base64@v0.22.0...v0.23.0) --- updated-dependencies: - dependency-name: base64 dependency-version: 0.23.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [jsonschema](https://github.com/Stranger6667/jsonschema) to permit the latest version. - [Release notes](https://github.com/Stranger6667/jsonschema/releases) - [Changelog](https://github.com/Stranger6667/jsonschema/blob/master/CHANGELOG.md) - [Commits](Stranger6667/jsonschema@ruby-v0.48.0...ruby-v0.49.1) --- updated-dependencies: - dependency-name: jsonschema dependency-version: 0.49.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
) ESPR Annex III specifies the DPP data elements including the product (b), operator (g)/(h) and facility (i) identifiers - three types, not four - while Art. 13 is the registry that stores them; ProductItemIdentifier is the product identifier at item granularity rather than a fourth Annex III class.
* ci: run sector plugin tests and build all ten in CI * ci: pin install-action to a commit SHA
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| Security | 9 high |
🟢 Metrics 640 complexity · -9 duplication
Metric Results Complexity 640 Duplication -9
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
LKSNDRTMLKV
force-pushed
the
refactor/crate-boundaries
branch
from
July 30, 2026 14:47
9309099 to
c795ae9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #73, whose branch is an ancestor of this one — the two semanticId commits are included here unchanged. Close #73 in favour of this.
Implements the 0.13.0 scope of
ADR-010(sealed). Every commit is a pure move or a pure fix; no behaviour changes.Crate layout after this
dpp-digital-linkkeeps its published name — what remains is exactly what the name says, so no crates.io name is abandoned and no shim is needed.dpp-aasanddpp-vcare new names, claimed permanently at publish.Commits
64b12f7urn:odal-node:*086921409c5b1edpp-aas(53 files, 25 renames)ecc6474dpp-vc(38 files, 17 renames)fa5f72c5377caecebc002dpp-domaina9e2a00ports/intodomain/9309099The semanticId fix
Six of seven third-party identifiers were wrong — the URI scheme, not the versions. IDTA's are name-based (
https://admin-shell.io/idta/nameplate/3/0/Nameplate); ours used a document-number form IDTA does not use. The ECLASS IRDI carried Code Space Identifier01(Classification Class) while serving as a Property semanticId, where02is the Property space. One,urn:idta:aas:submodel:digital-product-passport:1.0, was coined — IDTA's ishttps://admin-shell.io/idta/cds/dppMetadata/1.They are removed, not corrected: substituting one unverified identifier for another repeats the defect. An own-namespace identifier truthfully says a concept is ours; a wrong IRDI falsely says it is IDTA's, to a machine. Catena-X verified and kept.
Gate mutation-checked — reintroducing a bad identifier fails with the identifier, JSON path and sector named.
Why
dpp-cryptois now a leafaccess/was the only module indpp-cryptoreferencingdpp_domain. Moving it leaves the crate with zero workspace dependencies, which is what "primitives" should mean.LocalIdentityServicehad to move todpp-vcas well — it depends on bothjws/keystoreanddid_builder/passport_credential, so leaving it would have closed a dependency cycle.KeyStore::public_keyandPublicKeyInfowiden frompub(crate)topubso thedid:webbuilder can read public key material and revocation state. No private key material is reachable.The doctest harness found real defects
cargo nextestdoes not run doctests, so no README example in this workspace had ever been compiled. Adding aReadmeDoctestsitem per crate and atest-docrecipe tojust checksurfaced:dpp-domain:Passport::newdoes not exist; three wrong field namesdpp-registry:RegistryEnvelopeandRegistryStatusdo not exist;issuer_didis not a fielddpp-plugin-sdk: trait impl missing five required methods, comment naming the wrong onesdpp-calc: three examples with top-level?, one with no importsAll fixed; harness mutation-checked.
Blocking before publish
The Catena-X allowlist entry reads
verifiedBy: "assisted web verification, pending founder sign-off". It was checked against the Eclipse Tractus-X repository with the source recorded, but the allowlist is meant to record what a person read. Replace that field with a name before publishing.just checkgreen — fmt, clippy, workspace tests, doctests, all ten plugins, docs with-D warnings,cargo audit.Engine repin prepared in odal-node/dpp-engine#66 (blocked on this publishing).