Repository navigation
Author loops from a spec, and stop diff reporting Kizen's defaults - #97
Closed
jbedient-kizen wants to merge 2 commits into
Closed
jbedient-kizen wants to merge 2 commits into
jbedient-kizen wants to merge 2 commits into
Conversation
A spec can now describe a loop the way Kizen's builder makes one: the array and item variables, the loop, its body, the next_or_finish closer and any exit_loop steps. A loop is always sent as a branch group initiator, since the server stores that regardless, and closers no longer count toward the fan-out warning. The plan refuses a loop nested more than three deep, or one over the same array as a loop around it. The API accepts both, but Kizen's builder doesn't, and such an automation can't be edited in the UI. diff now compares a key the spec leaves out as the value Kizen stores for it (error_notification_email, deduplicate_array, array_separator, value_html and the per-type default descriptions), ignores the keys the server derives on a loop's item variable, and reads a null key in a variable definition as absent. Without this, a spec that omits defaults never diffs clean against what it created.
This was referenced Oct 27, 2026
Merged
Contributor
Author
|
Included in the 0.4.0 release PR #102; merge that instead. |
sangyeT
approved these changes
Oct 27, 2026
sangyeT
left a comment
Contributor
There was a problem hiding this comment.
Reviewed the loop authoring path (always-initiator loops, closers excluded from the fan-out warning, the builder-only depth/same-array rules via enclosing_loops) and the diff defaults (_with_default_description, _diffable_variable_block, _WIRE_TOP_DEFAULTS). The default-description fill is the right call since a PUT without one overwrites a UI-set description, so the diff stays honest. Approving.
Contributor
Author
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.
Stacked on #96; merge #96 first, then retarget this to main.
Problem
After #96, the CLI can read and edit automations with loops, but a spec author still can't write one cleanly. A spec loop isn't sent as a branch-group initiator, the fan-out warning fires on every loop, and
diffreports the keys Kizen adds to a loop's item variable. More widely,diffreported Kizen's defaults as changes whenever a spec left them out (error_notification_email,deduplicate_array,array_separator,value_html, the per-type default descriptions), so a lean spec never diffed clean against what it had just created.Solution
A spec describes a loop the way Kizen's builder makes one: the array and item variables, the
loopstep withstep_loop: {array_variable, item_variable}, its body, anext_or_finishcloser and anyexit_loopsteps.create,updateanddiffhandle it like any other step. A loop is always sent as an initiator, since the server stores that regardless, and closers no longer count toward the fan-out warning.The plan refuses a loop nested more than three deep, or one over the same array as a loop around it. The API accepts both, but Kizen's builder doesn't, and such an automation can't be edited in the UI.
diffnow compares a key the spec leaves out as the value Kizen stores for it, ignores the server-derived keys on a loop's item variable, and reads a null key in a top-level orinitialize_variabledefinition as absent.kizen docs show automationgains a Loops section with a worked example oversearch_recordsresults.Testing
Local checks after merging main: lint, format, typecheck, pytest (
2971 passed, 4 skipped, 1 xfailed) and the CLI-tree diff,passed: lint format typecheck test extra_checks.Live on a test tenant: a String-array loop, a Record-array loop over
search_recordswith a merged condition and anexit_loop, and nested loops with anexit_loopin the inner body were each created from a spec, thendiff→ "no changes"; a one-editupdatediffed as exactly that edit and clean after;roundtrip --execute→drift: []. The same three re-created from lean specs (no defaults, no descriptions) diffed clean. Test runs iterated once per item, and the nested run'sexit_loopended only the inner loop.create --dry-runof a four-deep spec and of a same-array nested pair exit 1 with the refusal text, writing nothing. Drift tier: 109 passed, 4 failed, all also failing on main (schema snapshot predates the 2026-10-26 release).Design notes / tradeoffs
Explicit over sugar: the author names the item-variable step and the closer. Having the builder insert them from
step_loopalone was rejected, becausediffwould then show steps the spec never named, and follow-on steps would need aparent_keyfor a closer the author never keyed. (steps addis a different case; see #98 (thesteps addloop PR).)Default-filling compares an omitted key as its default on both sides rather than dropping it, so a deliberate non-default value (a
semicolonseparator, say) still shows.Overlaps: as #96, plus
src/kizen_builder/translate.py. #95 (the webhook-auth fix) and #99 (the Call LLM MCP-server fix) also changetools/planners/automations.py,docs/specs/automation.mdandCHANGELOG.md.