Commit ac3079c
committed
fix(service-automation): scope a
`map` tracks progress through its collection in the flow variable
`<nodeId>.$mapState` and wrote it into the flow's SHARED variable scope
without ever removing it. A `loop` body region runs in that same scope by
construction, so the state written by iteration 1 was still there when
iteration 2 entered the map: it read back `started === collection.length`,
concluded there was nothing left to start, and returned success.
Measured on the real engine: 5 iterations x 2 items produced 2 child runs
instead of 10, the map step reported `success` on all five iterations, and
the run finished `completed` with `failed = 0` — silent partial work,
invisible to the very run-level counter built to expose that class.
The state key is now removed once the collection is exhausted, making its
lifetime one execution of the collection rather than the enclosing scope's.
The durable-pause path is deliberately untouched: the write made before
returning `suspend: true` is the mechanism a resume depends on, because
`resumeInternal` rebuilds the scope from the snapshot taken at that suspend
and can never see a later write. Only the terminal path clears the key. A
test pins that half — an unconditional delete leaves the loop assertions
green and fails only the resume pin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpTx2tbq3pZRYAdoGt6E6Ymap node's progress state to one execution of its collection1 parent b119d0e commit ac3079c
1 file changed
Lines changed: 13 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
0 commit comments