Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt

Use this file to discover all available pages before exploring further.

This is the platform changelog. It tracks notable user-facing changes to KaireonAI — new features, APIs, UI additions, and behavioral shifts — in reverse-chronological order. New capabilities land here when they are deployed to playground.kaireonai.com. For the forward-looking view, see the roadmap.

2026-05-12 (later) — Channel coupling, compute error surface, DNC

Channel-level coupling replaces Group.allowPartial. The legacy all-or-nothing allowPartial: false switch was a coarse fail that didn’t distinguish between “empty due to operator’s choice” and “empty due to contact policy fatigue”. It’s now deprecated and a no-op (the field still parses to keep existing IRs valid). Per-channel coupling takes its place:
  • Channel.couplingMode ("partial" default, "atomic" opt-in) — when atomic, an empty placement in this channel suppresses sibling placements in the same channel only. Cross-channel coupling is intentionally NOT supported — different channels are different attention surfaces.
  • DecisionFlow.couplingOverride — per-flow override that beats the channel default. Useful when one channel serves both atomic flows (e.g. weekly digest email) and partial flows (e.g. transactional email).
  • The post-group coupling pass writes trace.summary.channelCoupling[] so consumers can distinguish “we cascaded because X” from “this placement wasn’t configured.”
Compute formula errors surface in the response. Formula failures (missing customer field, divide-by-zero, type mismatch) used to be silently logged and the candidate’s personalization key just went missing. Now each failure lands in personalization._errors[] on the candidate with { name, kind, formula, error }, plus a count in trace.summary.computeErrors. The candidate stays in the response — operators can filter upstream if they want missing fields to drop the candidate entirely. do_not_contact contact-policy ruleType is now properly wired. It was seeded by industry-accelerator templates but the contact-policy engine had no explicit case — every DNC’d candidate fell through to the fail-closed default branch with a misleading “Unknown rule type” error log. Now there’s an explicit case "do_not_contact" that blocks with a clear reason and policy id. This is the only contact policy that suppresses across channels (legal/regulatory boundary).

2026-05-12 — File-arrival triggers (push + poll) + blue_green column cast

Triggers are now first-class — file_arrival no longer waits inside a scheduled run; the run itself is fired by the sentinel landing.
  • Poll path — the in-process scheduler tick now sweeps every active pipeline with trigger.kind === "file_arrival" alongside its schedule sweep. It probes the source’s configured path (via the same cloud-store wiring the source executor uses), matches keys against the trigger’s per-pipeline controlFilePattern, debounces against lastRunAt + debounceSeconds, and dispatches the run in-process.
  • Push path — new POST /api/v1/triggers/file-arrival endpoint accepts both native {pipelineId, tenantId, objectKey} payloads and S3 EventBridge envelopes. Self-authorizes via CRON_SECRET. Sub-second latency when S3 → EventBridge → API Destination is wired up.
  • Per-pipeline maskscontrolFilePattern lives on the trigger, so multiple pipelines watching the same inbox each declare their own sentinel (customers.done, accounts.done, propositions.done). Drop one → only the matching pipeline fires.
  • Sentinel cleanup — after a successful fire, the sentinel is archived to atomicity.successFolder (or failureFolder on a failed run) so the same trigger doesn’t re-fire on every tick.
  • Deadline enforcementtrigger.deadline.windowMinutes / onMiss is now actually checked. alert emits a system-health warning; fail writes a synthetic failed PipelineRun so SLA dashboards count the miss; skip logs and continues. Dedup key is the pipeline’s lastRunAt so the action fires once per missed window.
Blue_green load mode bug fixrunBlueGreen previously did INSERT INTO <table>_new SELECT * FROM <staging>, which Postgres rejected with 42804 (column "created_at" is of type timestamptz but expression is of type text) because staging columns are TEXT and target columns are typed. The target executor now passes its column-aware projection (NULLIF + ::pgCastType) into runBlueGreen, so blue_green produces the same explicit casts that append/truncate/upsert do. A leftover <table>_new from a prior failed run is dropped before the new CREATE-LIKE. LineageTab key warning — the row map was using <>...</> shorthand which doesn’t accept props; switched to <Fragment key={...}> so React stops warning about missing keys.

