Händelser, fullständighet och färskhet
Klockan 09.09 visar Nordic fyra gröna komponenter. Ett DocumentGenerated
har nyligen observerats och eventflödet är färskt. Ändå saknas fem av 142
verifierade mottagningskvitton.
Det är inget motsägelsefullt i detta. Tre olika frågor har besvarats:
- Lever komponenterna? Ja, enligt färska health-observationer.
- Har flödet nyligen producerat event? Ja.
- Har alla 142 dokument nått rätt slutstatus? Det vet Matrix ännu inte.
Ett kontrollager som blandar dessa frågor kan vara tekniskt realtidsuppdaterat och samtidigt operativt fel.
1. Eventet är ett påstående om en förekomst
Ett event representerar att något inträffade: ett processteg startade, ett dokument genererades, en deployment applicerades eller ett webhookkvitto observerades. Eventet är inte själva förekomsten. Det är en post skapad av en producent med den precision, identitet och täckning som producenten förmår.
Matrix eventkontrakt kräver i nuläget:
id,- en typ ur eventvokabulären,
occurredAtmed explicit tidszon,- minst en
sourceRef.
subjectNodeId, relatedNodeIds, metadata och bundlets generatedAt är
valfria (MATRIX-EVENT-CONTRACT). Kontraktet ger därmed en god miniminivå för
tid och källpekare, men varje event kan inte antas vara korrelerbart till ett
stabilt grafsubjekt.
CloudEvents använder source + id som unik identitet för en distinkt
händelseförekomst och låter en omsänd dubblett behålla samma identitet
(cloudevents10). Matrix har producerId på bundle och id på event. Parets
likhet med CloudEvents är en möjlig exportprofil, inte ännu ett uttalat
likhetstecken mellan modellerna.
2. Fem oberoende kvalitetsfrågor
Innan ett event används som kunskap bör Matrix pröva minst fem frågor:
| Dimension | Fråga | Fel som kan döljas |
|---|---|---|
| Giltighet | Följer posten schema och vokabulär? | trasig tid, okänd typ |
| Identitet | Är förekomsten unik eller en omsändning? | dubbelräkning |
| Korrelation | Vet vi vilket subjekt, flöde och scope den tillhör? | rätt event på fel objekt |
| Färskhet | Har relevanta flöden observerats inom avtalad tid? | död producent |
| Fullständighet | Har den mängd som beslutet kräver observerats? | tyst bortfall |
En grön rad i en dimension får inte färga de andra gröna.
3. Färskhet är ett flödeskontrakt
Matrix stalenessgrind arbetar per (producerId, eventType). Varje registrerad
producent måste ha en policy. Ett flöde kan antingen:
- vara levande med en positiv
maxAgeDays, - vara avsiktligt dormant genom
acceptedStaleoch en riktig orsak, - eller tillhöra en producent som uttryckligen inte förväntas emittera event.
Saknad policy, observerad men obokad eventtyp, ett levande flöde utan event
eller ett event äldre än tillåten ålder stoppar aggregate build
(MATRIX-EVENT-STALENESS). Undantag utan orsak är röda och stale bookings
lyfts för borttagning.
Detta löser ett viktigt problem: en eventström kan inte dö tyst och fortsätta
presenteras som aktuell. Det är också ett exempel på varför en enda global
freshnessgräns är fel. I den faktiska policyn har arbetsdrivna flöden olika
dagbudgetar. GeneratorFailed är avsiktligt acceptedStale, eftersom tystnad
är det normala när inget misslyckas. En policy som kräver färska fel skulle
kräva att systemet regelbundet producerar fel för att bli grönt
(CLAIM-EVENT-005).
3.1 En artefakt är inte färskare än sitt äldsta obligatoriska underlag
Matrix har nu även en fail-closed freshnessgrind för genererade
evidensartefakter. Den skiljer generatorns generatedAt från källornas
validAt: att bygga om en dashboard i dag gör inte gårdagens observationer
nya. Kedjans trovärdiga freshness begränsas av den äldsta obligatoriska
källan. Stale, malformed och obokade källor fäller grinden; en källa utan
tidsstämpel måste uttryckligen bokas i policyn. Detta skyddar Command Center
mot “nytt skal runt gammal grön bild” (MATRIX-EVIDENCE-FRESHNESS,
CLAIM-EVENT-007).
4. Färskt är inte fullständigt
Anta att Nordic får ett nytt kvitto för dokument 137 varje minut men aldrig
får kvitton för 138–142. WebhookDelivered kan förbli färskt för alltid.
Slutresultatet är ändå ofullständigt.
Matrix nuvarande stalenesspredikat väljer det senaste occurredAt per
eventtyp. Det bedömer inte:
- om alla förväntade subjekt har event,
- om sekvensnummer har luckor,
- om alla partitioner eller sidor lästes,
- om antal unika event matchar en deklarerad population,
- om varje start fått ett terminalt utfall,
- om en viss tenant eller miljö saknas.
Det är rätt avgränsning för en liveness-/stalenessgrind, men fel verktyg för
att hävda total täckning (CLAIM-EVENT-001).
5. Fullständighet kräver en nämnare
"Vi har 137 kvitton" är ett antal. "Vi har 137 av 142 förväntade unika
dokument före deadline" är ett fullständighetspåstående. Nämnaren, scope och
gränsen gör skillnaden (CLAIM-EVENT-002).
Vanliga fullständighetskontrakt är:
| Kontrakt | Exempel | Bevis för lucka |
|---|---|---|
| Population | 142 namngivna dokument ska få terminal status | subjektmängdens differens |
| Sekvens | offset 1001–1142 ska observeras | saknade intervall |
| Livscykel | varje ProcessStarted följs av terminalt event |
öppna instanser |
| Partition | alla 12 källpartitioner ska passera cursor C | partition-watermarks |
| Batch | manifest med 142 poster och digest | manifest kontra utfall |
| Sampling | 10 % enligt deklarerad urvalsregel | urvalsram och seed |
| Negativt flöde | fel emitteras endast vid fel | bevisad observationsförmåga, inte färska fel |
Alla eventflöden behöver inte alla kontrakt. Men varje beslutsfråga behöver ett svar på "komplett relativt vad?".
6. Händelsetid och observationstid
occurredAt är tiden då producenten säger att förekomsten inträffade. Om ett
kvitto skapas 09.07 men når Matrix 09.24 är det sent observerat, inte en
händelse som inträffade 09.24.
OpenTelemetry Logs Data Model skiljer Timestamp, mätt vid ursprunget, från
ObservedTimestamp, mätt när insamlingssystemet observerar posten
(otel-logs-data-model). Samma separation behövs för att mäta:
- transport- och insamlingsfördröjning,
- sena event,
- källklockans avvikelse,
- när Matrix faktiskt kunde känna till förekomsten,
- om en backfill felaktigt ser ut som realtid.
Matrix bundlets valfria generatedAt är inte samma sak som ett per-event
observedAt eller recordedAt. Ett bundle kan byggas om långt efter att
enskilda event samlades in. RESEARCH-014 prövar därför en additiv profil mot
CloudEvents och OpenTelemetry innan kärnschemat ändras (CLAIM-EVENT-003).
7. Ordning och korrelation
Sortering på occurredAt ger inte automatiskt kausal ordning. Två
källsystemklockor kan gå olika, och event kan transporteras olika vägar.
Lamports happened-before-relation visar varför kausalitet behöver explicita
meddelande- eller processrelationer, inte bara fysisk tid
(lamport1978time, CLAIM-TIME-002).
En användbar eventprofil kan därför behöva:
eventIdentity: source + id
subjectIdentity
tenant + environment
occurredAt
observedAt / recordedAt
correlationId
causationId
traceId + spanId när relevant
partition + sequence/offset när källan erbjuder det
sourceRef + source revision/cursor
correlationId grupperar exempelvis alla event i batchen. causationId
anger vilket event som direkt utlöste nästa. Trace context passar tekniska
requestkedjor men ersätter inte alltid verksamhetskorrelation: en batch kan
leva längre än en trace och passera asynkrona eller manuella gränser.
8. Dubbletter, retries och idempotens
Matrix validator räknar event-ID:n i varje bundle och vägrar dubbletter. Regeln
tillkom efter att en producent använde sekundupplösning och gav två distinkta
event samma ID (MATRIX-EVENT-VALIDATION). Det är en stark identitetsgrind.
Tre situationer måste ändå skiljas:
- Omsändning: samma förekomst skickas igen med samma ID.
- Retry: ett nytt försök är en ny förekomst med eget ID men samma correlation/causation-kedja.
- Kollision: olika förekomster får felaktigt samma ID.
Deduplicering kan hindra att samma event räknas två gånger i en viss läsmodell.
Den garanterar inte att en extern side effect bara utförs en gång. Om en
konsument skriver till xECM och kraschar före sitt acknowledgement kan samma
leverans behandlas igen. Stabil identitet behöver därför kombineras med
idempotency key, transaktionell inbox/outbox eller annan konsumentspecifik
effektgrind (CLAIM-EVENT-004).
9. Watermark: när slutar vi vänta?
I ett obegränsat och oordnat flöde vet konsumenten normalt inte att alla data
har anlänt. Dataflow-modellen gör avvägningen mellan korrekthet, latens och
kostnad explicit (akidau2015dataflow). Streamprocessorer använder
watermarks för att ange att eventtiden sannolikt avancerat förbi en gräns;
senare event behandlas enligt en deklarerad latenesspolicy
(flink-watermarks).
För Nordic kan policyn vara:
window: batchens start till receiptDeadline 09.10
firstResult: publicera preliminärt vid 09.10
allowedLateness: 20 minuter
stabilAccordingToPolicy: 09.30
lateHandling: korrigera additivt och märk tidigare assessment superseded
neverSilentlyDrop: sena avvisanden skapar finding även efter finalitet
En watermark är inte ett bevis på ontologisk fullständighet. Den är ett
versionsbundet beslut att sluta vänta enligt känd fördröjningsmodell
(CLAIM-EVENT-006). Därför bör gränssnittet säga stabil enligt policy v3,
inte bara final.
10. Nordic: från 137 till känt utfall
Vid 09.10 känner Matrix till:
- 142 förväntade dokument,
- 142 genererade,
- 137 verifierade kvitton,
- 5 okända slututfall.
Två event med occurredAt omkring 09.07 registreras först 09.24. Bedömningen
för deadline korrigeras då till 139 verifierade och 3 okända. Vid 09.31
kommer två retrykvitton. Vid 09.33 kommer ett belagt avvisande för dokument
142.
Observera språket:
- 09.10: preliminärt och ofullständigt, inte failed,
- 09.24: korrigerat med sen data, fortfarande tre okända,
- 09.31: 141 accepterade, ett okänt, inte 142 levererade,
- 09.33: 141 accepterade, ett avvisat, populationen har terminal status.
Komponenthälsan ändrar inget av dessa objektsutfall.
11. Täckning som operativ produktfunktion
För varje eventbaserad vy bör Matrix kunna redovisa:
expected subjects / partitions / sequence interval
observed unique events
duplicates and collisions refused
missing subjects or ranges
newest occurredAt
newest observedAt
watermark and allowed lateness
late/retracted/corrected counts
source cursor or revision
policy id and version
Om ingen nämnare finns ska vyn säga färskt flöde, okänd objektfullständighet. Detta är mer informativt än ett generellt gult eller grönt ljus.
12. Konsekvenser för Matrix självt
Samma krav gäller Coordinator och agenter. Ett färskt heartbeat visar kontakt, inte att agenten läst alla uppgifter, producerat korrekt resultat eller att alla run records nått terminal status. En kövy behöver därför separat visa:
- heartbeat-/leasefärskhet,
- antal förväntade och observerade run transitions,
- öppna körningar utan terminal post,
- dubbletter och redispatches,
- eventfördröjning och senaste lyckade materialisering,
- vad som aldrig instrumenterats.
Detta förbereder kapitel 11 och 15: Matrix måste mäta sin egen observationsförmåga med samma stränghet som kundsystemens.
13. Teknikbedömning
CloudEvents kan förbättra interoperabel identitet och routingkontext. OpenTelemetry kan förbättra observationstid och trace-korrelation. En streamprocessor kan ge fönster, watermarks och stateful deduplicering.
Ingen av dem definierar automatiskt Nordics nämnare på 142 dokument, rätt terminalstatus eller vilken sen korrektion verksamheten accepterar. Teknikerna kan bära kontraktet; domänen måste fortfarande formulera det.
RESEARCH-014 testar formatmappning och RESEARCH-015 klassificerar Matrix
flöden som puls, sparse-negative, per-entity, sequence eller bounded-batch.
Först därefter går det att avgöra vilka nya fält eller motorer som behövs.
Praktisk granskningslista
- Namnge förekomsten och dess stabila identitet.
- Bind eventet till producent, subjekt, tenant och miljö.
- Separera occurred, observed/recorded och processing time.
- Definiera omsändning, retry och kollision.
- Klassificera flödet: puls, negativt, per subjekt, sekvens eller batch.
- Sätt freshnessbudget per flöde och boka legitim tystnad med orsak.
- För härledda artefakter: skilj
generatedAtfrån varje källasvalidAtoch låt äldsta obligatoriska källa begränsa kedjan. - Ange nämnare: population, intervall, partitioner eller livscykel.
- Definiera watermark, allowed lateness och korrektionsregel.
- Gör side effects idempotenta oberoende av leveranslöftet.
- Visa luckor och observationsförmåga bredvid slutsatsen.
Sammanfattning
Ett event säger att en producent registrerat en förekomst. Ett färskt event säger att flödet nyligen producerat något. Inget av dessa påståenden säger automatiskt att alla relevanta förekomster eller subjekt observerats.
Matrix stalenessgrind är stark eftersom den vägrar tyst döda och obokade flöden. Den ska behållas som freshnesskontrakt, inte övertolkas som fullständighetsbevis. Beslutsrelevanta flöden behöver dessutom en uttrycklig nämnare, identitet, tidsdomäner och finalitetspolicy.
Det trovärdiga gränssnittet säger därför både hur färskt och komplett relativt vad. När en watermark passerats säger det stabil enligt policy, och när sen data anländer korrigerar det historiken additivt.
Läranderesultat
Efter kapitlet ska studenten kunna:
- skilja eventvaliditet, korrelation, färskhet och fullständighet,
- välja rätt fullständighetskontrakt för olika flödestyper,
- analysera event-, observations- och processing time,
- modellera retries och dubbletter utan falskt exactly-once-påstående,
- formulera watermark och late-data-policy,
- designa en coveragevy för både kundsystem och Matrix kontrollplan.
| FIG-06-01 — Från event till tids- och täckningsbedömt kunskapstillstånd |
Visa diagramdefinition
flowchart LR
O[Händelse i källsystem] -->|occurredAt| E[Event envelope]
E --> I[Insamling]
I -->|observed/recorded at| D[Identitet + deduplicering]
D --> F{Färskhetskontrakt}
F -- stale/refused --> U[Okänt eller begränsat svar]
F -- färskt --> C{Fullständighetskontrakt}
C -- gap/öppen gräns --> U
C -- tillräckligt enligt policy --> W[Preliminär eller stabil bedömning]
W --> L[Sen data / korrektion]
L --> W
Fördjupningsmaterial
Övningar och laboration
Övningar och laboration
Övning 1: grön men ofullständig
Utgå från Nordic-fixturen. Skriv två korrekta och två felaktiga slutsatser av
att WebhookDelivered är färskt 09.09. För varje slutsats, ange vilket
ytterligare underlag som krävs.
Övning 2: klassificera tystnaden
Klassificera följande flöden som puls, sparse-negative, per-entity, sequence eller bounded-batch:
- heartbeat,
GeneratorFailed,- dokumentkvitton,
- queue offset,
- nattlig inventering,
- manuell approval rejection.
Föreslå freshness- och completenessregel. En regel som kräver regelbundna fel ska uttryckligen underkännas.
Övning 3: identitet och retries
Modellera tre leveranser av samma transportmeddelande och två verkliga försök att importera dokument 142. Ange event-ID, correlation ID, causation ID och idempotency key. Visa när två poster är dubbletter respektive nya förekomster.
Övning 4: watermarkförhandling
Två grupper representerar drift respektive ekonomi. Drift vill publicera Nordic-resultat efter två minuter; ekonomi kräver hög fullständighet före fakturering. Förhandla fram:
- första resultat,
- allowed lateness,
- stabilitetsstatus,
- regel för sena accepteranden,
- regel för sena avvisanden,
- när mänsklig grind krävs.
Laboration: event completeness gate
Indata
Använd cases/nordic-ch02-timeline.json och transformera relevanta
observationer till ett event-envelope. Minst följande fält ska finnas:
source, id, type, subject, tenant, environment,
occurredAt, observedAt, correlationId, sourceRef
Skapa ett batchmanifest med de 142 förväntade dokument-ID:na.
Implementera
- schema- och tidszonsvalidering,
- unik identitet inom
source, - deduplicering av omsändningar,
- separat modell för retries,
- freshness per eventtyp,
- populationsfullständighet mot manifestet,
- preliminär/stabil-enligt-policy/korrigerad status,
- rapport över saknade subjekt och eventfördröjning.
Mutationstester
- duplicera ett event med samma
source + id, - ge två olika förekomster samma ID,
- ta bort dokument 140 ur förväntad population,
- håll flödet färskt genom att bara repetera dokument 137,
- flytta
observedAt20 minuter efteroccurredAt, - skicka ett avvisande efter watermark,
- gör
GeneratorFailedtyst i 60 dagar.
Lösningen ska skilja legitim tystnad, dubblett, kollision, sen data och populationslucka. Tyst grönt vid någon mutation är underkänt.
Inlämning
- envelope- och manifestformat,
- policy med motivering per flödestyp,
- testresultat för samtliga mutationer,
- coverage report för 09.10, 09.24, 09.31 och 09.33,
- kort jämförelse med CloudEvents/OpenTelemetry utan krav på adoption.
Bedömning, 20 poäng
| Del | Poäng |
|---|---|
| Eventidentitet och korrelation | 4 |
| Flera tidsdomäner och late data | 4 |
| Freshness och legitim tystnad | 3 |
| Fullständighetsnämnare och gaprapport | 5 |
| Mutationstester och fail-closed-beteende | 4 |
Godkänt kräver minst 12 poäng samt att ett färskt men ofullständigt flöde inte rapporteras som komplett.
Källor och begränsningar
Kapitelkällor
| Cite-key/käll-ID | Funktion | Begränsning |
|---|---|---|
akidau2015dataflow |
Event time, out-of-order-data och avvägningen correctness/latency/cost. | Storskalig stream processing; Matrix behöver en mindre profil. |
lamport1978time |
Kausal ordning i distribuerade system. | Ger inte ett färdigt event-envelope. |
cloudevents10 |
Interoperabel eventidentitet genom source + id, typ och kontext. |
Löser inte domänfullständighet eller exakt-en-gång-effekter. |
otel-logs-data-model |
Skiljer Timestamp från ObservedTimestamp och erbjuder trace context. |
Telemetrimodell, inte Matrix sanningsmodell. |
flink-watermarks |
Konkret watermark-, lateness- och completenesssemantik. | Produktspecifik dokumentation; används som designexempel. |
| MATRIX-EVENT-CONTRACT | Faktisk Matrix-vokabulär, tidszon och valfria subjektfält. | Saknar generell sekvens-/watermarkprofil. |
| MATRIX-EVENT-VALIDATION | Dubblettgrind för event-ID inom bundle. | Bevisar inte idempotent effekt hos konsumenter. |
| MATRIX-EVENT-STALENESS | Fail-closed policy och predikat för levande/dormanta flöden. | Bedömer senaste event per typ, inte objekttäckning. |
| MATRIX-EVENT-STALENESS-POLICY | Verkliga skillnader mellan kontinuerliga, arbetsdrivna och sällsynta flöden. | Konfigurerad nulägespolicy, inte generell teori. |
| MATRIX-EVIDENCE-FRESHNESS | Fail-closed källbokning och freshness genom hela evidenskedjan. | Freshness bevisar inte completeness eller att källinnehållet är sant. |
Argumentkarta
Argumentkarta: händelser, fullständighet och färskhet
Huvudtes
Eventbaserad kunskap blir beslutbar först när Matrix redovisar både att flödet lever och varför den observerade mängden är tillräcklig för den specifika frågan. Färskhet utan fullständighetsgräns kan ge en snabbt uppdaterad men systematiskt ofullständig bild.
Kedja
- Senaste eventet mäter flödets aktualitet, inte täckningen av förväntade
event eller subjekt (
CLAIM-EVENT-001). - Fullständighet kräver ett deklarerat universum eller en gräns
(
CLAIM-EVENT-002). - Händelsetid och insamlingstid behövs för att identifiera sen data
(
CLAIM-EVENT-003). - Identitet kan hitta dubbletter men skapar inte exakt-en-gång-effekt
(
CLAIM-EVENT-004). - Tystnadens betydelse beror på om flödet är puls, felhändelse, batch eller
per-subjekt-kvitto (
CLAIM-EVENT-005). - En watermark gör avvägningen mellan väntetid och fullständighet explicit,
men är fortfarande ett antagande (
CLAIM-EVENT-006).
Motbevisande test
Om senaste event per typ ensamt kan avslöja ett borttappat Nordic-kvitto, en saknad partition och en tyst felhändelse utan ytterligare förväntningar behövs ingen separat fullständighetsmodell. Laborationen är konstruerad för att visa att så inte är fallet.
Faktagranskning och öppna beslut
Kapitelgranskning
Status: första manusutkast 2026-08-10. Intern implementations-, standard- och pedagogisk granskning gjord. Extern stream processing-/eventarkitekturreview och körbar studentlösning återstår.
Faktagranskning
- Matrix event kräver ID, typ,
occurredAtmed tidszon och minst ensourceRef. subjectNodeId,relatedNodeIdsoch bundle-generatedAtär valfria.- Validatorn vägrar duplicerade event-ID:n inom ett bundle.
- Staleness bedöms per producent/eventtyp utifrån senaste giltiga
occurredAt. - Policyn skiljer levande flöden, motiverat
acceptedStaleoch producenter utan förväntade event. - Den granskade stalenessgrinden mäter inte population, sekvensluckor eller partitionstäckning.
Akademisk och standardmässig granskning
- Dataflow används för principen om obegränsad/out-of-order-data och correctness/latency/cost, inte som krav på Google-teknik.
- Flink används som konkret watermarkexempel och märks som produktspecifikt.
- CloudEvents används för
source + id-identitet, inte som exactly-once-garanti. - OpenTelemetry används för timestamp/observed timestamp och trace context, inte som generell kunskapsmodell.
Arkitekturgranskning
- Befintlig stalenessgrind föreslås inte ersättas.
- Fullständighetskontrakt läggs bredvid freshness per beslutsrelevant flöde.
- Evidensartefakter skiljer
generatedAtfrån källornasvalidAt; äldsta obligatoriska källa begränsar kedjans freshness och obokad källa fäller. - Freshnesskärnans hermetiska tester passerar, men två real-workspace-fall är
röda eftersom Command Center-producenter/policy ännu inte är fullt migrerade
(
RESEARCH-047). RESEARCH-014kräver round-trip-test före event-schemaändring.RESEARCH-015kräver flödesklassificering före generell sequence- eller watermarkmodell.- Öppet: duplicate-ID-grinden är lokal per bundle; verifiera om en framtida
sammanslagen eventvy behöver global
(producerId, id)-grind.
Pedagogisk granskning
- Nordic visar samma flöde som färskt men ofullständigt.
- Tystnadsövningen motverkar naiva freshnessregler för felhändelser.
- Laborationen kräver mutation som håller ett flöde färskt med samma subjekt.
Öppna beslut
- Vilka tre Matrix-flöden är först ut för completenesspilot?
- Ska
observedAtvara kärnfält, profilfält eller lagras i ingest journal? - Vilken identitet ska en omsändning behålla över adaptergränser?
- Hur visas "stabil enligt policy" utan att användaren läser det som absolut finalitet?
Kapitelkontrakt
Syfte
Visa varför färska event, ett levande flöde och ett fullständigt beslutsunderlag är tre olika saker. Kapitlet ger en modell för eventidentitet, flera tidsdomäner, dubbletter, luckor, tystnad, watermarks och korrektioner.
Lärandemål
Studenten ska kunna formulera ett fullständighetskontrakt, bedöma tystnad per flödestyp, skilja eventtid från observationstid, designa idempotent konsumtion och förklara finalitet som policy snarare än absolut sanning.
Fallstudiehändelse
Nordic har ett färskt dokumentflöde och friska komponenter, men bara 137 av 142 kvitton vid deadline. Två kvitton anländer senare och ett dokument avvisas. Kapitlet avgör vad som får kallas färskt, komplett och finalt.