Skip to content

spec: 22 more operations (community, birdwatch, lists, explore, viewer) and tonight's drift - #121

Merged
fa0311 merged 3 commits into
mainfrom
feat/more-operations
Oct 16, 2026
Merged

fa0311 merged 3 commits into
mainfrom
feat/more-operations

Conversation

@fa0311

@fa0311 fa0311 commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Adds the 22 placeholder operations that had a recorded response but no spec path (64 → 86 operations). Every response schema is typed from the recorded response (required = present in the sample); the strict live test now calls all of them with two cursor pages.

New operations

  • community (new tag → CommunityApi): CommunitiesFetchOneQuery (community page), CommunityQuery (settings / moderation pages), CommunitiesSearchQuery (cursor in slice_info.next_cursor), TopicCarouselQuery, GlobalCommunitiesPostSearchTimeline, GlobalCommunitiesLatestPostSearchTimeline.
  • birdwatch (new tag → BirdwatchApi): BirdwatchFetchAliasSelfSelectStatus, BirdwatchFetchAuthenticatedUserProfile, BirdwatchFetchBirdwatchProfile, BirdwatchFetchGlobalTimeline (segmented timelines), BirdwatchFetchPublicData (public data file urls).
  • tweet: BookmarkSearchTimeline, ExploreSidebar. user-list: ListSearchTimeline, CombinedLists (same UserTweetsResponse shape as ListOwnerships), ListsManagementPageTimeline. users: UsersVerifiedAvatars. default (paths/viewer.yaml): AuthenticatePeriscope, CreatorStudioTabBarItemQuery, DataSaverMode, GrokHome, PinnedTimelines.
  • Not added yet: getAltTextPromptPreference, isEligibleForVoButtonUpsellQuery, usePremiumPaywallOnLoadMutation (their placeholder keys start lowercase, which the strict harness's method-name → key mapping does not handle), and the catalog-only operations that have no placeholder entry.

Relay community pages

The three community queries are Relay fragments: node ids on the result wrappers and on rules, __is… interface markers on the action results, and partial users (facepile users are {__typename, avatar, id}, the settings creator is {__typename, core.screen_name, id, is_blue_verified, verification}). They get their own types (CommunityPageCommunity, CommunitySettingsCommunity, CommunitySearchCommunity, CommunityFacepileUser, CommunityRelayRule, CommunityPageActions, …) instead of widening Community / User; only the objects that are the same at every site are shared (CommunityBannerMedia, CommunityViewerRelationship, UserAvatar, AffiliatesHighlightedLabel, Timeline / TimelineResult). UsersVerifiedAvatars likewise returns a partial VerifiedAvatarUser. TypeName gains CommunityHashtagSlice and CommunityListMembersAction.

Placeholder / tooling

  • tools/update_placeholder.py now fills in variables for an entry that has none (X answers 422 without them); that completed CommunitiesFetchOneQuery, UsersVerifiedAvatars and isEligibleForVoButtonUpsellQuery from the stamped catalog lines. HomeTimeline is POST per the latest stamped catalog line.
  • The entries that carried the identifiers of the account that was logged in during the earlier recordings (ListOwnerships, UsersVerifiedAvatars, GenericTimelineById, ProfileSpotlightsQuery, Likes, isEligibleForVoButtonUpsellQuery) were re-recorded today on the sandbox account and their sample values set to the usual ones (screen_name elonmusk, userId 44196397, tweetId 1349129669258448897; the request shapes are the recorded ones). The same id is removed from the UserTweets id list of the strict test. catalog: re-record the viewer-bound requests on the sandbox account twitter_api_safe_relay#38 replaces the matching catalog rows.
  • tools/build_config.py registers the two new tags; test/python/test_serialize.py iterates CommunityApi and BirdwatchApi too, and treats X's partial errors beside complete data (match rate 1.0) as a warning instead of a failure, which is what CombinedLists, ListSearchTimeline, ListsManagementPageTimeline and ListByRestId always return (the ListByRestId skip is gone). tools/json_to_schema.py (local, not committed) drafted the schemas from the recordings; everything was reviewed and renamed by hand.

Drift found by the strict runs (X side, 2026-10-16)

  • ClientEventInfoDetails.timelinesDetails is optional: notification items carry notificationDetails {impressionId, metadata} instead.
  • RichMessage.entities on notifications: TimelineRichTextUser refs with user_results and TimelineRichTextList refs with id and a relative url.
  • ModuleFooter.displayType can be an empty string, so it is a plain string now.
  • AdMetadataContainer.unifiedCardOverride (a JSON string) on a promoted tweet.
  • Promoted trends: TimelineTrend.description / promoted_metadata (TrendPromotedMetadata: advertiser, impression ids, promotedTrend), TrendMetadata.meta_description; FeedbackAction.feedbackType gained Dismiss, so it is a plain string now.
  • New item type TimelineEventSummary (promoted event card on ExplorePage: event id, hero media with a tweet, title, its own promoted metadata whose ad container lacks renderLegacyWebsiteCard), added to ItemContentUnion, ContentItemType and TypeName.

Verification

  • 422 stored responses deserialize at match rate 1.0 (the 22 new operations and every response of tonight's strict runs among them).
  • Strict live test with the nightly settings on the sandbox account: 125 calls, every match rate exactly 1.0, exit 0 (8 responses carried X's partial errors beside complete data and are logged as warnings).

🤖 Generated with Claude Code

fa0311 and others added 3 commits October 16, 2026 15:12
…r), drift from tonight's strict runs

Adds the placeholder operations that had a recorded response but no path:
CommunitiesFetchOneQuery, CommunityQuery, CommunitiesSearchQuery,
TopicCarouselQuery, GlobalCommunities(Latest)PostSearchTimeline (tag
community), the five Birdwatch queries (tag birdwatch),
BookmarkSearchTimeline, ExploreSidebar, ListSearchTimeline, CombinedLists,
ListsManagementPageTimeline, UsersVerifiedAvatars, AuthenticatePeriscope,
CreatorStudioTabBarItemQuery, DataSaverMode, GrokHome, PinnedTimelines. The
Relay community pages get their own types instead of widening Community and
User. The strict harness iterates the two new API classes, tolerates X's
partial errors beside complete data (CombinedLists, ListSearchTimeline,
ListsManagementPageTimeline, ListByRestId) and tests ListByRestId again;
update_placeholder.py fills in variables for entries that have none.

Drift: ClientEventInfoDetails.notificationDetails (timelinesDetails optional),
RichMessage.entities, ModuleFooter.displayType and FeedbackAction.feedbackType
as plain strings, AdMetadataContainer.unifiedCardOverride, promoted trends
(TimelineTrend.description / promoted_metadata, TrendMetadata.meta_description)
and the TimelineEventSummary item.

Verified: 422 stored responses and the strict live test (125 calls) at match
rate exactly 1.0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
ListOwnerships, UsersVerifiedAvatars, GenericTimelineById,
ProfileSpotlightsQuery, Likes and isEligibleForVoButtonUpsellQuery carried
the identifiers of the account that was logged in during the earlier
recordings; they are recorded again on the development sandbox account.
UsersVerifiedAvatars.userIds keeps only the viewer id. HomeTimeline is POST
per the latest stamped catalog line. The same id leaves the UserTweets id
list of the strict test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…58448897)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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