Gesprekverloop
Dit document beschrijft het volledige verloop van één AI-ondersteund telefoongesprek via het Audact-platform, van de compliance-controle vóór het bellen tot de verificatie na het gesprek.
Fase 1: Vóór het bellen (Policy Engine)
POST /v1/evaluate — Staatloze compliance-controle. Er worden geen bewijsgebeurtenissen geschreven.
De Policy Engine beoordeelt landspecifieke regels (toestemmingsvereisten, DNC-register, stilte-uren) en geeft ALLOW of BLOCK terug met redenen. Bij BLOCK mag het gesprek niet worden voortgezet.
GET /v1/policies/{country} — Het actieve regelwerk voor een land opvragen (ISO 3166-1 alpha-2). Geeft het volledige regelschema terug, inclusief stilte-uren, toestemmingsvereisten en DNC-registerconfiguratie.
Fase 2: Begin van het gesprek
POST /v1/events met event_type: CALL_START
Het platform stuurt een CALL_START-gebeurtenis. De Evidence Layer maakt automatisch een calls-rij aan met status = 'active' als die nog niet bestaat.
Fase 3: Eerste beurt — Openbaarmaking vereist
POST /v1/validate (beurt 1)
In de eerste beurt wordt de openbaarmakingspoort geactiveerd, omdat call_state.disclosure_delivered == false. De validator geeft verdict: BLOCK terug met de originele tekst in het veld content. De overige 6 controles worden niet uitgevoerd (kortsluiting). Het platform moet zijn eigen openbaarmakingstekst uitspreken en disclosure_delivered = true instellen in de gespreksstatus voor volgende beurten.
Fase 4: Gesprek — Validator actief
POST /v1/validate (beurt N, herhaald per beurt)
De validator voert 7 controles uit binnen een harde tijdslimiet van 40 ms:
| # | Controle | Modus |
|---|---|---|
| 0 | Openbaarmakingspoort | Altijd afdwingen; kortsluiting bij BLOCK |
| 1 | Blokkeerlijst-scan | Schaduw of afdwingen (Aho-Corasick-patroonherkenning) |
| 2 | Prijsband | Schaduw of afdwingen (regex-prijsdetectie + bereikcontrole) |
| 3 | PII-scan | Schaduw of afdwingen (BSN, IBAN, creditcard via Luhn) |
| 4 | Escalatiedetectie | Schaduw of afdwingen (trefwoord + betrouwbaarheidsscore) |
| 5 | Toestemmingspoort | Schaduw of afdwingen (actie-toestemmingsledger-koppeling) |
| 6 | Consistentie tussen beurten | Afdwingen (prijs/feit/toezegging-consistentie) |
Uitspraken
Er zijn slechts drie uitspraken: ALLOW, BLOCK, MODIFY. Er is geen ESCALATE-uitspraak.
- ALLOW — Originele tekst wordt teruggegeven in
content. Bon:input_hash == output_hash. - MODIFY — Gewijzigde tekst wordt teruggegeven in
content. Bon:input_hash(origineel),output_hash(gewijzigd). - BLOCK — Originele tekst in
content; de aanroeper vervangt dit door zijn eigen fallback-antwoord. Bon:input_hash(origineel),output_hash(fallback).
Antwoordvorm (ACVFResponse)
json
{
"call_id": "uuid",
"turn": 1,
"verdict": "ALLOW | BLOCK | MODIFY",
"content": "validated or modified text",
"fail_open": false,
"receipt": { "..." },
"compliance_score": { "..." },
"checks": [
{
"check_id": "pii_scan",
"verdict": "ALLOW",
"reason": "",
"modified_content": "",
"duration_ms": 2
}
]
}De LLM Proxy schrijft na elke validatie een VALIDATION_RESULT-gebeurtenis naar de Evidence Layer (via POST /v1/events). Aan alle antwoorden die niet op fail-open zijn gebaseerd, wordt een compliance-bon toegevoegd.
Fail-Open (validator-timeout > 40 ms)
Als de validator de tijdslimiet van 40 ms overschrijdt: verdict: ALLOW, fail_open: true, content: originele tekst, receipt: nil. Onmiddellijk wordt een FAIL_OPEN-gebeurtenis geschreven voor waarschuwingen en asynchroon duurzaam opgeslagen. Het veld fail_open_meta bevat reason, deadline_ms, elapsed_ms en checks_completed.
PII-detectie (controle 4)
Detecteert BSN (Nederlands 9-cijferig), IBAN en creditcardnummers (Luhn-algoritme). Geeft MODIFY of BLOCK terug op basis van de huurdersconfiguratie.
Fase 4b: Audiogebaseerde validatie (alternatief pad)
POST /v1/validate-audio — Audio-validator
Voor spraakgesprekken waarbij het platform ruwe audio stuurt in plaats van vooraf getranscribeerde tekst. De audio-validator:
- Accepteert base64-gecodeerde PCM-audio (16-bit LE, 16 kHz, mono).
- Voert ASR-transcriptie uit (Deepgram, Whisper of AssemblyAI — per huurder configureerbaar via BYOK).
- Segmenteert de audio met een van twee strategieën:
asr_first(standaard) — Streaming-ASR stuurt de zinsgrenssegmentatie.prosodic_first— VAD-stiltedetectie maakt segmenten, waarna batch-ASR elk segment transcribeert.
- Voert dezelfde 7-controles-pipeline uit op de transcriptietekst (delegeert aan de validator).
- Bepaalt de audio-routering: forward (ALLOW), substitute (MODIFY — vervangt door vooraf gegenereerde TTS) of block.
- Geeft resultaten per segment terug met dubbele hashes (
audio_hash+text_hash) en een compliance-bon met een HMAC-integriteitsmarkering.
Parallelle ASR
Wanneer parallel_asr: true is, stuurt de audio-validator de audio tegelijkertijd naar meerdere ASR-modellen, slaat alle resultaten op in de bewijsketen en selecteert de transcriptie met de hoogste betrouwbaarheid.
Verzoeksvorm
json
{
"call_id": "uuid",
"audio_data": "base64-encoded PCM bytes",
"audio_format": "pcm_s16le_16000",
"turn_number": 1,
"configuration_id": "uuid",
"call_context": {
"language": "nl",
"disclosure_delivered": true
},
"segmentation_method": "asr_first",
"parallel_asr": false
}Antwoordvorm
json
{
"verdict": "ALLOW",
"segments": [
{
"segment_index": 0,
"audio_hash": "sha256hex",
"transcribed_text": "ASR output",
"text_hash": "sha256hex",
"verdict": "ALLOW",
"check_results": [...],
"segmentation_method": "asr_first",
"asr_confidence": 0.97,
"asr_model_id": "deepgram:nova-2",
"action": "forward"
}
],
"fail_open": false,
"evidence_event_id": "uuid",
"evidence_hash": "sha256hex",
"receipt": {
"input_hash": "sha256hex (original audio)",
"output_hash": "sha256hex (forwarded/substituted audio)",
"text_hash": "sha256hex (transcription)",
"verdict": "ALLOW",
"signature": "HMAC-SHA256"
}
}Fase 5: Gebeurtenissen tijdens het gesprek
POST /v1/events — De Evidence Layer accepteert elke event_type-tekenreeks. Veelgebruikte typen:
| Gebeurtenistype | Beschrijving |
|---|---|
CALL_START | Markeert het begin van het gesprek (maakt automatisch een calls-rij aan) |
VALIDATION_RESULT | Geschreven door de LLM Proxy na elke /v1/validate-aanroep |
AUDIO_VALIDATION | Geschreven door de audio-validator na elke /v1/validate-audio-aanroep |
CHECK_RESULT | Uitkomst van een individuele controle |
FAIL_OPEN | Validator-timeout-gebeurtenis |
DELIVERY_ATTESTATION | Bezorgingsbevestiging gekoppeld aan de validatiegebeurtenis |
TRANSCRIPT_RECONCILIATION | Resultaat van de transcriptieafstemming na het gesprek |
CALL_END | Markeert het einde van het gesprek |
CALL_FAILED | Markeert een mislukt gesprek |
Alle gebeurtenissen worden ongeacht het type toegevoegd aan de cryptografische hashketen. Aangepaste gebeurtenistypen (bijv. tool_call, consent_granted) kunnen vrij worden gestuurd.
Fase 5b: LLM Proxy
POST /v1/proxy/openai — Niet-streamende compliance-bewuste LLM-proxy.
POST /v1/proxy/openai/stream — Streamende compliance-bewuste LLM-proxy.
De LLM Proxy bevindt zich tussen het platform en de upstream LLM-aanbieder. Voor elk verzoek:
- Valideert het verzoek via de validator.
- Stuurt toegestane verzoeken door naar het upstream LLM (OpenAI-compatibele API).
- Valideert de LLM-respons voordat deze naar het platform wordt teruggestuurd.
- Schrijft bewijsgebeurtenissen voor zowel de validatie van het verzoek als de respons.
- Ondersteunt het genereren van meerdere kandidaten: stuurt dezelfde prompt tegelijkertijd naar N eindpunten, valideert alle kandidaten en geeft de beste conforme respons terug.
Fase 6: Bezorgingsattest
POST /v1/delivery-confirmation — Bezorgingsbevestiging indienen.
Nadat de gevalideerde respons aan de menselijke gesprekspartner is bezorgd, stuurt het platform (of Audacts eigen audiomonitor) een bezorgingsbevestiging. Dit legt een aantoonbare koppeling vast tussen de gevalideerde inhoud en wat daadwerkelijk is bezorgd:
- DC-1 (webhook): Het platform stuurt een webhook met de hash van de bezorgde inhoud.
- DC-2 (api_query): Audact bevraagt de platform-API naar de bezorgingsstatus.
- DC-3 (tts_completion): De TTS-engine signaleert voltooiing met de inhoudshash.
- DC-4 (audio_monitoring): Audacts eigen ASR legt het gesproken woord vast (onafhankelijk van het geauditeerde platform).
Elke bevestiging bevat:
linking_hash= SHA-256(validation_event_hash || confirmation_hash) — manipulatie-aantoonbare bewijsketenlink.confirmation_grade:independent(DC-4),platform_sourced(DC-1/2/3) ofunconfirmed(timeout).content_match: of de bezorgde inhoud overeenkomt met de gevalideerde inhoud.
Bezorgingsbevestigingen die niet binnen 30 seconden arriveren, worden automatisch als unconfirmed gemarkeerd.
GET /v1/calls/{call_id}/delivery — Status van het bezorgingsattest per beurt voor een gesprek opvragen.
Fase 7: Beëindiging van het gesprek
Het platform stuurt een eindgebeurtenis via POST /v1/events:
CALL_END— Steltcalls.status = 'completed'encalls.ended_atatomisch in in dezelfde transactie als het schrijven van de bewijsgebeurtenis.CALL_FAILED— Steltcalls.status = 'failed'encalls.ended_atatomisch in in dezelfde transactie als het schrijven van de bewijsgebeurtenis.
Belangrijk: Er is GEEN achtergrond-sweep-taak. Gesprekken die nooit een CALL_END- of CALL_FAILED-gebeurtenis ontvangen, blijven voor onbepaalde tijd op status = 'active'. Het platform is verantwoordelijk voor het sturen van eindgebeurtenissen.
Fase 7b: C2PA-inhoudsgeloofsbrieven
POST /v1/calls/{call_id}/c2pa — C2PA-manifest genereren voor een voltooid gesprek.
Na afloop van een gesprek kunnen huurders een C2PA-compatibel inhoudsgeloofsbrieven-manifest opvragen. Het manifest bevat:
- Claim: gespreksmetadata, samenvatting van de bewijsketen, config-seal-hash.
- Assertions: hashverwijzingen per gebeurtenis (geen ruwe gebeurtenisdata), kettenintegriteitsbewijs.
- Signature: HMAC-SHA256 over canonisch JSON (RFC 8785) van claim + assertions met de KMS-beheerde sleutel van de huurder.
- Merkle-bewijs-referentie: als de bewijzen van het gesprek zijn opgenomen in een cross-huurders-aggregatie, verwijst het manifest naar het branch-bewijs en de Merkle-wortel.
Het eindpunt controleert het eigenaarschap van het gesprek vóór het genereren van het manifest. HMAC-sleutelmateriaal wordt nooit in de respons opgenomen.
Fase 7c: Cross-huurders-aggregatie
De Aggregator-service verzamelt periodiek bewijshashes over alle huurders en bouwt een Merkle-boom voor manipulatiedetectie en controleerbaarheid door derden.
Aggregatiepijplijn (automatisch of handmatig)
POST /v1/admin/aggregate — Eindpunt uitsluitend voor beheerders om aggregatie voor een tijdvenster handmatig te activeren. Vereist de rol owner. Als er geen venster wordt opgegeven, wordt het vorige voltooide interval geaggregeerd.
De pijplijn:
- Verzamelt geaggregeerde hashes per huurder (SHA-256 van alle bewijshashes in het venster).
- Bouwt een uitgebalanceerde binaire Merkle-boom met minimaal 16 bladeren als opvulling.
- Vraagt een RFC 3161-tijdstempeltoken aan bij een TSA voor de Merkle-wortel.
- Voegt de wortel toe aan de metaketen (keten van ketens).
Bewijs opvragen (geverifieerd)
| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /v1/proofs | Aggregatievensters opvragen waaraan de huurder heeft deelgenomen (nieuwste eerst) |
| GET | /v1/proofs/{window_id} | Merkle-branch-bewijs + RFC 3161-tijdstempeltoken voor een specifiek venster opvragen |
Branch-bewijzen worden op aanvraag gereconstrueerd uit opgeslagen metadata. Bewijsstappen bevatten alleen ondoorzichtige zusterhashes en posities — er worden geen huurder-identifiers vrijgegeven.
Openbare verificatie (zonder authenticatie)
| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /v1/metachain | Volledige metaketen (keten van ketens) van Merkle-wortels in oplopende volgorde |
| POST | /v1/verify-inclusion | Offline cryptografische verificatie van een Merkle-branch-bewijs |
De metaketen stelt iedereen in staat de cross-aggregatie-integriteit te verifiëren:
chain_hash = SHA-256(sequence || merkle_root || previous_hash)- Genesis-vermelding:
previous_hash= 64 nullen - De keten dwingt integriteit af bij elke toevoeging
Het verify-inclusion-eindpunt werkt volledig offline — geen databasetoegang, geen authenticatie. Het branch_proof-object van GET /v1/proofs/{window_id} kan er direct in worden gevoerd.
Fase 8: Verificatie na het gesprek
| Eindpunt | Doel |
|---|---|
GET /v1/verify/{call_id} | Doorloopt de bewijsketen, herberekent de SHA-256-hash voor elke gebeurtenis en verifieert de previous_hash-koppelingen. Geeft VALID of INVALID terug met broken_at_sequence. |
GET /v1/chains/{call_id} | Gepagineerd ophalen van de bewijsketen. Parameters: after_sequence, limit. |
GET /v1/reconstruct/{call_id} | Herhaalt de bewijsketen om de exacte beleids- en validatorconfiguratie te reconstrueren die actief was tijdens elke gebeurtenis (config-seal-hash-resolutie). |
GET /v1/receipts/{call_id} | Haalt de compliance-bon voor een gesprek op en verifieert deze via HMAC. |
Transcriptieafstemming
POST /v1/transcript-reconciliation — Transcriptieafstemming na het gesprek.
Na afloop van een gesprek kan het platform het volledige transcript na het gesprek indienen voor afstemming met de bewijsketen. De reconciler vergelijkt elk transcriptiesegment met gevalideerde uitvoergebeurtenissen:
- MATCHED: Hash van het transcriptiesegment komt overeen met de gevalideerde uitvoerhash — bevestigde bezorging.
- MISMATCHED: Hash van het transcriptiesegment wijkt af — een
transcript_mismatch-bewijsgebeurtenis wordt gegenereerd. - UNVALIDATED: Het transcriptiesegment heeft geen overeenkomstige validatiegebeurtenis — een
unvalidated_content-gebeurtenis wordt gegenereerd (detecteert platform-invoegingen die Audact hebben omzeild).
Audio-afstemming
POST /v1/audio-reconciliation — Audio-afstemming na het gesprek.
Combineert ASR-transcriptie en transcriptieafstemming in één synchroon eindpunt. De aanroeper stuurt de volledige gespreksopname; de service transcribeert deze via ASR en stemt de transcriptie vervolgens af met de bewijsketen. Dit is het voorkeurseindpunt wanneer het platform ruwe audio heeft maar geen teksttranscript.
Dit is een synchroon eindpunt — de aanroeper blokkeert totdat transcriptie en afstemming zijn voltooid. Voor lange opnamen kan dit enkele seconden duren.
Verzoeksvorm
json
{
"call_id": "uuid",
"audio_data": "base64-encoded audio bytes",
"audio_format": "pcm_s16le_16000 | wav | mp3",
"language": "nl",
"asr_provider": "deepgram"
}audio_data: Standaard base64-gecodeerde audio. De body-limiet is 64 MiB (~34 min PCM bij 16 kHz mono).audio_format: Een vanpcm_s16le_16000(ruwe PCM 16-bit LE, 16 kHz, mono),wavofmp3.language: BCP-47-tag (optioneel, standaardnl).asr_provider: Overschrijft de standaard ASR-aanbieder (optioneel).- Geen
tenant_id-veld — de huurder-identiteit komt uit de authenticatiecontext.
Antwoordvorm
json
{
"call_id": "uuid",
"asr_model_id": "mock:deterministic-v1",
"asr_confidence": 0.95,
"total_segments": 5,
"matched_segments": 4,
"mismatched_segments": 1,
"unvalidated_segments": 0,
"segment_results": [
{
"sequence_number": 1,
"status": "matched",
"similarity_score": 1.0,
"validated_hash": "sha256hex",
"transcript_hash": "sha256hex"
}
]
}Verloop
- Authenticeren via API-sleutel.
- Eigenaarschap van het gesprek verifiëren.
- Base64-audiobytes decoderen.
- Volledige audio transcriberen via ASR (dezelfde ASR-client als
/v1/validate-audio). - Afstemmingssegmenten bouwen vanuit de ASR-uitvoer.
- Afstemmen met de bewijsketen (dezelfde reconciler als
/v1/transcript-reconciliation). - Segment-voor-segment-resultaten teruggeven.
Huurdersbeheer
Deze eindpunten beheren huurders, API-sleutels en configuraties. Ze maken geen deel uit van het per-gesprek-verloop, maar zijn vereist voor de inrichting.
Huurders
| Methode | Pad | Rol | Beschrijving |
|---|---|---|---|
| POST | /v1/tenants | Openbaar (snelheidsbegrensd) | Een nieuwe huurder aanmaken |
| GET | /v1/tenants/{tenant_id} | Viewer | Huurdergegevens opvragen |
| PUT | /v1/tenants/{tenant_id} | Owner | Huurder bijwerken |
API-sleutels
| Methode | Pad | Rol | Beschrijving |
|---|---|---|---|
| POST | /v1/tenants/{tenant_id}/keys | Owner | Een nieuwe API-sleutel genereren |
| GET | /v1/tenants/{tenant_id}/keys | Developer | API-sleutels opvragen (alleen prefix) |
| DELETE | /v1/tenants/{tenant_id}/keys/{key_id} | Owner | Een API-sleutel intrekken |
Configuraties
| Methode | Pad | Rol | Beschrijving |
|---|---|---|---|
| POST | /v1/configurations | Developer | Configuratie aanmaken |
| GET | /v1/configurations/{config_id} | Viewer | Configuratie opvragen |
| PUT | /v1/configurations/{config_id} | Developer | Configuratie bijwerken |
| DELETE | /v1/configurations/{config_id} | Owner | Configuratie voorlopig verwijderen |
| GET | /v1/tenants/{tenant_id}/configurations | Viewer | Huurdersconfiguraties opvragen |
Configuraties omvatten:
- Beleidsregels (blokkeerlijstpatronen, PII-detectie, prijsbanden, escalatietrefwoorden, toestemmingspoorten)
- Multi-kandidaten-LLM-eindpunten (BYOK: URL + API-sleutel per aanbieder, veilig opgeslagen)
- Uitvoerbeperkingen (antwoordlengtegrenzen met behoud van compliance-kritieke inhoud)
- ASR-aanbiedersleutels (BYOK: Deepgram, Whisper, AssemblyAI — API-sleutels veilig opgeslagen)
Authenticatie
| Methode | Pad | Beschrijving |
|---|---|---|
| POST | /v1/auth/exchange-key | API-sleutel inwisselen voor JWT-toegangs- en vernieuwingstokens |
| POST | /v1/auth/refresh | Een verlopen JWT vernieuwen met het vernieuwingstoken-cookie |
Gebruik
| Methode | Pad | Rol | Beschrijving |
|---|---|---|---|
| GET | /v1/tenants/{tenant_id}/usage | Viewer | API-gebruiksstatistieken van de huurder opvragen |
Volledig overzicht van eindpunten
| Methode | Pad | Beschrijving |
|---|---|---|
| POST | /v1/evaluate | "Mag dit gesprek plaatsvinden?" (vóór het bellen, staatsloos) |
| GET | /v1/policies/{country} | Landsregelwerk opvragen |
| POST | /v1/validate | "Mag de AI dit zeggen?" (per beurt, tijdslimiet 40 ms) |
| GET | /v1/receipts/{call_id} | Compliance-bon opvragen (na het gesprek) |
| POST | /v1/events | Gebeurtenis aan de keten toevoegen (tijdens het gesprek) |
| GET | /v1/calls | Gesprekken opvragen (gefilterd per huurder) |
| GET | /v1/chains/{call_id} | Gebeurtenisketen opvragen (na het gesprek, gepagineerd) |
| GET | /v1/verify/{call_id} | Keten-integriteitcontrole (na het gesprek) |
| GET | /v1/reconstruct/{call_id} | Configuratiegeschiedenis reconstrueren (na het gesprek / audit) |
| POST | /v1/delivery-confirmation | Bezorgingsbevestiging indienen |
| GET | /v1/calls/{call_id}/delivery | Status van het bezorgingsattest opvragen |
| POST | /v1/transcript-reconciliation | Transcriptieafstemming na het gesprek |
| POST | /v1/proxy/openai | Compliance-bewuste LLM-proxy (niet-streamend) |
| POST | /v1/proxy/openai/stream | Compliance-bewuste LLM-proxy (streamend) |
| POST | /v1/tenants | Huurder aanmaken |
| GET | /v1/tenants/{tenant_id} | Huurder opvragen |
| PUT | /v1/tenants/{tenant_id} | Huurder bijwerken |
| POST | /v1/tenants/{tenant_id}/keys | API-sleutel genereren |
| GET | /v1/tenants/{tenant_id}/keys | API-sleutels opvragen |
| DELETE | /v1/tenants/{tenant_id}/keys/{key_id} | API-sleutel intrekken |
| POST | /v1/configurations | Configuratie aanmaken |
| GET | /v1/configurations/{config_id} | Configuratie opvragen |
| PUT | /v1/configurations/{config_id} | Configuratie bijwerken |
| DELETE | /v1/configurations/{config_id} | Configuratie voorlopig verwijderen |
| GET | /v1/tenants/{tenant_id}/configurations | Configuraties opvragen |
| GET | /v1/tenants/{tenant_id}/usage | Gebruiksstatistieken opvragen |
| POST | /v1/auth/exchange-key | API-sleutel inwisselen voor JWT |
| POST | /v1/auth/refresh | JWT vernieuwen |
| POST | /v1/validate-audio | Audiosegment valideren (ASR + compliance) |
| POST | /v1/audio-reconciliation | Audio-afstemming na het gesprek (ASR + afstemming, synchroon) |
| POST | /v1/calls/{call_id}/c2pa | C2PA-inhoudsgeloofsbrieven-manifest genereren |
| POST | /v1/admin/aggregate | Handmatige aggregatie activeren (alleen owner) |
| GET | /v1/proofs | Aggregatievensters voor huurder opvragen |
| GET | /v1/proofs/{window_id} | Merkle-branch-bewijs + RFC 3161-token opvragen |
| GET | /v1/metachain | Metaketen van Merkle-wortels opvragen (openbaar) |
| POST | /v1/verify-inclusion | Merkle-inclusiebewijs verifiëren (openbaar) |
| GET | /v1/health | Statuscontrole |
Bewijseigenschappen
Alle bewijsgebeurtenissen zijn:
- Alleen-toevoegen — Geen bijwerkingen, geen verwijderingen
- Cryptografisch geketend — SHA-256 over pipe-gescheiden pre-image:
event_id|call_id|sequence|event_type|timestamp|canonicalJSON(data)|previous_hash - Server-van-tijdstempel-voorzien —
time.Now().UTC(), nooit van de client - Schrijfbeveiligd — Gelijktijdige schrijfbewerkingen op dezelfde
call_idworden geserialiseerd - Configuratiegebonden — Elke gebeurtenis bevat
config_seal_hash(SHA-256 van RFC 8785 canonisch JSON van de huurdersconfiguratie)
De gesprekstatuscache is afgeleid van de bewijsketen, niet onafhankelijk. Bij een cache-miss: gebeurtenissen uit de opslag herhalen, status reconstrueren, cache vernieuwen.
Beveiligingsmodel
- Huurderisolatie: Elk verzoek wordt geverifieerd via API-sleutel → huurder-identiteit wordt uit de authenticatiecontext gehaald. Geen
tenant_idin verzoekbodies. - Gesprekseigenaarschap:
call_idwordt geverifieerd als behorend tot de geverifieerde huurder vóór verwerking. - Bewijsintegriteit: Keten-kolommen zijn alleen-toevoegen; elke manipulatie is detecteerbaar door herberekening tegen opgeslagen commitments.
- Sleutelbeheer: LLM- en ASR-API-sleutels worden veilig opgeslagen; sleutels worden in GET-reacties geredigeerd tot
has_key: true. - Geen PII in logs: Transcripten, telefoonnummers en audio-inhoud worden nooit gelogd. Alleen hashes en metadata in gestructureerde logs.
