§

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?

Aktiv utveckling recursive provenanceCI/CDdependency decisionsdeployment tracing
— — — — —

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:

  1. Börja vid incidenten: “XBRL-periodformat ogiltigt i v0.9.2”
  2. Hitta driftsättningskörningen för v0.9.2: lode-deploy-2026-03-18
  3. Se driftsättningsbeslutet: godkänt av Klara, baserat på testrapport sha256:f2d4…
  4. Öppna testrapporten: 847 godkända, 0 underkända, 3 överhoppade — klicka på de överhoppade testerna
  5. Spåra överhoppningen: introducerad i CI-konfigurationsartefakt sha256:3a91…, committad i samma PR som timeout-ändringen
  6. Spåra beroendet: ex_xbrl 0.4.1 till 0.5.0, beslut av Erik, motivering registrerad
  7. 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ågaHur 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 ->]

— — — — —