Acerca de
Alcance
Un explorador de conocimiento del ecosistema de información de investigación: identificadores, agencias de registro, índices, sistemas institucionales, estándares, comunidades y coaliciones. Hoy reúne 169 entradas y 357 relaciones.
Es un sitio de solo lectura. No evalúa ni puntúa servicios.
Criterios de inclusión
Una entrada se incluye cuando tiene una URL pública estable, cuando otra entrada del grafo la menciona o es un registro, organismo de normalización o coalición reconocido, y cuando no es una herramienta interna de un solo proyecto.
Política editorial
- Un hecho, un solo lugar: los hechos derivados (relaciones inversas, capas, totales) se calculan, nunca se escriben a mano.
- Cada relación se escribe una sola vez, en su dirección canónica.
- Descriptivo, no evaluativo: sin adjetivos de calidad.
- Procedencia obligatoria: cada entrada cita al menos una fuente con fecha de consulta.
- Vigencia registrada: cada entrada indica su última revisión.
Cómo leer el mapa
Cada punto es una entrada: un concepto, un identificador, un servicio, una norma o una organización. Cada línea es una relación con dirección, que se lee como una frase: «Crossref emite DOI».
Las relaciones se agrupan en 5 familias, que el mapa y las fichas usan para ordenar lo que se muestra:
- Quién está detrás
- Quién emite, posee, gobierna, opera, desarrolla o financia la cosa.
- Se apoya en
- Estándares, protocolos y servicios sobre los que la cosa se construye o contra los que se evalúa.
- Se conecta con
- Interoperabilidad, indexación, membresía y pertenencia entre infraestructuras.
- Orienta
- Políticas, mandatos, respaldos y reemplazos que orientan lo que se hace.
- Qué es
- Clasificación — a qué concepto pertenece la cosa, o con qué concepto se relaciona.
Modelo de datos
Las tablas se generan desde los vocabularios del repositorio (vocab/entity-types.yaml y vocab/predicates.yaml), así que no pueden desviarse de las reglas que se aplican al validar los datos.
Tipos de entrada
| Tipo | Definición | Entradas |
|---|---|---|
| Agencia de registro | Una organización que acuña identificadores y guarda sus metadatos. | 4 |
| Agregador | Infraestructura que cosecha, enlaza o federa metadatos entre instituciones y países sin alojar el contenido. | 7 |
| Coalición | Una agrupación política que empuja cambios en lugar de escribir especificaciones. | 7 |
| Comunidad | Un cuerpo que escribe las reglas o certifica contra ellas. | 10 |
| Concepto | Una idea o término — identificador persistente, acceso abierto, metadatos — del que las cosas concretas son ejemplos. | 31 |
| CRIS | El registro administrativo interno de una institución sobre su propia actividad de investigación. | 5 |
| Estándar | Una especificación, conjunto de principios, protocolo o criterio de certificación al que otros se ajustan. | 21 |
| Identificador | Un código permanente que apunta a una cosa, y el compromiso de no borrarla. | 10 |
| Índice | Una base que recopila hechos sobre resultados de investigación y la infraestructura que los aloja. | 15 |
| Organización | El actor detrás de la cosa — empresa, ONG, universidad, agencia, organismo intergubernamental. | 42 |
| Plataforma editorial | Un programa que aloja, marca y publica revistas, preprints o libros bajo sus propios criterios de admisión. | 3 |
| Política | Un instrumento normativo que restringe comportamiento. | 3 |
| Repositorio | Donde se depositan y preservan los objetos, tanto el software como el servicio en producción. | 11 |
Relaciones
| Relación | Lectura inversa | Familia | Usos |
|---|---|---|---|
| aplica a | sujeto a | Orienta | 1 |
| exige | exigido por | Orienta | 1 |
| reemplaza a | reemplazado por | Orienta | 1 |
| respaldado por | respalda | Orienta | 8 |
| es un tipo de | incluye a | Qué es | 43 |
| se relaciona con | se relaciona con | Qué es | 98 |
| desarrollado por | desarrolla | Quién está detrás | 18 |
| emite | emitido por | Quién está detrás | 5 |
| es propiedad de | posee | Quién está detrás | 12 |
| financiado por | financia | Quién está detrás | 16 |
| gobernado por | gobierna | Quién está detrás | 15 |
| operado por | opera | Quién está detrás | 30 |
| certificado por | certifica | Se apoya en | 1 |
| cumple con | cumplido por | Se apoya en | 4 |
| depende de | del que dependen | Se apoya en | 22 |
| es un perfil de | tiene como perfil a | Se apoya en | 1 |
| implementa | implementado por | Se apoya en | 21 |
| es miembro de | tiene como miembro a | Se conecta con | 42 |
| es parte de | tiene como parte a | Se conecta con | 4 |
| indexa | indexado por | Se conecta con | 4 |
| interopera con | interopera con | Se conecta con | 10 |
Reglas de validación (35)
| Regla | Nivel | Definición |
|---|---|---|
| I1 | ERROR | `id` matches /^[a-z0-9]+(?:-[a-z0-9]+)*$/, 2–64 chars, equals the filename stem. |
| I2 | ERROR | `id` is unique across all entity types. No type-scoped namespacing. |
| I3 | ERROR | No dangling references: every relations[].target resolves. |
| I4 | ERROR | No self-loops. |
| I5 | ERROR | No duplicate triples (id, predicate, target). |
| I6 | ERROR | predicate ∈ vocab/predicates.yaml. Closed vocabulary. |
| I7 | ERROR | Canonical direction only. An inverse-form predicate (owns, issued-by, implemented-by, …) is rejected with a message naming the canonical form and the file it belongs in. |
| I8 | ERROR | Domain/range: subject.type ∈ predicate.domain, target.type ∈ predicate.range; where sameTypeOnly, also subject.type === target.type. |
| I9 | ERROR | Symmetric predicates authored once per unordered pair, on the lexicographically smaller id. |
| I10 | ERROR | Acyclic predicates form a DAG (part-of, supersedes, profile-of, depends-on, owned-by, member-of). Error prints the cycle path. |
| I11 | ERROR | No orphans: in-degree + out-degree ≥ 1 unless isolated: true with an explanatory note. |
| I12 | ERROR | Every declared EntityType has ≥1 instance and every declared predicate ≥1 edge. Unused vocabulary is removed or populated; an entry flagged `pending: true` is exempt until its first instance (WARN if the flag is then left behind). |
| I13 | ERROR | Every tags[], disciplines[], status, governance value exists in the corresponding vocab file. |
| I14 | ERROR | summary (in each locale file) is 40–200 chars, single-line, no Markdown syntax, not identical to name. |
| I15 | ERROR | sources.length ≥ 1; every Source.url is https:; accessed is a valid ISO date not in the future. Relations with confidence !== 'asserted' carry ≥1 source. |
| I16 | ERROR | codebase: open-source requires a licence-bearing sourceUrl or an explanatory note; SPDX identifiers validated against spdx-license-ids. |
| I17 | ERROR | url and all Source.url are syntactically valid absolute https: URLs. (Reachability checked weekly, non-blocking — §11.) |
| I18 | ERROR | Populated identifiers.* match their format regexes (§5.1). |
| I19 | ERROR | owned-by targets an organization with orgKind: company. Ownership by a non-company is governed-by or operated-by, not owned-by. |
| I20 | ERROR | since ≤ until where both present; valid partial ISO dates; neither >1 year in the future. |
| I21 | ERROR | EntityId-valued subtype fields resolve to an entity of the required type: persistentIdScheme[] → identifier, harvestProtocols[] → standard, markupStandard[] → standard. |
| I22 | ERROR | governance: commercial requires ≥1 outgoing owned-by edge, or a note on the entity explaining why none is recorded. Enforces the memo's central question at authoring time. |
| I23 | ERROR | layer is never present in an entity file — it is derived (§5.1, C1). |
| I24 | ERROR | Every View.query (§5.6) resolves against the current graph; kind: 'explicit' entity IDs must exist. |
| I25 | ERROR | A View.query resolving to zero entities is an error, not an empty page. |
| I26 | WARN | lastReviewed older than 18 months (the date itself is shown on the entity page). |
| I27 | WARN | An identifier entity with no inbound issues edge. |
| I28 | WARN | An entity authors more relations of one predicate than its maxOutDegree (the map shows the most relevant neighbours and "show more" for the rest; the page lists all); or the graph has >1 weakly connected component (prints each component's size and members). |
| I29 | ERROR | Every entity and every view has a prose file in the default locale, with a valid summary. A facts file without content/i18n/<default>/<id>.yaml fails the build (§5.7). |
| I30 | WARN / ERROR | WARN per missing non-default-locale prose file, aggregated as one line per locale (e.g. 'en: 12 of 78 entities untranslated') — or, with REQUIRE_FULL_I18N on (src/lib/invariants/config.ts / env), one ERROR per missing file. ERROR if a locale file declares a field outside the translatable set, if a relationNotes key does not resolve to a relation authored in the facts file, or if shortName is longer than the name or set in some locales but not others. |
| I31 | ERROR | An entity facts file carries prose (a body, summary or description field). Prose exists only in content/i18n/** (C10). |
| I32 | WARN | Every edge of a governance predicate (owned-by, governed-by, operated-by, developed-by, funded-by) carries relations[].verified: { date, url } recording the primary source it was checked against. |
| I33 | WARN | Completeness floor: every repository/index/aggregator/publishing-platform has ≥1 of {operated-by, developed-by, governed-by}; every standard has ≥1 of {developed-by, governed-by}. |
| I34 | WARN | Heuristic: an entity's note/relationNote/source-note text mentions another entity by name with no relation connecting the two — a likely fact-recorded-as-prose gap. |
| I35 | ERROR | Every predicate declares a `family` that exists in vocab/predicate-families.yaml (display grouping, ≤5 families). |
Descargas
Los datos completos se publican con licencia CC-BY-4.0 en formatos abiertos:
- Entradas (CSV)
- Relaciones (CSV)
- Grafo completo con textos en todos los idiomas (JSON)
- Cada entrada por separado en JSON, por ejemplo: /entity/doi.json
- Fuente RSS de entradas revisadas recientemente
- Mapa del sitio (XML)
Contribuir
No necesitas editar ningún archivo. Para agregar, cambiar o quitar algo, abre una propuesta (issue): elige un formulario, cuenta qué está mal o qué falta y dónde se puede comprobar. Una persona del equipo revisa la fuente y hace el cambio. Las propuestas son públicas. Abrir una propuesta en GitHub(se abre en una pestaña nueva)
The content of this site (entities, relations, translations, stories) is plain YAML in src/content/, checked by a Zod schema and a set of graph invariants every time you run npm run validate and every time you build. A change is good when the validator passes and a person can tell from the diff that it is true, sourced and in scope.
Suggest a change without editing files
Open an issue at https://github.com/Data-Observatory/open-ecosystem-explorer/issues/new/choose and pick the form that fits. The forms are in English and Spanish.
- New entry on the map: an institution, standard, identifier, infrastructure or concept that is missing.
- Connection between two entries: add, change or remove one line on the map (how entry A relates to entry B, from the list of 21 kinds of connection).
- Description or facts of an entry: the short description, the longer text, the name, a fact in the table, the note for Chile and Latin America, a translation, a source or link, or where it appears on the map.
- Remove an entry: it does not belong, is a duplicate, is not true or no longer exists.
- Bug or accessibility problem and Idea or feature: about the site itself, not the content of the map.
Every entry page has two links ("Suggest a change to the description or facts" and "Suggest a change to its connections") that open the matching form with that entry filled in, and the footer links to the chooser.
- A maintainer reads the issue, checks the source, and makes the change as a pull request that closes the issue, or answers why not. If in doubt, the change is left out.
- Give a source for what you propose: the organisation's own page or an authoritative register. A proposal without one may wait until one is found.
- Issues are public. Do not include personal data.
- Issues are labelled
new-entry,connection,description,remove-entry,bugandidea.
Everything below is for people who prefer to make the change themselves, in a pull request.
Before you start
You need Node 22 or newer and npm. Run npm install once. Run npx playwright install chromium only if you also want to run the browser tests.
Read the specs.md sections for the part you touch: §3 (curation policy), §5 (data model and invariants) and §8 (authoring format). docs/known-issues.md lists what is already known to be unverified, so you do not repeat it.
Add or change an entity
- For autocomplete and validation while you type, map
schema/entity.schema.jsontosrc/content/entities/*.yamlandschema/prose.schema.jsontosrc/content/i18n/*/*.yamlin your editor's YAML settings (for example theyaml.schemassetting of theredhat.vscode-yamlextension). Personal editor settings are not committed (.vscode/is ignored).
- An entity is two or three small files, never one big one. Facts and outgoing relations go in
src/content/entities/<id>.yaml. The filename is the id. - Prose goes in
src/content/i18n/es/<id>.yamlandsrc/content/i18n/en/<id>.yaml: a one-sentencesummaryand a shortbody. Both languages are required, and a missing one is a validation error. - Copy two existing files of the same
typeas models. The closed vocabularies insrc/content/vocab/(types, predicates, tags, disciplines, statuses) say which values are allowed. Do not invent terms; adding a vocabulary term is a separate change. - Author each relation once, in the canonical direction, in the file of the subject. The inverse is derived. If the target entity does not exist, add it in the same change or leave the relation out.
- Every entity needs at least one entry in
sourceswith a real URL and the date you read it. Cite the organisation's own page or an authoritative register, not a summary of it. - Descriptions are neutral and descriptive, not evaluative. Chile and Latin America specifics go in an optional
localNote(30 words at most), never in the definition. - If in doubt, leave it out. A missing relation costs less than a wrong one.
- Ideas such as open access, metadata or FAIR are entities of type
concept. Link concrete things to them withis-aorrelated-to(with a shortnote), not with the other predicates. prominence(core,extendedordetail) controls what a newcomer sees first. Leave the default unless you have discussed it.
prompts/add-entity.md is a ready-made prompt for an LLM agent doing the same job. An agent edits, the validator checks, a person reviews and merges.
The check loop
Run these after every edit, from the repository root:
npm run validatemust end with 0 errors. It takes a few seconds and prints the rule, the file, the field and the fix. Warnings are information; report them, do not hide them.npm run layout:generateafter you add, remove or change a relation or an entity, then commitsrc/generated/graph-layout.json. The build fails (layout:check) if it is stale.npm run check,npm run lintandnpm testbefore you open a pull request.npm run buildthennpm run test:e2ewhen you touch pages or the map. The e2e tests run against the build. SetPW_PORTto a free port, andPLAYWRIGHT_CHROME_PATHto use a system Chrome.
Change the site or the UI text
UI strings live in messages/es.json and messages/en.json. Every key must exist in both. Code under src/lib/model, graph, i18n, invariants, views, stories and export must stay free of Svelte and SvelteKit imports. docs/architecture.md explains the routes and the map.
Commits and reviews
- Use conventional commits (
feat:,fix:,docs:,chore:,refactor:,test:,style:) and small, incremental commits: one idea per commit. - Do not add co-author or tool attribution lines to commit messages.
- The reviewer reads for what the validator cannot see: is the relation true, is the source the right one, is the summary neutral, is the entity in scope.
mainis protected: work on a branch and open a pull request. It can be merged only when the CI jobstestandinfraare green and the branch is up to date withmain; direct pushes are refused, for administrators too. Merging is squash or rebase, so keep the pull request title a conventional commit.- CI (
.github/workflows/ci.yml) runs the check loop above on every pull request and on every push tomain. - Every change merged to
mainis deployed to https://oee.dataobservatory.net by.github/workflows/deploy.ymlafter CI passes onmain, with no further approval. Merge only what you are ready to publish. - Analytics, hosting and deployment settings (
static/consent-loader.js,infra/,.github/workflows/deploy.yml) are decided by the project owner. Open an issue instead of changing them.
Plantilla para agregar una entrada
Add an entity
Add <name> to this repository as an entity.
Read first: specs.md §5.1–5.2 (fields per type), specs.md A.2 (the predicates, with domain and range), src/content/vocab/*.yaml (closed vocabularies — do not invent terms), and two existing files of the same type as models.
Then: create src/content/entities/<id>.yaml with the facts and outgoing relations only, and src/content/i18n/es/<id>.yaml with summary and body prose (en too if you can source it). Author relations in the canonical direction only; if a target entity does not exist, either add it in the same change or omit the relation. Every entity needs ≥1 sources entry with a real URL and today's accessed date — do not cite the memo for an external fact, cite the thing itself.
Optional prominence: core | extended | detail (default extended) controls progressive disclosure; set core only for the handful of nodes a newcomer must see first. A new idea or term (persistent identifier, open access, metadata, ...) is a concept (13th type; governance: not-applicable, url = its reference page, no type-specific fields): link concrete things to it with is-a (any type -> concept; concept -> concept for subtypes; acyclic; only when the thing genuinely *is a kind of* the concept) or related-to (symmetric, any type -> concept, at most 5 per node (a warning beyond that), always with a short note saying how; use it when the thing operates, practises or addresses the idea without being a kind of it), and write the concept's own relations in the same direction. Principles and frameworks (FAIR, CARE, TRUST) are concepts, not standards: tie them to things with related-to, never complies-with or developed-by. For a symmetric edge between two concepts, author it on the file whose id sorts first. Prose: an optional localNote (<=30 words) carries a Chile/LatAm-specific fact about a global concept; definitions stay neutral. Provide both es and en files: a missing locale is a validation ERROR (REQUIRE_FULL_I18N in src/lib/invariants/config.ts).
Finally: run npm run validate and fix every ERROR before stopping; if you added or changed any relation or entity, also run npm run layout:generate and keep the changed src/generated/graph-layout.json. Report the WARN lines rather than suppressing them. Do not add a vocabulary term (that is a separate PR, C6), and do not edit any other entity's file to add the inverse relation.
Historial de cambios
Los cambios de los datos y del sitio se registran en el historial.
- Proposals through GitHub issues (2026-11-14)
- CI and deployment infrastructure (2026-11-14)
- Spec brought in line with the code (2026-11-14)
- Contributor documentation (2026-11-14)
- Clean-up after the SvelteKit migration (2026-11-14)
Privacidad y cookies
Para entender cómo se usa el sitio, se mide la actividad de las visitas mediante Google Tag Manager, un servicio de Google que carga las herramientas de analítica configuradas para este sitio (por ejemplo, Google Analytics). Se reciben datos técnicos de uso, como las páginas visitadas, el tipo de navegador y dispositivo y la ubicación aproximada, junto con una cookie que identifica al navegador con un código aleatorio. El sitio no pide nombre, correo ni ningún otro dato personal, y la analítica no se usa para publicidad.
La analítica está activada por defecto. El aviso que aparece en la primera visita permite mantenerla o desactivarla, con el mismo peso, y se vuelve a mostrar pasado un año.
Puede desactivarla o volver a activarla en cualquier momento con el botón de ajustes de analítica de esta página o del pie de página. Al desactivarla se deja de cargar Google Tag Manager en las visitas siguientes y se borran las cookies de Google Analytics de este sitio.
Su elección se guarda únicamente en este navegador (localStorage, clave oee-consent), junto con la fecha. No se envía a ningún servidor. Fuera de eso, el sitio solo recuerda en el navegador su preferencia de modo del mapa.