Skip to content

Latest commit

 

History

History
89 lines (72 loc) · 15.9 KB

PARITY.md

File metadata and controls

89 lines (72 loc) · 15.9 KB

Parity

This is the parity matrix for the three native clients: Cobalt (Wii U, this repository), Indigo (3DS) and Platinum (Mac OS 9, a Node bridge plus a C89 client). I wrote the Cobalt column from this repository's code. The Indigo and Platinum columns are what their own repositories claim: Indigo's docs/PARITY.md and Platinum's parity issues. I read their code to check the cells that looked doubtful, but I did not run either client.

Each cell starts with one of these words, and tools/check-parity.sh enforces that:

  • implemented: the code is on main.
  • partial: some of it is, with the issue for the rest.
  • issue: a gap, with its issue. Written issue #N for this repository or issue repo#N for another.
  • declined: a decision with a reason. Not the same as impossible.
  • impossible: the hardware cannot do it, with the evidence. Nothing here is in this state, because I have not proved any of the declined rows against the hardware.
  • n/a: the row does not apply to that client.

"Verified" means what was actually run. Cobalt's README says it is installed and running on a Wii U; that is the owner's report and I have no console, so nothing below is claimed on hardware by me. "Host" means the unit tests, mock-PDS end-to-end tests and the snapshot renderer, which are not an emulator and not a console.

Sign-in

The two flows have different dependencies, so they are two rows.