2026-05-02 (evening) — Schema-joins UX + customer profile lookup

  • Customer Lookup was returning “no customer found” for valid IDs because the profile route only matched schemas with entityType="customer". The schema-create form sets schemaType="customer" but leaves entityType at its default “custom”, so the lookup missed the actual customer table. Fixed: the route now matches either field.
  • Schema-joins page redesigned around the customer-as-primary best practice. Primary schema is no longer a picker — the tenant’s customer schema is auto-resolved and shown as a read-only chip with its primary key. The foreign-schema dropdown excludes the customer schema (no self-joins). Foreign-key column auto-populates when a column matching the primary key exists, otherwise the user picks from a dropdown of the foreign schema’s actual columns. The redundant primary-schema field picker was removed.

2026-05-02 (late PM) — Three bugs caught in testing

Surfaced during the IAM-role + custom-PK end-to-end test:
  • Schema detail no longer fakes an id BIGSERIAL row when the user defined a custom PK. The list of AUTO columns now matches the actual ds_* table contents — created_at + updated_at only (when a custom PK is set), or those plus id (when no custom PK).
  • Pipeline Runs rowsProcessed was 4× the real count because the run-handler reducer summed rowsLoaded + rowsOut across every node. Now it only sums target rows. Existing run records in the test tenant were backfilled.
  • Sample-row preview evaluates the common single-call formulas inline (concat, coalesce, min, max, round, abs, identity reference). Complex formulas still defer to the runtime but with a friendlier placeholder. Default sample row no longer miscategorises state (and other fields containing “at”) as a date.
Companion to the data-platform end-to-end walkthrough also added today: API Walkthrough.

2026-05-02 (also PM) — {YYYY-MM-DD} token expansion fix

Found during the same E2E test: archived files in S3 / GCS / Azure were landing at literal .archive/{YYYY-MM-DD}/ instead of .archive/2026-05-02/. The local_fs archive helper expands tokens, but the cloud-store impls took the destination verbatim. The source executor now expands {YYYY-MM-DD} / {YYYYMMDD} / {YYYY} / {MM} / {DD} / {HH} / {mm} / {ss} before calling store.archive().

2026-05-02 (PM) — System Health + load-mode safety

Two coupled shipments in the same day: System Health widget (docs). New top-bar Activity icon — distinct from the bell — surfaces operational alerts across the platform. DB-backed with per-user read state. New API at /api/v1/system-health (GET cursor-paginated, PATCH read, POST read-all, DELETE dismiss). Severity taxonomy info | success | warning | error | critical; 30-second polling that pauses on tab background; error/critical route to existing external Slack/Teams/email providers when configured. A retention purge cron at /api/v1/cron/system-health-purge honors each tenant’s retention settings (data class system_health, default 90 days). The previously dead bell icon + in-memory notification store are retired. Load-mode safety (docs). Real data-loss footguns closed:
  • truncate and blue_green now run an empty-source guard by default — pipelines no longer wipe live tables when the upstream produces 0 rows. Override per-target with failOnEmptySource: false.
  • truncate and incremental_watermark wrap the destructive + INSERT statements in prisma.$transaction so a failed INSERT rolls back the TRUNCATE / watermark advance.
  • incremental_watermark now persists the high-water in a pipeline_watermarks checkpoint table (falls back to MAX(target.col) on first run for backwards compat).
  • upsert with all columns in upsertKey now throws at SQL build time instead of silently emitting ON CONFLICT DO NOTHING. UI + parsePipelineIR block the misconfiguration before save.
  • TargetForm gains: full-refresh-shape hard warning recommending blue_green over truncate, failOnEmptySource toggle for destructive modes, mode-switch validation matrix, dedicated config panes for upsertKey / watermarkColumn / cdcSource.
  • Source onMissAction: alert finally fires an actual alert into System Health.
  • Optional expectedRowCountDelta per target node emits a warning alert when today’s load is wildly outside the recent average.
