Skip to content

index

Durante la validazione dell’allineamento Meta/OpenAlex ho scoperto un problema grave nella classe di normalizzazione dei DOI dell’oc_ds_converter. Il commit che integrava la logica di correzione automatica dei DOI (quella dell’esame di Computational Thinking) l’aveva distribuita su due punti: la parte principale in is_valid che, dopo le mie correzioni, chiama attempt_repair solo con le API attive, e lo strip di vari suffissi in normalize, che viene eseguito sempre. Credevo di aver contenuto il problema delegando la correzione alle sole chiamate API, ma lo strip in normalize agiva a prescindere. Poiché esistono DOI validi che terminano con #, 4043 DOI sono stati alterati (almeno), generando duplicati in Meta difficili da mergiare: per ogni caso esistono due varianti dello stesso identificatore, una con e una senza cancelletto.

Esempio: 10.1002/(sici)1096-9896(199912)189:4<623::aid-path475>3.0.co;2-#

https://github.com/opencitations/oc_meta/issues/64

arcangelo7
arcangelo7May 29, 2026 · opencitations/oc_ds_converter

fix(doi): stop normalise from destructively stripping DOI content

Suffix stripping (16 regex patterns including #, query params, PMID, year, delimiters) and embedded URL prefix stripping ran unconditionally in normalise(), silently corrupting valid DOIs with legitimate characters like #.

Moved all heuristic correction to attempt_repair(), which only runs when API is enabled and verifies the repaired DOI exists. Merged base_normalise() into normalise() (redundant after removing the stripping logic) and dropped the prefix regex (URL prefix handling was already covered by extracting from “10.”).

arcangelo7May 30, 2026 · opencitations/oc_meta

fix(patch): repair SICI DOIs truncated by the oc_ds_converter suffix bug

oc_ds_converter’s suffix regex stripped the trailing ”#” check character from SICI DOIs (e.g. Wiley ”…CO;2-#”), leaving “…co;2-” and creating a duplicate bibliographic resource next to the entity that already held the correct DOI.

The script collects the omid_mismatch errors from check_results, reconstructs the DOI by reappending ”#”, confirms it on Crossref, and scores the duplicate’s metadata against the Crossref record to avoid wrong merges. Confirmed cases are merged into the surviving entity and the truncated identifier is removed; when the same article was minted under several OMIDs the duplicates are merged N-way into one survivor. The run is refused unless the triplestore is updated directly (rdf_files_only=False) so every case reads consistent state.

Ho usato l’euristica di Martijn Visser, Nees Jan van Eck, Ludo Waltman; Large-scale comparison of bibliographic data sources: Scopus, Web of Science, Dimensions, Crossref, and Microsoft Academic. Quantitative Science Studies 2021; 2 (1): 20–41. doi: https://doi.org/10.1162/qss_a_00112

arcangelo7Jun 1, 2026 · opencitations/oc_meta

feat(patch): add omid mismatch fixer and extract shared matching module

Extract bibliographic matching logic (Crossref fetching, triplestore metadata retrieval, weighted scoring) into oc_meta.lib.bibliographic_matching.

Add fix_omid_mismatches.py for merging duplicate entities caused by DOI normalization issues (trailing periods). Validates merges via doi.org resolution and Crossref metadata scoring.

arcangelo7Jun 9, 2026 · opencitations/oc_ds_converter

fix: correct ORCID reconciliation in agent string builders

The DOI->ORCID index matching attributed one author’s ORCID to unrelated co-authors in two ways:

Surname matching used bidirectional substring containment, so a short indexed surname like “Li” matched every co-author whose surname merely contained it (“Gladilin”, “Poggioli”, “Zwalinski”…). Combined with the given-name initial fallback this smeared a single ORCID across many distinct people in large collaborations. Replace containment with token-subset matching, so compound surnames still match while short fragments no longer do.

arcangelo7
arcangelo7Jun 5, 2026 · opencitations/ramose

feat(skgif): omit empty optional fields from JSON-LD output

arcangelo7
arcangelo7Jun 5, 2026 · opencitations/ramose

fix(skgif): emit url scheme for Zenodo and SWH identifiers in Wikidata API

arcangelo7
arcangelo7Jun 6, 2026 · opencitations/ramose

feat(openapi): upgrade OpenAPI from 3.0 to 3.1

The generated spec only uses Schema Object constructs that are already compatible with JSON Schema 2020-12 (type/properties/items/enum/format/ pattern/$ref/required), so moving from 3.0.3 to 3.1.0 is a plain version bump with no semantic change.

Add automated validation through openapi-spec-validator.

arcangelo7
arcangelo7Jun 6, 2026 · opencitations/ramose

feat(openapi): serve Swagger UI and fix exported response media types

Serve interactive Swagger UI at /docs with a dropdown over every loaded API spec

An operation can now declare the content type of a custom output format as an optional third field of #format, for example skgif,to_skgif,application/ld+json.

Tabular JSON examples also gain a matching CSV example.

https://colab.research.google.com/github/opencitations/ramose/blob/master/docs/09-demo-skgif.ipynb

arcangelo7
arcangelo7Jun 6, 2026 · opencitations/ramose

feat: negotiate response format via the Accept header

Pasted image 20260606211836.png

arcangelo7
arcangelo7Jun 7, 2026 · opencitations/ramose

feat: add SPARQL write operations with bearer-token authentication

POST, PUT and DELETE operations now run a SPARQL 1.1 Update against #update_endpoint (falling back to #endpoint) and return a JSON confirmation. Routing is method-aware, so the same #url can host several operations differing by method.

Body and path values bind through iri()/literal() typed parameters: literals are escaped, IRIs are validated and rejected with 400 on forbidden characters, guarding against update injection. A request that leaves any [[placeholder]] unfilled is rejected with 400 before anything reaches the endpoint.

The #auth directive (API-level default, per-operation override) marks operations that require a bearer token. The web layer validates the Authorization header against TokenStore, a local SQLite registry that keeps only the SHA-256 hash of each token and supports creation, expiry, revocation and listing. Manage tokens with —token-create, —token-ttl, —token-list, —token-revoke and —auth-db.

#url /resources
#type operation
#method post
#auth required
#resource iri(.+)
#title literal(.+)
#identifier iri(.+)
#scheme iri(.+)
#value literal(.+)
#description Create a bibliographic resource with a title and an identifier.
#field_type str(x)
#sparql INSERT DATA {
<[[resource]]> a <http://purl.org/spar/fabio/Expression> ;
<http://purl.org/dc/terms/title> "[[title]]" ;
<http://purl.org/spar/datacite/hasIdentifier> <[[identifier]]> .
<[[identifier]]> a <http://purl.org/spar/datacite/Identifier> ;
<http://purl.org/spar/datacite/usesIdentifierScheme> <[[scheme]]> ;
<http://www.essepuntato.it/2010/06/literalreification/hasLiteralValue> "[[value]]" .
}
Terminal window
uv run python -m ramose --token-create demo --auth-db .auth
Token created for 'demo': bw5qGD2PKjzc17qJY9QbE89SFO4vVUFvE4Pa2yjd6VA
Terminal window
uv run python -m ramose -s test/fixtures/write_api.hf -w 127.0.0.1:8080 --auth-db .auth
POST /resources
Authorization: Bearer bw5qGD2PKjzc17qJY9QbE89SFO4vVUFvE4Pa2yjd6VA
Content-Type: application/json
{
"resource": "https://w3id.org/oc/meta/br/062104388184",
"title": "OpenCitations Meta",
"identifier": "https://w3id.org/oc/meta/id/062106312420",
"scheme": "http://purl.org/spar/datacite/doi",
"value": "10.1162/qss_a_00292"
}
Terminal window
curl -X POST "http://127.0.0.1:8080/bibliography/v1/resources?resource=https://w3id.org/oc/meta/br/062104388184&title=OpenCitations%20Meta&identifier=https://w3id.org/oc/meta/id/062106312420&scheme=http://purl.org/spar/datacite/doi&value=10.1162/qss_a_00292" \
-H "Authorization: Bearer bw5qGD2PKjzc17qJY9QbE89SFO4vVUFvE4Pa2yjd6VA"

