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 }}
[P0] build-time vs runtime validation parity: objectstack build accepts metadata the runtime rejects #1876
objectstack build accepts metadata that the runtime then rejects, so "CI green" does not guarantee "boots".
Repro (observed on 9.5.1)
Dashboard widgets in the legacy object/aggregate shape pass objectstack build but the runtime com.objectstack.metadata plugin rejects them (requires dataset/values), so the app fails to start.
A hook handler referencing a module-scope helper passes build, then throws ReferenceError at runtime (handler ships body-only).
Expected
Build validates against the same schema/rules the runtime enforces. "build clean" ⇒ "boot clean".
Found while runtime-testing objectstack-ai/templates (all 9 templates via objectstack dev all) on @objectstack 9.5.1. Build + typecheck pass; these only surface at runtime.
Resolved — closing. Both repros in this issue are addressed, and a parity sweep confirmed no remaining schema-level divergence:
Repro Add metamodel interfaces for ObjectQL/ObjectUI contract #1 (legacy object/aggregate dashboard widgets pass build, runtime rejects) — already closed by the ADR-0021 single-form cutover. DashboardWidgetSchema requires dataset/values, and objectstack build (ObjectStackDefinitionSchema.safeParse) + the runtime metadata plugin (ObjectStackDefinitionSchema.parse) validate with the same schema. Verified empirically that a legacy widget is rejected at build; there's an existing regression test.
Parity sweep: build and runtime both validate the artifact via ObjectStackDefinitionSchema, and the runtime per-item validate() adds no stricter check — so schema-level "build accepts what runtime rejects" no longer occurs. The remaining divergences are semantic/callable-level, and those instances (#1877 conditions, #1870 callables, #1876 repro #2 hook bodies) are now fixed.
If a new build↔runtime divergence surfaces, please file it as a fresh focused issue rather than reopening this umbrella.
Activity
fix(cli): keep non-self-contained hook handlers out of body-only lowe…
os-zhuang commentedon Jun 15, 2026
Resolved — closing. Both repros in this issue are addressed, and a parity sweep confirmed no remaining schema-level divergence:
object/aggregatedashboard widgets pass build, runtime rejects) — already closed by the ADR-0021 single-form cutover.DashboardWidgetSchemarequiresdataset/values, andobjectstack build(ObjectStackDefinitionSchema.safeParse) + the runtime metadata plugin (ObjectStackDefinitionSchema.parse) validate with the same schema. Verified empirically that a legacy widget is rejected at build; there's an existing regression test.ReferenceError) — fixed in fix(cli): keep non-self-contained hook handlers out of body-only lowering (#1876) #1907 (PR):detectFreeIdentifiersrefuses body-only lowering for handlers referencing module-scope identifiers, falling back to bundling the real closure.Parity sweep: build and runtime both validate the artifact via
ObjectStackDefinitionSchema, and the runtime per-itemvalidate()adds no stricter check — so schema-level "build accepts what runtime rejects" no longer occurs. The remaining divergences are semantic/callable-level, and those instances (#1877 conditions, #1870 callables, #1876 repro #2 hook bodies) are now fixed.If a new build↔runtime divergence surfaces, please file it as a fresh focused issue rather than reopening this umbrella.