Flow Cobalt Indigo Platinum Evidence
App password implemented implemented implemented Cobalt: src/app/signin.c, the login job in src/atproto/session_auth.c; host and mock-PDS tests. Platinum: bridge/src/auth/app-password.ts and macos9/apppw.c.
OAuth implemented implemented implemented Cobalt: run_oauth() in src/atproto/session_auth.c through a Wolfram OAuth node (docs/oauth-node.md in Wolfram). An empty password in the form selects it. The pairing exchange (begin, a terminal error, completion into a session) has an e2e test against a mock node (tests/e2e_main.c); that test found wolfram#124, which had stopped the last step since 0.5.0. Not verified on a console by me. Platinum's bridge pairs differently (its own Node protocol).
Pairing client shared in Wolfram implemented implemented n/a Cobalt calls wf_oauth_pair_run (wolfram#101); covered by an e2e test against a mock node.

OAuth on a console is not the AT Protocol browser flow running on the console. The node holds the OAuth session and the DPoP key; the console holds a bearer token for the node and never sees the account password, MFA or a refresh token. The token is not logged.

Features

Feature Cobalt Indigo Platinum Evidence
Diagnostics implemented implemented issue platinum#37 Cobalt: ACTION_DIAGNOSTICS in src/app/app_home.c
Credits screen implemented implemented n/a Both list Cobalt, Indigo, Wolfram, Platinum and Channel Blue with the full https://github.com/ewanc26/... address, because neither console can open a browser. Cobalt: src/app/credits_view.c, reached from the home menu; a snapshot case checks the screen and B. Indigo: src/app/credits.c and the More menu; host tests check both displays and the return path.
Settings screen implemented: theme, post text scale, high contrast and reset implemented: theme, text scale, high contrast, alt text, diagnostics and startup feed issue platinum#42 Cobalt: four rows, reached from the home menu, each saved immediately; src/app/settings_view.c owns the screen and src/app/settings_store.c the file. Indigo: eight rows, reached from More; reduce motion is stored but reserved because Indigo draws no animation.
Light/dark theme implemented implemented issue platinum#42 Cobalt: Settings, cobalt_theme_apply() in src/ui/theme.c; the choice is persisted in settings.dat by src/app/settings_store.c and host-tested for the codec, the palette and the toggle. The renderer rebuilds its baked background and header band when the theme generation changes, so a switch is visible without restarting. Indigo: Settings > Theme, every layout surface follows the palette; a legacy Auto value loads as Dark. Defaults are platform-native: Light on the Wii U, Dark on the 3DS.
Text scale implemented implemented issue platinum#42 Cobalt: 100/115/130% applies to post text only, through a separate COBALT_FONT_POST face reopened by cobalt_render_set_text_scale(); the renderer drops its text and wrap caches so both the glyphs and line breaks change on the next frame. NORMAL is the size cards already used, so an untouched install is unchanged. Indigo scales the post body against its 0.6 default.
High contrast implemented implemented issue platinum#42 Cobalt: a third palette in src/ui/theme.c (black ground, white text, brighter accents), applied over whichever theme is selected and saved independently in settings.dat. cobalt_theme_set_high_contrast() bumps the same palette generation as a theme switch, so the baked background and header band rebuild immediately. Host tests check WCAG AA contrast for body, dim, accent, chip and header roles in all three palettes; snapshot cases cover the popup, image viewer and chat screen. Indigo: Settings > High contrast.
Persistent session, sign-out implemented implemented implemented Cobalt stores the session encrypted (src/cache/session_store.c); see AGENTS.md on what that is worth
Home timeline, paging implemented implemented partial, issue platinum#26 Platinum parses the cursor and never uses it
Thread view implemented implemented issue platinum#27
Profiles implemented implemented partial, issue platinum#31 Platinum shows the signed-in account only
Follow, unfollow, followers, following implemented implemented issue platinum#31
Profile tabs implemented implemented issue platinum#31 Cobalt: posts, replies, media, likes (src/atproto/actor_profile.h). Indigo: the same four, cycled from the header box on a person's posts (likes on the signed-in account only).
Pinned posts implemented implemented issue platinum#31
Notifications implemented implemented implemented
Mark notifications seen implemented implemented issue platinum#30
Avatars implemented implemented issue platinum#32
Images on posts, with alt text implemented implemented issue platinum#32
Full-size image viewer implemented implemented issue platinum#32
Link cards implemented implemented issue platinum#32
Who liked or reposted a post implemented implemented issue platinum#36
Compose, reply, quote implemented implemented partial, issue platinum#27 Platinum posts only
Attach an image when composing implemented implemented issue platinum#33 Cobalt: wf_agent_upload_blob_ex, picker in src/app/compose.c. Indigo: picker and upload path are implemented; host-verified, but upload and DCIM listing have not been verified on a console (#19 remains open for that).
Reply gates implemented implemented issue platinum#29
Like and repost, with undo implemented implemented issue platinum#28
Delete your own post implemented implemented issue platinum#42 Cobalt: confirm_delete in src/app/thread.h. Indigo: explicit confirmation; worker checks the post AT-URI against the signed-in DID before deleting. Host tests and 3DS build pass; hardware behaviour is unverified.
Actor search, post search implemented implemented issue platinum#34
Custom feeds implemented implemented issue platinum#34 Both read the account's saved feeds. Cobalt: run_saved_feeds in src/atproto/session_lists.c; B from a feed goes Home, not back to the picker.
Lists and members implemented implemented issue platinum#34 Read-only in both consoles
Mute and block, with lists implemented implemented issue platinum#35
Muted words, hide reposts implemented implemented issue platinum#35 Both call Wolfram's wf_muted_list
Direct messages partial, issue #107 partial, issue #107 issue platinum#42 Cobalt: read-only inbox on the home menu, from Wolfram's listConvos; each conversation names its counterpart or "Group", shows the last message and the unread count, and pages. A conversation opens read-only, newest messages first, from getMessages. Replying to a conversation is in: A writes a reply on the keyboard and Y sends it. Starting a new conversation is in: a handle or DID typed on the keyboard, found or created by the service, then opened. Message requests are in: Y on Messages lists them, A accepts one (it joins the inbox and opens) and X declines one (it leaves the list, by leaveConvo); each is one press and one request, never sent on entry or retried. A group's join requests are in: X on the conversation lists them (listJoinRequests), A approves the highlighted one and X rejects it (approveJoinRequest/rejectJoinRequest), and the row leaves the list on success; only a group's owner may list them. Indigo now matches this DM surface, including start-a-conversation and both decisions, with the same screen split it already uses (top reads, bottom lists and acts). Groups themselves — creating one, editing its name or members, join links — remain open in both clients on #107.
Post to a thread (several posts at once) implemented implemented issue platinum#42 Cobalt: cobalt_compose_extend (src/app/compose.c) and wf_agent_post_thread; text only. Indigo: Add to thread composes up to eight top-level text posts and uses wf_agent_post_thread; partial publication is reported and the draft cleared to avoid duplicates. Host tests and 3DS build pass; hardware behaviour is unverified.
Video poster and external-media embeds implemented partial, issue indigo#22 issue platinum#42 Cobalt: video poster frame with cannot-play line and the video's duration, read from its HLS playlist when the poster is drawn (src/ui/videoduration.c; host-tested with fake fetches, not checked against a live Bluesky playlist; a master playlist is followed to one variant, lowest bandwidth, at most two fetches per video, so a master shows the duration of its variant). A gallery embed (app.bsky.embed.gallery#view, including the media half of a quote) draws its first four pictures through the image row, and an enriched external card names its publication and reading time (source.title/readingTime) instead of only the host; both shapes are read through Wolfram's embed-view parser. A link with external.associatedRefs is hydrated once when its card is first drawn through the public AppView's getEmbedExternalView: an article names its publication and reading time, a gallery shows up to four pictures, and a livestream says live or ended; the answer and a failed answer are cached for the process, so scrolling does not retry. Host-tested with fake responses and snapshot frames; no live-record or hardware pass. Indigo: video poster frame with its duration, read from the HLS playlist and following a master playlist once to its lowest-bandwidth variant, and the cannot-play line; the formatter and variant rule are host-tested, the fetch is not hardware-verified. Other external-media variants remain open.
Open a link on a phone via QR code implemented implemented issue platinum#42 Cobalt: cobalt_popup_show_text in src/ui/popup.c encodes with Wolfram's wf_qr_encode; host-tested for the matrix, not scanned from a screen. Indigo: More-menu link view draws the QR on the top screen and the URL below; host-tested, not scanned from a physical screen.
Auto-update from GitHub releases declined implemented issue platinum#47 Cobalt: removed on purpose. Home has no Updates entry, src/app/update.c and src/update/selfupdate.c are deleted, and Cobalt downloads and replaces nothing; updates come from the Homebrew App Store package, which carries each release's .wuhb and is moved on per release by tools/submit-hbas.sh (docs/homebrew-app-store.md). No release manifest is published either — no update.json, no signature and no signing job — so there is nothing for the console, or for anything else, to read. Indigo: implemented in More > Check for updates; host-verified only, not run on emulator or hardware (#23 closed).
Video and GIF playback declined declined declined Cobalt README: no decoder in the dependency and performance budget. This is a decision; I have not tried a decoder, so it is not recorded as impossible.
Push notifications declined declined declined No push service a homebrew or Classic Mac application can register with; notifications are fetched when the screen is opened.

Cobalt only

These are Wii U specific and have no row in the other clients.

Item Cobalt Evidence
GamePad touch coverage of the popup and header pills implemented tests/snapshot_main.c taps the Back pill (leaving every screen that has one, and checking that a screen without one ignores it), taps the popup's rows through the rects the draw recorded, and taps hint pills for the button they name. Every one of those is at least 44 pixels tall on the pad, built from the same geometry the tap is tested against. Host only: no finger has been near a console.
TV layout uses the extra space partial #111 The TV timeline and thread show the selected post in full beside the list. A post longer than the column ends in a "More below" line, and L and R scroll its text without moving the selection (tests/snapshot_main.c checks the marker's pixels, the offset, the list selection and the reset; tests/test_main.c checks the shoulder mapping). With both screens on, the two surfaces divide the work rather than drawing the same picture: the TV keeps that reading layout, and the GamePad paired with it is a compact list — one line of post text, no media — with the keyboard and the actions on the pad (cobalt_surface_role, src/ui/render.h); the compact card and the roles are asserted in tests/snapshot_main.c. Host only: the L and R shoulder buttons are not confirmed to arrive as SDL shoulder buttons on the console, and neither layout has been seen on hardware.
Remember scroll position when returning from a thread or profile partial #110 The timeline keeps its cursor and scroll across a thread and across a profile, and notifications across a thread or profile; snapshot checks in tests/snapshot_main.c assert it on the host. A nested chain (timeline, thread, profile, thread) used to loop between the profile and the outer thread on B, and now unwinds one screen at a time through a return stack. Going back to a thread fetches it again, so the outer conversation is the one shown; tests/snapshot_main.c asserts both. I could not reproduce a timeline rewind and have not seen it on a console, so issue #110 stays open for the owner to confirm.
More menu unified with the thread and profile screens implemented Y opens it on the timeline, thread, notifications and profile. The profile's X, Y and + moved into it; notifications get profile, post and refresh. Snapshot checks in tests/snapshot_main.c; search results are the timeline screen and already had it. Host only.
User guide with controls per screen and screenshots implemented docs/guide.md, checked by tools/check-guide.py.
First on-console acceptance pass issue #24 Needs the owner's console.

Duplication

Shared logic lives in Wolfram. Muted words, time, failure kinds, SHA-256 and the OAuth pairing client are all Wolfram's in Cobalt and Indigo, and tools/check-shared-logic.sh fails if a copy grows back. What is left is the repeated list-screen scaffolding inside Cobalt (cobalt#185).

Keeping this honest

tools/check-parity.sh fails when a cell does not start with a known state, when an issue cell has no reference, or when the README or AGENTS.md disagree with this page about OAuth. Change a feature and this page in the same pull request.