Skip to content

Registry rows that need a person give no reason and cannot be settled #485

Closed

Description

@LKSNDRTMLKV

What is missing

#484 (draft, needs odal-node/dpp-core#486) makes the registry drain recover a submission whose correlation identifier was lost, by the unique product identifier the passport was submitted under. It settles the common case on its own. Three cases it deliberately does not settle still need a person:

  • Ambiguous: more than one registry submission reports the passport's identifier (a successor can be submitted under its predecessor's), so the lookup refuses to choose. Choosing would give a passport another passport's registration.
  • Never found: the identifier is not among the tasks read, or a task that might be the one is still being checked, so absence proves nothing. The row is retried and counted as an attempt until it stalls.
  • Unsupported or unreadable: an adapter that cannot look a submission up, or a row whose frozen payload cannot say what was submitted.

For those, two things are missing, and #484's runbook text says so plainly.

1. The row does not say why it is waiting

mark_submitted clears the row's message on every pass. The candidate correlation identifiers of an Ambiguous lookup, and the reason a lookup found nothing, are only written to the log. GET /vault/api/v1/dpp/{dppId}/registry therefore shows a submitted row with no handle and no explanation, and an operator has to go to the logs of the node to learn that it needs a person and what the candidates are.

2. There is no way to settle it

No route or command records a correlation identifier for a row. An operator who has worked out which candidate is the passport's can do nothing with the answer. The row stays where it is and loses nothing, but it never registers.

Proposed shape

This is a design of its own, because it puts a write on a registry row behind the HTTP surface.

  • A route, for example POST /vault/api/v1/dpp/{dppId}/registry/handle with { "correlationId": "…" }, behind the admin scope, for a row that is submitted and has no handle, and for nothing else.
  • It does not trust the operator's say-so. It reads the submission by that identifier (check_submission) and refuses unless the registry reports this passport's unique product identifier under it: the check that stops a typo from giving a passport another passport's registration. A found submission then takes its ruling in the same step, as a recovered one does.
  • An entry in the passport's audit trail recording who recorded which identifier.
  • The reason is kept on the row so GET …/registry shows it, which needs a way to write a message without counting an attempt or clearing it.
  • odal gets the matching command, and the OpenAPI description, the contract fixtures and the documented_error_codes_are_the_ones_handlers_return gate follow the route.

Open questions

  • Is admin the right scope, or does recording a handle deserve a narrower one?
  • Should the route also accept "this passport is not registered, give it up", for a row whose submission was never accepted? That is a different and more dangerous write.
  • Does the idempotency policy table (KEYED) need an entry?

Done when

A stalled submitted row says why on the per-passport registry route, and an operator can settle one that needs a person, with the registry confirming the identifier belongs to the passport, in one call and with an audit entry.

Activity

  1. added
    enhancementNew feature or request
    type/defectSomething published or encoded here is wrong or unbackable now
    surface/registryMoves EU registry enrolment or the unique product identifier
    on Oct 20, 2026
  2. added this to the v0.16.0 milestone on Oct 30, 2026
  3. added
    epic/registryEU registry loop: registration, transfers, handles, the local stand-in
    on Oct 30, 2026
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

    enhancementNew feature or requestepic/registryEU registry loop: registration, transfers, handles, the local stand-insurface/registryMoves EU registry enrolment or the unique product identifiertype/defectSomething published or encoded here is wrong or unbackable nowurgency/backlogOwed, unscheduled

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions