Skip to content

SysMetadataRepository — the implementation backing every production metadata write — is not run through the shared runRepositoryContractTests suite #10420

Description

@os-elon

Found incidentally while running the runtime put() caller census for #8006 (measurement only; no accept set was touched).

The observation

packages/metadata-core/src/contract-suite.ts exists so that one table of invariants holds for everyMetadataRepository implementation. Its own header says so, and the #7856/#7992 serialized-form pins were deliberately placed there rather than beside either bug for that reason.

Every call site of the suite, repo-wide:

packages/metadata-core/test/in-memory-repository.test.ts:8 runRepositoryContractTests('InMemoryRepository', …)
packages/metadata-fs/test/contract.test.ts:23 runRepositoryContractTests('FileSystemRepository', …)

Two implementations. SysMetadataRepository (packages/metadata-protocol/src/sys-metadata-repository.ts) is a third — it implements the same interface (put/get/getByHash/delete/history/watch), it calls hashSpec(body) itself at put(), and it is the implementation that backs the live runtime path. It is never handed to the suite.

Why this is worth a card rather than a shrug

Measured during the #8006 census, with put() instrumented across nine packages: of 1,729 runtime put() invocations observed, 561 went through SysMetadataRepository — including all four production put() call sites in the repo. The two implementations that are contract-tested carry the test traffic; the one that carries the production traffic is not held to the contract.

Concretely, the invariants that go unexercised for it include the ones #7992 added — put().version === get().hash and get().hash === hashSpec(get().body) — plus the older ConflictError / monotonic-seq / tombstone clauses. Note that #7992 fixed exactly this class of divergence in two implementations and found each had broken a different face of it, which is the argument that a third unexercised implementation is not safe by inspection.

⚠️Not a claim that it is broken. Nothing observed in the census suggests a defect; 561 invocations ran clean. This is an unexercised-surface finding, not a bug report.

Not necessarily a plain "add it to the suite"

SysMetadataRepository is engine-backed (it needs a sys_metadata table and an engine double), and it carries dimensions the suite's factory() shape does not model — state: 'draft' | 'active', packageId, org scoping. Whether it should be adapted into the existing suite, or whether the suite needs a narrower "serialized-form identity" slice that an engine-backed repository can be held to, is a design question and deliberately not decided here.

Provenance

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions