Skip to content

spec: enum where it decides shape or is user-facing, string for UI plumbing - #124

Merged
fa0311 merged 1 commit into
mainfrom
refactor/enum-policy
Oct 17, 2026
Merged

fa0311 merged 1 commit into
mainfrom
refactor/enum-policy

Conversation

@fa0311

@fa0311 fa0311 commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

Stacked on #123. Applies one rule to every enum in the spec and writes it down in CONTRIBUTING.md:

  • enum when the value decides the shape of the data or the branch a client takes (__typename, itemType, *Ref.type, cursorType, urlType, media.type, binding value type), or when it is user-facing and a closed set. A new value should fail loudly in the strict test and be added the same day. twitter-snap is the reference consumer: anything a renderer branches on belongs here.
  • plain string when the value is UI plumbing that changes nothing structurally. Known values stay in a comment next to the field.

The lists below come from a census of every enum-like value in 858 stored responses (the two strict sweeps, the HAR capture, the nightly and drift recordings).

Back to enum (user-facing, closed)

  • LimitedAction.action / LimitedActionResultsData.action: 19 observed values (Reply, Retweet, QuoteTweet, Like, React, AddToBookmarks, AddToMoment, PinToProfile, ViewHiddenReplies, VoteOnPoll, ShowRetweetActionMenu, ReplyDownVote, SendViaDm, ViewPostEngagements, CopyLink, ShareTweetVia, Embed, HideCommunityTweet, ViewTweetActivity). What a user may do with a tweet.
  • ConversationControl.policy: ByInvitation, Community, Co, Subscribers, Verified, MyNetwork. Co is what X sends for some Community-limited tweets (39 occurrences). Who may reply.
  • TweetCardLegacyBindingValueData.type: STRING, IMAGE, USER, BOOLEAN, IMAGE_COLOR. Decides which *_value is present; twitter-snap reads cards through it.
  • Community.role: Member, Moderator, Admin, NonMember (was [NonMember]; same backend enum as AuthorCommunityRelationship.role).

To plain string (UI plumbing, 24 fields)

Session.superFollowsApplicationStatus, ModuleHeader.displayType, TimelinePromptContent.contentType / .displayType, TimelineMessagePromptContent.contentType, TimelineTombstone.tombstoneDisplayType, TimelineTopicContext.functionalityType, TimelineShowAlert.alertType / .displayLocation, TimelineHalfCover.halfCoverDisplayType, CoverCta.buttonStyle, CtaClientEventInfo.action, FeedbackAction.confirmationDisplayType / .icon, UnifiedCard.card_fetch_state, Community{Delete,Leave}ActionResult.reason, CommunityJoinActionUnavailable.reason, CommunityInvitesResult.reason, BirdwatchPivot.footerIconType, TweetCardPlatformAudience.name, TweetPostCta.display_locations[], CtaLimitedActionPrompt.cta_type.

Kept as enum (all observed values already present): TypeName, InstructionType, ContentEntryType, ContentItemType, CursorType, DisplayType, tweetDisplayType, userDisplayType, every *Ref.type / urlType, TimelineGeneralContext.contextType, TimelineCoverBehavior.type, TweetInterstitial.displayType, Media.type, MediaSize.resize, ExtMediaAvailability.status, TweetView.state, richtext_types, TweetLegacy.limited_actions, verified_type, profile_image_shape, parody_commentary_fan_label, professional_type, UserLabel.*, birthdate visibilities, TwitterList.mode, community join_policy / invites_policy, AuthorCommunityRelationship.role, BirdwatchPivot.visualStyle, ai_generated_detection_source.

Generated clients

The Python enum classes of the 24 fields disappear and three new ones appear (limited action, policy, binding value type). Neither wrapper, twitter-snap nor the snap apps reference any of the removed classes (checked by grep; twitter-snap uses RichtextTypesEnum and TimelineTweetTweetDisplayTypeEnum, both kept).

Verification

  • 805 stored responses deserialize at match rate exactly 1.0 with the new enums.
  • Strict live test: 124 calls, all 124 at match rate exactly 1.0 (nightly settings, sandbox account). 7 responses carried X's partial errors beside complete data and are logged as warnings.

🤖 Generated with Claude Code

…umbing

Documented in CONTRIBUTING.md. From a census of 858 stored responses:
back to enum: LimitedAction.action / LimitedActionResultsData.action (19
values), ConversationControl.policy (6, incl. Co), TweetCardLegacyBindingValueData.type
(5), Community.role aligned with AuthorCommunityRelationship.role. To plain
string with the known values in comments: 24 UI fields (prompt / cover /
alert display styles, feedback icon and kind, community action reasons,
footer icon, card fetch state, CTA type, ...). 805 stored responses still at
match rate exactly 1.0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@fa0311
fa0311 changed the base branch from fix/sweep-2026-10-17 to main October 17, 2026 17:27
@fa0311
fa0311 merged commit 6252df3 into main Oct 17, 2026
@fa0311
fa0311 deleted the refactor/enum-policy branch October 17, 2026 17:28
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