DataSchema docs clarified: marking a schema field as the primary key skips the auto-generated id BIGSERIAL column at table creation; the runtime has supported user-defined PKs since the DDL helper landed. Docs: System Health · Loading Modes · File Ingestion · Data Model

2026-05-02 — Flow editor UX cleanup

A focused pass cleaned up rough edges in the IR-native flow editor:
  • Lineage tab no longer 500s on tables with bigint or Postgres numeric/decimal columns. The lineage payload now serialises large integers as strings (preserves precision past Number.MAX_SAFE_INTEGER) and renders Decimal columns in their human-readable form, so lifetime_value etc. render as "10552.97" instead of internal-state JSON. See Flow Lineage.
  • Pipeline Runs heading aligned with sidebar — the standalone runs page H1 now matches the “Pipeline Runs” sidebar entry, the table uses fixed column widths via shadcn <Table>, and the Error column truncates with a title= tooltip for the full text.
  • Editor is now 2-pane — the redundant “Recent runs” left pane was removed; the bottom strip + dedicated /data/flow-runs page cover run history. Center pane fills the freed width.
  • Branch node formthen and default route inputs are dropdowns of existing IR nodes (excluding self + sources). Stale refs render with a red border.
  • Enrich node form — output-field input now badges columns missing from the destination schema and offers a one-click ”+ Add as <dataType>” button that POSTs to /api/v1/schemas/fields with a sensible default type per provider.
  • Archive node form — connector picker (Select limited to S3 / GCS / Azure / SFTP / local_fs), per-connector folder-creation help text (cloud=auto-create, SFTP/local=parent must exist), and a Test connection button reusing the existing POST /api/v1/connectors/test. IR archiveNodeSchema gains an optional connectorId field (backwards compatible — runtime executor still parses destination URLs until the cross-cutting wiring lands).
  • Transform + Validate sample-row preview — collapsible widget inside both forms takes one JSON row and shows a per-op before/after diff (added/removed/changed fields highlighted) or per-rule pass/fail badge. Complex ops (aggregate, lookup_join, vector_embed, geo_resolve, sentiment_score, language_detect) and the expression op render as “preview-limited — run the pipeline” since they need server-side runtime context.
Docs: Flow Editor UI · Flow Lineage

2026-04-29 — Decisioning depth + ecosystem surfaces

A multi-pass sprint landed across 14 capability surfaces. Highlights:
  • Counterfactual training — pre-train hook augments the gradient_boosted training set with synthetic neighbors of marginal rows. See Counterfactual Training.
  • Cross-offer ranking constraints — a new constraint type with three rule shapes (channel_quota, portfolio_budget, category_cap) feeds the existing Lagrangian solver. See Lagrangian ranking.
  • KernelSHAPPOST /api/v1/decisions/:id/shap now dispatches gradient_boosted to TreeSHAP and neural_cf to KernelSHAP. See SHAP.
  • Three new fairness metrics — Gini coefficient, DeLong paired-AUC test, two-sample Kolmogorov-Smirnov. See Advanced Fairness.
  • Multi-stage four-eyes approvals + DSAR purge cron — approvals now move through a sequence of named stages with per-stage state transitions; GET /api/v1/cron/dsar-purge sweeps decision traces, interaction history, and AI attachments past the strictest tenant retention setting. See Governance four-eyes.
  • Negotiation apply-mode + multi-turn sessions — three new routes (POST /api/v1/decisions/:id/negotiate/apply, POST /api/v1/negotiate/sessions, POST /api/v1/negotiate/sessions/:id/turn) with a 7-gate apply pipeline. See Negotiation Apply-Mode.
  • 26 new connector entries added — registry expansion spanning CRM / MAP / CDP / audience-sync / helpdesk / workflow vendors. New entries ship as coming_soon form-only stubs.
  • 4 new pipeline transformsvector_embed, geo_resolve, sentiment_score, language_detect with HTTP-pointed runtime adapters under lib/flow/runtime/transforms/external-model-call.ts.
  • SCIM 2.0 + WebAuthn + SIEM audit-log shipping/scim/v2/Users endpoints, full COSE-key parse with ES256 / RS256 assertion verification, and Splunk HEC / Datadog Logs / Elastic _bulk backends gated by SSRF validation.
  • Multi-region overlayhelm/values-multi-region.yaml chart for 2-region active-active topology, plus per-tenant region routing driven by a new tenant-region pinning table.
  • In-repo SDK + CLI + Postman + MCP scaffolds — TypeScript SDK, Python SDK, npx kaireon CLI, Postman v2.1 collection, and MCP marketplace manifest under sdks/.
  • OpenAPI auto-discoverytools/scripts/gen-openapi.mjs walks every app/api/v1/**/route.ts and emits platform/public/openapi.json covering the full v1 surface.
