Skip to content

Generate complete reply coverage contracts - #28

Merged
kriptoburak merged 2 commits into
mainfrom
codex/reply-extraction-contract-20260731
Jul 31, 2026
Merged

Generate complete reply coverage contracts#28
kriptoburak merged 2 commits into
mainfrom
codex/reply-extraction-contract-20260731

Conversation

@kriptoburak

@kriptoburak kriptoburak commented Jul 31, 2026

Copy link
Copy Markdown
Member

What changed

  • Regenerate the SDK from production OpenAPI commit 6613f3219.
  • Add complete reply mode, nested-reply separation, and typed incomplete diagnostics.
  • Preserve rich tweet, user, media, and connection contracts.
  • Keep create TOTP required and reauth TOTP optional where the SDK exposes connection methods.

Why

X can rank, hide, or omit replies counted on a post. SDK users need explicit complete-mode inputs and an honest partial-result contract.

Validation

The generated output passed its complete language-specific test, lint, coverage, audit, licensing, and reproducibility gates before publication. Production REST, MCP, pagination, load, and Apify canaries are green. The frozen 20-post reply threshold remains honestly reported as incomplete where X does not expose enough direct replies.


Summary by cubic

Adds complete reply coverage with a new complete mode and a typed replies response that separates nested replies and includes diagnostics. Regenerates the SDK from the production OpenAPI and aligns rich read-model types across tweets, users, media, trends, support tickets, and account-connection flows.

  • New Features

    • X::TweetGetRepliesResponse: new return type for tweets#get_replies; adds diagnostic and nested_replies on top of PaginatedTweets.
    • X::TweetGetRepliesParams: adds mode (:complete) and limit for complete-coverage fetching.
    • Expanded tweet models: EmbeddedTweet, SearchTweet, and X::TweetDetail add shared fields (e.g. article, card, community_note, edit, note_tweet, place, possibly_sensitive, previous_counts, view_state).
    • Account connections: AccountCreateResponse is now a typed union; attempt retrieval is discriminated by status (:pending, :success, :failed, :requires_email_code); challenge/reauth status is :active.
    • Support tickets: required fields with typed Status/Sender enums; TweetMedia gains geometry/accessibility/crop metadata; trends add promoted_content, tweet_volume, url; UserProfile adds affiliation/verification details; X::TweetAuthor now requires followers and verified.
  • Migration

    • Replies: tweets#get_replies now returns X::TweetGetRepliesResponse. Use mode and limit for complete mode; complete mode accepts only limit (drop cursor, pageSize/count, time ranges, and tweet filters). Read diagnostic for coverage; nested_replies are separate from direct coverage.
    • Enums/symbols: statuses are symbols; attempt retrieval is discriminated by status; challenge/reauth status is :active.
    • Support tickets: several fields are now required; update parsers and type checks.
    • Removed fields: ContentDisclosure::AIGenerated#can_edit, UserProfile#can_dm, community is_member/role.

Written for commit 443ea3b. Summary will update on new commits.

Review in cubic

Note

Add complete reply coverage contracts with structured response types and expanded tweet/user models

  • Introduces TweetGetRepliesResponse with a Diagnostic submodel and TweetGetRepliesParams gains limit and mode (:complete) parameters; get_replies now deserializes into this typed response instead of PaginatedTweets.
  • Expands TweetDetail, SearchTweet, and EmbeddedTweet with shared optional fields: article, card, community_note, edit, note_tweet, place, possibly_sensitive, previous_counts, and view_state, each backed by new nested model classes.
  • Replaces AccountCreateResponse's unknown converter with a typed union (SanitizedXAccount, XAccountConnectionAttemptPending, XAccountConnectionChallenge); renames AccountConnectionAttemptRetrieveResponse variants to Pending, Success, Failed, RequiresEmailCode and adds a status discriminator.
  • Expands UserProfile with 14 new fields (e.g. highlights_info, identity_verification, affiliates_highlighted_label) and removes can_dm, viewer_followed_by, viewer_following; expands TweetMedia with geometry, accessibility, and crop metadata.
  • Promotes TicketListResponse, TicketRetrieveResponse, and TicketUpdateResponse fields from optional to required and narrows status/sender to typed enum modules.
  • Risk: UserProfile, TweetAuthor, and the support ticket models now require previously optional fields at initialization; callers constructing these models directly will break.