Si possono configurare update di endpoint multipli, diversi a seconda dell’operazione, ma non si può federare un update.

arcangelo7
arcangelo7Jun 7, 2026 · opencitations/ramose

feat: authenticate RAMOSE to SPARQL backends per endpoint

This adds a configurable credential on the RAMOSE to backend boundary, kept separate from the client to RAMOSE bearer token.

Configure via RAMOSE_BACKEND_AUTH (newline-separated endpoint=header entries,) or a repeatable —backend-auth flag.

The header is applied to every request to its endpoint, reads and writes alike, and to no other.

Terminal window
python -m ramose -s apis.hf -w 127.0.0.1:8080 \
--backend-auth 'https://qlever.example/sparql=Bearer <token>' \
--backend-auth 'https://fuseki.example/ds/update=Basic <base64>'

RAMOSE non interpreta quello che metti dopo l’uguale, quindi vengono gestiti anche schemi di token speciali tipo il GDB di GraphDB. Ciò che si mette dopo l’uguale viene inviato nell’header Authorization all’endpoint così com’è.

Applied research, per i seguenti motivi:

  • Ho trovato un articolo in applied research su IEEE Access su uno strumento comparabile a RAMOSE:

    G. Vega-Gorgojo, “CRAFTS: Configurable REST APIs for Triple Stores,” in IEEE Access, vol. 10, pp. 32426-32441, 2022, doi: 10.1109/ACCESS.2022.3160610

  • Sia Scopus che WoS classificano tutti i paper IEEE Access come Article Pasted image 20260529121725.png Pasted image 20260529121919.png

