perform your own verifications verifier.psingletary.com/verifier
verifier PRODUCT.md
5.9 kB · 107 lines
Markdown

Product #

Platform #

web

Users #

Individual Bluesky users who want to vouch for accounts they trust. They discover the tool during normal browsing, authenticate with their existing Bluesky handle, and use it to attest to the identity of other accounts they know are legitimate.

No secondary audiences confirmed. Admin/org use is explicitly NOT the target.

Product Purpose #

Create and manage app.bsky.graph.verification records — entries written to the user's Personal Data Server (PDS) that attest to the identity of another AT Protocol account. Users can verify single accounts or bulk-verify all members of a Bluesky user list. Previously verified accounts are detected and skipped.

The product also serves as a reference implementation for the app.bsky.graph.verification lexicon, demonstrating how to read, write, and delete verification records using the AT Protocol's standard APIs.

Positioning #

A working tool AND a reference implementation. Unlike scoring/labeler/analytics tools in the AT Protocol ecosystem, this product does one simple thing (verification records) correctly and transparently. Any developer can read the source to understand how verification records work.

Key differentiator: verification records live on the user's PDS — decentralized, not controlled by any central service. No one can revoke a verification you issued.

Operating Context #

Users encounter the tool via shared links or word of mouth. They authenticate with their existing Bluesky handle via OAuth. The primary workflow is:

  1. Land on the verifier page (after login)
  2. Choose Account mode (type a handle) or User List mode (select a list they own)
  3. Submit — the tool checks for existing verification, creates a record if none exists
  4. View and optionally revoke verification records in the "Your Verifications" list

The tool is deployed at two URLs: verifier.psingletary.com (Wisp custom domain) and psingletary.tngl.io/verifier (Tangled sub-path). Both serve the same single-page application.

Capabilities and Constraints #

Capabilities:

  • Bluesky OAuth login (BrowserOAuthClient)
  • Create verification records (single account)
  • Bulk verify user list members with progress indicator
  • Detect and skip already-verified accounts
  • View all issued verifications with dates
  • Revoke individual verification records
  • Typeahead search for Bluesky handles

Constraints:

  • Decentralized: All records live on the user's PDS via com.atproto.repo.createRecord / listRecords / deleteRecord. The tool owns no data.
  • Single CSS file: All styling in one App.css (~300 lines). No CSS framework, no Tailwind, no CSS-in-JS. CSS custom properties for theming.
  • No framework dependencies beyond React: Only react, react-dom, react-router-dom, and @atproto/* packages. No build pipeline beyond react-scripts.
  • Fast loading: ~259 kB JS + 2 kB CSS (gzipped). No external CSS framework, no icon library, no analytics.
  • Dual deployment: Must serve correctly from both root-path (Wisp) and sub-path (Tangled). OAuth client metadata must list both redirect URIs.

Undecided:

  • Whether to add theme selection UI (plan exists in agent/plan_themes.md, not implemented)
  • Whether to support additional AT Protocol lexicons beyond verification
  • Long-term hosting strategy (Wisp vs Tangled vs both)

Brand Commitments #

  • Name: "Verifier" (derived from the tool's function, not a brand)
  • No logo beyond text
  • No brand colors — uses witchsky.app's cyan base palette (hsl(174, 83%, 38%) primary)
  • No marketing copy, no tagline beyond the functional README
  • Domain: verifier.psingletary.com (primary), psingletary.tngl.io/verifier (secondary)

Evidence on Hand #

Codebase: React 18 SPA with 9 source files:

  • src/App.jsx, src/App.css — main layout and all styles
  • src/contexts/AuthContext.js — OAuth client initialization and session management
  • src/contexts/ThemeContext.js — dark mode toggle (UI not exposed)
  • src/components/Verifier/Verifier.js — main verification logic (orchestration)
  • src/components/Verifier/VerifierForm.jsx — mode selector, input, submit
  • src/components/Verifier/VerifierSuggestions.jsx — typeahead dropdown
  • src/components/Navbar/Navbar.jsx — header with logo and login/logout
  • src/components/Login/Login.js, LoginCallback.js — OAuth flow
  • src/components/Home/Home.js — landing page with "Go to Verifier" CTA
  • src/components/Footer/Footer.js — copyright footer
  • src/components/ProtectedRoute.jsx — auth guard

Deployed: Live at verifier.psingletary.com (verified 2026-08-01).

No: testimonials, case studies, press coverage, analytics data, user research, accessibility audits.

Product Principles #

  1. Decentralized by default. Every record lives on the user's PDS. The tool owns no data, has no backend, requires no server.

  2. Do one thing well. Verification records only. Reject scope creep into scoring, labeling, analytics, or community management.

  3. Transparent reference. Source is readable, documented, and serves as the canonical example of app.bsky.graph.verification usage.

  4. Minimal dependencies. No CSS frameworks, no icon libraries, no analytics, no build pipeline beyond react-scripts. Every dependency must justify itself.

  5. Accessible by default. 48px touch targets, 18px base font, WCAG-informed color contrast. Accessibility is not a separate feature.

Accessibility & Inclusion #

  • 48px minimum touch targets (Material Design standard)
  • 18px base font size
  • Dark theme default with CSS custom property-based color system
  • Semantic HTML (header, footer, nav, main, form, ul/li)
  • aria-hidden="true" on decorative elements (removed with AnimatedBackground)
  • Color contrast designed against witchsky.app's cyan palette (not formally audited)