Schema migration: platform/prisma/manual-sql/09_parity_w11_to_w19.sql (idempotent) creates 5 new tables and backfills existing single-stage approvals.

2026-04-17 — Action Insights + Reporting Platform

Four coordinated phases shipped as a single milestone: close analytics gaps, make alerts actually fire, ship a full report builder and scheduler, and deliver a C-suite executive dashboard with Export + Save-as-Report across every view.
Pilot deployment posture. This release ships as manual-only automation. The alert evaluator, report scheduler, and scheduled report runner all run through /api/cron/tick, but CRON_TOKEN and AWS EventBridge are intentionally not wired during pilot to avoid runaway LLM / notification cost. Run Now buttons, Export buttons, ad-hoc notification sends, and on-demand alert evaluation all work unconditionally. See EventBridge Setup for the optional wiring path, and the roadmap for the pilot guardrails we plan to ship before enabling automation by default.

Phase 01 — Analytics Foundation

New analytical primitives that power every downstream surface in this milestone.
  • New dashboard-data case selection_frequency — per-offer eligibleCount, scoredCount, selectedCount, selectionRate, avgRank, and rankDistribution[]. Accepts channelId, categoryId, decisionFlowId, segmentId filters.
  • New dashboard-data case anomaly_candidates — compares current vs. baseline period across acceptance rate, revenue, and degraded scoring rate; classifies severity (info / warning / critical) from z-score + absolute percent change.
  • New dashboard-data case why_not_ranked — aggregate misses per offer: scoredTooLow, filteredByContactPolicy, filteredByQualification, and beatenBy (top-5 competing offers).
  • Segment dimension added to acceptance_rate, offer_performance, offer_performance_grouped, channel_effectiveness, daily_trend, revenue_trend.
  • Enriched decision-trace JSON shapes — structured rejectionReason, rankBefore / rankAfter on scoring results.
  • Cross-decision narrative helpers that explain offer underperformance, segment coverage, and anomalies in plain language.
Docs: AI Insights · Dashboards · Dashboard Data API

Phase 02 — Notification Providers + AlertRule Execution

Pluggable notification system and live alert evaluation.
  • Pluggable notification provider interface + registry with Slack, Microsoft Teams, outbound webhook, and Ops-Email (SES) adapters.
  • New notifications tab in /settings/integrations — add / test / enable / disable / delete destinations.
  • Encrypted credential storage in the platform-setting vault (AES-256-GCM); GET endpoints return redacted configs.
  • An alert-rule evaluator compares observed vs. threshold over windowMinutes, derives severity, fans out to every destination in channels, and respects cooldownMinutes.
  • New settings page /settings/alerts — CRUD for alert rules.
  • New API surface:
    • GET /api/v1/notifications/providers and POST /api/v1/notifications/providers
    • GET /api/v1/notifications/providers/:id, PATCH /api/v1/notifications/providers/:id, DELETE /api/v1/notifications/providers/:id
    • POST /api/v1/notifications/providers/:id/test
    • POST /api/v1/notifications/send
    • GET /api/v1/alerts and POST /api/v1/alerts (alert rules — later renamed from /alert-rules to /alerts)
    • GET /api/v1/alerts/:id, PUT /api/v1/alerts/:id, DELETE /api/v1/alerts/:id
    • POST /api/cron/tick (token-authenticated; intended caller is an external scheduler such as AWS EventBridge).
