LodeTime — DevOps som provenanskedja
Kan en körmiljö spåra sin egen utveckling? När produktionen går sönder, kan du spåra bakåt från incidenten till beslutet som orsakade den?
Forskning | rekursiv provenans, CI/CD som DAG, beroendebeslut, driftsättningsspårning
Scenariot
Proliminal släpper Liminara v0.9.2 på en tisdag. På torsdag rapporterar en kund att VSME-packetets XBRL-renderare producerar ogiltigt utdata — elementet xbrli:period använder ett felaktigt datumformat för varaktighetsupplysningar. Fixen är enkel (en tvåradspatch), men frågan i efteranalysen är svårare: hur hamnade detta i produktion?
Svaret involverar en beroendeuppgradering, en CI-konfigurationsändring, ett testgap och ett driftsättningsbeslut — utspritt över tre veckor och fyra personer. Idag kräver rekonstruktionen av denna kedja att man söker genom Slack-meddelanden, CI-loggar, GitHub PR-kommentarer och driftsättningsposter. Med LodeTime är hela utvecklingslivscykeln i sig en provenance-spårad pipeline. Kedjan finns redan.
Pipelinen
LIMINARA v0.9.2 RELEASE — traced backward from the incident
═════════════════════════════════════════════════════════════
Week 1: Dependency decision
┌───────────────────────────────────────────────────┐
│ dev.dependency_review │
│ │
│ ex_xbrl 0.4.1 → 0.5.0 │
│ Decision: upgrade │──→ decision record:
│ Reason: "0.5.0 adds ESRS 2024 taxonomy; │ dep = "ex_xbrl"
│ changelog shows no breaking changes" │ from = "0.4.1"
│ Decided by: erik.lindqvist │ to = "0.5.0"
│ │ rationale = "ESRS 2024
│ What wasn't noticed: duration period format │ taxonomy support"
│ changed from ISO 8601 basic to extended │
└───────────────────────────────────────────────────┘
│
Week 2: CI configuration
┌───────────────────────────────────────────────────┐
│ dev.ci_config_update │
│ │
│ .github/workflows/ci.yml updated │──→ ci-config (förseglad)
│ Change: XBRL validation step timeout │ sha256:3a91...
│ increased from 30s to 120s │
│ (unrelated, but the XBRL validation suite │
│ was skipped in the same PR due to flakiness) │
└───────────────────────────────────────────────────┘
│
Week 2: Test execution
┌───────────────────────────────────────────────────┐
│ dev.run_tests │
│ │
│ mix test — 847 pass, 0 fail, 3 skip │──→ test-report (förseglad)
│ Skipped: xbrl_validation_test.exs │ sha256:f2d4...
│ (marked @tag :skip in the CI config PR) │
│ │
│ The three skipped tests would have caught │
│ the period format change. │
└───────────────────────────────────────────────────┘
│
Week 3: Deployment decision
┌───────────────────────────────────────────────────┐
│ dev.deploy_decision │
│ │
│ Deploy target: production (fly.io, arn region) │──→ decision record:
│ Decision: deploy v0.9.2 │ version = "0.9.2"
│ Decided by: klara.nilsson │ target = "production"
│ Based on: test report (847 pass), │ approved_by =
│ staging smoke test (pass), │ "klara.nilsson"
│ changelog review │
└───────────────────────────────────────────────────┘
│
Week 3: Deployment execution
┌───────────────────────────────────────────────────┐
│ dev.deploy_execute │
│ │
│ fly deploy --app liminara-prod │──→ deploy-receipt
│ Image: sha256:9c17... │ (förseglad)
│ Healthy: 3/3 instances │ sha256:b5e0...
└───────────────────────────────────────────────────┘
│
Thursday: Incident
┌───────────────────────────────────────────────────┐
│ Customer report: XBRL period format invalid │
│ │
│ Trace backward: │
│ deploy-receipt → deploy decision │
│ → test-report (3 tests skipped!) │
│ → ci-config change (skip was here) │
│ → dependency decision (format change) │
│ │
│ Root cause visible in < 2 minutes. │
└───────────────────────────────────────────────────┘
Den rekursiva egenskapen
LodeTime behandlar Liminaras egen utveckling som en Liminara-körning. Detta är inte metaforiskt — det är en bokstavlig pipeline:
- Beroendeversioner är beslut (registrerade med motivering, beslutade av en person)
- CI-konfiguration är versionerad och förseglad
- Testkörning är deterministisk (samma indata producerar samma resultat)
- Val av driftsättningsmål är ett beslut (registrerat med motivering och godkännande)
- Driftsättning är grindad och kvitterad
Samma fem koncept som driver VSME-packet (Artefakt, Op, Beslut, Körning, Pack) driver utvecklingsprocessen som bygger VSME-packet. Körmiljön som tillhandahåller provenans har provenans över sig själv.
Efteranalysen, spårad
Utan LodeTime tar efteranalysen en dag av forensik: läsa commit-meddelanden, söka CI-loggar, fråga Erik varför han uppgraderade ex_xbrl. Med LodeTime är hela kedjan navigerbar i observationsgränssnittet:
- Börja vid incidenten: “XBRL-periodformat ogiltigt i v0.9.2”
- Hitta driftsättningskörningen för v0.9.2:
lode-deploy-2026-03-18 - Se driftsättningsbeslutet: godkänt av Klara, baserat på testrapport sha256:f2d4…
- Öppna testrapporten: 847 godkända, 0 underkända, 3 överhoppade — klicka på de överhoppade testerna
- Spåra överhoppningen: introducerad i CI-konfigurationsartefakt sha256:3a91…, committad i samma PR som timeout-ändringen
- Spåra beroendet: ex_xbrl 0.4.1 till 0.5.0, beslut av Erik, motivering registrerad
- Grundorsak: beroendeuppgraderingen ändrade periodformatbeteendet, och testerna som hade fångat det hoppades över i en orelaterad CI-ändring
Varje länk i denna kedja är en förseglad artefakt eller ett registrerat beslut. Kedjan kan inte brytas genom att någon raderar ett Slack-meddelande eller en CI-logg löper ut.
Vad du kan fråga efteråt
| Fråga | Hur den besvaras |
|---|---|
| ”Varför uppgraderades ex_xbrl till 0.5.0?” | Beslutspost: Eriks motivering (“ESRS 2024-taxonomistöd”), ändringsloggen han granskade (förseglad) och datumet. |
| ”Vem godkände driftsättningen till produktion?” | Beslutspost: Klara, med de underlag hon förlitade sig på (testrapport, staging-resultat). |
| ”Varför kördes inte XBRL-valideringstesterna?” | Spåra: CI-konfigurationsartefakt sha256:3a91… introducerade @tag :skip. Den konfigurationen committades i PR #137 (timeout-fix). Överhoppningen var en sidoeffekt av en annan ändring. |
| ”Vad hade hänt om vi inte hoppat över de testerna?” | Hypotetisk omspelning: kör om lode-test-2026-03-15 med överhoppningen borttagen. De tre testerna fallerar. Driftsättningsbeslutets indata (testrapporten) ändras. Grinden hade inte passerat. |
| ”Vilka andra driftsättningar använde denna CI-konfiguration?” | Fråga: alla körningar som refererar ci-config sha256:3a91… som indata. Returnerar varje bygge som körde med de överhoppade testerna. |
| ”Har detta beroende orsakat problem tidigare?” | Fråga: alla beslutsposter där dep = "ex_xbrl". Returnerar hela uppgraderingshistoriken med motiveringar och nedströmseffekter. |
Före och efter
Idag: Efteranalysen tar en dag. Erik minns uppgraderingen men inte detaljerna. CI-konfigurationsändringen var två veckor sedan och PR-beskrivningen säger “fix timeout.” Kopplingen mellan timeout-fixen, testöverhoppningen och driftsättningen är osynlig. Retron producerar en åtgärdspunkt: “lägg till XBRL-validering i CI.” Ingen minns detta sex månader senare när samma mönster upprepas med ett annat beroende.
Med provenans: Efteranalysen tar femton minuter. Kedjan från incident till grundorsak är navigerbar. Beslutet att hoppa över tester är en registrerad artefakt — inte en bortglömd commit i en bortglömd PR. Beslutet att uppgradera beroendet inkluderar motivering och beslutsfattare. När någon föreslår att hoppa över tester i en framtida CI-ändring kan systemet visa: “förra gången tester hoppades över i CI-konfiguration ledde det till incident #47 i produktion.” Det institutionella minnet finns i provenanskedjan, inte i folks huvuden.
Söker team intresserade av att tillämpa provenansinfrastruktur på sina egna utvecklings- och driftsättningsprocesser — särskilt de med revisions- eller efterlevnadskrav på mjukvaruslippar. [Kontakt ->]