https://github.com/CLARIAH/grlc/issues/573

Espinoza-Arias, P., Garijo, D., & Corcho, O. (2021). Crossing the chasm between ontology engineering and application development: A survey. Journal of Web Semantics, 70, 100655. https://doi.org/10.1016/j.websem.2021.100655

Pasted image 20260608150615.png

Pasted image 20260608150625.png

Anziché riutilizzare la tabella dell’articolo originale di RAMOSE, ho preferito adottarne una presente in un survey scritto non da noi perché:

  1. È meno autoreferenziale
  2. Permette di confrontare tutti i tool su categorie meno sbilanciate verso il modo di RAMOSE di vedere la soluzione al problema
  3. È più strutturata e meno discorsiva

Della tabella originale si perde running interface, che fa emergere nulla di interessante, secondo me. I running requirements invece sono divisi su colonne più granulari (language, input, configuration format).

Si perdono anche le colonne pre-processing e post-processing, che però fanno emergere dettagli implementativi, cioè differenze tra approcci dichiarativi vs imperativi, quindi si rischia di tiltare troppo verso RAMOSE. In un certo senso, valgono già le colonne configurable queries e control over JSON per questi due aspetti.

Ho pensato di aggiungere 5 colonne, ben distanziate dalle altre, che mettono in luce specificamente le novità di RAMOSE v1. Queste colonne sono sufficientemente generiche e coperte da diversi tool (a parte non-RDF sources), il che le rende categorie neutre, secondo me.

Inoltre, ho aggiunto la colonna licenza, presente nella tabella originale di RAMOSE ma assente in Espinoza.

Ho corretto le licenze

Aloha: https://github.com/skg-if/api/issues/62#issuecomment-4660975585

L’endpoint SPARQL di Index non ritorna JSON valido rispetto a SPARQL 1.1 Query Results JSON Format

Terminal window
curl -s -H 'Accept: application/sparql-results+json' -G 'https://sparql.opencitations.net/index' --data-urlencode 'query=SELECT ?s WHERE { ?s ?p ?o } LIMIT 1'

C’è un campo meta di troppo. Me ne sono accorto perché ho provato a costruire un’API con CRAFTS, che valida le risposta rispetto a uno schema.

Inoltre, tool come Walder, che utilizzano Comunica come query engine, non possono fare query sui nostri endpoint SPARQL, perché si aspettano una SPARQL Service Description al GET sull’endpoint, non una pagina HTML.

Cosa dico a Sergei? Gli devo scrivere quantomeno per chiedergli di creare un ORCID.

Ho sempre citato le specifiche del W3C come riferimenti bibliografici, non come URL. Li cito come URL?

We find that the use of alphabetical authorship is declining over time. In 2011, the authors of less than 4% of all publications intentionally chose to list their names alphabetically. The use of alphabetical authorship is most common in mathematics, economics (including finance), and high energy physics.

  • In finanza l’ordine alfabetico è la norma, sono felici?
    • Joanis ST, Patil VH. Alphabetical ordering of author surnames in academic publishing: A detriment to teamwork. PLoS One. 2021 May 5;16(5):e0251176. doi: doi.org/10.1371/journal.pone.0251176. PMID: 33951084; PMCID: PMC8099113.
      • lo studio empirico è condotto solo su riviste di business. ordine alfabetico → minor incentivo a collaborare (perché il tuo contributo extra non viene reso visibile) → meno coautori per pubblicazione
      • L’ordine alfabetico in finanza, dove è la norma, non è neutro, ma ha un effetto, che è quello di discriminare chi è nato con un cognome che viene dopo nell’alfabeto:
arcangelo7
arcangelo7May 29, 2026 · dharc-org/changes-metadata-manager

feat(zenodo): add sync-status and cleanup-duplicates subcommands

sync-status queries each record’s actual state from the Zenodo API, updates drafts.json with current status/DOI/URL, and regenerates doi_table.csv. Falls back to draft endpoint on 404 for unpublished records.

cleanup-duplicates finds user records whose title matches drafts.json but whose ID is not tracked, deletes draft duplicates and reports published ones. Supports —dry-run.

RAMOSE

  • Confronto performance
  • Aggiungere connextion

TAL

  • Aggiungere skolemizzazione

Vizioso

HERITRACE

  • C’è un bug che si verifica quando uno seleziona un’entità preesistente, poi clicca sulla X e inserisce i metadati a mano. Alcuni metadati vengono duplicati.
  • Se uno ripristina una sotto entità a seguito di un merge, l’entità principale potrebbe rompersi.
  • Per risolvere le performance del time-vault non usare la time-agnostic-library, ma guarda solo la query di update dello snapshot di cancellazione.
  • Ordine dato all’indice dell’elemento
  • date: formato
  • anni: essere meno stretto sugli anni. Problema ISO per 999. 0999?
  • Opzione per evitare counting
  • Opzione per non aggiungere la lista delle risorse, che posso comunque essere cercate
  • Configurabilità troppa fatica
  • Timer massimo. Timer configurabile. Messaggio in caso si stia per toccare il timer massimo.
  • Riflettere su @lang. SKOS come use case. skos:prefLabel, skos:altLabel
  • Possibilità di specificare l’URI a mano in fase di creazione
  • la base è non specificare la sorgente, perché non sarà mai quella iniziale.
  • desvription con l’entità e stata modificata. Tipo commit
  • display name è References Cited by VA bene
  • Avvertire l’utente del disastro imminente nel caso in cui provi a cancellare un volume

Meta

  • Matilda e OUTCITE nella prossima versione
  • Rilanciare processo eliminazione duplicati
  • Fusione: chi ha più metadati compilati. A parità di metadato si tiene l’omid più basso
  • frbr:partOf non deve aggiungere nel merge: https://opencitations.net/meta/api/v1/metadata/omid:br/06304322094
  • API v2
  • Usare il triplestore di provenance per fare 303 in caso di entità mergiate o mostrare la provenance in caso di cancellazione e basta.

oc_ocdm

RML

Crowdsourcing

  • Quando dobbiamo ingerire Crossref stoppo manualmente OJS. Si mette una nota nel repository per dire le cose. Ogni mese.
  • Aggiornamenti al dump incrementali. Si usa un nuovo prefisso e si aggiungono dati solo a quel CSV.
  • Bisogna usare il DOI di Zenodo come primary source. Un unico DOI per batch process.
  • Bisogna fare l’aggiornamento sulla copia e poi bisogna automatizzare lo switch

Citazioni

  • Fare diff DataCite per togliere le citazioni che non sono più citazioni. è da fare in post. Snapshot 2 di provenance. Fare lo snapshot 3 con la creazione con il derived from al nuovo dump. La lineage viene data dallo specialization of. Colleghi sia al 2 che al dump.
  • Repo cerotti. meta/index/sorgenti