consent-record
privacy specs/privacy/consent-record.kmd
Specification body
Cookie / tracking consent-record contract
Status
Draft v0.1.0 — written 2026-06-02 alongside WEBKIT-034 (GDPR) +
WEBKIT-036 (LGPD). Reference implementation:
engines/sdk/koder_web_kit window.KoderConsent + <koder-cookie-banner>.
Scope
Defines the client-side consent record every Koder web surface (landing, Hub, web app) persists when a visitor makes a cookie/tracking choice, plus the rules that govern when the consent UI shows and how non-essential data collection (analytics, marketing) gates on it.
This is the web tracking-consent contract. It is distinct from
identity/consent.kmd (server-side Scoped
Consent Tokens — signed JWTs for sensitive ops like voice-clone), which
is unrelated. Retention of any server-persisted consent records follows
policies/identity-data-retention.kmd
(LGPD Art. 15-16 / GDPR Art. 5(1)(e)).
Record shape
Persisted at localStorage["koder.consent"] as JSON:
{
"v": 1,
"policyVersion": "1",
"ts": "2026-06-02T18:00:00.000Z",
"locale": "pt-BR",
"method": "accept-all | reject-all | custom",
"categories": { "necessary": true, "analytics": false, "marketing": false }
}
v— record schema version (this contract); bump on a breaking shape change.policyVersion— the site's consent-policy version; re-prompt on change (R3).ts— ISO-8601 timestamp the choice was recorded.locale—<html lang>at record time.method— how the choice was made.categories— per-category booleans;necessaryis alwaystrue.
Categories
| Category | Gated? | Meaning |
|---|---|---|
necessary | never (always true) | Required for the site to work. |
analytics | yes (opt-in) | Usage measurement. |
marketing | yes (opt-in) | Personalisation / measurement. |
Surfaces MAY define additional opt-in categories; necessary is reserved
and always allowed.
Rules
- R1 — Opt-in, default-deny. Until a record exists, only
necessaryis allowed.KoderConsent.allows(cat)MUST returnfalsefor any non-necessary category absent an explicit opt-in. No analytics/marketing script may run before consent (LGPD/GDPR lawful basis). - R2 — Reject as easy as accept. The first-tier banner MUST offer "Reject all" with the same prominence as "Accept all" (no scrolling, no extra clicks) — ANPD guidance / GDPR. A granular second tier ("Manage") is offered alongside, not instead.
- R3 — Re-show conditions. The consent UI re-appears when: (a) no
record, (b)
policyVersiondiffers from the surface's current value, or (c) the record is older than the surface'smax-age-days(default 365). Percomponents/banners.kmd§R4, re-show conditions are documented here rather than left implicit. - R4 — Audit trail (optional). A surface MAY POST the record to a
record-endpointfor a server-side audit log; the client record is the source of truth for gating. Server copies followidentity-data-retention.kmd. - R5 — Gating API. Consumers gate collection on
window.KoderConsent.allows('<category>')and react to changes via thekoder:consent-changewindow event (detail = the record).
Reference implementation
engines/sdk/koder_web_kit:
window.KoderConsent—get/allows/needed/set/acceptAll/rejectAll/reset/subscribe.<koder-cookie-banner policy-version max-age-days policy-href record-endpoint>— two-tier banner (R2) + granular dialog, localized (en/pt/es), emitskoder:consent/koder:consent-change.