Changes since #28 opened

  • Relaxed type signatures across multiple model type definition files to use ::Hash[Symbol, top] instead of specific structured types [443ea3b]
  • Added nested Object and Status modules with enum constants to all variant classes in Models::X::AccountConnectionAttemptRetrieveResponse [443ea3b]
  • Added legacy alias constants in Models::X::AccountConnectionAttemptRetrieveResponse module mapping to existing variant classes [443ea3b]
  • Updated documentation in Internal::Type::Union module to include RequiresEmailCode variant in pattern-matching examples [443ea3b]
  • Adjusted wording in parameter comment for Resources::X::Communities class method [443ea3b]

Macroscope summarized d03581f.

@kriptoburak
kriptoburak requested a review from furkanerday as a code owner July 31, 2026 02:18
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@kriptoburak, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 23 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 154e0561-810f-4004-a869-44ff7b107c89

📥 Commits

Reviewing files that changed from the base of the PR and between 9b2e7d9 and 443ea3b.

📒 Files selected for processing (108)
  • .stats.yml
  • lib/x_twitter_scraper.rb
  • lib/x_twitter_scraper/internal/type/union.rb
  • lib/x_twitter_scraper/models/content_disclosure.rb
  • lib/x_twitter_scraper/models/embedded_tweet.rb
  • lib/x_twitter_scraper/models/paginated_tweets.rb
  • lib/x_twitter_scraper/models/search_tweet.rb
  • lib/x_twitter_scraper/models/support/ticket_list_response.rb
  • lib/x_twitter_scraper/models/support/ticket_retrieve_response.rb
  • lib/x_twitter_scraper/models/support/ticket_update_response.rb
  • lib/x_twitter_scraper/models/trend_list_response.rb
  • lib/x_twitter_scraper/models/tweet_media.rb
  • lib/x_twitter_scraper/models/user_profile.rb
  • lib/x_twitter_scraper/models/x/account_connection_attempt_retrieve_response.rb
  • lib/x_twitter_scraper/models/x/account_connection_challenge_submit_response.rb
  • lib/x_twitter_scraper/models/x/account_create_response.rb
  • lib/x_twitter_scraper/models/x/account_reauth_response.rb
  • lib/x_twitter_scraper/models/x/communities/tweet_list_by_community_params.rb
  • lib/x_twitter_scraper/models/x/communities/tweet_list_params.rb
  • lib/x_twitter_scraper/models/x/community_retrieve_info_response.rb
  • lib/x_twitter_scraper/models/x/community_retrieve_search_params.rb
  • lib/x_twitter_scraper/models/x/list_retrieve_tweets_params.rb
  • lib/x_twitter_scraper/models/x/tweet_author.rb
  • lib/x_twitter_scraper/models/x/tweet_detail.rb
  • lib/x_twitter_scraper/models/x/tweet_get_quotes_params.rb
  • lib/x_twitter_scraper/models/x/tweet_get_replies_params.rb
  • lib/x_twitter_scraper/models/x/tweet_get_replies_response.rb
  • lib/x_twitter_scraper/models/x/tweet_get_thread_params.rb
  • lib/x_twitter_scraper/models/x/user_retrieve_likes_params.rb
  • lib/x_twitter_scraper/models/x/user_retrieve_media_params.rb
  • lib/x_twitter_scraper/models/x/user_retrieve_mentions_params.rb
  • lib/x_twitter_scraper/models/x/user_retrieve_replies_params.rb
  • lib/x_twitter_scraper/models/x/user_retrieve_tweets_params.rb
  • lib/x_twitter_scraper/models/x_get_article_response.rb
  • lib/x_twitter_scraper/models/x_get_trends_response.rb
  • lib/x_twitter_scraper/resources/x/account_connection_attempts.rb
  • lib/x_twitter_scraper/resources/x/accounts.rb
  • lib/x_twitter_scraper/resources/x/communities.rb
  • lib/x_twitter_scraper/resources/x/communities/tweets.rb
  • lib/x_twitter_scraper/resources/x/lists.rb
  • lib/x_twitter_scraper/resources/x/tweets.rb
  • lib/x_twitter_scraper/resources/x/users.rb
  • rbi/x_twitter_scraper/models/content_disclosure.rbi
  • rbi/x_twitter_scraper/models/embedded_tweet.rbi
  • rbi/x_twitter_scraper/models/paginated_tweets.rbi
  • rbi/x_twitter_scraper/models/search_tweet.rbi
  • rbi/x_twitter_scraper/models/support/ticket_list_response.rbi
  • rbi/x_twitter_scraper/models/support/ticket_retrieve_response.rbi
  • rbi/x_twitter_scraper/models/support/ticket_update_response.rbi
  • rbi/x_twitter_scraper/models/trend_list_response.rbi
  • rbi/x_twitter_scraper/models/tweet_media.rbi
  • rbi/x_twitter_scraper/models/user_profile.rbi
  • rbi/x_twitter_scraper/models/x/account_connection_attempt_retrieve_response.rbi
  • rbi/x_twitter_scraper/models/x/account_connection_challenge_submit_response.rbi
  • rbi/x_twitter_scraper/models/x/account_create_response.rbi
  • rbi/x_twitter_scraper/models/x/account_reauth_response.rbi
  • rbi/x_twitter_scraper/models/x/communities/tweet_list_by_community_params.rbi
  • rbi/x_twitter_scraper/models/x/communities/tweet_list_params.rbi
  • rbi/x_twitter_scraper/models/x/community_retrieve_info_response.rbi
  • rbi/x_twitter_scraper/models/x/community_retrieve_search_params.rbi
  • rbi/x_twitter_scraper/models/x/list_retrieve_tweets_params.rbi
  • rbi/x_twitter_scraper/models/x/tweet_author.rbi
  • rbi/x_twitter_scraper/models/x/tweet_detail.rbi
  • rbi/x_twitter_scraper/models/x/tweet_get_quotes_params.rbi
  • rbi/x_twitter_scraper/models/x/tweet_get_replies_params.rbi
  • rbi/x_twitter_scraper/models/x/tweet_get_replies_response.rbi
  • rbi/x_twitter_scraper/models/x/tweet_get_thread_params.rbi
  • rbi/x_twitter_scraper/models/x/user_retrieve_likes_params.rbi
  • rbi/x_twitter_scraper/models/x/user_retrieve_media_params.rbi
  • rbi/x_twitter_scraper/models/x/user_retrieve_mentions_params.rbi
  • rbi/x_twitter_scraper/models/x/user_retrieve_replies_params.rbi
  • rbi/x_twitter_scraper/models/x/user_retrieve_tweets_params.rbi
  • rbi/x_twitter_scraper/models/x_get_article_response.rbi
  • rbi/x_twitter_scraper/models/x_get_trends_response.rbi
  • rbi/x_twitter_scraper/resources/x/accounts.rbi
  • rbi/x_twitter_scraper/resources/x/communities.rbi
  • rbi/x_twitter_scraper/resources/x/communities/tweets.rbi
  • rbi/x_twitter_scraper/resources/x/lists.rbi
  • rbi/x_twitter_scraper/resources/x/tweets.rbi
  • rbi/x_twitter_scraper/resources/x/users.rbi
  • sig/x_twitter_scraper/models/content_disclosure.rbs
  • sig/x_twitter_scraper/models/embedded_tweet.rbs
  • sig/x_twitter_scraper/models/search_tweet.rbs
  • sig/x_twitter_scraper/models/support/ticket_list_response.rbs
  • sig/x_twitter_scraper/models/support/ticket_retrieve_response.rbs
  • sig/x_twitter_scraper/models/support/ticket_update_response.rbs
  • sig/x_twitter_scraper/models/trend_list_response.rbs
  • sig/x_twitter_scraper/models/tweet_media.rbs
  • sig/x_twitter_scraper/models/user_profile.rbs
  • sig/x_twitter_scraper/models/x/account_connection_attempt_retrieve_response.rbs
  • sig/x_twitter_scraper/models/x/account_connection_challenge_submit_response.rbs
  • sig/x_twitter_scraper/models/x/account_create_response.rbs
  • sig/x_twitter_scraper/models/x/account_reauth_response.rbs
  • sig/x_twitter_scraper/models/x/community_retrieve_info_response.rbs
  • sig/x_twitter_scraper/models/x/tweet_author.rbs
  • sig/x_twitter_scraper/models/x/tweet_detail.rbs
  • sig/x_twitter_scraper/models/x/tweet_get_replies_params.rbs
  • sig/x_twitter_scraper/models/x/tweet_get_replies_response.rbs
  • sig/x_twitter_scraper/models/x_get_article_response.rbs
  • sig/x_twitter_scraper/models/x_get_trends_response.rbs
  • sig/x_twitter_scraper/resources/x/accounts.rbs
  • sig/x_twitter_scraper/resources/x/tweets.rbs
  • test/x_twitter_scraper/resources/support/tickets_test.rb
  • test/x_twitter_scraper/resources/x/account_connection_attempts_test.rb
  • test/x_twitter_scraper/resources/x/account_connection_challenges_test.rb
  • test/x_twitter_scraper/resources/x/accounts_test.rb
  • test/x_twitter_scraper/resources/x/tweets_test.rb
  • test/x_twitter_scraper/resources/x/users_test.rb

