Repository navigation
rc.5 cannot load a requirements ledger rc.3 accepted: @verifiedBy unregistered, and abandoned/superseded dropped from @status #337
Description
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
— "@verifiedByasked you to name a test, andverifychecked that the name …" - read by your own CLI:
@metaobjectsdev/cli/dist/src/commands/verify.js(andsrc/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
- Register
@verifiedByon the requirement provider, alongside whatever registration@trackedBy
/@disposition/@notesalready have. - Restore
abandonedandsupersededto the@statusenum — 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 on0.24.0-rc.3 - Adopter: TypeScript + Bun + Postgres,
meta migrate-owned schema, 75-node requirements ledger - Also blocks
meta gen, not justverify
Activity
fix(cli): a stale comment made a retired attribute look live to a grep (
feat(metadata): retired vocabulary explains itself instead of reading…
docs(llms): correct the retired requirement vocabulary (#343)
dmealing commentedon Aug 23, 2026
Status, so this issue is not read as untouched:
Both reported causes are addressed and shipped in
0.24.0. The retirements weredeliberate (FR-038), the loader now EXPLAINS them instead of reading as a broken install
(
retired-vocabulary.tscovers all seven), the CLI no longer consumes@verifiedBy, themigration guide is
docs/features/migrations/verified-by-retirement.md, andmeta upgraderewrites 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:
@verifiedByas live after retirement.metaobjects-authoringgave{"@fields": [...], "@expr": ...}as a workedexample, the exact spelling that release made a load error. Five byte-gated copies.
docs/llms/*taught@verifiedByand the pre-0.24.0@statusenum a fullrelease 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'sretirement 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.
feat(gates): shipped metadata examples must load under the strict reg…
dmealing commentedon Aug 23, 2026
The last open piece — the gate — landed on
mainin 1ebd82c, shipping in0.24.1. (Both reported causes shipped in0.24.0; this closes the durable fix your final paragraph asked for.)scripts/check-doc-examples.tsloads every fenced JSON example underdocs/and the agent-context skills against the strict registry, in thegateslane.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:
extendstarget defined in the next code block. That is fragment-ness.A fragment gets wrapped in a synthetic host, and the fields its
@fieldsnames 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, onERR_ENUM_INT_VALUE_MAP_ARRAY, which isn't in the main error ledger.docs/superpowers/anddocs/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: abandonednode data loss rather than a migration.scripts/test-doc-examples.tsreplays 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.fix(codegen-csharp,gates): an unconfigured FK is NoAction, not EF's c…
docs(release): refresh version references for 0.24.1
fix(scripts): the doc-example gate never counted what it couldn't parse
fix(metadata): the @emit* attributes were retired without ever being …
fix(scripts): the doc-example gate graded a build artifact, and passe…
docs: the API base URL moves to the provider, and a gate that keeps i…
fix(metadata): five retirements named a release that was never cut
fix(docs): the auto-loading codegen rule taught metadata that no long…