fix(spec): reject unknown top-level keys on ObjectSchema.create() (#1535)#1540
Merged
Conversation
) Object-level `workflows: [...]` (and any unknown ObjectSchema key) was silently stripped at build by Zod's default `.strip()`, with no error, no warning, and a green `tsc` — the metadata-shape analogue of ADR-0032's "no silent failure". Declarative on-update automation authors believed they shipped vanished from every built artifact. `ObjectSchema.create()` now rejects unknown top-level keys with a precise, fixable error: it names the offending key(s), suggests the intended key on a likely typo (`validation` -> `validations`), and for known-confusable keys like `workflows` points authors at the supported mechanism (a lifecycle hook or a top-level `record_change` flow). The factory signature also constrains excess keys to `never`, catching the mistake at `tsc` time too. The non-strict `ObjectSchema.parse()` load path is unchanged. Also fixes two platform objects (sys_secret, sys_setting_audit) that carried silently-stripped `views`/`scope`/`defaultViewName` keys — their intended list views are migrated to the supported `listViews` field (`type:'list'` -> `'grid'`) so they now render. Repairs the objectstack-data skill's CRM blueprint row that taught the non-existent `workflows[]` shape. https://claude.ai/code/session_01KHJTd48x76KVcAK1e494wr
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…1535) The new strict ObjectSchema.create() correctly surfaced a latent #1535 instance: todo_task carried an object-level `workflows: [...]` block that Zod stripped at build, so it never ran. Its intent is already realized through the supported mechanisms — `task.hook.ts` (lifecycle hook), `task.handlers.ts` (completion stamping), and `flows/task.flow.ts` (record_change + schedule flows). Removed the dead block (and the now-unused `cel` import) and documented where the automation actually lives. https://claude.ai/code/session_01KHJTd48x76KVcAK1e494wr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1535.
Problem
ObjectSchemaBaseis a plainz.object({...})(Zod default.strip()), andObjectSchema.create()parses through it. So any unknown top-level key — object-levelworkflows: [...], or a typo'dvalidation/indexs— was silently discarded: no error, no warning, and a greentsc. Declarative on-update automation authors believed they shipped vanished from every built artifact (15 object-level workflows acrossobjectstack-ai/templates, dead from day one). This is the metadata-shape analogue of ADR-0032's "no silent failure".Fix
1. Reject unknown keys, loudly and fixably (ask #1)
ObjectSchema.create()now detects unknown top-level keys before parsing and throws a located, fixable error that:validation→validations, via edit distance),workflows,hooks,triggers) points at the supported mechanism.The factory signature also constrains excess keys to
never(NoExcessObjectKeys<T>), so the mistake surfaces attsctime as well as at build. The non-strictObjectSchema.parse()load path (registry/artifact validation) is unchanged.2. Object-workflow story (ask #2)
Decided (b): lifecycle hooks and top-level
record_changeflows are the supported paths; there is no object-levelworkflows[]field. The build now flagsworkflowsexplicitly and routes authors there.3. Docs/skill (ask #3)
The
objectstack-dataCRM-blueprint row that taught the non-existentworkflows[]shape is repaired to point at hooks /record_change.Bonus: two latent #1535 instances in the framework's own objects
Enabling the strict check surfaced real dead config in
sys_secretandsys_setting_audit— both carried silently-strippedviews/scope/defaultViewNamekeys (viewsshould belistViews, andtype: 'list'isn't a validListViewSchematype — it's'grid'). Migrated to the supportedlistViewsfield so the intended list views now actually render. A repo-wide scan confirmed no otherObjectSchema.create()call carries stray top-level keys.Verification
packages/spectest suite: 6619 passed (incl. 4 new unknown-key tests).packages/platform-objects: 52 passed (migrated objects load + validate).tscconfirms the excess-key guard errors onworkflowswhile valid usage compiles clean.listViewsshapes validated against the builtObjectSchema.https://claude.ai/code/session_01KHJTd48x76KVcAK1e494wr
Generated by Claude Code