Skip to main content
Wildo.ai Coming soon

Privacy and subject rights

Keep people’s processing choices explicit

Record consent as a set of independently granted purposes, ask for it instead of assuming it, and keep optional processing off until it is given.

An analytics choice is stored for the application to consult, with a record of the preference change.

Keep people’s processing choices explicit

A person agrees to optional processing one purpose at a time — analytics, marketing — and each answer stands on its own. Agreeing to one never implies another.

Nothing is assumed. A new person has granted nothing, and the moment they decide is recorded, so “declined everything” and “was never asked” stay different facts. The signed-in application asks once and waits for the answer; the marketing website asks each visitor before any analytics start.

Example — Respect an analytics choice

A visitor lands on the marketing site and declines analytics. The analytics client never loads, the choice is remembered on the next page, and a “privacy choices” link lets them change it later. After sign-up, the application asks the same question once; declining there is recorded with the value before and after.

For engineers

ConsentPurpose names the purposes. Each person stores the set they granted and the instant they decided. The set is audit evidence, so every change is recorded with its previous and resulting value.

Source: privacy.shared.schemas.ts (selected excerpt).

const consentedPurposesField = (subject: string) => z.array(z.enum(ConsentPurpose)).default([])
  .describe(
    `The optional purposes ${subject} has granted, each independently. A set, not a level: granting one purpose implies nothing about another. Empty means nothing optional was granted.`,
  );

const consentDecidedAtField = (subject: string) => z.date().optional()

The decision instant is written by the server when the set changes, never taken from the caller, so a decision cannot be backdated. Use the preference resource operations — the application’s consent gate already does — so the audit emission records both values. Reset returns the set to empty and clears the instant: a withdrawal of everything, after which the person is asked again.

An application that must not be used without a purpose declares it once, as operatorComplianceIdentity.serviceConsentRequirement.requiredPurposes in wildo.saas.config.ts. wildo config service-consent carries it into the runtime: the backend refuses everything that person initiates — API and MCP operations, queued work, live-update subscriptions, agent tools, conversations and their results, charts and analytics — except their own profile and preferences, where they record the consent, and cancelling work they already started. Updates the server pushes on its own are not held back. Every signed-in page is withheld until they grant it. Signing in and out stay open, so the decision is always reachable. An empty set states that nothing is gated.

Use the inherited analytics consumer

Wildo’s mounted AnalyticsContextProvider starts the configured analytics providers only while the person has granted ANALYTICS, unless the application declares analytics.requiresConsent: false.

Selected source from AnalyticsContext.tsx, inside its configuration-and-consent effect:

const hasConsent = analyticsConfig.requiresConsent === false
  || hasGrantedConsentPurposes(grantedPurposes, [ConsentPurpose.ANALYTICS]);

if (!hasConsent) {
  providersRef.current.forEach(p => p.reset());
  setIsActive(false);
  return;
}

On the marketing website the same rule is enforced where provider code starts: a provider whose capability rests on consent — product analytics — is neither loaded nor scripted until the visitor grants its purpose, and is stopped when they withdraw. Error monitoring and captcha start regardless, because they protect a service the visitor asked for. It does not recall events already sent. Other processing consumers still need their own declared purpose and enforcement.

Building a B2B product or an internal tool?

Wildo is not self-service yet. Tell us what you have in mind and we will say plainly whether it fits, and what happens next.