4.8 KiB
Scholarr agent brief
This file is the canonical brief for every coding agent working in this repository. Read it and
TASKS.md before making changes.
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 moreAuthorSourceIdentityrecords. - 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/scholarris 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
On tank, the authoritative project runbook is:
/opt/stacks/server-docs/runbooks/scholarr-rewrite/README.md
It owns doctrine, locked decisions, empirical calibration results, and project state. Its companion files own the identity model and testing strategy. This brief is self-contained for agents without tank access, but any state or design decision reached on tank must also be written to that runbook in the same session.
Frozen UI contract
design/DESIGN.mdis the frozen Vue handoff contract.design/tokens.css,design/component-reference.html, anddesign/assets/are canonical UI inputs.design/reference/Scholarr.dc.htmlis the reviewed proof implementation.design/reference/support.jsbelongs 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 through
TASKS.mdin order. Each task has a goal and acceptance criteria. - Freeze one spec at a time. Decided items are labeled decided; open items remain open for owner review.
- Do not start implementation for an area whose spec is not frozen.
- 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
httptestfixtures, including 429 responses, missingRetry-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.