Skip to content

Privacy

Everything the customisation system stores stays on your device: the action log, audit log, flavor library, and prompt overlay never leave your browser. The default local-file loader runs parsing and geometry in your browser. Hosted cloud imports also send source data through IFClite services for downloading or native conversion. This page covers what's stored, where, and how to inspect or clear it, plus what the hosted viewer sends over the network.

TL;DR

  • Action log — content-free intents (model loaded, lens applied, export run) used by the local pattern miner. Never records model content, chat content, file names, or API keys.
  • Audit log — append-only ledger of extension lifecycle events.
  • Flavor library — your extensions, lenses, queries, layout, settings, prompt overlay.
  • Prompt overlay — durable notes the AI assistant sees in every chat (per flavor).

All four live in your browser's IndexedDB. None of it is sent off-device unless you explicitly export. Separately, the hosted viewer can emit anonymous, scrubbed product analytics — see What flows over the network.

Where data is stored

Store Backend Purpose TTL
ifc-lite-user-content IndexedDB Saved validation/comparison reports, document templates, migration originals Until explicit deletion or browser/site-data clearing; originals have a recovery download
ifc-lite-extensions IndexedDB Installed .iflx bundles + their records Forever (or until uninstall)
ifc-lite-flavors IndexedDB Flavor library + snapshots Forever (snapshots cap at 10 per flavor)
Action log IndexedDB (ring buffer) Pattern miner input 50,000 events / 8 MiB rolling
Audit log IndexedDB (ring buffer) Lifecycle events 10,000 entries / 10 MiB rolling

The action and audit logs are held in an in-memory ring buffer and mirrored to IndexedDB, so they survive a reload (both are hydrated from IDB on startup). Clearing a log wipes both the in-memory copy and its persisted copy.

Settings → Privacy

Open Settings → Privacy to control product analytics and inspect or clear local data. The hosted viewer sends anonymous, coarse usage and error events unless you opt out. The switch is stored in this browser and stops both explicit event calls and PostHog automatic capture. A self-hosted viewer without a PostHog key sends no product analytics.

The page also contains these local-data controls:

What we store locally

A plain-English summary of the stores above — the same content as this page in short form.

Action log

Shows the current size: event count + byte size. Two buttons:

Button What it does
Export JSON Downloads a JSON snapshot you can audit / archive. Includes every event with timestamp, intent, and content-free parameters.
Clear Wipes the action log. Confirms first. Suggestions reset until the miner builds up new patterns.

Prompt overlay

Per-flavor durable notes the AI assistant sees in every chat for that flavor. Used for stable preferences ("Always export CSV with semicolon separators", "Default lens for IfcWall: by-fire-rating").

Field Notes
Textarea Markdown content. Capped at ~4000 tokens (~16 KB). Excess is truncated client-side on save with a [truncated] marker.
Extract from chat Scans the current session transcript for stable preferences and proposes them (see Memory extractor below).
Save overlay Persists to the active flavor.

What the action log records

The action log uses a content-free vocabulary defined in packages/extensions/src/log/types.ts. Each event is {seq, ts, intent, params, success, durationMs?}. The full intent + param shape:

Intent Params What's recorded
model.load schema, entityCount, sizeBytes Schema string, integer counts
model.unload — No params
query.run type, resultCount IFC type name, integer count
lens.apply id Hashed lens id (djb2 → 8-char hex) — user-named lenses don't leak
lens.clear — No params
export.run format, entityCount Format label, integer count
script.execute templateId, durationMs Optional template id, ms duration
chat.message intent Coarse classifier output — authoring / query / one-shot / fork
extension.{install,uninstall,enable,disable} id Extension id
flavor.{activate,export,import} id or {} Flavor id where relevant
selection.change count Integer selection count
section.apply — No params
view.change mode '2d' or '3d'

What is never in the log:

  • Model content, GlobalIds, property values
  • Chat message text
  • File names or file paths
  • API keys or credentials
  • User identifiers (the system doesn't have any)

Memory extractor

Settings → Privacy's Extract from chat button runs a rule-based scanner over your current session transcript. It looks for stable preferences (sentences starting with Always, Never, I prefer, etc.) and proposes them as overlay additions.

The extractor is privacy-first by design:

  • Drops anything matching the blocklist. GUIDs, file paths, email addresses, API key fragments, long alphanumeric blobs, and any phrasing with 2+ numeric tokens get filtered out. Borderline cases are dropped silently — the UI never says "we couldn't redact this".
  • Drops modal-verb noise. "I will always check" doesn't extract; only direct preferences do.
  • Rule-based, not LLM-driven. No round trip to a model. The extractor runs entirely on your device.
  • Always reviewable. Every proposal lists its confidence + lets you discard before saving.

A caveat banner sits above the proposal list: "Rule-based scan — review each line before saving." Heuristics are heuristics; the user is the final filter.

What flows over the network

The customisation system itself does not make network calls. The default local-file loader parses and renders files in your browser without uploading them. Opening a hosted cloud source downloads source data through IFClite services, and native Autodesk conversion runs on a server. Attaching model content to an AI chat message sends that content to your chosen provider. The following surfaces send data over the network.

  1. Hosted viewer product analytics. The hosted viewer at ifclite.com emits anonymous, coarse product-usage events via PostHog. This is the only telemetry in the project, and it lives only in the viewer app (apps/viewer). The published npm packages (@ifc-lite/*) contain no analytics code at all, and a viewer you build yourself with no PostHog key configured (VITE_POSTHOG_KEY / VITE_POSTHOG_HOST) sends nothing.

What it records: coarse product events such as viewer_session_started, ifc_model_loaded (schema string and integer counts/sizes), export_completed, ids_validation_completed, clash_detection_run, lens_applied, tour progress, AI chat turns (ai_chat_message_sent and ai_chat_response_completed: built-in or own-key provider, the model family from the viewer's fixed model list, the turn kind, message and attachment counts, the outcome (success, error or aborted), a coarse error class, latency and time to first token; never the prompt, the response, an attachment or the provider's error text), stale_reload_resumed (after the viewer reloads onto a new version: how many open models were reopened automatically and how many the user was asked to open again, counts only; the file names stay in the tab's own session storage), UI interaction events (command_executed, panel_opened, panel_replaced, tool_activated, tool_exited, view_reset, error_shown, file_open_rejected, onboarding_surface: which command, panel, tool or surface was used, as fixed ids only; opens the app makes by itself are not counted), and crash/error reports tagged with the build version for regression triage. viewer_session_started marks consenting viewer sessions, including those that load no model. Events are anonymous by default (PostHog person_profiles: 'identified_only', no autocapture, no page-view capture).

What it never records: every event passes through a before_send scrubber (apps/viewer/src/lib/analytics-scrub.ts) that strips any property whose key looks like a file name, model name, title, path, comment, query, or property/pset name; redacts string values that look like a file path or a model file name; and removes the query string and hash from URLs (keeping only the route). The UI interaction events are held to a stricter allowlist (apps/viewer/src/lib/analytics-ui-events.ts): any property not declared for the event, and any value that is not a plain id, is dropped. Model content, GlobalIds, property values, and file names never leave the browser through analytics.

To measure the first-run charter (#5614), use a PostHog SQL insight grouped by $session_id: count distinct sessions with viewer_session_started as the denominator and those with ifc_model_loaded as the numerator. Measure over a 30-day window: keep only sessions whose first viewer_session_started has timestamp >= now() - INTERVAL 30 DAY, and count their ifc_model_loaded and tour events from the same sessions; without that filter the query counts all time. Several tabs or reloads can send start events for one session, so count distinct IDs rather than raw events. For tour noncompletion, group tour_started and tour_completed by $session_id and tour_id, and count starts without a completion after at least 30 minutes without captured activity. Filter cohorts by the start event's app_build_sha; later events can come from a newer deploy. Sessions opted out before capture are absent; opting out later stops future events but does not erase earlier events. Do not use PostHog's page-view-based web analytics session count for this viewer, because page-view capture is disabled.

  1. Chat with the AI assistant. When you send a chat message, your prompt + the (cached) system prompt + any attachments + recent conversation goes to your chosen provider (Anthropic / OpenAI), either through the BYOK direct flow or the proxy. Attachments can include model content (GlobalIds, property values, selected entities), so attaching model context to a chat message deliberately sends that content off-device to the provider. The chat panel's existing privacy notes apply.

  2. Extension code with network.fetch:<host> capability. An extension can ONLY make fetches you explicitly grant during install. The capability is host-scoped — network.fetch:api.example.com cannot reach any other host. Network egress is red-tier in the Capability Review screen; you have to type approve to grant it.

  3. Hosted cloud sources. Signing into Autodesk, Dropbox or OneDrive authorizes the configured IFClite gateway to read data from your vendor account. The gateway handles account identity, project/file references and downloaded model bytes. Native Forma resources are converted on the Autodesk gateway; Data Exchange conversion also sends the initiating user's delegated token and source reference to the authenticated Windows worker. The resulting IFC or IFCX then loads through the viewer's browser loader.

Vendor passwords are entered on the vendor's sign-in page. IFClite keeps delegated access and refresh tokens in backend memory; the browser receives a secure HttpOnly session cookie. Gateways use temporary artifact files while preparing and delivering imports, with deletion on completed, cancelled or expired jobs. Unclaimed prepared results expire after two minutes and active jobs are bounded to fifteen minutes. Sign-out or gateway restart ends the IFClite session. See Cloud sources for consent, source access and deployment details.

What you can do

Goal How
Audit what's stored Settings → Privacy → Export JSON on the action log; Extensions → Audit → Export on the audit log
Wipe pattern suggestions Settings → Privacy → Clear the action log
Stop the assistant from "remembering" preferences Settings → Privacy → clear the textarea + Save overlay
Stop product analytics Settings → Privacy → Opt out of product analytics
Stop the miner entirely Disable every action log emit by clearing the log; the miner has no input to act on
Forget an extension Extensions tab → trash icon — removes bundle bytes, install record, granted capabilities
Forget a flavor Flavors dialog → delete on the row (active flavor can't be deleted; switch first)
Reset everything Flavors dialog → Reset restores the baseline empty flavor and deactivates extensions
Start clean for one session Append ?safe=1 to the URL (see Safe mode)

First-launch disclosure

On the first launch where the extensions subsystem comes up, a one-time toast surfaces the headline:

IFClite stores an action log on your device. The hosted viewer also sends anonymous product analytics unless you opt out in Privacy settings.

The toast has a Privacy settings action that opens the opt-out switch and local-data controls. The acknowledgement is persisted in localStorage so you only see it once per browser. To re-show it, clear the ifclite.extensions.privacy-disclosure.v2 key.

Source-of-truth references

  • The no-content rule: RFC §06 §7
  • Action log schema: packages/extensions/src/log/types.ts
  • Memory extractor: packages/extensions/src/flavor/memory-extractor.ts
  • Audit log: packages/extensions/src/audit/log.ts
  • Capability gating: packages/extensions/src/host/check.ts

Saved reports and documents

Validation reports, comparison reports, and documents stay in the browser’s ifc-lite-user-content IndexedDB database. Library backup and recovery downloads are local exports; no account or upload is required. Migrated originals are retained for recovery, including content that cannot be parsed. Storage controls report failures and let you export unsaved drafts. Protecting browser storage requests permission from the browser; it does not send report content to a server. See Storage, backup, and migration.

Next steps

  • Extensions — install, run, audit
  • Flavors — what's in a flavor (and what isn't — the action log doesn't travel)