Skip to content

fix(all): report server-sent event operations and field deprecations in SDK diffs - #148

Open
mfbx9da4 wants to merge 2 commits into
mainfrom
claude/speakeasy-diff-dual-content-bug-304a31
Open

mfbx9da4 wants to merge 2 commits into
mainfrom
claude/speakeasy-diff-dual-content-bug-304a31

Conversation

@mfbx9da4

@mfbx9da4 mfbx9da4 commented Oct 23, 2026 •

Copy link
Copy Markdown

[skip changelog]

Why

speakeasy diff and the release notes that speakeasy run writes to gen.lock both build SDK ASTs through pkg/changes. Two gaps made those diffs incomplete.

  1. Operations with a text/event-stream response disappeared from the diff. resolveAST ran the generator with a context that carried no generation access state. When the generator reaches an event-stream response, it calls licensing.ValidateAccountHasFeatureAccess. Without access state, that check returns ErrMissingGenerationAccess, which is wrapped as an UnsupportedError, and g.skip silently drops the whole operation. Because the operation was missing from both the old and new AST, it was never reported as added or removed, and changes to its request or response (for example a new enum value) were never reported either. This hits both an operation whose 200 response offers application/json and text/event-stream, and an operation that only streams. The same gate covers other feature-gated constructs, such as JSONL responses and webhooks.
  2. Field deprecation was ignored. diffFieldDefs compares nullability, optionality, defaults, consts and annotations, but not Comments.Deprecated. So marking a request or response field deprecated: true produced no change.

What changed

  • resolveAST attaches direct generation access state when the caller supplies none. This matches internal/generate.Generate. Callers that already provide access state are unaffected.
  • A field that becomes deprecated is now reported with a new field_deprecated diff reason, rendered as **Deprecated**. It is non-breaking, and only the transition into deprecation is reported, consistent with method-level deprecation. If the field also changed in another way, it is still reported as **Changed**.
  • The duplicated reason-to-action switches in markdown.go are now one formatDiffAction helper.

Before (old spec has generateReport with a json + event-stream 200 response; new spec adds the html enum value to its request, adds createWidget (json + event-stream) and tailEvents (event-stream only)):

No changes detected.

After:

## Python SDK Changes:
* `sdk.create_widget()`: **Added**
* `sdk.tail_events()`: **Added**
* `sdk.generate_report()`: 
  *  `request.format.enum(html)` **Added**

Before (request field color and response field nickname marked deprecated: true):

No changes detected.

After:

## Typescript SDK Changes:
* `sdk.updateWidget()`: 
  *  `request.color` **Deprecated**
  *  `response.nickname` **Deprecated**

No generated SDK output changes, so this PR skips the changelog.

Testing

  • New snapshot tests TestChanges_MethodChanges_ServerSentEvents and TestChanges_FieldChanges_FieldDeprecated. Both fail with CI=true against the previous pkg/changes sources and pass with this change.
  • go test ./pkg/changes/... ./cmd/changes/... passes, with no changes to existing snapshots.
  • golangci-lint run ./pkg/changes/... reports 0 issues. make lint also reports a gofmt issue in templates/perms.go, which is unchanged from main.
  • Ran go run ./cmd/changes on a pair of specs combining json + event-stream operations, an enum addition and a deprecated response field. All expected changes are now reported.
  • git diff --check flags only trailing spaces in the new snapshots. Those are literal markdown output (: before a nested list), the same as in 43 existing snapshots.

Public-safety check

  • This change contains no credentials, customer documents, private repository URLs, private filesystem paths, or unredacted private logs.
  • Title, body, comments, and commit messages name no customers or customer-derived identifiers, private paths or trackers, or workflow provenance, and are understandable without private context (.claude/skills/public-repo-communication/SKILL.md).
  • Generated fixtures and review SDK changes are public-safe.
  • I reviewed git diff --check.

Summary by cubic

Fixes two gaps that made speakeasy diff and release notes written to gen.lock miss real SDK changes.

  • Operations with text/event-stream responses were dropped because resolveAST ran the generator without generation access state; it now attaches direct access state when none is provided, matching internal/generate.Generate. This also covers other feature-gated constructs such as JSONL responses and webhooks.
  • Marking a request or response field deprecated: true produced no change; fields that become deprecated are now reported with a new field_deprecated diff reason, rendered as **Deprecated**. Only the transition into deprecation is reported, consistent with method-level deprecation, and fields that also changed otherwise are still reported as **Changed**.
  • The duplicated reason-to-action switches in markdown.go are now one formatDiffAction helper.

No generated SDK output changes, so the changelog is skipped.

Written for commit 3993b62. Summary will update on new commits.

View guided diff Turn on auto-fix

…in SDK diffs

The SDK diff resolved both ASTs with a context that carried no generation
access state. Feature-gated constructs such as text/event-stream responses
then failed the access check, and the generator skipped the whole operation,
so any operation with a server-sent event response was missing from the diff:
never reported as added, removed or changed.

resolveAST now attaches direct generation access state when the caller
provides none, matching internal/generate.Generate.

Field comparisons also ignored deprecation, so marking a request or response
field deprecated produced no change. A field that becomes deprecated is now
reported with a new field_deprecated reason, rendered as **Deprecated**.

[skip changelog]
@mfbx9da4
mfbx9da4 requested a review from a team as a code owner October 23, 2026 17:09
@mfbx9da4
mfbx9da4 requested a review from simplesagar October 23, 2026 17:09
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 8 files

Shadow auto-approve: would not auto-approve because issues were found.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread pkg/changes/changes_field_deprecated_test.go

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 2 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Bounded bug fix in diff/release-note tooling: includes previously skipped SSE/feature-gated operations and reports field deprecations, with new snapshot tests pinning both behaviors.

View guided diff | Turn on auto-fix | Re-trigger cubic

@mfbx9da4
mfbx9da4 enabled auto-merge October 23, 2026 17:20
@mfbx9da4

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Oct 23, 2026
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