Skip to content

feat(vault): retire sector, record instruments - #187

Open
LKSNDRTMLKV wants to merge 5 commits into
mainfrom
feat/product-group-engine
Open

feat(vault): retire sector, record instruments#187
LKSNDRTMLKV wants to merge 5 commits into
mainfrom
feat/product-group-engine

Conversation

@LKSNDRTMLKV

Copy link
Copy Markdown
Member

Follows the core library: sector is retired for product group, the passport records the acts it was issued under, and the determination gate stops enforcing obligations that do not exist.

⚠️ CI cannot pass on this PR yet

This builds against unreleased core changes. The local-core override is git-ignored, so CI resolves the published crates and will fail. It is green locally against the sibling checkout — 864 tests, full gate.

Releasing core is the gate, and that is a separate decision. Opened now for review, not to merge.

The substantive change

The determination gate asked "is this product group in force?" — which answers yes both for an act that imposes no passport at all (ESPR Arts. 24–25) and for one whose information duty is discharged through EPREL (Art. 9(4)(b)). So the engine enforced passport obligations that do not exist.

It now requires an in-force act that also requires a passport, in all three places that gate: the plugin host, the vault publish path, and the node's compliance-trust tier.

Database

Migration 0032 renames passport.sector to passport.product_group, renames its index, and drops and rebuilds the identity index — that one indexes an expression over the document, and the JSON key inside it changed too, so a rename would have left it matching a key no passport emits.

Added as a new migration rather than edited into 0004/0019: sqlx::migrate! checksums every file, so editing an applied one stops a node that already ran it from booting. No data moves — the column's values are catalog keys like battery, which did not change.

⚠️ The frozen-document guard is now vacuous

Every fixture under crates/dpp-dal/tests/fixtures/passport_docs predates the wire rename and is listed in UNREADABLE_FIXTURES. productGroup is required, so a document of the old shape is refused loudly rather than read with the field silently missing.

That is the mechanism the test itself sanctions for an accepted, permanent break — and it is defensible only because no such document exists in any deployment, which is the condition the guard states. The consequence is that it passes because every failure is documented, not because the read path works, and the file says so at the top. Re-seeding it needs a document captured from a real create, not hand-authored.

API

PassportResponse is now this service's own type rather than the core aggregate serialised straight out of the handler. The two shapes are identical today and a test proves it byte for byte — on a minimal passport as well as a populated one, because skip_serializing_if differences are invisible when every field is set. What changed is that they are now allowed to differ, and the OpenAPI contract gate checks the spec against this type instead of a library's internal struct.

A second test checks it against PASSPORT_WIRE_KEYS, so a field added to core is either served or listed as deliberately withheld — otherwise a mirror would trade one silent drift for a quieter one.

The create request is one type

dpp_types::CreatePassportRequest — the vault deserialises it, the bulk importer serialises it. They were separate structs in separate crates coupled by a comment reading "Shape must match …", and the copy had drifted four fields short. One of them was placedOnMarketDate: the regulated event that fixes which law governs a product, and the moment its applicable-instrument set is frozen. The same product imported rather than posted got a passport that could not say what it was issued under, and nothing failed.

Merging the types made the compiler demand a decision on the rest. commodityCode is now importable and validated at import, so the error names the offending row — the vault rejects a bad code too, but cannot say which line of a thousand-row sheet carried it. parentPassportRef and componentRefs stay absent, now explicitly and with a test: each carries a URI and a hash of the referenced passport's public signature, and an invented hash produces a link that fails verification.

@codacy-production

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 1 medium

Alerts:
⚠ 1 issue (≤ 0 issues of at least minor severity)

Results:
1 new issue

Category Results
Compatibility 1 medium

View in Codacy

🟢 Metrics 236 complexity · 38 duplication

Metric Results
Complexity 236
Duplication 38

View in Codacy

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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant