Changelog
Per-product release notes for Sankofa — engine, SDKs, and dashboard. New features, breaking changes, deprecations, and bug fixes, oldest at the bottom.
Sankofa publishes release notes at every meaningful boundary — major engine releases, SDK version bumps, dashboard feature ships. This page is the canonical timeline.
For programmatic access (RSS, ATOM, JSON feeds), see the Subscribe section at the bottom.
2026
2026-05-11 · Flutter native crash bridge (Phase C)
Flutter SDK — sankofa_flutter converts from a pure-Dart package to a Flutter plugin with a standalone native crash reporter living inside ios/Classes/ and android/src/main/kotlin/. No dependency on the public SankofaIOS Pod or dev.sankofa:sankofa Maven artifact — the Flutter package owns its own crash surface so Flutter hosts don't pull in the iOS/Android SDKs' analytics + replay code.
What gets captured on top of FlutterError.onError / PlatformDispatcher.onError / isolate listeners:
- iOS:
NSSetUncaughtExceptionHandler, POSIX signals (SIGSEGV/SIGABRT/SIGBUS/SIGILL/SIGFPE/SIGTRAP/SIGSYS), main-queue stall detector. - Android: chained
Thread.setDefaultUncaughtExceptionHandler, ANR watcher (main thread blocked > 5s).
Both POST to the same /api/catch/events endpoint the Dart side uses. Sankofa.setUser / setTag / setTags / flushCatch mirror to the native side automatically. No host wiring needed — auto-bootstrapped from Sankofa.instance.init.
2026-05-11 · Catch ergonomics — withScope + beforeSend (Phase B)
All client SDKs (Web, Flutter, React Native, Android, iOS) ship matched APIs:
Sankofa.withScope(fn)— Sentry-style temporary scope overlay. Tags / extras / user / level / fingerprint set inside the closure layer onto captures inside the closure; the global scope is untouched. Stack-scoped; nestedwithScopecalls compose; async captures deferred past the closure's return don't see the scope. Android scopes are thread-local — captures fired on a background worker don't pick up the UI thread's scope.beforeSend: (event) => event | null— synchronous hook fired AFTER event composition but BEFORE the transport sends. Returnnullto drop entirely; return the (possibly mutated) event to ship. Throws are swallowed — a buggy hook can never break the capture pipeline. Pass at init time (Sankofa.instance.init(beforeSend: ...),catchPlugin({ beforeSend }), etc.).
iOS extra — main-queue stall detector. Background timer pings a sentinel block onto the main queue; if it doesn't fire within catchStallThresholdSeconds (2.0s default, matching Sentry), an anr event is emitted. Set to 0 to disable.
2026-05-11 · Crashlytics + Sentry merged (Phase A)
All client SDKs ship a unified Catch API. Crashlytics' one-line ergonomics plus Sentry's surface area:
- Auto-init —
Sankofa.init(...)(orSankofa.instance.init/Sankofa.shared.initialize) auto-installs the Catch singleton and the platform-specific uncaught-exception handlers. No separateSankofaCatch.init(...)call needed. - Static helpers —
Sankofa.captureException(err),Sankofa.captureMessage(msg),Sankofa.log(msg, [category]),Sankofa.setUser,Sankofa.setTag(s),Sankofa.setExtra,Sankofa.addBreadcrumb,Sankofa.flushCatch— every helper works from anywhere with no instance to thread through. Sankofa.log()— Crashlytics-style breadcrumb log. Pushes a free-text trail entry onto the ring buffer that rides on the next captured event. Doesn't bill.- Auto-discovered flag + config snapshots — when Switch + Config (or RemoteConfig on native) are linked, every captured event carries
flag_snapshot+config_snapshotof the active decisions. The dashboard shows "which flags were ON when this error fired" with no host wiring. - New init params —
enableCatch(default true),catchEnvironment,release,appVersion. Old explicitSankofaCatch.init(...)calls still work for legacy hosts.
2026-05-10 · Heatmap accuracy (Web + Flutter + Android + iOS + RN)
Cross-SDK — six heatmap + replay correctness fixes:
- Per-event screen attribution —
screenmoved fromdata.screento event-level on Android + iOS so the worker's high-precision attribution path activates. Carryover buckets spanning a screen change no longer mis-attribute. - Cold-start screen guard — replay upload skipped until the host tags a screen; cold-start frames no longer flood the dashboard's "Unknown" bucket. Framework-host activities (
MainActivity,ReactActivity,FlutterActivity,UIHostingController,RCTRootViewController,FlutterViewController) excluded from auto-tagging — the host language is responsible forSankofa.screen(...). Sankofa.tagScrollContainer { offset }— new explicit scroll-offset registration API on Android (Compose) + iOS (SwiftUI / custom hosts). Below-the-fold taps inLazyColumn/ opaque hosting views now resolve to the correct Y offset. Returns an idempotentScrollContainerHandlewhose.remove()unregisters; multiple registrations allowed (first non-zero wins).- Move + pinch capture (Android) — touch dispatcher rewritten to handle DOWN, UP, MOVE (50ms throttle + 4px coalesce, matching iOS), pinch (two-pointer midpoint), and double-tap via
event.actionMasked. - NaN / Infinity coord filter (iOS) — non-finite coords drop instead of plotting at
(0, 0). - Chunk-index persistence (iOS) —
syncChunkIndex(forSessionId:)reads from UserDefaults on first upload, mirroring Android's SharedPreferences-backed counter. Replay chunks survive process death.
React Native — useSankofaNavigationTracking(navRef) hook for @react-navigation/native. Drop once in your app shell and every screen change tags into the heatmap pipeline. Tags the initial route synchronously, dedupes redundant retags, tolerates null refs and pre-mount getCurrentRoute() throws. Plus a typed bridge surface (SankofaBridge) that caught two latent bugs hiding behind any (snake_case vs camelCase on os_version / device_model; missing typeof === 'function' guards on optional Deploy methods).
2026-05-09 · Vision GA
Engine — ee/vision/ shipped. Five surfaces (Canvas, Roadmap, OKRs, Initiatives, Strategy Docs) live behind one board container. Cross-product bonds via InitiativeTicketLink and InitiativeObjectiveLink — Plan ticket close auto-progresses linked OKR Key Results.
Dashboard — /dashboard/vision/ route, with multi-page editor + cross-surface index pages (/canvases, /roadmaps, /okrs, /initiatives, /docs).
API — Full REST surface at /api/v1/vision/*. Public read-only sharing for Roadmaps + Docs.
2026-04-17 · Catch profiles GA
Engine — /api/catch/profiles endpoint accepts wallclock + CPU profiler output up to 20 MB per profile.
SDKs — Node + Go + Python + Java sampling profilers. Web profiles deferred (browser limitations).
2026-04-12 · Decision-handshake unification
Engine — GET /api/v1/handshake consolidates Switch + Config + Deploy + Catch + Analytics module decisions in a single ETag-cached response. Deprecates per-product decision endpoints (still served for backward compatibility).
SDKs — every client SDK migrates to the unified handshake. The change is internal — no app-code change required.
2026-03-08 · Pulse branching
Engine — ee/pulse/ adds pulse_survey_branching_rules table. Server-side branching evaluator — the SDK only fetches questions the user qualifies for.
Dashboard — visual branching editor with mock-answer preview.
2026-02-22 · Web SDK v0.1.2
SDKs — @sankofa/browser, @sankofa/catch, @sankofa/switch, @sankofa/config, @sankofa/pulse, @sankofa/replay-rrweb, @sankofa/react all bumped to 0.1.2. New: getSnapshot(), getTransportStatus(), onTransportStatus() accessors on the core client. React: usePulse + usePulseEvent hooks.
2026-01-30 · Outbound webhooks GA
Engine — /ee/webhooks/ framework live. ~40 event types across products (catch.alert.fired, deploy.release.promoted, switch.flag.halted, plan.ticket.transitioned, etc.). HMAC-SHA256 signing, exponential-backoff retries, dead-letter queue with manual replay.
2025
2025-Q4 · Public beta
Soft launch of the Sankofa platform. Hobby tier free, Pro and Growth on Stripe checkout.
2025-Q3 · Closed beta
Selected design partners. Engine in production for first customer in Sept.
Subscribe to changelog updates
Three options:
- RSS —
https://docs.sankofa.dev/resources/changelog/feed.xml. Atom 1.0 feed, regenerated on every docs deploy. - Webhook — subscribe to the
changelog.entry.publishedevent via the outbound webhook framework. Same delivery + signing as product events. - Email digest — opt in at
/dashboard/account/notifications → Changelog digest. Weekly or per-release.
How we version
- Engine — semver. Major bump only on incompatible wire changes (we've never bumped past
v1and don't expect to soon). Minor every ~4 weeks; patch as bugs are fixed. See SDK versioning policy — same rules apply. - SDKs — semver per SDK, independent. Minor releases ~monthly per SDK. Major bumps coordinated across the matrix.
- Dashboard — continuously deployed. The "release" notion is per-feature, not per-version. Notable shipments are recorded above with a date.