scholarr/AGENTS.md

4.8 KiB

Scholarr agent brief

For sprint work, read SPRINT.md before changing the repository. It is the single product, decision, provider-safety, and execution reference.

Product

Scholarr is a public, self-hosted FOSS author watchlist and publication tracker. A user follows authors, learns when they publish, and finds legal open-access PDFs. It must serve a real multi-user household deployment while remaining straightforward for the wider self-hosting community.

Immutable doctrine

There is zero Google Scholar network contact, ever.

  • No application code, test, tool, CI job, or documentation example may request a Google endpoint.
  • No scraping, browser automation, CAPTCHA handling, anti-bot behavior, or evasion machinery.
  • Scholar IDs and URLs may exist only as inert imported metadata and human-clickable links.
  • Acquisition uses documented APIs: OpenAlex, Crossref, arXiv, Unpaywall, and ORCID.
  • Semantic Scholar is not a v1 requirement.
  • Provider clients must use a contact identity, conservative persisted rate limits, restart-safe cooldowns, and user-visible health. OpenAlex must stay at or below 2 requests per second.

This doctrine outranks convenience and implementation shortcuts.

Locked architecture

  • Backend: Go.
  • Frontend: Vue.
  • Database: SQLite only. Design for single-writer discipline from the start.
  • Root author entity: FollowedAuthor, with one or more AuthorSourceIdentity records.
  • Names are labels, never identity keys. External source IDs anchor identity.
  • Publications are globally deduplicated. Follows and read state are per user.
  • Auth v1 includes internal username/password, generic OIDC, and trusted-header/forward-auth.
  • The service is config-driven. One declarative config controls providers and behavior.
  • GitHub justinzeus/scholarr is the intended public primary. Forgejo keeps a copy.

Do not silently change a locked decision. Record a proposed change as open and ask the owner.

Decision record

SPRINT.md governs an explicitly owner-approved sprint. The historical charter and identity/calibration/testing records live in runbooks/rewrite/.

Track acceptance and next actions in Forgejo. Record sprint implementation decisions in SPRINT.md; do not add another plan or a separate freeze queue.

Frozen UI contract

  • design/DESIGN.md is the frozen Vue handoff contract.
  • design/tokens.css, design/component-reference.html, and design/assets/ are canonical UI inputs.
  • design/reference/Scholarr.dc.html is the reviewed proof implementation.
  • design/reference/support.js belongs only to that design proof. Never ship it in production.
  • Port the design faithfully. Do not redesign while implementing.
  • Carry two cleanup items into the Vue port: avoid em dashes in bulk-import copy, and do not show raw match percentages as user-facing confidence labels.

UI QA is manual and performed by the owner against the frozen contract. Do not add or run Playwright, Selenium, or other browser automation. Unit, integration, build, and curl smoke tests are expected.

Work process

  • Work the integration issue's acceptance items in order, against SPRINT.md.
  • Preparation does not authorize execution. Start only after the owner approves the concrete nightly plan and explicitly says to launch.
  • An approved sprint replaces separate spec-freeze ceremonies with the bundled defaults in SPRINT.md. Preserve locked requirements; report conflicts.
  • Keep commits focused and use plain imperative commit messages without trailers.
  • Stage only files you changed.
  • Do not use em dashes in prose, code comments, commit messages, or user-facing copy.
  • Never commit secrets, real user data, database dumps, provider payloads containing private data, API keys, tokens, or real email addresses.
  • Keep configuration examples synthetic and safe to publish.

Correctness obligations

  • Pure normalization, fingerprinting, parsing, and scoring logic gets table tests, property tests for invariants, and Go fuzz tests for external input parsers.
  • Provider clients use deterministic httptest fixtures, including 429 responses, missing Retry-After, truncated JSON, and empty pages. Rate and cooldown tests use a fake clock.
  • Sync tests prove one active run per user, idempotent reruns, additive-only baseline import, resumability after interruption, and SQLite concurrency behavior. Run the race detector.
  • Every migration is tested up and down, including upgrade from a seeded prior-version database.
  • End-to-end smoke boots a seeded SQLite database with stub providers and exercises onboarding, import, sync, review, read state, and export through the API.
  • Matching and dedup changes may not regress the recorded golden-corpus baseline.

Dry-run import previews and dry-run destructive admin actions are product features, not test-only helpers.