Skip to content

feat(expression): ADR-0032 phase 1 — validate-by-default expression layer (no silent failure) - #1517

Merged
xuyushun441-sys merged 2 commits into
mainfrom
feat/adr-0032-expression-layer
Jun 2, 2026
Merged

feat(expression): ADR-0032 phase 1 — validate-by-default expression layer (no silent failure)#1517
xuyushun441-sys merged 2 commits into
mainfrom
feat/adr-0032-expression-layer

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

What

Phase 1 of ADR-0032 — the AI-safety spine: make a malformed expression impossible to ship silently, and give authors (esp. agents) a precise, fixable error. Fixes the #1491 class where a brace-in-CEL condition ({record.rating} >= 4) was silently swallowed to false, so a flow "fired" with success but did nothing.

Scope = the parts that are non-breaking and verifiable; the breaking cutovers are staged follow-ups (see below).

Changes

  • service-automationevaluateCondition no longer swallows a CEL failure to false; it throws an attributed, corrective error. registerFlow now parse-validates every predicate (start / decision / edge condition) at registration and fails loudly with location + source + the fix.
  • formula — new shared validatorvalidateExpression(role, src, schema?) + introspectScope + CEL_STDLIB_FUNCTIONS (schema-aware field-existence with did-you-mean). The {{ }} template engine gains a formatter whitelist (currency/number/percent/date/datetime/truncate/upper/lower/default/json) with defined value→string semantics; arbitrary-logic holes rejected; plain {{ path }} stays back-compatible.
  • cliobjectstack compile validates every flow / validation-rule / field-formula predicate against the resolved object schema and fails the build with located, corrective messages. (Resolves ADR open question Add metamodel interfaces for ObjectQL/ObjectUI contract #1.)
  • service-ai — agent-callable validate_expression tool for author-time self-correction.
  • spec — fix the FlowSchema JSDoc example that taught the bad single-brace condition: "{amount} < 500" form.

Both ADR open questions resolved: #1 (schema available at compile) and #2 (formatter catalog decided).

Verification

All green locally: formula 74, service-automation 149, service-ai 412, cli 152, spec 6608, objectql 484, runtime 334. All touched packages build. New negative tests cover brace-in-CEL rejection at runtime/registration/build; formatter tests cover the catalog.

Deliberately NOT in this PR (staged, breaking / cross-repo)

  • Step 3 cutover — remove string→CEL coercion + migrate authoring sites to typed builders (examples + templates).
  • Step 6 finish — delete the single-brace resolver + migrate ~191 {x} node-field usages to {{x}}.
  • Step 7 — designer (../objectui, separate repo).
  • Step 4 v2 — bool-return / type inference (CEL type env) + converging remaining objectql runtime swallows.

Phase 1 already contains the #1491 risk (loud at runtime, registration, and build).

🤖 Generated with Claude Code

…ayer, no silent failure
Fixes the #1491 class: a malformed predicate (notably the `{record.x}`
template-brace-in-CEL mistake) was silently swallowed to `false`, so a flow
"fired" with success but did nothing.
- service-automation: evaluateCondition throws an attributed/corrective error
instead of returning false; registerFlow parse-validates every predicate at
registration (loud, located).
- formula: shared validator (validateExpression / introspectScope /
CEL_STDLIB_FUNCTIONS) with schema-aware field-existence + did-you-mean; the
{{ }} template engine gains a formatter whitelist with defined value→string
semantics (plain {{ path }} stays back-compatible; arbitrary-logic holes
rejected).
- cli: objectstack compile validates flow / validation-rule / field-formula
predicates against the resolved object schema, failing the build with
located corrective messages.
- service-ai: agent-callable validate_expression tool for author-time
self-correction.
- spec: fix FlowSchema JSDoc example that taught the bad single-brace form.
Tests: formula 74, service-automation 149, service-ai 412, cli 152, spec 6608,
objectql 484, runtime 334 — all green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJun 2, 2026 4:51am

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file tests tooling size/xl labels Jun 2, 2026
while ((m = PATH_RE.exec(source)) !== null) {
refs.push(m[1]);
HOLE_RE.lastIndex = 0;
while ((m = HOLE_RE.exec(source)) !== null) {
CodeQL flagged the template hole matcher `/\{\{\s*([^}]*?)\s*\}\}/` as a
polynomial-ReDoS: `\s` ⊆ `[^}]`, so wrapping the lazy group in `\s*` makes the
matcher ambiguous on untrusted template source. Switch to a single greedy
`/\{\{([^}]*)\}\}/` and strip surrounding whitespace in parseHole — provably
linear, identical behavior (74 formula tests green).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xuyushun441-sys
xuyushun441-sys merged commit c4a4cbd into mainJun 2, 2026
12 of 13 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the feat/adr-0032-expression-layer branch June 2, 2026 05:03
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filedocumentationImprovements or additions to documentationsize/xlteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@xuyushun441-sys@github-advanced-security@os-zhuang