feat(schema): add data_class, expressions field, and mutual exclusivity#11
feat(schema): add data_class, expressions field, and mutual exclusivity#11
Conversation
…ty validation Add data_class array (pii, financial, credentials, internal) to all node types and lanes for trace redaction policy. Add expressions object to action nodes for engine-native transforms. Enforce mutual exclusivity: action nodes cannot have more than one of expressions, rules, or entry_points. Update serializer key ordering for deterministic output and add dedicated lane serializer to handle data_class arrays.
…sivity Cover schema validation, structural validation, serialization round-trips, and key ordering for the new data_class and expressions fields. 23 new test cases across validation and serialization.
| * Markdown notes for documentation and design rationale | ||
| */ | ||
| notes?: string; | ||
| /** | ||
| * Data classification labels for trace redaction policy | ||
| */ | ||
| data_class?: ("pii" | "financial" | "credentials" | "internal")[]; | ||
| metadata?: { | ||
| [k: string]: string; | ||
| }; | ||
| entry_points?: EntryPoint[]; | ||
| rules?: RulesRef; |
There was a problem hiding this comment.
validateExpressions ignores node.expressions, should we treat it like node.inputs, call validateSingleExpression for each value, and verify structural.ts/serialize.ts consistency?
Finding type: Logical Bugs | Severity: 🔴 High
Want Baz to fix this for you? Activate Fixer
Other fix methods
Prompt for AI Agents:
In packages/engine/src/expressions/validator.ts around lines 157-175, the
validateExpressions logic does not handle the new ActionNode.expressions property, so
expression syntax in that map is not being validated. Update the validator to treat
node.expressions like node.inputs: if node.expressions is present, iterate over its
key/value pairs and call validateSingleExpression (or the existing per-expression
validation helper) for each value, attaching the same error context used for inputs.
After that, run a quick review of packages/schema/src/structural.ts and
packages/schema/src/serialize.ts to confirm those files’ mutual-exclusion checks and
serialization order remain consistent with the validator change and adjust any error
messages or ordering if necessary.
Heads up!
Your free trial ends tomorrow.
To keep getting your PRs reviewed by Baz, update your team's subscription
| "data_class": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "string", | ||
| "enum": ["pii", "financial", "credentials", "internal"] |
There was a problem hiding this comment.
The new data_class definition (lines 117‑124) is copied verbatim across every lane and node schema entry (lanes, action, switch, parallel, wait, etc.). That is the same non-trivial property shape repeated at lines 212‑219, 293‑300, 367‑374, 430‑437, 508‑515, 558‑565, 606‑613, and so on. If we ever need to tweak the enum or description (or add constraints), every copy has to be updated in lockstep. Can we move this to a single shared schema definition (e.g. #/definitions/DataClassLabels and $ref it in each object) so the constraint lives in one place and serialization/validation changes stay consistent?
Finding type: Code Dedup and Conventions | Severity: 🟢 Low
Want Baz to fix this for you? Activate Fixer
Heads up!
Your free trial ends tomorrow.
To keep getting your PRs reviewed by Baz, update your team's subscription
| "data_class": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "string", | ||
| "enum": ["pii", "financial", "credentials", "internal"] | ||
| }, | ||
| "description": "Data classification labels for trace redaction policy" | ||
| }, |
There was a problem hiding this comment.
packages/schema adds data_class and expressions but doesn't include a .changeset/*.md — should we add one describing those additions?
Finding type: AI Coding Guidelines | Severity: 🟠 Medium
Want Baz to fix this for you? Activate Fixer
Other fix methods
Prompt for AI Agents:
In packages/schema/flowprint.schema.json around lines 117-124, the new "data_class"
array (and similarly the new "expressions" property elsewhere) constitutes a
package-level API change for packages/schema but no .changeset/*.md entry was added.
Create a new .changeset markdown file describing the addition of the data_class field
and expressions (brief summary, type of change: minor or patch per repo policy), list
the affected files (packages/schema/flowprint.schema.json,
packages/schema/src/serialize.ts, packages/schema/src/structural.ts,
packages/schema/src/types.generated.ts, and
packages/schema/src/__tests__/data-class-expressions.test.ts), and ensure the changeset
follows the repository's CLAUDE.md format so release tooling will pick it up. If your
repo requires updating package.json version or changelog metadata in the changeset,
include that as well.
Heads up!
Your free trial ends tomorrow.
To keep getting your PRs reviewed by Baz, update your team's subscription
| // Mutual exclusion: expressions vs rules vs entry_points on action nodes | ||
| if (type === 'action') { | ||
| const hasRules = node.rules !== undefined | ||
| const hasEntryPoints = node.entry_points !== undefined | ||
| const hasExpressions = node.expressions !== undefined | ||
|
|
||
| if (hasExpressions && hasRules) { | ||
| errors.push({ | ||
| path: `/nodes/${nodeId}`, | ||
| message: 'Action node cannot have both "expressions" and "rules". Use one or the other', | ||
| severity: 'error', | ||
| }) |
There was a problem hiding this comment.
Should we update packages/engine/src/expressions/validator.ts to allow zero entry_points when expressions are present and sync structural.ts mutual-exclusion logic with the schema that now permits expressions-only action nodes?
Finding type: Logical Bugs | Severity: 🔴 High
Want Baz to fix this for you? Activate Fixer
Other fix methods
Prompt for AI Agents:
In packages/schema/src/structural.ts around lines 44 to 72 in the validateStructure
function (the mutual-exclusion checks for action nodes), confirm that action nodes are
allowed to have expressions-only (no entry_points) and keep the current mutual-exclusion
errors for pairs of expressions/rules/entry_points. Then update the engine validator in
packages/engine/src/expressions/validator.ts (around the epCount !== 1 check near lines
63-72) so that it permits epCount === 0 when the action node has an expressions property
(i.e., allow zero entry_points if expressions are present), preserving the existing
requirement of exactly one entry_point when neither expressions nor rules are present.
Make these two changes so schema-level and engine-level validation rules are consistent
and include a brief unit test or assertion demonstrating an action node with only
expressions passes validation.
Heads up!
Your free trial ends tomorrow.
To keep getting your PRs reviewed by Baz, update your team's subscription
| // Mutual exclusion: expressions vs rules vs entry_points on action nodes | ||
| if (type === 'action') { | ||
| const hasRules = node.rules !== undefined | ||
| const hasEntryPoints = node.entry_points !== undefined | ||
| const hasExpressions = node.expressions !== undefined | ||
|
|
||
| if (hasExpressions && hasRules) { | ||
| errors.push({ | ||
| path: `/nodes/${nodeId}`, | ||
| message: 'Action node cannot have both "expressions" and "rules". Use one or the other', | ||
| severity: 'error', | ||
| }) |
There was a problem hiding this comment.
Schema now allows expressions-only action nodes but packages/engine/src/runner/walker.ts still assumes an entry_point or rules and throws for expressions-only actions — should we update executeAction/walker to short-circuit by evaluating expressions-only actions and setting results without loading an entry_point?
Finding type: Logical Bugs | Severity: 🔴 High
Want Baz to fix this for you? Activate Fixer
Other fix methods
Prompt for AI Agents:
In packages/schema/src/structural.ts around lines 44 to 72 the validator was changed to
allow action nodes that have an "expressions" block mutually exclusive with "rules" and
"entry_points". However, update packages/engine/src/runner/walker.ts (around the earlier
referenced executeAction/walker logic near lines ~174-177) so that when an action node
has expressions present and does NOT have rules or entry_points the runtime
short-circuits: evaluate the expressions (reuse the existing expression evaluator used
elsewhere), populate the action result/output/state accordingly, and return/advance
without attempting to load or call an entry_point or rules. Also review and, if
necessary, update packages/schema/src/types.generated.ts and
packages/schema/src/serialize.ts to ensure the engine and serializer/types remain
consistent with expression-only action nodes, and add/adjust unit tests to cover
expression-only actions.
Heads up!
Your free trial ends tomorrow.
To keep getting your PRs reviewed by Baz, update your team's subscription
| 'label', | ||
| 'description', | ||
| 'notes', | ||
| 'data_class', | ||
| 'metadata', | ||
| 'position', | ||
| 'entry_points', |
There was a problem hiding this comment.
NODE_KEY_PREFIX inserts data_class before metadata and entry_points, breaking CLAUDE.md's canonical order that requires metadata and entry_points directly after description — should we move data_class so metadata/entry_points remain after description or update CLAUDE.md and align serializers with the chosen ordering?
Finding type: AI Coding Guidelines | Severity: 🟠 Medium
Want Baz to fix this for you? Activate Fixer
Other fix methods
Prompt for AI Agents:
In packages/schema/src/serialize.ts around lines 25 to 31, the NODE_KEY_PREFIX was
modified to insert 'data_class' before 'metadata' and 'position', which breaks the
canonical node field order documented in CLAUDE.md (description should be followed
immediately by metadata and entry_points). Fix by moving 'data_class' out of the spot
before 'metadata' so that NODE_KEY_PREFIX is restored to label, description, metadata,
entry_points, ...; place 'data_class' after position or at the end of the prefix
(whichever preserves the CLAUDE.md canonical order). Then review serializeNode (around
lines 154-216) and the new lane/field serializers you added to ensure special-casing for
data_class, expressions, and entry_points still emits keys in the chosen canonical
order; if you decide to adopt a new canonical ordering instead, update CLAUDE.md to
document the exact order and adjust tests/serialization code accordingly.
Heads up!
Your free trial ends tomorrow.
To keep getting your PRs reviewed by Baz, update your team's subscription
| if (key === 'data_class' && Array.isArray(value)) { | ||
| const seq = new YAMLSeq() | ||
| for (const item of value as string[]) { | ||
| seq.add(createScalar(item)) | ||
| } | ||
| laneMap.add(new Pair(key, seq)) | ||
| } else { |
There was a problem hiding this comment.
serializeLanes copies data_class arrays into a YAMLSeq, which is identical to the block added inside serializeNode a few lines later (lines 164‑170). If we ever need to change how data_class values are emitted (e.g. formatting, escaping, or enforcing ordering), we would need to touch both blocks. Can we extract a small helper such as function addArrayField(map: YAMLMap, key: string, values: string[]) and reuse it in both serializeLanes and serializeNode so the serialization behaviour stays consistent and easy to update?
Finding type: Code Dedup and Conventions | Severity: 🟢 Low
Want Baz to fix this for you? Activate Fixer
Heads up!
Your free trial ends tomorrow.
To keep getting your PRs reviewed by Baz, update your team's subscription
Deploying flowprint with
|
| Latest commit: |
298527c
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://92b064c2.flowprint.pages.dev |
| Branch Preview URL: | https://feat-engine-pr0c-schema-addi.flowprint.pages.dev |
Code Review FindingsCritical invariants verified
Important (80-89 confidence)1. PR description enum values don't match implementation (85)
2.
3.
|
User description
Summary
data_classenum (public,internal,confidential,restricted) to node metadataexpressionsfield for labeled expression definitions on action nodesnextvscases,nextvsbranches)Dependency
Base:
main(independent of PR 0a, 0b)PR 3 of 16 in the execution engine implementation.
Test plan
data_classenum valuesexpressionsfield structureGenerated description
Below is a concise technical summary of the changes proposed in this PR:
Extend the flowprint schema to track
data_classlabels across lanes and nodes, ensuring serialization ordering and generated types reflect the new metadata. Regenerate validation, serialization, and tests so action nodes can exposeexpressionswhile enforcing their mutual exclusivity withrules/entry_points.expressionsalongside their serialization ordering and enforce mutual exclusivity withrules/entry_points, covering the schema, validator, and tests.Modified files (4)
Latest Contributors(1)
data_classmetadata to lanes and nodes, updating the schema, serializer ordering, generated types, and regression tests to preserve the new enum-driven labels in YAML output.Modified files (4)
Latest Contributors(1)