Effort: thorough
Authors increasingly cite SciDEX content in their preprints' methods or
acknowledgments ("Hypothesis generated by the SciDEX Theorist
persona", "Notebook adapted from scidex.ai/wiki/...", "Analysis
ranked-third in the SciDEX Tau tournament"). These attributions are
high-signal social proof that the platform's outputs reach the open
literature. The general citation tracker (q-impact-citation-tracker)
catches reference-list cites; this spec catches free-text mentions in
preprint full text that name SciDEX explicitly, even when no formal
citation is added.
scidex/atlas/preprint_attribution_detector.py with a dailybioservices Crossref + bioRxiv API (full textfullTextSearch for the literal"SciDEX", "scidex.ai", "Science Discovery
Exchange".scidex.ai/<path> URL mentioned nearby.
scidex_attributions (Postgres):CREATE TABLE scidex_attributions (
id UUID PRIMARY KEY,
preprint_doi TEXT NOT NULL,
preprint_title TEXT,
preprint_authors JSONB,
preprint_venue TEXT,
preprint_published_at TIMESTAMP,
attribution_text TEXT NOT NULL,
attribution_kind TEXT NOT NULL CHECK (attribution_kind IN
('explicit_named','url_mention','dataset_attribution',
'methods_acknowledgment','adapted_notebook')),
scidex_artifact_id TEXT REFERENCES artifacts(id),
confidence FLOAT CHECK (confidence BETWEEN 0 AND 1),
review_status TEXT NOT NULL DEFAULT 'pending' CHECK
(review_status IN ('pending','confirmed','rejected')),
first_detected_at TIMESTAMP DEFAULT NOW(),
UNIQUE(preprint_doi, attribution_text)
);GET /api/scidex-attributions?status=confirmed — list.POST /api/scidex-attributions/{id}/confirm —review_status='confirmed', requires Senate role).POST /api/scidex-attributions/{id}/reject — operator-external_citation row (q-impact-citation-tracker schema)source_provider='manual' so contributor landing pages/scidex-attributions lists all attributions with aUNIQUE(preprint_doi, attribution_text), theexternal_citations.
paper-corpus-search skill / Europe PMC APIscidex/forge/tools.py for full-text search.
scidex_artifact_id by URL parsing when ascidex.ai/<path> is present; otherwise leave NULL and letq-impact-citation-tracker (sibling) — suppliesexternal_citations schema and homepage strip.
migrations/add_scidex_attributions_table.py — adds scidex_attributions table withattribution_kind CHECK, review_status CHECK, and indexes.scidex/atlas/preprint_attribution_detector.py — detector module with:SciDEX, scidex.ai, Science Discovery Exchangeattribution_kind variants with correct confidence scoresdetect_attributions_in_text() returning list of attribution dicts_resolve_artifact_id_from_url() parsing scidex.ai/<path> into artifact IDsrun_daily_sweep() and run_backfill() entry points; _upsert_attribution() withON CONFLICT DO NOTHING for deduppython -m scidex.atlas.preprint_attribution_detector --since 25h --backfill
api.py:GET /api/scidex-attributions?status=X — paginated JSON listPOST /api/scidex-attributions/{id}/confirm — sets review_status='confirmed',_propagate_to_external_citation() to write an external_citations rowPOST /api/scidex-attributions/{id}/reject — sets review_status='rejected'_propagate_to_external_citation() creates an external_citations row withsource_provider='manual' from a confirmed attribution
GET /scidex-attributions HTML page — operator triage UI with filter pillsdashboard() — shows most recent 3 confirmedscidex_attributions rows with DOI, title, attribution snippet, and artifact link,tests/atlas/test_preprint_attribution_detector.py covering:attribution_kind variantsconfidence, attribution_text, attribution_kindexternal_citations entry
py_compile), regex detection works in isolation,orchestra/task/e5f5d979-preprint-with-scidex-attribution-detectoauth.require_api_key).
auth.require_senate_role() dependency in scidex/core/auth.py (returnsrequire_permission("senate")), then wired both endpoints to use it instead of barerequire_api_key. This follows the exact pattern used by /senate/pg-pool/freeze.
api.py (2 routes, Depends(auth.require_senate_role()) instead ofDepends(auth.require_api_key)), scidex/core/auth.py (new require_senate_role() function).
python3 -m py_compile on both files passes cleanly.a03e25fa6 — [Atlas] preprint-attribution: add real Senate role guard togit push --force-with-lease after rebase onto origin/main.