Comment @coderabbitai help to get the list of available commands.

@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.

8 issues found across 110 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="sig/x_twitter_scraper/models/trend_list_response.rbs">

<violation number="1" location="sig/x_twitter_scraper/models/trend_list_response.rbs:74">
P2: `Trend#to_hash[:url]` can be nil when `url` is omitted, but the new `trend` and `to_hash` records expose it as a guaranteed `String`, allowing statically accepted calls such as `.upcase` to fail at runtime. The hash declarations should model `url` as nullable/optional consistently with the initializer and reader.</violation>
</file>

<file name="lib/x_twitter_scraper/models/x/account_connection_attempt_retrieve_response.rb">

<violation number="1" location="lib/x_twitter_scraper/models/x/account_connection_attempt_retrieve_response.rb:27">
P2: SDK upgrades now raise `NameError` for callers that pattern-match or instantiate the previously published variant constants, including challenge enum constants, because they are renamed rather than aliased. Retaining deprecated aliases in Ruby/RBS/RBI, or shipping and documenting this as an explicit breaking release, would make the compatibility impact clear.</violation>
</file>

<file name="sig/x_twitter_scraper/models/x/tweet_author.rbs">

<violation number="1" location="sig/x_twitter_scraper/models/x/tweet_author.rbs:8">
P2: Typed consumers lose the inherited `UserProfile` contract because this alias and the matching `initialize`/`to_hash` signatures expose only `followers` and `verified`, even though runtime `TweetAuthor` instances retain all superclass fields. The generated contract should merge the inherited required and optional profile fields rather than replace them.</violation>
</file>

