# Landvex Ingest — automationsspec v0 ## Datafabriken: från källa till validerad graf utan handpåläggning ⸻ ## Kedjan **Källor → Skördare → Källpaket → Extraktor (LLM) → Kandidatposter → Ingest (deterministisk) → Master + Graf + Bounty-förslag → Rapport** Två halvor med olika natur: * **Skörd + extraktion** är probabilistisk (sök, läs, referera). Får föreslå — aldrig besluta. * **Ingest** är deterministisk kod (`ingest.py`). Den beslutar: upplöser entiteter, verkställer merge-policyn, mintar ID, validerar, bygger grafen. Samma indata ger alltid samma bibliotek. ⸻ ## Stegen **1. Skördare.** Hämtar källor per kö (se Drift). Output: *källpaket* — referat med URL-lista, aldrig kopierad text. Rätten till originalet stannar hos källan; biblioteket bär referat + referens. **2. Extraktor.** LLM med `lvx-extraktionsprompt.md` som kontrakt. Output: *kandidatposter* i patch-format. Får högst föreslå nivån källbelagd. **3. Ingest (`ingest.py`).** * **Entitetsupplösning:** lvx_id → slug → namnlikhet ≥ 0,88 (difflib). Dublett stoppar `ny`. * **Merge-policy:** källor unionas på URL; standarder dedupe:as på normaliserad beteckning (så att "EN 1917 (kartläggs)" ersätts av "EN 1917:2002"); tomma fält fylls; **ifyllda fält skrivs aldrig över** — konflikter loggas till granskningskö. * **Verifieringstrappan:** lyft sker endast uppåt, och källbelagd kräver icke-tom källista. Fältverifierad/tillverkarbekräftad kan bara sättas av foto- respektive portalflödet. * **ID-mintning:** `lvx-id-register.json` håller nästa nummer per serie; register skrivs tillbaka atomärt; ID återanvänds aldrig. * **Validering:** samma regler som konsolideringen (ID-format, domän, namn sv/en, predikatenum, problem-källa, parent, källkrav). Fel ⇒ batchen flaggas. * **Grafexport:** kantlista regenereras ur posterna varje körning — grafen är alltid härledd, aldrig handredigerad. **4. Bounty-generatorn.** Varje körning skannar posterna: källbelagd + OCR-fält + ingen aktiv bounty ⇒ bounty-förslag. Flyhjulet matas automatiskt av ny data. **5. Rapport.** Körningslogg: uppdaterade/nya, nivålyft, källor, konflikter, valideringsfel, grafstatistik. ⸻ ## Drift: tre köer in i skördaren | Kö | Trigger | Exempel | |---|---|---| | **Schemalagd** | Domän-/klasscykel | "Alla TRP-standarder omkontrolleras kvartalsvis" | | **Kunddriven** | `POST /v0/feedback` + svaga identify-svar | Okänd modell i Leeds ⇒ riktad skörd + bounty | | **Fält** | Zoomer-foton godkända | OCR-data ⇒ individposter + nivålyft till fältverifierad | Kunddrivna kön är SaaS-motorn: betald efterfrågan bestämmer var datafabriken gräver härnäst, och kostnaden bärs av intäkten den skapar. ⸻ ## Kostnadsmåttet **Kostnad per verifierat faktum** = (skörd + extraktion + granskning) / antal nivålyft & nya källbelagda fält. Våg 7-demon: 3 sökningar + 1 korsreferens gav 4 nivålyft, 9 nya källor, 9 standardposter och 1 ny modell — korsreferenssteget (återanvänd källa, noll ny skörd) är gratis-lyften som automationen ska hitta själv i produktionen. ⸻ ## Miljönot I denna arbetsyta: Claude är skördare + extraktor (web_search/web_fetch), containern kör ingest. I produktion: crawler med källvitlista + LLM-API bakom extraktionsprompten + granskningskö-UI för konflikter. `ingest.py` är samma kod i båda miljöerna. ⸻ ## Filkarta | Fil | Roll | |---|---| | `intag/kallpaket-*.json` | Skördarens output | | `intag/kandidatposter-*.json` | Extraktorns output | | `lvx-extraktionsprompt.md` | LLM-kontraktet | | `lvx-id-register.json` | ID-serier (mintning) | | `ingest.py` | Pipelinens kärna | | `lvx-klassposter-master-vN.json`, `lvx-graf-kanter-vN.json` | Beslutade utdata | | `lvx-bounty-kandidater-*.json` | Flyhjulsförslag till granskning |