Skip to content

th-ef78d0: add the missing changeset for the interaction-ordering fix - #521

Merged
brentrager merged 1 commit into
mainfrom
fix/interaction-ordering-changeset
Aug 20, 2026
Merged

th-ef78d0: add the missing changeset for the interaction-ordering fix#521
brentrager merged 1 commit into
mainfrom
fix/interaction-ordering-changeset

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

Follow-up to #520, which landed the Rich Interaction ordering fix (interaction_required before the raise tool's toolCall chunk, in Go / TypeScript / Python / .NET) but carried no changeset — so the fix would version and publish nowhere.

What this adds

1. The changeset. @smooai/smooth-operator: patch, describing the fix, the ruling behind it, and the mechanism each port reused.

2. The divergence note, refreshed. spec/conformance/scenarios/README.md still documented the divergence as live — "Park event vs. the raise tool's stream_chunk — Rust is 1 of 5, and Rust is right" — and interaction-park-resume's own description still told readers "Go / TypeScript / Python / .NET emit the chunk first." Both now record it as FIXED, in the same struck-through style the corpus already uses for the cancel divergence, and note that every port reused its own write-confirmation mechanism rather than inventing a second one: suppress the chunk in the engine stream loop on a tool-name predicate, re-emit it from the park path after the park event.

3. Formatting restored. interaction-choices-park-resume.json had been rewritten by a JSON re-serializer (2-space indent, escapes), turning a two-line change into a 152-line diff and diverging from the corpus's formatting. Restored to the corpus style with the marker and reason intact.

Scenario matrix

All five servers pass all 18 scenarios, with one tracked exception:

scenario rust go ts python dotnet
interaction-park-resume
interaction-declined
interaction-invalid-retryable
interaction-stale-id-rejected
interaction-conversational-fallback
interaction-choices-park-resume ⚠️ marked
other 12

knownDivergences is now gone from four of the five interaction scenarios. The fifth keeps ["go"], re-pointed at a different bug — this is the marker contract working as intended, not the original divergence surviving.

The second bug, uncovered by the first

Fixing the order let interaction-choices-park-resume run past step 2 for the first time, and it still fails on Go — for an unrelated reason. splitIntoChunks in smooth-operator-core Go (go/core/llm_provider.go) slices the mock reply by bytes:

size := (len(s) + parts - 1) / parts // ceil
out = append(out, s[i:end])

"Pro it is — pulling that quote up." is 36 bytes; 3 parts puts a boundary at byte 12, mid-em-dash (bytes 10–12). Each fragment is invalid UTF-8 and arrives as U+FFFD — the accumulated token is "Pro it is ��� pulling that quote up.". interaction-park-resume's reply is 33 bytes and its boundaries miss the rune, which is exactly why only this one scenario trips. Fix is one line upstream (slice []rune) plus a core release; it is not a protocol divergence and not a reason to weaken the scenario.

Verification

  • Go: full go/server suite green (18/18 scenarios; choices correctly tolerated with the new reason). Two failures seen mid-session (TestCancelMidTurnAbortsAndEmitsCancelled, one TestScenarioParity blip) did not reproduce across four subsequent runs and occurred at load average 30–47 on 12 cores — load-induced, and this branch touches no Go code.
  • TypeScript: 385 passed / 0 failed. Python: 387 passed. .NET: 405 + 101 passed / 0 failed.
  • .NET's pass was confirmed with a control — temporarily re-adding "dotnet" to a marker made the runner fail with remove dotnet from knownDivergences … it now passes, proving the scenario genuinely runs and passes rather than being silently skipped.
  • Rust is untouched; it was never listed in any marker, so removing marker entries cannot change its behavior.

PR #520 landed the ordering fix itself but carried no changeset, so the fix
would version and publish nowhere. Adds it, and cleans up two things that
outlived the fix:

- spec/conformance/scenarios/README.md still documented the divergence as
  live ("Rust is 1 of 5, and Rust is right") and interaction-park-resume's
  description still told readers the four ports emit the chunk first. Both now
  record it as FIXED, with the mechanism each port reused, and name the second
  bug the fix uncovered.
- interaction-choices-park-resume.json had been rewritten by a JSON
  re-serializer (2-space indent, \u escapes), diverging from the corpus's
  formatting for a two-line change. Restored, marker and reason intact.
@changeset-bot

changeset-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b5886f9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@smooai/smooth-operator Patch
@smooai/smooth-operator-web-chat-example Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@brentrager
brentrager merged commit 12dcb43 into main Aug 20, 2026
8 checks passed
@brentrager
brentrager deleted the fix/interaction-ordering-changeset branch August 20, 2026 00:46
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.

1 participant