<file name="lib/x_twitter_scraper/models/x/tweet_get_replies_params.rb">

<violation number="1" location="lib/x_twitter_scraper/models/x/tweet_get_replies_params.rb:127">
P2: Complete-mode calls remain type-valid with `cursor` and filter parameters even though the new contract excludes those combinations. Since `dump_request` serializes every supplied field, consider separate parameter alternatives or validation that rejects incompatible keys before sending the request.</violation>
</file>

<file name="lib/x_twitter_scraper/models/paginated_tweets.rb">

<violation number="1" location="lib/x_twitter_scraper/models/paginated_tweets.rb:37">
P3: Pagination users lose the guidance needed to distinguish filtered/credit-limited pages and continue via `next_cursor`; the replacement “see PaginatedTweets” link does not preserve those details. Restoring the prior behavior notes alongside the new complete-mode fields would keep the public contract actionable.</violation>
</file>

<file name="sig/x_twitter_scraper/models/search_tweet.rbs">

<violation number="1" location="sig/x_twitter_scraper/models/search_tweet.rbs:292">
P2: Hash results are typed as containing every newly added optional field, so Steep can allow nil-unsafe access such as `tweet.to_hash[:article]` even when runtime omitted `article`. These fields should use optional record keys (`?article:`, `?id:`, etc.) in the added aliases and `to_hash` records.</violation>
</file>

