0048 — Camino único de co-citación: chain forward puebla cited_by_id¶
- Estado: Aceptada
- Fecha: 2026-07-18
- Decidido por: Product Owner humano (2026-07-18). La elección entre el camino implícito
(que el forrajeo hacia adelante, que ya existe, pueble además
cited_by_id) y un camino explícito (un comando/flag nuevo tipobuild --cocitationque orquesteaccept → chain forward → build) es decisión del PO: eligió el camino implícito. El encuadre —diagnosticar que hoy no hay un camino feliz único a la red de co-citación, que tres comandos tocancited_by_idy ninguno lo completa solo, y que sumar superficie tensiona con la poda de "10 verbos"— es síntesis de la IA (architect) validada por el PO. - Relacionada con: 0025 (
Enricheropt-in: refs→DOI + co-citación — la pasada 8b poblabacited_by_idsolo sobre semillas aceptadas; este ADR fija que la co-citación se puebla enchain forward, el forrajeo que ya trae los citantes, y no en unenrichsuelto ni condicionada aaccepted), 0020 (método de forrajeo:forward= red de citantes —chain forwardya trae los citantes; este ADR solo hace que, de paso, complete el campo que la proyección necesita), 0014 (la co-citación es una proyección: elCoCitationProjectorcuentacited_by_idcompartido — no cambia; solo cambia quién puebla su insumo), 0037/0038 (poda: por qué NO un comando nuevo — la superficie se consolidó a 10 verbos yenrichse absorbió enchain/build; unbuild --cocitationreabriría superficie que estos ADR cerraron), 0016 (FSM del lazo:chaintransiciona aCHAINED; este ADR no cambia la transición). - No introduce IA (coherente con 0022): es un cambio de qué campo puebla un comando determinista ya existente; sin modelo generativo.
- Origen: sub-issue #270 (P1b de la
auditoría AX #204), Bloque A del release
0.12.0. Fricción P1 de la auditoría: el lazo end-to-end
seed → chain forward → curate accept → buildproduce redes de co-citación vacías sin señal clara de por qué.
Contexto¶
La red de co-citación es una proyección determinista (ADR
0014): el CoCitationProjector cuenta los
cited_by_id compartidos entre papers (dos papers están co-citados cuando comparten citantes).
Su insumo es la columna cited_by_id; si esa columna está vacía, la red sale vacía.
Hoy tres comandos tocan cited_by_id y ninguno lo completa solo en el camino del lazo:
enrich(verbo deprecado, alias que se elimina en 0.11.0 — ADR 0038; capacidad viva del ADR 0025) pueblacited_by_iden su pasada 8b, pero solo sobre papersaccepted(is_seed=True AND curation_status=accepted). Requiere haber curado antes, y es un verbo que ya no se anuncia.buildhereda esa misma pasada 8b (ADR 0025, nota append-only del 0038): corre la co-citación automáticamente cuando hay semillas aceptadas — por esobuilddejó de ser "puro/sin red". También condicionado aaccepted.chain forward(forrajeo hacia adelante = red de citantes, ADR 0020) ya trae los citantes de las semillas para hacer el chaining, pero NO pueblacited_by_id: usa esa información para proponer candidatos y se descarta.
El resultado: un agente que corre el lazo natural seed → chain forward → curate accept → build
obtiene una red de co-citación vacía sin señal clara de la causa. La información de citantes
estuvo disponible durante chain forward —el comando que la fue a buscar— pero no se persistió
en el campo que la proyección consume. No hay un camino feliz único a la co-citación; hay tres
comandos que la tocan a medias, dos de ellos atados a accepted y uno deprecado. Esa es la fricción
P1 de la auditoría AX (#204): el lazo
end-to-end no cierra.
Decisión¶
chain forward puebla cited_by_id además de la metadata del citante que ya materializa.
- El forrajeo hacia adelante ya va a OpenAlex a buscar los citantes de las semillas (ADR 0020:
forward= red de citantes). Con esta decisión, esa misma pasada completa el campocited_by_idde los papers alcanzados, dejando listo el insumo delCoCitationProjector(ADR 0014). - Es el camino implícito: el lazo existente
seed → chain forward → curate accept → build"just works" —buildproyecta la red de co-citación porquecited_by_idya viene poblado del chaining, sin un comando ni un flag que el agente tenga que descubrir. - Alcance: esta decisión cambia qué campo puebla
chain forward(sumacited_by_ida la metadata del citante). NO cambia el envelopeschema="1", los exit codes, ni la FSM del lazo (chain→CHAINED, ADR 0016/0021). ElCoCitationProjector(ADR 0014) no se toca: sigue contandocited_by_idcompartido; solo cambia quién llena su insumo. - La implementación, los tests y el cambio de
docs/API.mdviven en el issue #270, no en este ADR (coherente con cómo 0044/0045 dejaron la edición deAPI.mdpara el hito de implementación).
Consecuencias¶
- (+) El lazo end-to-end cierra con el camino natural.
seed → chain forward → curate accept → buildproduce una red de co-citación no vacía sin superficie nueva. Se disuelve la fricción P1 de #204: el agente no tiene que descubrir un verbo/flag ni saber que la co-citación vive escondida enbuildo en elenrichdeprecado. - (+) No crece la superficie CLI. Se respeta la poda a 10 verbos (ADR 0037/0038): la co-citación se puebla dentro de un comando que ya existe y ya hace la petición de citantes, no en uno nuevo.
- (+) La co-citación deja de estar atada a
accepted. El chaining forward pueblacited_by_idal traer los citantes, no en build-time condicionado a la curación. El camino se vuelve más transparente: quien pidió los citantes (chain) es quien deja el campo listo. - (+) El
CoCitationProjectorno cambia (ADR 0014): sigue siendo función pura sobrecited_by_id. La proyección permanece determinista y reproducible (ADR 0022/0017). - (−) Se solapa transitoriamente con la pasada 8b heredada en
build/enrich(ADR 0025 / nota 0038). La unión sobrecited_by_ides idempotente (ADR 0025: "mergea… unión, idempotente"), así que poblarla desdechain forwardy desdebuildno duplica ni corrompe. Reconciliar dónde vive definitivamente la pasada 8b —y sibuilddeja de hacer red al recibir el insumo ya poblado— es trabajo del issue #270, no de este ADR; aquí se fija el principio (chain forward la puebla), no la limpieza de código. - (−)
chain forwardhace un poco más de trabajo de persistencia (escribecited_by_idde los papers alcanzados). Es información que el comando ya trajo de la red; el costo incremental es de escritura, no de I/O de red adicional. docs/API.mda precisar en la implementación. La sección dechaindebe declarar quechain forwardpueblacited_by_id, y la debuild/ la co-citación reconciliarse con este camino. Esa edición es trabajo delcoderal implementar #270, no parte de este ADR.
Alternativas¶
- Comando/flag explícito
build --cocitation(un flag —o comando— nuevo que orquesteaccept → chain forward --mode cite → builden un paso, materializando la co-citación bajo demanda). Rechazada: - Suma superficie nueva justo cuando la poda la está reduciendo. El ADR 0037/0038 consolidó la
superficie a 10 verbos y absorbió
enrichenchain/buildprecisamente para no tener verbos por acreción; unbuild --cocitationreabre superficie que esos ADR cerraron y tensiona con el conteo "10 verbos". - Menos transparente para un agente. Un flag/comando nuevo es algo que hay que descubrir; si
el agente no lo conoce, vuelve a obtener la red vacía sin señal. El camino implícito hace que el
lazo que el agente ya corre —
chain forward— produzca el insumo, sin conocimiento previo. - Dejar la co-citación solo en
build/enrich(statu quo) y solo documentarla mejor. Rechazada: es exactamente la fricción P1 de #204. La co-citación queda atada aacceptedy escondida en un verbo deprecado (enrich) o en un efecto lateral debuild; el caminochain forward—el que fue a buscar los citantes— sigue tirando esa información. Documentar un camino confuso no lo vuelve un camino feliz único.