You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
verify: strict-by-default (ADR-0023) enforced in Java but NOT in the TS/Python verify CLIs — port-dependent provenance verdict #96
ADR-0023 / CLAUDE.md advertise that the library "boots strict + seals the registry" (an undeclared own @-attr → ERR_UNKNOWN_ATTR). That holds for Java, but the shipped TypeScript and Pythonverify CLIs load lax by default, so an unregistered (or typo'd) attribute passes verify silently in TS/Python but is rejected in Java. The flagship provenance/drift gate gives a port-dependent answer on identical metadata.
cli.py:108_load_root → from_directory(dir) (no strict kwarg)
No
In Python, ERR_UNKNOWN_ATTR is raised only inside if strict: (validation_passes.py:339, comment: "In lax mode (the default) this is a no-op"). The "strict + sealed" guarantee is enforced only in the internal conformance harness (conformance_adapter.py passes strict=True) and the Java Maven goal — not the shipped TS/Python verify.
Why it matters
verify is sold as the provenance/drift gate. An adopter wiring meta verify / metaobjects verify into CI reasonably believes it enforces ADR-0023 — but on TS/Python it silently accepts made-up attributes a typo or a stale rename would introduce. (Observed in the wild: an adopter ships unregistered custom @attrs on template.prompt; their TS+Python CI is green, but Java's meta:verify would reject them.)
Proposed fix
Make verify strict-by-default consistently across ports (the verify command should opt into strict=true, matching Java), or add an explicit --strict/--lax flag with one documented default in all ports. Add a shared conformance fixture asserting verify rejects an unregistered own-attr identically in all five ports — today the verify-CLI strictness is ungated cross-port.
Note: ADR-0023 deliberately lets downstream apps loosen strict to carry unenforced attrs — that's fine. The gap is that the gate itself is inconsistent and silently lax in two of the three CLI ports.
Found via the metaobjects-audit skill against a real adopter.
Reopening: #101 completed the TS + Python verify CLIs (strict-by-default + --lax), but the consistency is not finished — C# dotnet meta verify is still lax and Java's Maven goal is force-strict with no --lax escape (an upgrade-blocker for adopters with unregistered attrs). Two follow-up PRs in progress complete the C# default + Java meta.lax param. Closing again when both land.
Done across all four CLI ports. Correction to the original premise: #108 discovered Java was not actually enforcing strict — the loader records ERR_UNKNOWN_ATTR (record-not-throw) but the Maven mojo never drained getErrors(), so it silently passed. So the real state was that all four ports were effectively lax. Now uniformly strict-by-default + an escape: TS+Python --lax (#101), C# --lax (#107), Java -Dmeta.lax with a real fail-on-recorded-error gate (#108). Migration: bump → run with the lax escape to inventory breakage → register providers / use attr.properties → drop the escape.
Activity
feat(verify)!: strict-by-default with --lax escape (ADR-0023 cross-po…
dmealing commentedon Jun 29, 2026
Reopening: #101 completed the TS + Python verify CLIs (strict-by-default +
--lax), but the consistency is not finished — C#dotnet meta verifyis still lax and Java's Maven goal is force-strict with no--laxescape (an upgrade-blocker for adopters with unregistered attrs). Two follow-up PRs in progress complete the C# default + Javameta.laxparam. Closing again when both land.feat(csharp)!: verify strict-by-default with --lax escape (complete #96…
feat(maven-plugin): add meta.lax strict opt-out to the metaobjects go…
dmealing commentedon Jun 29, 2026
Done across all four CLI ports. Correction to the original premise: #108 discovered Java was not actually enforcing strict — the loader records
ERR_UNKNOWN_ATTR(record-not-throw) but the Maven mojo never drainedgetErrors(), so it silently passed. So the real state was that all four ports were effectively lax. Now uniformly strict-by-default + an escape: TS+Python--lax(#101), C#--lax(#107), Java-Dmeta.laxwith a real fail-on-recorded-error gate (#108). Migration: bump → run with the lax escape to inventory breakage → register providers / use attr.properties → drop the escape.feat!: remove seven attributes codegen read that no provider registers