Skip to content

rc.5 cannot load a requirements ledger rc.3 accepted: @verifiedBy unregistered, and abandoned/superseded dropped from @status #337

Description

@dmealing

Summary

0.24.0-rc.5 cannot load a requirements ledger that 0.24.0-rc.3 loaded without complaint. Both
meta verify and meta gen fail at metadata load, so the RC is a hard block for this adopter — not
a warning, not a gate failure, a refusal to read the model.

Two independent root causes, both in the requirement metamodel, both cases where the shipped
documentation still describes what the loader now rejects. Happy to split into two issues if you'd
rather track them separately.

1. @verifiedBy is rejected as undeclared, but it is your attribute

meta: failed to load metadata: Unknown attribute '@verifiedBy' on requirement.architectural
'auditRowNamesItsTrigger' — not declared by any registered provider for requirement.architectural
meta: meta verify is strict (ADR-0023): every authored @attr must be declared.

@verifiedBy is not something this project invented. In the rc.5 tarball itself:

  • documented in @metaobjectsdev/sdk/agent-context/skills/metaobjects-verify/references/requirements.md
    — "@verifiedBy asked you to name a test, and verify checked that the name …"
  • read by your own CLI: @metaobjectsdev/cli/dist/src/commands/verify.js (and src/commands/verify.ts)

So strict-attr enforcement landed without registering an attribute that the tool documents and its
own verify command consumes. Any ledger that followed the documentation now fails to load.

Used 12 times in this project's ledger.

2. @status: abandoned and superseded are no longer allowed values

With --lax (which gets past #1) the load fails differently:

meta: failed to load metadata: requirement.functional 'recallMeasurement' attribute '@status'
has value 'abandoned' which is not one of the allowed values: planned, live, partial

abandoned and superseded are gone from the enum. But your shipped docs in the same tarball still
reference both (abandoned` and `superseded`, abandoned`/`superseded), and rc.3 counted
them without issue — its own summary line read:

requirements: 75 entries (52 functional, 23 architectural) — 14 planned, 56 live, 2 partial, 3 abandoned

This one has a semantic cost beyond the load error. abandoned records that a requirement was
retired on purpose. The alternative — deleting the node — destroys exactly the history the status
exists to preserve, so "just remove them" is not a migration, it is data loss. This project has three,
each with a recorded reason.

Reproduction

Any project with a requirements ledger using @verifiedBy or @status: abandoned:

$ bunx meta verify --db <url>      # exit 1, fails at load (cause 1)
$ bunx meta verify --lax --db <url> # exit 1, fails at load (cause 2)
$ bun run gen                       # exit 2, same load failure

Same project on rc.3: meta verify exit 0, meta gen clean, 877 tests green.

Suggested fix

  1. Register @verifiedBy on the requirement provider, alongside whatever registration @trackedBy
    / @disposition / @notes already have.
  2. Restore abandoned and superseded to the @status enum — or, if their removal is deliberate,
    say so in the CHANGELOG with a migration path that preserves the retirement record, and update
    the agent-context docs that still name them.

Worth noting the class: both are cases where ADR-0023's strictness outran the metamodel's own
registrations and its documentation. A conformance check that every attr and enum value appearing in
the shipped docs and fixtures actually loads under strict mode would catch this family.

Environment

  • Broken on 0.24.0-rc.5; clean on 0.24.0-rc.3
  • Adopter: TypeScript + Bun + Postgres, meta migrate-owned schema, 75-node requirements ledger
  • Also blocks meta gen, not just verify

Activity

  1. dmealing commented on Aug 23, 2026

    @dmealing
    MemberAuthor

    Status, so this issue is not read as untouched:

    Both reported causes are addressed and shipped in 0.24.0. The retirements were
    deliberate (FR-038), the loader now EXPLAINS them instead of reading as a broken install
    (retired-vocabulary.ts covers all seven), the CLI no longer consumes @verifiedBy, the
    migration guide is docs/features/migrations/verified-by-retirement.md, and meta upgrade
    rewrites the mechanical part — including YAML estates as of 0.24.1 (#339).

    Staying open for the last paragraph, which is the durable fix and has now fired three
    times:

    A conformance check that every attr and enum value appearing in the shipped docs and
    fixtures actually loads under strict mode would catch this family.

    1. rc.5 cannot load a requirements ledger rc.3 accepted: @verifiedBy unregistered, and abandoned/superseded dropped from @status #337 — agent-context docs described @verifiedBy as live after retirement.
    2. index @expr is unreachable: @fields is required on both index.lookup and identity.secondary, and @fields+@expr silently drops the fields #342 — metaobjects-authoring gave {"@fields": [...], "@expr": ...} as a worked
      example, the exact spelling that release made a load error. Five byte-gated copies.
    3. docs/llms: the AI-facing index still teaches @verifiedBy and the pre-0.24.0 @status enum, both of which now fail the loader #343 — docs/llms/* taught @verifiedBy and the pre-0.24.0 @status enum a full
      release after retirement.

    Each was found by an adopter or a review, never by a gate, and each was fixed by hand in a
    different file — which is why the family recurs rather than converging. meta upgrade's
    retirement map already exists and is the natural source of truth for "what must no longer
    appear in an example".

    The hard part is not extraction but classification: many doc blocks are deliberately
    partial fragments, and some are intentional counter-examples showing what fails. Those need
    a convention before the gate can tell a real drift from an illustration.

  2. dmealing commented on Aug 23, 2026

    @dmealing
    MemberAuthor

    The last open piece — the gate — landed on main in 1ebd82c, shipping in 0.24.1. (Both reported causes shipped in 0.24.0; this closes the durable fix your final paragraph asked for.)

    scripts/check-doc-examples.ts loads every fenced JSON example under docs/ and the agent-context skills against the strict registry, in the gates lane.

    The hard part was the classification, as noted above — and the resolution is that no marker convention was needed for the ordinary case. The rule is the kind of error:

    • fail on errors about vocabulary the block uses — an attribute that no longer exists, a value outside its enum, an illegal combination. Wrong at any size.
    • allow errors about what it omits or references — an elided required attribute, an extends target defined in the next code block. That is fragment-ness.

    A fragment gets wrapped in a synthetic host, and the fields its @fields names are synthesised alongside it, so the scaffolding can't manufacture a finding the document never made. An error code in neither list stops the gate as unclassified rather than defaulting — one default widens the blind spot silently, the other floods hundreds of fragments. That fired on its first run, on ERR_ENUM_INT_VALUE_MAP_ARRAY, which isn't in the main error ledger.

    docs/superpowers/ and docs/features/migrations/ are deliberately out of scope: they are records, not instructions, and a migration guide's purpose is to show the retired spelling next to its replacement. Editing one to satisfy a gate would falsify it — the same argument that makes deleting an @status: abandoned node data loss rather than a migration.

    scripts/test-doc-examples.ts replays all three incidents (#337, #342, #343) and asserts the gate rejects each, plus that a partial fragment, an unresolved reference and a plain config block stay quiet — a gate that flags illustrations gets switched off, and then catches nothing.

  3. added 5 commits that reference this issue on Sep 1, 2026
    4ebf611
    7e83020
    d571cb5
    e848ebf
    9d47323
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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions