Experimental Bluesky client for agents
perch docs ACCEPTANCE.md
5.4 kB
Markdown
at main

First-delivery acceptance — 2026-09-05 #

The contract in PLAN.md was exercised through the actual CLI, real public and authenticated Bluesky reads, browser-produced PNGs, and focused offline regressions. The repository contains the implementation and tests; credentials, local databases, and generated render files are not committed.

Evidence by contract #

Contract Evidence
B1, B2 Opened all four real post identities in examples.json. The selected 3/4 retained two ancestors and its 4/4 continuation. Source ordering, snapshot-relative timestamps, public/authenticated mode, and independent creation/indexing fields were inspected. Tests cover source order, unavailable nodes, known unhydrated edges, cycles and depth/node/parent bounds.
B3 Actual burger framing, selected-post images, quoted link card, and two separately owned quote images were inspected. Unicode facet tests use UTF-8 byte offsets after emoji; exact text, zero/unknown counts and media ownership are checked. Raw unhydrated quote targets and absent-versus-empty profile descriptions have regressions.
B4, B5 Separate CLI processes opened an author ref, peeked an old ref, navigated/backed/refreshed, and forked a session. Back returned an identical serialized snapshot; refreshing allocated a new view without retargeting the old ref. Invalid navigation preserved position. SQLite tests cover reopening, independent forks, unhydrated edge refs and stale-revision rejection/rollback.
B6 Real HTML/text/JSON/PNG bundles were produced for image-bearing, ancestor-bearing and nested conversations. Liv inspected the PNGs, rejected the initial metadata-heavy surface, and inspected the refined panels. Deep branches stay full-width; verbose record data and alt text use native HTML disclosure. A real browser regression compares the unchanged card's pixels under short and oversized overviews, allowing only small scroll-rounding differences.
B7 One explicit authenticated read used the existing local OMP configuration and PDS. The source named the actual viewer DID and returned mutual-follow information absent from the public view. Credentials were not displayed or copied into the project. No social mutation, server deployment or push was performed.
I1–I4 Source markup is tested as inert text. An actual capture with a local non-CDN image origin made zero requests to that origin and showed a visible failure cue. Renderer input immutability and local navigation semantics are covered. Image requests explicitly reject redirects through maxRedirects: 0; that redirect policy was source-reviewed, not exercised against a live redirecting CDN. Forks are positions, not identity claims.

Reading the conversation, not only its API #

The initial bounded sarcasm view stopped before Anthony's clarification. A deliberate open of its Asura reply reference fetched the next branch and recovered: “my first side was pure sarcasm.” The original reading session stayed unchanged. This checked the intended activity: follow the turn that changes how the earlier sentence reads, while keeping a route back.

The default database now has main on the burger and clarification on that reply branch, with independent positions. From the repository:

bun run perch show
bun run perch show --session clarification
bun run perch render --out .perch/current

Local view bundles already exist in .perch/current/ and .perch/clarification/. Additional specimen and diagnostic captures are retained under .perch/; all are ignored by git. Reference prefixes are local to the selected database.

Independent falsification and repairs #

A read-only reviewer inspected the source and tests, without executing tests or accessing credentials. Three concrete production defects were found, reproduced, and repaired:

  1. A quoted record's raw nested quote target disappeared when optional hydrated embeds were absent or empty. Known typed targets now remain navigable with honest unhydrated placeholders, without fabricated speech or media.
  2. An omitted profile description became an explicitly empty description. Absence now survives the model, normalization and both renderers.
  3. Capturing a tall overview scrolled the browser; viewport-relative card coordinates were then misused as document coordinates, cutting off the reading panel. Coordinates now include the measured scroll offset. The original defect was visible in an actual PNG and is covered by a dynamic pixel comparison.

The reviewer rechecked the changed paths and reported no remaining material findings in this bounded review. An overly specific regression assertion about which node must carry an unhydrated marker was removed; retained relationships and absence of invented content remain asserted.

Final checks #

  • bun test: 27 passed, 0 failed, 290 assertions across five files.
  • bun run typecheck: passed with strict TypeScript checking.
  • Actual public/authenticated CLI reads, independent-process navigation, and PNG production: exercised as described above.

This is not a full Bluesky client. Arbitrary article bodies, video playback, custom pronoun/labeler hydration, feeds/search/notifications, authentication-session caching, MCP/OMP packaging and a Liv-oriented scout definition remain explicit later choices. No complete-thread claim or universal visual-perception benchmark is made.