<file name="lib/x_twitter_scraper/models/support/ticket_retrieve_response.rb">

<violation number="1" location="lib/x_twitter_scraper/models/support/ticket_retrieve_response.rb:55">
P3: Non-empty ticket responses remain untested because `MockPayload.example` always supplies an empty `messages` array. Consider adding a coercion test with one message to cover the new required fields and `Sender` enum.</violation>
</file>

<file name="sig/x_twitter_scraper/models/paginated_tweets.rbs">

<violation number="1" location="sig/x_twitter_scraper/models/paginated_tweets.rbs:12">
P2: Hashes from `PaginatedTweets.new(...).to_hash` may omit `diagnostic` and `nested_replies`, but both new record signatures claim the keys and non-nil values are always present. Mark these fields as optional (`?diagnostic:` / `?nested_replies:`) in both `paginated_tweets` and `to_hash` so RBS consumers do not rely on values absent at runtime.</violation>
</file>

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

?rank: Integer
?rank: Integer,
?tweet_volume: Integer?,
?url: String

@cubic-dev-ai cubic-dev-ai Bot Jul 31, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Trend#to_hash[:url] can be nil when url is omitted, but the new trend and to_hash records expose it as a guaranteed String, allowing statically accepted calls such as .upcase to fail at runtime. The hash declarations should model url as nullable/optional consistently with the initializer and reader.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At sig/x_twitter_scraper/models/trend_list_response.rbs, line 74:

<comment>`Trend#to_hash[:url]` can be nil when `url` is omitted, but the new `trend` and `to_hash` records expose it as a guaranteed `String`, allowing statically accepted calls such as `.upcase` to fail at runtime. The hash declarations should model `url` as nullable/optional consistently with the initializer and reader.</comment>

<file context>
@@ -48,18 +58,30 @@ module XTwitterScraper
-          ?rank: Integer
+          ?rank: Integer,
+          ?tweet_volume: Integer?,
+          ?url: String
         ) -> void
 
</file context>
Fix with cubic

Comment thread sig/x_twitter_scraper/models/x/tweet_detail.rbs Outdated
Comment thread sig/x_twitter_scraper/models/x/tweet_detail.rbs Outdated
Comment thread sig/x_twitter_scraper/models/embedded_tweet.rbs Outdated
Comment thread sig/x_twitter_scraper/models/x_get_trends_response.rbs
Comment thread lib/x_twitter_scraper/internal/type/union.rb
# @return [Array<XTwitterScraper::Models::Support::TicketRetrieveResponse::Message::Attachment>, nil]
optional :attachments,
# @return [Array<XTwitterScraper::Models::Support::TicketRetrieveResponse::Message::Attachment>]
required :attachments,

@cubic-dev-ai cubic-dev-ai Bot Jul 31, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Non-empty ticket responses remain untested because MockPayload.example always supplies an empty messages array. Consider adding a coercion test with one message to cover the new required fields and Sender enum.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/x_twitter_scraper/models/support/ticket_retrieve_response.rb, line 55:

<comment>Non-empty ticket responses remain untested because `MockPayload.example` always supplies an empty `messages` array. Consider adding a coercion test with one message to cover the new required fields and `Sender` enum.</comment>

<file context>
@@ -11,70 +11,70 @@ module Support
-          #   @return [Array<XTwitterScraper::Models::Support::TicketRetrieveResponse::Message::Attachment>, nil]
-          optional :attachments,
+          #   @return [Array<XTwitterScraper::Models::Support::TicketRetrieveResponse::Message::Attachment>]
+          required :attachments,
                    -> { XTwitterScraper::Internal::Type::ArrayOf[XTwitterScraper::Models::Support::TicketRetrieveResponse::Message::Attachment] }
 
</file context>
Fix with cubic

Comment thread sig/x_twitter_scraper/models/user_profile.rbs Outdated
Comment on lines 37 to 41
# Some parameter documentations has been truncated, see
# {XTwitterScraper::Models::PaginatedTweets} for more details.
#
# An empty page can still have has_next_page true after filtering.
#

@cubic-dev-ai cubic-dev-ai Bot Jul 31, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Pagination users lose the guidance needed to distinguish filtered/credit-limited pages and continue via next_cursor; the replacement “see PaginatedTweets” link does not preserve those details. Restoring the prior behavior notes alongside the new complete-mode fields would keep the public contract actionable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/x_twitter_scraper/models/paginated_tweets.rb, line 37:

<comment>Pagination users lose the guidance needed to distinguish filtered/credit-limited pages and continue via `next_cursor`; the replacement “see PaginatedTweets” link does not preserve those details. Restoring the prior behavior notes alongside the new complete-mode fields would keep the public contract actionable.</comment>

<file context>
@@ -22,16 +22,286 @@ class PaginatedTweets < XTwitterScraper::Internal::Type::BaseModel
+      optional :nested_replies, -> { XTwitterScraper::Internal::Type::ArrayOf[XTwitterScraper::SearchTweet] }
+
+      # @!method initialize(has_next_page:, next_cursor:, tweets:, diagnostic: nil, nested_replies: nil)
+      #   Some parameter documentations has been truncated, see
+      #   {XTwitterScraper::Models::PaginatedTweets} for more details.
+      #
</file context>
Suggested change
# Some parameter documentations has been truncated, see
# {XTwitterScraper::Models::PaginatedTweets} for more details.
#
# An empty page can still have has_next_page true after filtering.
#
# Paginated tweet results. The item count can be lower than pageSize when the
# source returns fewer tweets, filters remove tweets, or remaining credits cover
# fewer results. Follow next_cursor while has_next_page is true. An empty page can
# still have has_next_page true after filtering. Zero affordable results returns
# 402 insufficient_credits.
#
Fix with cubic

Comment thread sig/x_twitter_scraper/models/search_tweet.rbs Outdated

@furkanerday furkanerday left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Blocking findings remain, and 19 current review threads are unresolved. Representative contract defects:

  1. Optional runtime fields are incorrectly declared required/non-nil in RBS records and to_hash contracts, including sig/x_twitter_scraper/models/trend_list_response.rbs:33-42 and 77-85, tweet_detail.rbs:8-48 and 252+, embedded_tweet.rbs:7-47, paginated_tweets.rbs:7+, tweet_media.rbs:7-29 and 137-158, and search_tweet.rbs:7-47 and 251+. This rejects valid runtime objects.

  2. Hash-coercible nested runtime inputs are typed class-only at tweet_detail.rbs:69-89 and 220-243 and tweet_media.rbs:72-102 and 126-132. TweetAuthor also loses the inherited UserProfile contract at sig/x_twitter_scraper/models/x/tweet_author.rbs:8-21.

  3. lib/x_twitter_scraper/models/x/account_connection_attempt_retrieve_response.rb:9+ renames public variant constants without compatibility aliases.

  4. The documented 424 incomplete-replies path still has no typed IncompleteTweetReplies model/error-path test.

Resolve every actionable thread and these runtime/RBS compatibility gaps, then re-request review.

Regenerate every SDK from the exact production OpenAPI contract.
@kriptoburak
kriptoburak force-pushed the codex/reply-extraction-contract-20260731 branch from e12e544 to d03581f Compare July 31, 2026 14:15
Signed-off-by: kriptoburak <kriptoburak@users.noreply.github.com>
@kriptoburak
kriptoburak merged commit f638d05 into main Jul 31, 2026
12 checks passed
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