Docs: Notifications · Alert Rules · Notifications API · Alerts API · Cron API · EventBridge Setup (optional during pilot)

Phase 03 — Report Builder + Scheduler

User-configurable reports with LLM narration, four output formats, and scheduled delivery through Phase 02 providers.
  • New persistent objects for report templates, report schedules, and report runs (additive migration; no changes to existing data).
  • Report data-source registry — 10 built-in sources (offer_performance, channel_effectiveness, selection_frequency, anomaly_candidates, why_not_ranked, decision_traces_summary, funnel, revenue_trend, daily_trend, budget_burn). Extension point: drop a new file in src/lib/reports/data-sources/ and register it.
  • Report format registry — built-in PDF (via @react-pdf/renderer), CSV, Markdown, HTML.
  • LLM narrative engine — uses the tenant AI provider, produces an executive summary + per-section narratives + key takeaways, and caps input at ~5000 tokens worth of rows with explicit truncation signals.
  • Report runner — loads the template, runs the configured data sources, calls the narrative engine, renders every requested format, records the run, and dispatches it to the configured destinations.
  • Full API surface:
    • GET|POST /api/v1/reports/templates, GET|PATCH|DELETE /api/v1/reports/templates/[id]
    • POST /api/v1/reports/templates/[id]/preview (transient render, no persistence)
    • POST /api/v1/reports/templates/[id]/run-now (immediate run; works without the cron)
    • GET|POST /api/v1/reports/schedules, PATCH|DELETE /api/v1/reports/schedules/[id]
    • GET /api/v1/reports/runs, GET /api/v1/reports/runs/[id]
    • GET /api/v1/reports/runs/[id]/artifacts/[format]
  • /settings/reports builder UI — compose sources, pick formats/narrative, schedule + destinations, live preview, runs history drawer.
  • /api/cron/tick extended to also process due report schedules; response JSON gains reportsEvaluated, reportsRan, reportErrors.
Docs: Reports · Report Templates · Report Schedules · First Scheduled Report guide · Reports API

Phase 04 — Executive Dashboard + Share-as-Report

C-suite-ready view and one-click sharing across every dashboard.
  • New page /dashboards/executive — LLM-narrated weekly summary, six KPI cards with period-over-period deltas and sparklines, anomaly feed (last 7 days), segment × offer heatmap, and quick-links to operational dashboards.
  • Reusable dashboard widgets:
    • Period delta — headline + Δ% vs. prior period + sparkline.
    • Anomaly feed — severity pill / metric / delta / explain button.
    • Segment-by-offer heatmap — top-10 × top-10 selection rate grid.
    • Export menu — PDF / CSV / Markdown / HTML dropdown (uses /api/v1/reports/preview under the hood; no cron required).
    • Save-as-Report — modal pre-filled from the current view; creates a report template plus a report schedule in one click.
  • Export + Save-as-Report wired into every dashboard — Business, Operations, Model Health, Data Health, Attribution (in addition to Executive).
  • Backend support for period-over-period (summary_with_comparison, model_auc_summary_with_prev, and sparklines on core metrics).
Docs: Executive Dashboard · Dashboards · Share a Dashboard guide

Earlier changes

Earlier changes are tracked in commit history — see the platform repo. Notable recent work prior to this milestone:
  • Mar–Apr 2026 — Docs remediation and sample-data corrections (connector count corrected to 24, transform count to 15, API response shapes aligned end-to-end with code).
  • Apr 2026 — Repo open-sourced under a single “Initial open source release” commit. CI and CodeQL workflows temporarily disabled pending the public repo cut-over.
  • Apr 2026 — API Explorer auto-creates an API key on first visit to the playground for streamlined onboarding.
This changelog starts with the 2026-04-17 milestone because that’s when we introduced it. For older history, consult the commit log.