Skip to content

feat(registry): implement stable identifier registry - #509

Closed
jdacoello wants to merge 1 commit into
COVESA:masterfrom
jdacoello:feat/spec-registry
Closed

feat(registry): implement stable identifier registry#509
jdacoello wants to merge 1 commit into
COVESA:masterfrom
jdacoello:feat/spec-registry

Conversation

@jdacoello

Copy link
Copy Markdown
Contributor

Context

This PR addresses the issue #508 .

It introduces a new vspec registry command group that assigns stable, persistent, namespace-scoped identifiers to VSS nodes.

What this adds

New top-level command group: vspec registry. It is not meant to be an exporter, but a governance tool.

Two subcommands:

  • vspec registry sync — reads the current vspec, mints IDs for any FQNs not yet in the registry, writes the updated CSV. Safe to run repeatedly; existing rows are never modified or deleted.
  • vspec registry validate — checks schema and row-level hash integrity without writing anything. Designed for pre-commit hooks and CI gates.

Working file format (two files):

  • namespaces.yaml — declares the one namespace this project owns (prefix + URI) and any external namespaces it imports. Human-maintained, rarely changes.
  • registry.csv — append-only ledger of composed_id → fqn mappings. Tool-managed, committed to version control. Each row carries a SHA-256 hash of its immutable fields to detect manual edits.

Optional JSON-LD sidecar with flag --export-jsonld:

A derived artifact regenerated on every sync. Provides a @context + @graph representation consumable by any linked data toolchain without changing the working format.

Key design decisions

  • One owned namespace per project — enforced at load time. A project cannot accidentally mint into an imported namespace.
  • IDs are sequential per prefix, starting from 0 — simple, human-readable, independent per namespace.
  • IDs are never deleted — when a node disappears from the vspec, its row remains and its status transitions to deprecated. Downstream consumers are never left with a broken reference.
  • Hash-based tamper detection — verifies every row's hash on read. Any manual edit is caught before the tool proceeds.
  • Prefix in namespaces.yaml, not a CLI flag — cannot be overridden by accident in a script.

…lidate commands

Signed-off-by: JD Alvarez <8550265+jdacoello@users.noreply.github.com>
Comment thread docs/registry.md
- `fqn` — the fully qualified node name at the time the ID was minted
- `int_id` — the numeric part of `composed_id`, per-prefix counter
- `status` — `active` or `deprecated`. If a concept is not present in a future release of the model, then it is because it was deleted from the model. However, the id is persisted forever in the registry.
- `row_hash` — SHA-256 of `"{composed_id}|{fqn}"`, used to detect tampering

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the benefit of having a row sha. What does it protect against? Someone modifying the row by accident? But since it's commited you would see that anyway?

If we go for sha, I would probably vote for a hash chain to also fix the ordering and not allow inserting something. Meaning the sha is the sha of the row before + hashing the current row

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the observation. I later realized that using sha here is of little value because I actually want to remove the dependency of fqn. So, hashing the fqn contradicts that. The initial idea of hashing was to be able to detect changes easily. But, now I am re working this idea and new commits will refactor it.

Comment thread docs/registry.md
uri: "https://www.example.org/myModel#"
description: "Private VSS extension"

imports:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we maybe also just add more then one namespaces.yaml and therefore we don't need imports?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of that separation is that the tool creates ids under the provided namespace only. Otherwise, the function that creates the identity would always need to receive the namesake as parameter. The declaration of imports serve as a validation of the registry. Such that only declared namespaces are in use.

@erikbosch

Copy link
Copy Markdown
Collaborator

Is the intention to store the registry (for VSS) in the vss repo? If so we need to come up with a working model. I assume, as long as we just work on master, that generating a new csv file as part of release preparations would be easy. One could theoretically do it also for every merge to master, but that is possibly not needed and it is also so that we sometimes on master may roll back or fix unreleased changes.

@jdacoello

Copy link
Copy Markdown
Contributor Author

Is the intention to store the registry (for VSS) in the vss repo? If so we need to come up with a working model. I assume, as long as we just work on master, that generating a new csv file as part of release preparations would be easy. One could theoretically do it also for every merge to master, but that is possibly not needed and it is also so that we sometimes on master may roll back or fix unreleased changes.

The intention is to release the registry as one more artifact in every release. So, it becomes an immutable reference of identity for the concepts. We can create the registry on demand and also uploaded it to previous releases (at least from V5 on). For sub sequent use, the previous released registry can be used as an input for the update.

@jdacoello

jdacoello commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

Update:

I am elaborating this idea of the registry further. This is the plan:

  • Implement a snapshot exporter that composes all the modular vspec files and creates a unique stand alone sorted vspec. --> Useful to identify differences between releases
  • Implement a diff function/command that compares two stand-alone vspec files and reports the differences with a pre defined structure. --> Useful to assign the proper semantic version tag
  • Split the registry idea into two:
    • concepts_registry --> To persist the future-proof identity of the concepts and their meaning
    • variants_registry --> To persist the realization of the concepts with specific metadata

@erikbosch

Copy link
Copy Markdown
Collaborator

MoM:

  • Daniel working on it

@erikbosch

Copy link
Copy Markdown
Collaborator

MoM:

  • D: Will need to manage registry as stand-alone packages
  • D: Working on it
  • D: Will take 10 minutes of the call when PR is ready

@jdacoello

Copy link
Copy Markdown
Contributor Author

The registry has been decomposed into smaller parts:

  • compose and diff commands --> vss-tools Feat/diff #521
  • Spec registry tables manipulation will be implemented outside vss-tools and then imported as dependency (work in progress)

Thus, this PR is closed since the initial solution was too simple for the things we want to achieve with the identity management.

@jdacoello jdacoello closed this May 13, 2026
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.

3 participants