Repository navigation
Release 0.4.0 - #102
Merged
Merged
Release 0.4.0#102
Conversation
A Call LLM step runs its MCP tools as a service account, and builds had no way to make one without clicking through Settings. The new group lists, creates, updates, deletes and shows the history of integration accounts, with permission groups by name as roles takes them. Kizen returns the new account's API key in full on create, under an api_key object the schema doesn't declare. The API wrapper drops it before anything else sees the response, so no plan, result, table or --json output can contain it; reads show only Kizen's own preview. A rename sends the current api_name with the new name, because Kizen re-derives it from any PATCH that includes name. Update and delete refuse automation and plugin accounts, which Kizen or a plugin manages, and create refuses a duplicate name, which Kizen answers with a 500.
Since Kizen's 2026-10-26 release a webhook trigger carries auth_type, headers and secret, and a PUT without auth_type resets the trigger to Kizen API auth, which also changes its URL under external callers. Every spec written before the release omits the key, so an update now carries the live trigger's auth across, matched by trigger id and then by webhook name. Setting auth_type still changes it. Specs can now set all four auth types. The model refuses headers or secret on a type Kizen silently drops them for, and the retired auth_header_* keys. Headers get the same html_value the UI writes, labelling a secret reference with the secret's description, and automations get shows each webhook's auth type.
Kizen's 2026-10-26 release gave every Call LLM step mcp_server, run_tools_as, max_sequential_turns and tool_failure_policy. The CLI refused the unread keys, so show, diff, steps, activate, deactivate, move and roundtrip all stopped on any automation with such a step. Specs can now name the server by api_name and the account by name, resolved against the step's own pickers, and dry-run refuses one without the other, as Kizen does. The builder always sends all four keys: a PUT that omits both ids keeps the server and clears the account, storing a step Kizen's own validator then rejects. A spec without them therefore detaches a server attached in the UI, so update's preview names each step that loses its server or account.
An MCP server is the set of Kizen tools a Call LLM step or an outside MCP client can call, and builds had no way to make or change one from the CLI. The new group lists, creates, updates and deletes servers from a spec, and shows a server's tools and change history. Tool names are checked against the live catalogue, because Kizen rejects the whole request for one unknown tool. Tools compare as a set and sharing compares after normalising both sides, so get --raw output sent back unchanged plans a skip. Kizen-managed servers are refused, except for setting one back as the business default. Kizen keeps one default per business, so the preview names the server that loses it and how to restore it.
Kizen's 2026-10-26 release added loop steps, which the CLI read with no config block. Every read-modify-write verb then PUT the loop without its step_loop and got a 400 after a clean --dry-run, so activate, deactivate, move, steps and roundtrip --execute failed on any automation with one. Loops now translate with their array and item variables by name, and next_or_finish and exit_loop as the configless closers they are. --dry-run checks the server's loop rules and names the broken step, show puts each loop's body under it, and steps add and remove keep a loop closed. Translate also refuses a live step carrying a config block it doesn't read, instead of silently dropping it on PUT.
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.
Kizen's builder creates a loop's next_or_finish and its item variable together, but 'steps add' refused a loop and sent a one-step edit through a whole-automation spec. It now adds all three: the item variable is always created, named '<array>_item', and the parent's children follow the closer so they still run once, after the loop. Removing a loop needed --cascade, which also deleted every step after it. A loop with an empty body now goes with its closer and the steps after it move up.
This was referenced Oct 27, 2026
sangyeT
approved these changes
Oct 27, 2026
sangyeT
left a comment
Contributor
There was a problem hiding this comment.
Reviewed #95-#101 individually and approved each; this branch carries their merge commits plus the 0.4.0 bump, changelog section and link definitions, and the lockfile re-lock. Approving. Per the plan: merge this with a merge commit (not squash), don't merge #95-#101 separately, then tag v0.4.0 on the merge commit.
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.
What's in it
Seven open PRs, merged here with merge commits and released together as 0.4.0:
automations updatekeeps a webhook trigger's auth when the spec leaves it out, and webhook specs can setauth_type,headersandsecret.activate,deactivate,move,steps,roundtrip --execute) no longer fail on automations that contain loops, andshowrenders loops.diffstops reporting Kizen's defaults as changes.steps addof a loop adds its closer and item variable, andsteps removetakes an empty loop's closer with it.kizen mcp-serverscommand group.kizen service-accountscommand group.The last commit,
Release 0.4.0, moves the[Unreleased]entries under## [0.4.0] — 2026-10-27(oneAddedand oneFixedblock), adds the link definitions, bumpspyproject.tomlto 0.4.0 and re-locks. None of the entries is a breaking change.Plan
Merge this PR with a merge commit, not a squash. GitHub then marks Keep a webhook trigger's auth when an update spec leaves it out #95–Add a kizen service-accounts command group #101 as merged, because their heads are in main's history.
Tag the merge commit on
mainand push the tag:Pushing the tag runs
release.yml. It checks that the tag matchespyproject.toml, runs the suite and the packaging tests, and creates the GitHub Release from the## [0.4.0]changelog section with the sdist and wheel attached.Please don't merge #95–#101 to main separately in the meantime. They're all included here, and merging one on its own would put changes on main without the version bump.
Testing
check.sh(ruff check, ruff format --check, mypy, pytest, CLI tree baseline) passed after each of the five merges and again on the release commit. Final pytest run: 3128 passed, 5 skipped, 1 xfailed.uv run pytest -m wheel: 1 passed.tests/test_release_metadata.py: 3 passed.kizen --versionafteruv sync:kizen-builder 0.4.0.Drift tier, run once against the disposable test environment (business id checked before the run): 114 passed, 3 failed. The automation count was 49 before and 49 after. The three failures are known and pre-existing. They come from the schema snapshot, which predates Kizen's 2026-10-26 release:
test_no_schema_drifttest_write_schema_keys_are_honoured_or_known_unsent:action_schedule_activitygainedtarget_variableandvariable_field_resolutiontest_live_read_keys_are_all_classified[drift_activity_steps]A fourth known failure,
test_live_read_keys_are_all_classified[drift_ai_steps], now passes because Model a Call LLM step's MCP server and run-as account #99 classifies the new Call LLM keys.