fix(editor): traject-eigen indexscan resolvet token strikt en meldt scan-falen per source#953
Conversation
…can-falen per source De promote-flow (#952) schrijft een wet met het user-OAuth-token naar de traject-repo, maar de server-side indexscan van de writable-own source las met een ánder token-resolutiepad: 'resolve_token_for_source' mét legacy 'CORPUS_GIT_TOKEN'-fallback, waar push/backend strikt resolven. Zonder geconfigureerd per-repo token scant de server een privé-repo dan unauthenticated, krijgt 404 van de Trees-API, en valt de wet stil terug op het centrale corpus — de traject-source toont alleen 'law_count: 0'. - 'Source.strict_auth' (gezet voor writable-own rows) laat élk token-resolutiepad — indexscan, favorites-fetch, backendconstructie — dezelfde strikte regels volgen via 'auth::resolve_source_token'. Dit sluit ook het leespad-lek waarbij de legacy-fallback het centrale token naar een user-gekozen repo zou sturen. - 'index_all_sources_async' geeft per gefaalde source de fout terug ('SourceIndexFailure'); 'build_traject_corpus' bewaart die in 'CorpusState.index_failures' en GET /api/trajects/{ref}/sources (en /api/sources) tonen ze als 'index_error' per source — scan-falen is niet langer stil. - error!-log bij een gefaalde writable-own-scan draagt nu de fout mee; de bestaande 'NO token'-diagnostiek benoemt naast pushes ook reads. - Integratietest reproduceert het prod-symptoom (promote slaagt, onleesbare repo → fallback naar seed met priority 2 + index_error) en pint het happy path: gepromote wet zichtbaar op source_priority 0.
|
CI: alles groen behalve Security Audit — die faalt op |
|
Review-pipeline doorlopen: geen codebevindingen — |
Closes tdjager/development#6
Wat
Een via de promote-flow (#952) naar de traject-repo geschreven wet laadde op een deployment zonder per-repo servertoken niet uit de traject-eigen source (priority 0), maar viel stil terug op het centrale corpus — de traject-source toonde alleen
law_count: 0.Root cause (token-hypothese bevestigd)
De hypothese uit het ticket klopt op codeniveau en is in een integratietest 1-op-1 gereproduceerd:
token_overrideviauser_write_token_for_backend) — die kant slaagt.CorpusRegistry::index_all_sources_async→index_one_source) las met een ander resolutiepad:resolve_token_for_sourcemét legacyCORPUS_GIT_TOKEN-fallback, waar push/backendconstructie strikt resolven (resolve_token_strict).CORPUS_AUTH_<owner-repo-slug>_TOKEN(en zonder bruikbaar legacy-token) scant de server een privé-repo unauthenticated → Trees-API 404 → source faalt te enumereren → lege index → wet resolvet uit de seed (priority 2). Precies het waargenomen prod-gedrag;traject_own_index_test.rsreproduceert het zonder netwerk (wiremock).Naast de deploy-config-kant (ontbrekende env-var; de exacte naam staat als bevinding op het ticket — bewust niet in deze publieke PR) zat er dus ook een echte code-inconsistentie: scan en push konden over verschillende tokens beschikken, en de legacy-fallback op het scanpad zou het centrale token naar een user-gekozen repo sturen — het exfiltratie-lek waarvoor
resolve_token_strictjuist bestaat, maar dan op het leespad.Fix
Source.strict_auth(gezet voor writable-own rows, ook in de pipeline-worker) laat élk token-resolutiepad — indexscan, favorites-fetch, backendconstructie — dezelfde strikte regels volgen via de nieuweauth::resolve_source_token.index_all_sources_asyncgeeft per gefaalde source de fout terug (SourceIndexFailure);GET /api/trajects/{ref}/sources(en/api/sources) tonen die alsindex_errorper source, zodatlaw_count: 0mét fout te onderscheiden is van een écht lege repo.tracing::error!bij een gefaalde writable-own-scan draagt nu de onderliggende fout mee; de "resolved NO token"-diagnostiek benoemt naast pushes ook reads/scans.Tests
packages/editor-api/tests/traject_own_index_test.rs: (1) prod-repro — promote slaagt, onleesbare traject-repo → fallback naar seed (priority 2) +index_errorop de source; (2) happy path feat(editor): wet zoeken in centraal corpus, promoten naar traject en harvest-fallback via taken #952 — leesbare repo → gepromote wet in de traject-index opsource_priority: 0,law_count: 1, geenindex_error.resolve_source_token(strict vs. legacy) enbuild_source_summaries(index_error).just checkgroen (format, clippy, check, validate, unit tests, harvester-, pipeline-, admin- en editor-api-tests; testcontainers viaTESTCONTAINERS_HOST_OVERRIDE).