All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- OAuth permission sets now grant the rpc lexicons backing ORCID verification, admin endpoints, claiming flows, and profile-config writes. Production had been silently rejecting every
getServiceAuthTokencall since 0.6.0 droppedtransition:genericwithout enumerating the rpc grants the corresponding lxm need. Closes #85. - Resolved the audience-format contradiction between
@atproto/oauth-scopes(whoseisAtprotoAudiencevalidator requires<did>#fragment) andcom.atproto.server.getServiceAuth(whose lexicon rejects anaudcontaining a fragment) by settingaud: "*"on the rpc permissions inside the fourpub.chive.{basicReader,authorAccess,reviewerAccess,fullAccess}permission-set lexicons. Frontend now requestsgetServiceAuthwith the plain DID and matches the wildcard rpc grant at the PDS. - Retry
com.atproto.server.getServiceAuthonce when the user's PDS responds withuse_dpop_nonce. The OAuth client's auto-retry occasionally leaks the nonce-mismatch error through to caller code on the first request against a previously-unseen origin; the explicit retry consumes the freshly-issuedDPoP-Nonceheader on the second attempt.
- Bumped
@atproto/oauth-client-browserfrom 0.3.37 to 0.3.42 to pick up DPoP-handling fixes from@atproto/oauth-client0.5.12–0.6.1. - Production now emits
include:pub.chive.*permission-set references instead of individualrepo:pub.chive.*scopes (NEXT_PUBLIC_USE_PERMISSION_SETS=true). The consent screen shows one named entry per Chive permission set rather than one row per collection.
- Hybrid OAuth scope layout: client metadata now emits
include:scopes for cooperating apps that publish a covering permission-set lexicon (Margin'sat.margin.authFull, Standard.site'ssite.standard.authFull, Semble'snetwork.cosmik.authFull), and falls back to individualrepo:scopes only for gaps Semble's authFull omits (network.cosmik.connection,network.cosmik.follow) and for Bluesky (which publishes no covering set). Collapses the consent screen from a wall of opaque collection names to one named entry per cooperating app, each with publisher-authored title and detail copy.
- Renamed Chive's permission-set lexicons from
pub.chive.auth.{basicReader,authorAccess,reviewerAccess,fullAccess}topub.chive.{basicReader,authorAccess,reviewerAccess,fullAccess}. ATProto'sIncludeScope.isAllowedPermissiononly honorslxm/collectionreferences that share the permission set's group prefix (everything up to its last dot). The four-segment names had a group prefix ofpub.chive.auth.and silently dropped every referenced collection; the three-segment names authorize the fullpub.chive.*namespace, matching Bluesky'schat.bsky.authFullChatClientprecedent. Permission set records now live inlexicons/permission-sets/(excluded from@atproto/lex-clicodegen, which can't generate types forpermission-setdefinitions). - Conformed Chive's Margin dual-write to Margin's actual published lexicons: a single
at.margin.notecollection (W3C Web Annotation Data Model) with themotivationfield distinguishing comment, highlight, and bookmark. Replaces the Chive-fictionalat.margin.annotationandat.margin.bookmarkcollections that Margin's AppView never indexed.MarginAnnotationsPlugin,MarginHighlightsPlugin, andMarginBookmarksPluginconsolidated into a singleMarginNotesPlugin. Therecord-creator.tsMarginAnnotation*types/functions renamed toMarginNote*;createMarginBookmark/deleteMarginBookmarkcollapse to thin wrappers that forward to the note machinery withmotivation: 'bookmarking'. - Lead permission-set detail strings with eprints (the primary Chive use case) instead of knowledge-graph governance.
- Owner-private collection reads in the dashboard hooks (
useMyCollections,useCollection,useCollectionsContaining,useSubcollections,useParentCollection,useCollectionFeed) now use the authenticated client. The owner-side visibility filter onpub.chive.collection.listByOwnerand friends gatesunlistedcollections to the authenticated owner; the unauthenticated client masked the viewer as anonymous and hid their own collections after reload. pub.chive.collaboration.listInvitesnow requires authentication and rejects queries that aren't scoped to the caller (invitee = me,inviter = me, orsubjectUriauthored by me). Closes an enumeration gap.
- "Created a new community/collection but it disappears on reload" (#79) for users who picked the
unlistedvisibility option in the wizard.
NEXT_PUBLIC_USE_PERMISSION_SETSbuild-time env var. When set, both client metadata and the OAuth login request emitinclude:pub.chive.auth.*permission-set references instead of individualrepo:pub.chive.*scopes. Staging ships with the flag on so we can validate the permission-set flow against the now-live_lexicon.<sub>.chive.pubDNS TXT records.
- Handle resolution falls back to the public Bluesky AppView's
com.atproto.identity.resolveHandleXRPC when DNS-over-HTTPS returns no record. Direct browser fetches ofhttps://<handle>/.well-known/atproto-didare blocked by CORS in nearly every case (most identity-publishing servers don't setAccess-Control-Allow-Origin); the AppView runs both ATProto resolution methods server-side and serves a permissive CORS policy. Unblocks Eurosky users (luismmontilla.comand similar) who publish identity only via the HTTPS path. - OAuth client metadata
logo_urinow points at/chive-logo.svg(was pointing at/logo.pngwhich 404'd), so the consent screen header renders the Chive logo instead of a generic placeholder.
- "Failed to resolve identity: " sign-in error for users whose handle is published only via
.well-known/atproto-didrather than a DNS TXT record.
- Individual
repo:pub.chive.*scopes for all 22 Chive collections (eprint, actor, review, annotation, graph, discovery, collaboration namespaces) - External cross-post scopes for
app.bsky.*,network.cosmik.*,at.margin.*, andsite.standard.*collections - Permission-set lexicon schemas at
pub.chive.auth.{basicReader,authorAccess,reviewerAccess,fullAccess}(served but not yet requested in the OAuth flow) did:web:chive.pubDID document at/.well-known/did.json, host-aware for staging vs production- Minimal
com.atproto.repo.*XRPC surface (getRecord,listRecords,describeRepo) that serves Chive's 219 lexicon JSON files ascom.atproto.lexicon.schemarecords with real DAG-CBOR CIDs, enabling NSID resolution for any ATProto service
pub.chive.collaboration.inviteandpub.chive.collaboration.inviteAcceptancelexiconsCollaborationServicewith full invite/acceptance lifecycle- Firehose indexing and XRPC endpoints for collaboration records
- Collaboration invite flow in the submission wizard
- Invitations inbox page for pending invites
DidAutocompleteInputcomponent for collaborator selection (replaces raw DID text input)
- Knowledge-graph-based Cosmik connection-type mapping
- Firehose plugin bridge for cross-AppView sync
syncEdgeToCosmikwired through all edge paths- Repair-mirror UI for fixing out-of-sync edges
- Enriched Cosmik card metadata (DOI, author, description, publishedDate, externalIds)
- Semble badge on relation-type autocomplete suggestions
pub.chive.*lexicons and XRPC handlers for follow count, follow status, and Margin annotations
- Canonical external-ID routes (
/doi/<id>,/arxiv/<id>,/orcid/<id>,/ror/<id>,/isbn/<id>,/pmid/<id>,/wikidata/<id>) - Zotero/Citoid-compatible server metadata endpoint
- OAuth client metadata no longer declares
transition:generic— the legacy scope short-circuited granular permissions and caused consent screens to display "any public record" instead of Chive's specific collections - OAuth login requests use individual
repo:scopes instead ofinclude:pub.chive.auth.fullAccessreferences, because bsky.social cannot resolve permission-set lexicons until the DNS TXT records at_lexicon.<sub>.chive.pubare live - User profile is now fetched from the public Bluesky AppView (
public.api.bsky.app) rather than through the authenticated session, so avatars and handles resolve correctly under granular scopes (session-boundagent.getProfile()returns 403 without an explicitrpc:app.bsky.actor.getProfilegrant) - Container log rotation enabled across all services (JSON logs capped at 150 MB per container) to prevent unbounded disk growth
- Cosmik dual-write edges now emit HTTP URLs and resolve connection types through the AppView
- Wikidata URLs for properties use the
Property:prefix - Collaborators column migration no longer trips on dollar-quoting
- Plugin DI dependencies registered in the indexer entry point so the plugin manager can resolve
ILogger - Deploy App workflow no longer wipes
chive-docsafter a concurrent Deploy Docs (new step restores the container fromdocker-compose.docs.ymlif a build exists) - React hook placement and
useCurrentUserdestructuring errors - Compliance test expected index/table counts updated for new collaboration tables
- Granular OAuth scopes limit Chive to writing only to its declared
pub.chive.*collections plus the explicit external cross-post targets, instead of the blanket write access granted bytransition:generic
- Docs deploy workflow missing
environment: productionfor secret access - Rate limits too low for SPA usage patterns (Traefik raised to 2000 avg / 500 burst, backend authenticated raised to 1200 req/min)
- Public landing page with inline ATProto login and open alpha notice
- Bug report button in site header and mobile nav with pre-filled GitHub issue URL
- Open alpha banner for authenticated users (dismissable, localStorage-persisted)
- Onboarding prompt banner for new users to link academic accounts (auto-dismisses when ORCID is linked)
- Permanent redirects from
/applyand/pendingto/
pub.chive.moderation.createReportXRPC endpoint for user-submitted content reportscontent_reportsdatabase table with migrationContentReportServicewith atomic upsert, pagination, and admin review methods- Report dialog on eprint detail pages with reason categories and description (2000 char limit)
- Lexicon schema for moderation createReport
- ORCID OAuth 2.0 authorization code flow for verifying researcher identity
pub.chive.author.initiateOrcidVerificationXRPC endpoint generating state and returning ORCID authorize URL/api/v1/auth/orcid/callbackREST handler for token exchangeorcid_verified_atcolumn onauthors_indexfor tracking verification statusorcidVerifiedboolean field inpub.chive.author.getProfileresponse- "Sign in with ORCID" button in onboarding wizard (replaces "Coming soon" placeholder)
- "Verify with ORCID" button in profile settings form
- Verified badge (ShieldCheck icon) on
OrcidBadgecomponent for OAuth-verified ORCIDs - Popup-based OAuth flow with localStorage event fallback for cross-origin communication
- Writes verified ORCID to user's PDS profile record after OAuth completion
- Graceful fallback to "Coming soon" when ORCID OAuth credentials are not configured
- ORCID credentials wired into staging and production deploy workflows
- All user-facing Bluesky references replaced with ATProto in login form, login dialog, and handle input
- Landing page restored to inline login style with ATProto handle input
- ConditionalHeader only hides on
/login(was also hiding/,/apply,/pending) - OAuth callback redirects to
/dashboarddirectly instead of/
- Alpha gate (
AlphaGatecomponent) removed from all 16 layout/page files - Alpha application system: frontend components, hooks, pages, admin pages, scripts, E2E tests
- Alpha XRPC handlers (
pub.chive.alpha.apply,pub.chive.alpha.checkStatus) - Alpha admin handlers and lexicon schemas
AlphaApplicationServiceandrequireAlphaTestermiddleware- Alpha type re-exports from
web/lib/api/schema.ts
- Open redirect vulnerability in login page redirect parameter
- localStorage SSR safety guards in banner components
- Stale alpha references in admin nav, coming-soon page, and OAuth callback
- Login redirect parameter validated to prevent open redirects (blocks
//evil.comandhttps://...) - AT-URI and NSID format validation on content report submissions
- Description length limit (2000 chars) enforced on frontend and backend for content reports
- ORCID client secret kept server-side only; state parameter is crypto-random, single-use, Redis-backed with TTL
0.4.0 - 2026-03-11
- ATProto-standard
revisionfield on all lexicon files andschemaRevisionon record-type lexicons - Central
lexicons/manifest.jsonregistry tracking revision, project version, and change date for every lexicon lexicons/VERSIONING.mddocumenting the versioning strategy, changelog, and migration table
- Backend migration service (
src/services/migration/) that transforms old-format PDS records at index time - Migration 0001: convert abstract string to rich text array, add titleRich for LaTeX titles, add license URI from slug mapping (submission rev 1 to 2)
- Migration 0002: replace flat
departmentfield on affiliations with recursivechildrentree (submission rev 2 to 3, profile rev 1 to 2) - Migration chaining so records at any prior revision are brought up to current in a single pass
- Replace flat
departmentfield with recursive tree structure (childrenarray) supporting arbitrary institutional hierarchies (university, school, department, lab, etc.) - Define canonical
pub.chive.defs#affiliationshared type withname,institutionUri,rorId, andchildren - All lexicons now reference the shared affiliation type via cross-lexicon ref instead of local definitions
- Each level in the affiliation tree can independently link to a knowledge graph node via
institutionUri - Eprint cards display only the top-level institution name; full hierarchy shown in author detail views
- Alpha dashboard returning 500 because
affiliationsandresearchKeywordslexicon schemas defined items as strings but actual data contains objects
institutionUridropped from affiliations in eprint card, edit sections, submission wizard Zod schemas, and sub-unit editing- Profile record creator missing
institutionUriandchildrenfields, silently stripping tree structure on profile save - Eprint submission Zod schema missing
institutionUri, stripping institution graph links on submit
0.3.1 - 2026-03-10
- Eprint card abstracts not rendering when API returns plain text string instead of rich text array (eprints page, field pages)
- Browse page missing author avatars because
browseFacetedhandler did not fetch profiles from Bluesky API
0.3.0 - 2026-03-10
- Personalized authors page showing authors the user follows or has interacted with
- Mute author feature allowing users to hide papers from specific authors in feeds and discovery
pub.chive.actor.mutelexicon record type for storing mute preferences in user PDSes
- Configurable discovery weight settings allowing users to tune recommendation signal strengths (field affinity, citation overlap, recency, collaborative filtering)
- XRPC array parameter parsing for multi-value query parameters
- GHCR image registry for CI-built Docker images, eliminating on-server builds during staging deploys
- Staging docs container added to CI/CD pipeline
- Consolidated rich text
$typereferences to usepub.chive.richtext.defsnamespace across all tests, lexicons, and frontend code - Replaced
EprintsByAuthorResponsewithListByAuthorResponsefrom generated types inuse-eprint.ts - Replaced
EprintChangelogsResponsewithListChangelogsOutputfrom generated types inuse-eprint-mutations.ts - Replaced manual
Backlink,BacklinkCounts, andListBacklinksResponsewith generated types inuse-backlinks.ts - Added backlink and changelog type re-exports to
schema.tsfrom generated lexicon types - Replaced
EdgesResponseinuse-edges.tswith generatedOutputSchemafrompub.chive.graph.listEdges - Replaced
AuthorEprintsResponseinuse-author.tswithListByAuthorResponsefrom generated types - Derived
ProposalStatusandProposalTypefrom generatedProposalViewinstead of manual string unions - Derived
VoteActionfrom generatedVoteView['vote']instead of manual string union - Derived
AlphaSectorandAlphaCareerStagefrom generatedalpha/applyInputSchemainstead of manual string unions
- Comprehensive mobile responsiveness overhaul across the entire frontend
- Dashboard, admin, and governance sidebars collapse into Sheet drawers on mobile instead of stacking above content
- Mobile hamburger menu now includes dashboard navigation items for authenticated users
- Mobile search access via dedicated search icon button that opens a top Sheet
- Admin tables wrapped in horizontal scroll containers to prevent page overflow on narrow screens
- Grid layouts use progressive responsive breakpoints (
sm:grid-cols-2 md:grid-cols-3) instead of jumping directly to multi-column - Tab lists hide scrollbars for cleaner horizontal scrolling on mobile
- Popover widths constrained to viewport with
max-w-[calc(100vw-2rem)] - PDF viewer minimum height reduced on mobile (
min-h-[400px] md:min-h-[600px]) - New
useIsMobilehook and shadcn Sheet component for consistent mobile patterns
- Replace redundant annotation hook types (
AnnotationView,EntityLinkView,ListAnnotationsResponse,AnnotationThread) with generated lexicon types frompub.chive.annotation - Replace
ListUserEndorsementsResponsewith generatedOutputSchemafrompub.chive.endorsement.listForUser - Derive
AnnotationMotivationfrom generatedAnnotationView['motivation']instead of manual string union - Derive
ContributionTypefrom generatedEndorsementView['contributions'][number]instead of manual string union
- Related papers scoring: lowered combined score threshold from 0.2 to 0.05, reduced ES MLT discount from 0.6 to 0.85, and added author overlap to default signals
- Removed For You feed in favor of configurable discovery weights
- Enabled server-side XRPC output validation (
validateOutput: true) to catch schema mismatches at the source before responses reach clients
getHierarchyhandler missing defaultrelationSlugvalue, causing 500 when output validation is enabled- Authors page only showing search box instead of author grid due to incorrect conditional rendering
- Eprint integration tests failing due to stale PostgreSQL data from prior runs; added
beforeEachcleanup
- Field name mismatches between admin API responses and frontend expectations
- Role name references corrected from
moderatortoadminacross admin endpoints - Silent auth failures in admin routes now surface proper error messages
- Paper PDS auth wired through all edit and delete flows, fixing unauthorized errors when modifying papers
- Unified auth error messages across all endpoints for consistent error handling
- Removed broken "View all related papers" link pointing to nonexistent page
- Flaky mention-popover arrow key navigation test stabilized by replacing
fireEvent.keyDownwithuserEvent.keyboard
- Staging deploy workflow now builds web frontend image in CI and pins both API and web images to the exact commit SHA, preventing frontend-backend version skew
- Production deploy fixed to build web image with
docker buildinstead of silent no-opdocker compose build(compose file had nobuild:section for chive-web) - Split Docker build and push steps to fix GHCR authentication failure
- Test expectations updated to match unified auth error messages
- Discovery test expectations updated for new default weights and weight normalization
0.2.0 - 2026-03-06
- Admin dashboard with 15 pages: overview, health, alpha access, users, content, firehose, backfill, PDS, graph, metrics, search analytics, activity, endpoints, runtime, and governance
- AdminService for aggregating system health, content statistics, and user management operations
- BackfillManager for triggering and monitoring PDS record backfills from the admin UI
- XRPC handlers for all admin dashboard endpoints across health, content, users, firehose, PDS, graph, metrics, search, activity, and governance
- Frontend admin auth guard component that restricts dashboard access to users with admin roles
- Role-based access hooks (
useMyRoles,useIsAdmin) and admin dashboard query hooks - Admin role seeding from
ADMIN_DIDSenvironment variable on server startup pub.chive.actor.getMyRolesXRPC endpoint for querying the authenticated user's roles- Direct alpha access grant dialog on the admin alpha management page
- Lexicon schemas for admin and actor role endpoints
- Permission set lexicon schemas (
basicReader,authorAccess,reviewerAccess,fullAccess) following the ATProtopermission-setLexicon type - Hierarchical permission model: basicReader (read-only RPC) < authorAccess (eprint/profile writes + claiming + blobs) < reviewerAccess (reviews + annotations) < fullAccess (graph governance + proposals)
- Scope constants for all 19
pub.chive.*repo collections, 6 external namespace collections (Bluesky, Standard, Cosmik), and 5 blob MIME type wildcards buildScopeStringutility for constructing space-separated OAuth scope strings with automaticatprotoprefix and deduplication- Intent-based login flow with
AuthIntenttype (browse,submit,review,full) that requests only the scopes needed for each activity - Frontend
getScopesForIntentandhasScopeutilities withtransition:genericbackward compatibility CLIENT_METADATA_SCOPEconstant combining full access permission set with all external namespace scopes- OAuth client metadata updated to declare granular scopes alongside
transition:genericfor backward compatibility with PDSes that don't support granular scopes
- Docker smoke tests and staging deployment workflow with environment branch strategy
NEXT_PUBLIC_CHIVE_SERVICE_DIDbuild arg for per-environment service DID configuration
- Prometheus metric groups for jobs, workers, auth, search, blob proxy, dead letter queue, admin, and backfill operations
- OpenTelemetry span instrumentation for auth verification, background jobs, worker processing, and blob proxy requests
- Faro error boundary around eprint detail page for rendering crash diagnostics with trace ID references
- Field label resolution job and indexer retry for unresolved UUID field labels
makeJobIdutility for sanitizing AT URIs into valid BullMQ job identifiers
- Admin dashboard documentation covering API endpoints, backfill operations, observability metrics, architecture, and role management
- OAuth scopes documentation covering permission set definitions, intent-based login, and backward compatibility
- Documentation suite overhaul with formatting improvements, accuracy corrections, and staging deploy workflow
- Unit tests for AdminService, BackfillManager, admin XRPC handlers, admin seed script, and observability Prometheus instrumentation
- Frontend unit tests for admin hooks, admin auth guard, and role hooks
- Backend and frontend unit tests for OAuth scope constants, permission sets,
buildScopeString,getScopesForIntent, andhasScope
- Collection visibility renamed from
public/privatetolisted/unlistedacross lexicon, backend, frontend, and tests to reflect ATProto semantics (visibility controls AppView listing, not data access) - PostgreSQL migration to rename existing visibility column values with backward-compatible normalization for old values
- GitHub Actions CI workflows updated with
ADMIN_DIDSenvironment variable, admin health check endpoints, and expanded Prometheus metrics collection targets - Documentation accuracy: removed non-existent content moderation features, corrected role names, fixed contact emails, replaced Semble references with Cosmik
- OAuth scope requests fall back to
transition:genericuntil PDSes support granular permission sets - Grafana Alloy Faro log pipeline switched from JSON stage to regex stages for Faro's key=value log format
- React 19 + Radix UI infinite loop crash (error #185) when selecting endorsement types by replacing Radix Checkbox with native HTML input
- BullMQ job ID validation errors caused by colons in AT URIs by sanitizing job IDs in enrichment, freshness, and index-retry workers
- AlphaGate redirecting approved users to login on transient auth refetch failures
- Null reference crashes on eprint detail page from missing
abstract, endorser display names, or contribution arrays - ~90 incorrect Wikidata Q-IDs across governance seed data
- Invalid lexicon schemas for citation record and listCitations query
- Permission set scopes to cover all frontend writes including external namespaces and blob types
- Docker smoke test to use
/readyendpoint instead of nonexistent/xrpc/_health - Backend
SERVICE_DIDenvironment variable name to match deploy configuration - Reindex script to use MERGE instead of CREATE to handle Neo4j uniqueness constraints
- Staging deploy to pull from
origin/staginginstead oforigin/main - Admin role reference from
moderatortoadminin getPendingClaims endpoint - Alpha applications table sync when granting access via admin role assignment
- Permission-set lexicons excluded from codegen to prevent build errors
- Neo4j Cypher syntax error in recommendation queries that prevented related papers from loading (moved
UNION ALLinsideCALL {}blocks for Neo4j 5.x compatibility)
0.1.0 - 2026-03-03
Initial release of Chive, a decentralized eprint service built on AT Protocol.
- ATProto-native AppView that indexes scholarly records from the relay firehose without writing to user PDSes
- Hono-based API framework serving both XRPC and REST endpoints (~130 XRPC endpoints across 19 service areas)
- Modular service architecture with all services behind abstract
I*interfaces for dependency injection - Multi-database storage layer: PostgreSQL (metadata indexes), Elasticsearch (full-text search), Neo4j (knowledge graph), Redis (caching and rate limiting)
- All database tables use
_indexsuffix and track PDS source URLs for staleness detection and rebuild-from-firehose capability - Plugin system with hybrid TSyringe (DI) and EventEmitter2 (hooks) architecture, isolated-vm sandboxing, and declared permissions
- Background worker system with enrichment, freshness, and index-retry workers
- Scheduled jobs for citation extraction, field promotion, governance sync, graph algorithms, PDS scanning, and tag sync
- OAuth-based authentication with DID resolution, session management, and ATProto identity verification
- Rate limiting with configurable fail-open/fail-closed behavior when Redis is unavailable
- Firehose consumer with WebSocket connection to ATProto relay, filtering for all
pub.chive.*collections - Support for both full firehose events (CAR/CBOR parsing) and Jetstream events (pre-decoded JSON)
- Cursor management with batched persistence to PostgreSQL for resumption after restarts
- Dead letter queue for failed events with error classification (transient, permanent, rate limit) and exponential backoff retry
- Backpressure handling to prevent memory exhaustion when queue depth exceeds threshold
- Reconnection manager with exponential backoff and jitter for network failure recovery
- PDS Discovery system with three discovery sources: PLC directory enumeration, relay listHosts queries, and DID mention extraction
- PDS Scanner that backfills records from all 19
pub.chive.*collections on discovered PDSes - PDS registry with scan priority scheduling (24h for active, 7d for inactive) and consecutive failure tracking
- User-facing
pub.chive.sync.registerPDSendpoint for self-hosted PDS registration - Graceful shutdown with queue draining and cursor flushing
- 164 lexicon JSON schemas across 21 namespaces under the
pub.chive.*namespace - Record types for eprints (
submission,version,changelog,tag,userTag,citation,relatedWork) - Record types for reviews (
comment,endorsement,entityLink) - Record types for annotations (
comment,entityLink) - Record types for the knowledge graph (
node,edge,nodeProposal,edgeProposal,vote) - Record types for actor profiles (
profile,profileConfig) - Query and procedure schemas for collections, discovery, governance, claiming, metrics, activity, tags, backlinks, sync, notifications, and import
- Lexicon code generation pipeline producing TypeScript types and runtime
isRecordtype guards - Rich text facet definitions for cross-references
- Eprint submission with structured metadata: title, abstract, keywords, authors with affiliations and contribution types, publication tracking
- Eprint versioning with version number tracking, previous version references, and change descriptions
- Eprint changelog tracking for edit history
- LaTeX-to-Unicode abstract migration with
needsAbstractMigrationschema hint detection - License metadata with URI-based license identification
- PDF blob reference storage (CID pointers only, never blob data) with on-demand PDS fetching
- Eprint soft deletion support
- OG image generation for social media sharing
- Full-text search powered by Elasticsearch with KStem stemmer,
bool_prefixqueries, and field-specific boosting - Faceted search filtering by field, author, date range, keywords, and publication status
- Search autocomplete with search-as-you-type suggestions
- Personalized discovery dashboard with multi-signal scoring (field affinity, citation overlap, recency, collaborative filtering)
- "For You" feed with personalized paper recommendations
- Similar papers with "More Like This" fallback when primary signals are insufficient
- Field-filtered trending eprints
- Citation-based paper discovery
- Dismiss flow for unwanted suggestions with
recordInteractiontracking - Elasticsearch index lifecycle management policies, ingest pipelines, and index templates
- Community-governed taxonomy using SKOS/FAST faceted classification stored in Neo4j
- Node types: fields, methods, datasets, tools, platforms, licenses, and custom personal nodes
- Edge types with semantic relation labels (broader, narrower, related, applied-to, uses, etc.)
- Bidirectional edge support with configurable directionality
- Graph hierarchy browsing with faceted navigation
- Subgraph expansion for exploring node neighborhoods
- Community detection, PageRank, and centrality graph algorithms
- Wikidata integration via SPARQL for external identifier enrichment
- Node autocomplete with search-as-you-type across all node types
- Node proposals and community voting for Wikipedia-style moderation
- Governance PDS (
did:plc:chive-governance) for storing community-approved authority records as ATProto-native portable data - Governance sync job for periodic authority record synchronization
- Trusted editor elevation requests with approval/rejection workflow
- Role delegation system for governance authority distribution
- User-owned collections stored as personal graph nodes in user PDSes
- Collection wizard with multi-step creation flow (basics, items, edges, structure, cosmik integration, review)
- Subcollection nesting with
SUBCOLLECTION_OFedges and automatic parent propagation on add - Add-to-collection buttons on eprint, review, endorsement, and graph node cards throughout the UI
- Inter-item edge editing for creating relationships between items within a collection
- Collection activity feeds tracking changes to watched items
- Collection search, public listing, and owner listing
- Hierarchical collection dashboard with depth-based indentation and expand/collapse
- Direct-only vs all-items view toggle for subcollection content
- Delete propagation from subcollections to parent collections
- Drag-and-drop item reordering
- Cosmik dual-write integration for cross-platform collection mirroring
- Nine XRPC endpoints for collection management
- Inline review comments with threaded discussion support
- Formal endorsement records with contribution type classification (methodology, results, novelty, clarity, significance, overall)
- Endorsement summary aggregation per eprint
- Entity linking from review text spans to knowledge graph nodes
- Review listing by eprint and by author
- Thread context retrieval for navigating discussion hierarchies
- Notifications for new reviews and endorsements on authored papers
- Inline text annotations on eprint PDFs using W3C Web Annotation data model
- Text selection anchoring with highlight persistence
- Entity link annotations connecting selected text spans to knowledge graph entities
- Annotation sidebar with navigation and deletion
- Dedicated annotation lexicon schemas separated from review system
- Annotation listing by eprint, by page, and by author
- Citation extraction pipeline with GROBID integration for parsing reference sections from PDFs
- Extracted citation indexing in PostgreSQL with eprint cross-referencing
- User-curated related works linking between eprints
- Related papers panel with unified display of extracted citations and curated links
- Citation-based discovery signals feeding into recommendation engine
- Actor profile records with display name, bio, ORCID identifier, and institutional affiliations
- Profile configuration with customizable display sections
- Featured collection display on author profile pages
- Author claiming workflow with coauthor verification for papers imported from external sources
- Coauthorship request and approval/rejection flow
- Autocomplete for ORCID, affiliations, keywords, and OpenReview profiles
- External paper claiming from arXiv, OpenReview, and other integrated sources
- Claimable paper suggestions with dismiss capability
- Author-assigned tags on eprint submission
- User-contributed tags (folksonomy) with quality scoring
- Tag trending with time-decay algorithms
- Tag search and autocomplete
- Tag detail pages showing tagged eprints
- Tag suggestions based on eprint content
- Tag sync job for periodic data consistency
- Cross-platform backlink aggregation from Bluesky, Cosmik, Whitewind, and Leaflet
- Backlink creation and deletion endpoints
- Backlink count aggregation per eprint
- Cosmik backlink source type support
- View, download, and dwell time recording for eprints
- Search click and search download tracking
- Trending calculation based on engagement metrics
- Activity feed logging with correlation metrics
- Failed activity tracking for monitoring
- arXiv plugin with paper search and metadata retrieval
- OpenReview plugin for conference paper search
- PsyArXiv plugin for psychology preprint search via OSF API
- LingBuzz plugin for linguistics preprint scraping with respectful rate limiting
- Semantics Archive plugin for semantic web publication scraping
- Plugin import scheduling with configurable intervals and run-on-start support
- Bluesky, Cosmik, Whitewind, and Leaflet backlink plugins
- Plugin framework with lifecycle management, hook system, and sandboxed execution
- Next.js 15 application with React 19 and App Router
- 68 page routes covering search, eprints, authors, collections, governance, dashboard, submission, discovery, and authentication
- 350+ React components organized by domain
- TanStack Query data fetching with optimistic updates and cache management
- TipTap rich text editor with cross-reference
[[autocomplete for knowledge graph entities - PDF viewer with text selection, highlight anchoring, and annotation overlay
- Responsive design with mobile-friendly tab scrolling
- Radix UI component library with Tailwind CSS styling
- Grafana Faro frontend observability with configurable trace and session sampling
- OpenTelemetry instrumentation for distributed tracing across all services
- Grafana Alloy agent for receiving frontend Faro and backend OTLP telemetry
- Tempo for distributed trace storage and querying
- Loki for centralized log aggregation
- Prometheus metrics collection with custom Chive metrics (indexing events, queue depth, lag, PDS scan durations)
- Grafana dashboards for visualization
- Structured JSON logging with configurable log levels
- Health check endpoints (
/health,/readiness) with detailed service status
- Multi-stage Docker build with separate
productionanddevelopmenttargets - Docker Compose configurations for production, local development, observability, and documentation
- Traefik reverse proxy with automatic Let's Encrypt SSL certificate management
- Governance PDS container running Bluesky PDS image for authority record storage
- GROBID container for PDF citation extraction with tuned memory limits and health check timing
- Kubernetes manifests with Helm charts, horizontal pod autoscaling, pod disruption budgets, and RBAC
- CI pipeline with 7 jobs: unit tests, type checking, lint and format, ATProto compliance, integration tests, build, and deploy
- Automated deployment via GitHub Actions with environment file generation, Docker image building, and post-deploy verification
- Build cache cleanup to prevent disk space accumulation from
--no-cacheDocker builds - Separate indexer process for resource isolation from the API server
- Docusaurus documentation site with auto-generated interactive API docs from OpenAPI specification
- User guide covering searching, submitting eprints, editing, peer review, endorsements, profiles, authorship claiming, tags, collections, discovery, and Bluesky sharing
- Developer guide covering API layer, authentication, core services, lexicon validation, frontend architecture, rich text, eprint lifecycle, and observability
- Service documentation for indexing, collections, discovery, claiming, and PDS discovery
- Plugin documentation with creation guide and built-in plugin reference
- Storage documentation for PostgreSQL, Elasticsearch, Neo4j, and Redis
- Architecture overview, concepts (AT Protocol, knowledge graph, data sovereignty), governance, operations, and reference documentation
- ATProto compliance test suite with 100% pass rate requirement validating data sovereignty principles
- End-to-end test suite with 42 Playwright test files covering all major user workflows
- Integration test suite with 32 test files covering API endpoints, services, and storage layers
- Unit test suite with 134 test files covering handlers, services, storage adapters, plugins, and utilities
- Test infrastructure with Docker test stack, seed data scripts, and cleanup utilities