Skip to content

Collapse expand-on-read reference keys before writing them back - #31

Merged
jbedient-kizen merged 1 commit into
mainfrom
bug/collapse-expanded-keys-before-put
Sep 4, 2026
Merged

Collapse expand-on-read reference keys before writing them back#31
jbedient-kizen merged 1 commit into
mainfrom
bug/collapse-expanded-keys-before-put

Conversation

@jbedient-kizen

Copy link
Copy Markdown
Contributor

Problem

GET expands references that PUT expects narrow — change_field_value.fields_to_clear comes back as full field objects, and start_automation.automation_variable_overrides as a flat list with every reference expanded. The translator handed that read shape straight back to PUT.

Because a PUT is a full replace, any automation containing either key 400'd on every write verb — activate, deactivate, steps add|edit|remove, roundtrip --execute — including on steps nobody touched. automations activate is the flow the spec docs explicitly recommend, and it could not complete on such an automation.

Solution

fields_to_clear collapses to bare field UUIDs. automation_variable_overrides collapses into the write dialect's grouped-by-target-automation shape, narrowing each reference: field references to bare UUIDs, variable references to bare names, specific_value through as-is.

The collapse is keyed by payload key, not by value_source. Which key holds the value is observable on any entry; the value_source string that selects it is only knowable from a capture that exercises it. Driving off the key means an override whose value_source this code has never seen still round-trips — which is what keeps an automation editable, since activate/deactivate/steps all PUT the whole automation back and a step nobody touched has to survive the trip.

Testing

bin/check.sh — all five steps pass: 1468 passed, 4 skipped (+12).

Verified live against a disposable tenant on a real automation carrying six overrides across five sources: GET -> PUT -> GET came back byte-identical.

An earlier build of this fix carried through only two keys and silently dropped the override's value whenever value_source was specific_value — caught live against a real boolean-typed override, which collapsed to a payload with no value at all while roundtrip still reported clean. That is why the fixture in this PR is a real capture rather than a synthetic one.

Design notes / tradeoffs

An earlier revision raised on an unrecognised value_source. That was wrong: it would strand an automation Kizen itself accepted, on operations that never touch the override. Carrying the value across is strictly better than both raising and dropping. If the server rejects a carried key, that surfaces as a 400 at write time — which tells you something true about that automation, where refusing to try tells you nothing.

automations roundtrip (without --execute) now also says plainly that its validation is client-side only and does not prove the PUT will succeed, rather than reporting "translated + validated" unqualified.

Last of six stacked branches.

GET expands references that PUT expects as bare ids or names, so a
read-modify-write handed the read shape straight back. The variable
override collapse also dropped the value for every source other than
context_entity_field and automation_variable — a specific_value override
round-tripped as an override with no value, while roundtrip reported
clean.

Overrides now collapse per value_source through an explicit map, and an
unrecognised source raises rather than silently emitting a payload
missing its value. Confirmed live: six overrides across five sources
survive a GET -> PUT -> GET byte-identical.
@jbedient-kizen
jbedient-kizen changed the base branch from feat/permission-group-update to main September 4, 2026 16:40
@jbedient-kizen
jbedient-kizen merged commit 8e1fe95 into main Sep 4, 2026
4 checks passed
@jbedient-kizen
jbedient-kizen deleted the bug/collapse-expanded-keys-before-put branch September 4, 2026 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants