Skip to content

2026-06-10 La x sulla tabella

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.pngPasted 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.

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.

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: