fix(spec): hook condition row declares expression, not javascript - #20475
objectstack-fleet[bot] merged 4 commits into
Conversation
HookSchema.condition is a CEL predicate (EvaluatedExpressionInputSchema), but hook.form.ts declared its `condition` row `language: 'javascript'`, same as the real script rows (body.source, action.source). A consumer keyed on the declared language cannot tell the predicate apart from a script. Change the row to `language: 'expression'`, matching every sibling predicate row, and pin it beside the existing form-row pins. --- _Generated by [Claude Code](https://claude.ai/code)_ Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014EJ1ED8X4MMrT18BhVx4tx
en.metadata-forms.generated.ts picks up the new condition helpText (node scripts/check-i18n-bundles.mjs --write). The other 8 packages' bundles regenerated byte-identical; zh-CN/ja-JP/es-ES kept their existing translated-locale values under merge mode (now stale relative to the new English source, per the tool's documented behaviour). --- _Generated by [Claude Code](https://claude.ai/code)_ Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014EJ1ED8X4MMrT18BhVx4tx
…ok-condition-expression-row
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 2 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 137 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
Contract reviewServed-tier: ① Derived judgmentsInputs: card #20439 (body; triage grade
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
…ok-condition-expression-row
Fixes #20439
Clause-②: no
What
packages/spec/src/data/hook.form.ts'sconditionrow declaredlanguage: 'javascript'overHookSchema.condition, which isEvaluatedExpressionInputSchema— a CEL predicate, not a script (hook.zod.ts:'Predicate (CEL); hook runs only when TRUE …'). Every sibling predicate row (field.form.ts/object.form.ts'svisibleWhen/readonlyWhen/requiredWhen, and the formulaexpressionrow) already declareslanguage: 'expression'. A consumer keyed on the row's declared language (objectui#10963'sCodeWidgetfix) could not tell this row apart from a real script row (body.source,action.source, both genuinely'javascript').conditionrow now declareslanguage: 'expression',helpText: 'CEL predicate — the hook runs only when TRUE'(triage's wording, matching the sibling rows' phrasing).packages/spec/src/system/metadata-form-declared-rows.pin.test.ts(no existing row-language assertion was found, so the pin was added beside that file's existing form-row pins): assertshook.conditiondeclarestype: 'code'/language: 'expression', with a control againstfield.visibleWhen(a sibling predicate row already correct) so the assertion is shown to actually discriminate.en.metadata-forms.generated.tsregenerated (node scripts/check-i18n-bundles.mjs --write) to pick up the new helpText.zh-CN/ja-JP/es-ESkept their existing translated values under the tool's merge behaviour (now stale relative to the new English source — the tool does not auto-translate).@objectstack/specpatch.Why this landing site
Matches the constraint's expected surface exactly:
hook.form.ts, the pin, the regenerated translation bundles, and the changeset. No other producer or consumer needed a change.Tests
pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/system/metadata-form-declared-rows.pin.test.ts src/system/metadata-form-zod-reconciliation.test.ts src/data/hook.test.ts src/data/hook-body.test.ts— 173 passed.pnpm --filter @objectstack/platform-objects exec vitest run --maxWorkers=2 src/apps/translations— 399 passed (21 files), includingmetadata-forms-vocabulary.test.tsandhook-execution-panel-echo-decisions.test.ts.pnpm --filter @objectstack/spec build && pnpm --filter @objectstack/spec check:generated— all 15 generated artifacts up to date.pnpm check:i18n— all 9 packages in sync, no undeclared authoring keys.pnpm --filter @objectstack/spec typecheck— clean.node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands→ 85 derived families, all run and reconciled (--ran): 84 green, 1 honestly NOT-MEASURED —pnpm check:dual-build-cjs-loadsexits its ownPREREQUISITE NOT MET(3) because this worktree never ran a fullpnpm buildacross every package in the monorepo (studio, client-react, several connectors/plugins/services have nodist/); that whole-workspace build is disproportionate to this one-row change and is CI's own "Build Core" job to run. Nothing about this diff is implicated in that gate.Acceptance notes
None — no out-of-scope findings surfaced while making this change.
Generated by Claude Code