Skip to content

epic: web-parity index - the remaining work to match interlinedlist.com #66

Open

Description

@Adron

This epic is a pointer, not a backlog.

The master plan — ordering, architecture, probe evidence, API shapes, the re-measure log, and the release path — lives in work-consolidation.md. Its §1f work index maps every open item to its issue.

The plan work-consolidation.md — why, and in what order
Execution Issues #38–#81 — live status; what PRs close
Per-endpoint coverage docs/api-coverage.md — implementation + verified reachability

When this file and an issue disagree, the issue wins.


Why this epic was emptied (2026-09-14)

It previously restated the entire backlog — the defect table, the parity-feature list, the decisions, the blocked items — while work-consolidation.md carried the same material in its §1/§2/§3. Two sources of truth, each drifting from the code and from each other.

Between 2026-09-07 and 2026-09-13, seven PRs (#67–#73) shipped and neither was updated: the doc drifted ~330 tests and two API re-measures behind, and six issues both described as open had already shipped. Re-syncing them without removing the duplication would only have restarted the clock.

So the duplication is cut in one direction. The doc is master; issues are execution; this epic points at both.

Two claims this epic made that are now disproved

1. "45 operations are x-auth-type: session and reject Bearer — a hard ceiling on native parity."

Re-measured 2026-09-14: it is 32, and 28 of those are routes a native client should never call (24 /api/admin/*, 2 /api/architecture-aggregates/*, 2 /api/stripe/*). The genuinely limiting set is four: GET /api/auth/accounts, POST /api/auth/switch, POST /api/auth/remove-account (#60) and POST /api/auth/send-verification-email.

2. "The Dashboard is backend-blocked, not merely undecided."

No longer true. Both layout routes and all five widget routes are sync-token now, confirmed 200 under Bearer by live read-only probe:

GET /api/user/dashboard-layout   -> 200 {"layout":null}
GET /api/user/front-wall-layout  -> 200 {"layout":null}
GET /api/user/engagement         -> 200 {"totalDigs":24,"totalPushes":6,...}
GET /api/widgets/news            -> 200
GET /api/widgets/markets         -> 200

Controls probed the other way — /api/auth/accounts and send-verification-email both 401 — so the four that remain really are session-only. #61 is now a product decision only.

The invite/share claim routes also moved to sync-token, which makes PR #70's "genuinely out of reach" note on document-invite accept stale.

Standing constraints (unchanged)

  • SwiftUI only in the App target — no AppKit / NSViewRepresentable under App/** without asking.
  • Decision 0003 — no import InterlinedKit in App/Features/**, App/Navigation/**, App/MenuCommands/**.
  • Probe before you decode. OPTIONS proves the verb, never the envelope. This API has a documented history of shape drift, and three separate silent-decode defects (G21 link metadata, G25 org members, and the latent bug(lists): GET /api/lists/{id} envelope mismatch makes ListsService.detail(listId:) undecodable #75) all had green tests against fabricated fixtures.
  • Verification is mandatory. .claude/skills/swift-engineer/assets/e2e-gate-checklist.md, plus the BDD quartet.
  • Same-PR doc-sync rule. A PR that ships a G-item or closes a parity issue updates work-consolidation.md in that same PR.

Baseline on origin/dev @ 01bc1a9 (2026-09-14): Kit 478 · Domain 946 · Persistence 140 · App 954, all green.

Activity

  1. added
    parityWeb-parity gap with the InterlinedList web app
    on Sep 7, 2026
  2. Adron commented on Sep 16, 2026

    @Adron
    MemberAuthor

    2026-09-15 sweep — index update

    This epic is a pointer, so here is where the pointed-at work now stands after a full pass over the backlog.

    Closed this pass (each has an open PR carrying it)

    Issue PR
    #82 test flake #86 root cause was a production race in all four event buses
    #75 + #85 list schema #87 the schema wire contract was a string client-side, an object server-side
    #39 AI copy + #49 decision record #88
    #80 notifications tray #89 scope=all already existed
    #44 My Profile (G32) #90
    #46 Profile settings (G34) #92
    #47 Integrations (G33) #93 three live identity defects underneath it
    #45 sidebar Profile group (G31) #94
    #95 notification vocabulary #96 every notification was mapping to .other
    #65 docs/chore #97
    #98 Xcode 27 build break #99
    #84 outbox FIFO ordering #100
    #50 lists authoring #101 three of four items; From Template has no route
    #56 Applications pane #102 five wrong DTO guesses, found by probing

    Also closed: #40, #41, #42 (PR #83's work, verified on dev) and #55 (macOS side complete; #74 is the upstream anchor).

    Filed this pass

    #84 outbox ordering · #85 list schema contract · #91 profile location cannot be cleared · #95 notification vocabulary · #98 Xcode 27 build break · #103 APIError discards structured error bodies · #104 sync-agent config migration.

    Two claims in this epic that the sweep touched

    The re-measure holds and paid off. #61's dashboard option 3 really is unblocked — I re-confirmed GET /api/user/engagement returns 200 under Bearer. The four genuinely session-only routes are also confirmed still session-only: #60's three auth-switching routes reject a valid sync-token, so that one is in the residue rather than an annotation error.

    "Probe before you decode" earned its place again. Four separate silent-decode defects were found and fixed this pass — the list schema (#85), the notification vocabulary (#95), the Mastodon provider token and the app-settings device fields. Every one had green tests written against fabricated fixtures, which is the exact failure mode this epic's standing constraints name. The count in that section should now read seven rather than three.

    A new standing constraint worth adding

    The SDK is a moving target. Xcode 27 added SwiftUI.Document, which collided with InterlinedDomain.Document and broke dev mid-session (#98). Any domain type sharing a name with a SwiftUI symbol is one update away from the same break. Nothing to do pre-emptively — but it belongs next to "probe before you decode" as a thing that bites without warning.

    What remains, by why it is stuck

    The baseline on these branches: Kit 485 · Domain 1022 · Persistence 147 · App 1002, all green on Xcode 27.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    parityWeb-parity gap with the InterlinedList web app

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions