Skip to content

Native X bookmarks as a collection source #6

Description

@oojBuffalo

Problem

Once #5 lands there is no way to get X/Twitter bookmarks into Scrolls at all. import fieldtheory was the only path, and it worked by reading another application's local store rather than talking to X.

Scrolls should do natively what Field Theory does — pull the user's own X bookmarks directly — and go further, by putting them under the same custody model as everything else: capture proof, drift detection, fidelity tiers, lossless export.

ADR 0009 named this exact follow-up: "Native scrolls sync x --bookmarks remains open as a later, separate decision." IDEAS.md:239 sketched the same command. This is that work.

Scope

Second implementation of the collection on-ramp contract from #2, after Wikipedia (#4) proves the shape.

Deliberately sequenced second, not first: X is the harder auth story and the more volatile API surface, so it should consume a contract that already exists rather than define one under pressure.

Acceptance criteria

  • X declares bookmarks as an enumerable collection per the Collection on-ramp: a fourth ingest path for user-saved collections #2 contract.
  • Authenticating as the user, per the credential posture settled in Collection on-ramp: a fourth ingest path for user-saved collections #2. Verify the current X API bookmarks endpoint, its auth requirements, its rate limits, and any access-tier restrictions against live documentation before building — and if the endpoint is not reachable under a tier the user actually holds, stop and report that rather than shipping something that cannot run.
  • Item ids remain x:<tweetId>, matching what detect.py produces for x.com status URLs — so bookmarks pulled natively dedupe against anything previously added by URL, and against anything imported from Field Theory before Remove the Field Theory dependency; supersede ADR 0009 #5 deleted that path. This identity alignment is the one property from ADR 0009 that must survive its supersession.
  • saved_at from X's own bookmark timestamp, never published_at.
  • Captures at least what the Field Theory import captured, so nothing regresses for an existing library: text, author handle and name, posted-at, media references, expanded links, and quoted-tweet text folded into the extracted body (fieldtheory.py:78-83).
  • Pagination across the full bookmark collection, with the rate-limit posture from Collection on-ramp: a fourth ingest path for user-saved collections #2.
  • Fixture-driven tests covering pagination, dedupe against an existing x: item, quoted-tweet capture, media references, and the no-credentials failure.
  • docs/adapters.md gains an x entry — today there is no x adapter at all, because imported items entered at stage fetched with no fetch path (ADR 0009). Decide and document whether a real x fetch adapter now exists, which also determines whether scrolls verify can detect drift on a bookmarked post.

Verification

uv run pytest -q
uv run scrolls list --source x
uv run scrolls doctor

Depends on #2. Blocked-by relationship to #5 is deliberate and accepted: #5 lands first and leaves a gap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentFully specified and ready for an AFK agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions