Changelog
All notable changes to Ektasi Core are documented here. Format follows Keep a Changelog; this project adheres to Semantic Versioning.
[1.10.0] - 2026-06-21
Added — Platform shell (acquisition · billing sync · telemetry · ops docs)
- Subscription → license sync (migration
0014):marketplace.licenses.subscription_ref/status; the marketplace webhook now normalizes Stripe/Razorpay events — cancel/payment-failed →revokeLicense, renew/payment-succeeded →reactivateLicense. NewlinkSubscription/reactivateLicense. (Validated against real Postgres.) - Public docs hub
/docs(getting-started, license API reference, SDK integration, anti-nulling) with sidebar +docs.*host routing; public/changelogrenderingCHANGELOG.md. - Product telemetry: server-side
captureServer(PostHog) onlicense_activated; complements the privacy-first client pageview analytics. - Ops docs:
ENVIRONMENTS.md(staging parity + role/secret hygiene),DISASTER_RECOVERY.md(PITR + off-site/WORM),PLATFORM_AUDIT.md(reconciliation — most "outer shell" items already shipped). - SEO: sitemap now includes
/docs,/changelog,/eula; footer links added.
[1.9.0] - 2026-06-21
Added — Launch readiness (resilience · comms · monitoring · legal)
- Envato cache + outage fallback (
verifyEnvatoPurchaseCodeCached): 24h fresh cache via Upstash; serves a previously-valid result if Envato is down so customer sites stay online. - Transactional emails:
LicenseEmail+EmailService.sendLicenseActivated/Revoked, fired on activation/revocation (best-effort, skips synthetic addresses). - Zoho Desk sync:
lib/marketplace/zoho.tsmirrors new tickets to a configured webhook. - Abuse alerting:
abuseGuard.noteForbidden— Redis-windowed 403 counter → Sentry alert past a threshold; wired into all license API routes. - Domain-reset escalation (migration
0013): auto-approve early resets, open a HIGH review ticket on the Nth + log aDOMAIN_RESETevent. - Legacy migration:
scripts/migrate-legacy-licenses.mjs(idempotent CSV import, optional email notice, dry-run) +docs/LEGACY_MIGRATION.md. - EULA:
/eulapage + footer link (internet-required activation, domain lock, non-transfer, remote revocation).docs/LAUNCH_CHECKLIST.mdmaps every checklist item to its status. - Validated against real Postgres: migrations
0011–0013apply; domain-reset escalation verified.
[1.8.2] - 2026-06-21
Added — End-to-end DB integration test + CI
tests/marketplace.integration.test.ts(gated byRUN_DB_IT=1): proves activation → domain-lock → heartbeat → revoke → heartbeat-revoked across providers, plus RLS isolation (a portal user cannot read/insert another user's licenses) against a real Postgres..github/workflows/integration.yml— spins apostgres:16service and runs it in CI.- Validated locally against a real Postgres: migrations
0011+0012apply cleanly and all RLS invariants hold (cross-tenant insert rejected byWITH CHECK; admin override scoped correctly).
[1.8.1] - 2026-06-21
Added — Client SDK
- Ektasi License Guard reference SDK in
/sdk:js/ektasi-license-guard.js(Node/browser) andphp/EktasiLicenseGuard.php(PHP/WordPress). Drop-in activate → cached fail-soft heartbeat → entitlement-gatedguard()for premium features, with graceful degradation on revoke/offline. Integration + security guide insdk/README.md. JS verified vianode --check+ a mocked-API behavioral smoke (activate / cache / revoke / entitlement gating).
[1.8.0] - 2026-06-21
Added — Provider-agnostic licensing + anti-nulling enforcement
- Verifier registry (
lib/marketplace/providers/): activation now routes byproducts.provider—envato(Author API) anddirect(our own-platform signedEKD.codes, forgery-proof + revocable). Extensible for gumroad/paddle/etc. (migration0012). - Own-platform codes:
MarketplaceService.issueDirectCode+POST /api/v1/license/issue(server-to-server) mint codes recorded inmarketplace.direct_codesfor later revocation. - Anti-null layers: authoritative
POST /api/v1/license/heartbeat(active|revoked|expired| domain_mismatch), refund/disputePOST /api/webhooks/marketplace(signed) → revoke, admin revoke control in/adminMarketplace Oversight, and a remote-executionentitlementendpoint that issues short-lived signed capabilities only when a license is live. - Forensic trail: append-only
marketplace.license_events(activate/heartbeat/entitlement/ revoke/deny + IP) surfaced in the admin event panel. - Unit-proven crypto:
directCode+entitlement(sign/verify/tamper/expiry). Strategy + client-side responsibilities documented indocs/ANTI_NULLING.md.
[1.7.1] - 2026-06-21
Docs
- Added
docs/LOCAL_DEV.md— exact local bring-up (env + secrets,prisma migrate deploythrough0011, seed, demo logins, end-to-end satellite walkthrough with theTEST-dev bypass, and curl examples for the license API).
[1.7.0] - 2026-06-21
Added — Satellite Licensing & Support Portal (support.ektasi.io)
- Hub-and-spoke marketplace: new isolated
marketplacePostgreSQL schema (0011_marketplace_schema) with ENABLE+FORCE RLS — per-user isolation viaapp.current_marketplace_user_idplus a server-onlyapp.marketplace_adminoverride for hub oversight. - License protocol: Envato purchase-code verification (
lib/envato.ts), domain-locked activation, and stateless HMAC license tokens (lib/marketplace/licenseToken.ts, unit-tested: sign/verify/tamper/expiry). Edge-style heartbeat via/api/v1/license/status(no DB); product call-home via/api/v1/license/validate(client-secret gated). - Portal UI (
/portal): email sign-in (IdP seam), Activation Gate, Asset Vault with SHA-256 checksums + connection diagnostic, and a search-first Smart Support Center (tickets). - Admin oversight:
/adminnow shows Marketplace Oversight (users/licenses/tickets + recent activity) read through the admin override — one source of truth, no context switch. - Host routing:
middleware.tsrewritessupport.*→/portal; enterpriseHeaderhidden there. - Deps:
pg+@types/pg. New env in.env.example; runbook indocs/SATELLITE_PORTAL.md.
Changed — Branding & domain
- New logomark (refined secure-loop + kinetic spark) wired into the global
Header, footer,app/icon.svgfavicon, and the OG image (opengraph-image.tsx). - Email scheme rationalized to
@ektasi.io; privacy/DPO contact →privacy@ektasi.io. Full inventory + subdomain map indocs/EMAIL_ADDRESSES.md. (Primary domain alreadyektasi.io.)
[1.6.1] - 2026-06-21
Security & Fixes (QA review pass)
- Tenant-scoped mutations (defense-in-depth):
ContentService.revise/revertTo/transitionnow mutate viaupdateMany({ where: { id, tenant_id } })+findFirstOrThrow, so the tenant boundary is enforced on the write itself, not only on the preceding read guard. - Razorpay fail-loud config:
RazorpayService.verifyWebhooknow throwsConfigurationErrorwhenRAZORPAY_WEBHOOK_SECRETis missing instead of silently returningfalse; the/api/webhooks/razorpayand/api/webhooks/financeroutes catch it and return503(was a misleading400 Invalid signature). - Middleware anti-spoof: middleware now strips any inbound
x-ektasi-*identity headers before injecting verified ones, so client-supplied identity headers can never be trusted. - API auth model documented as canonical: localized JWT guards (
getSession/withAdminGuard) verify the cookie on every/apiroute; routes never trust request headers (docs/ARCHITECTURE.md).
1.6.0 — 2026-06-20
Added — Persistent dashboard shell + operational desk pages
app/dashboard/layout.tsx(server) fetches the real tenant + renders a persistentDashboardShell(collapsible sidebar, breadcrumb, logout) that wraps all dashboard pages.- Tech & Protocol desk (
/dashboard/tech): routing-control view, simulated SecOps stream, crypto posture; shred action routes to the guarded admin flow. - Creative desk (
/dashboard/campaigns): premium shell embedding the real live CampaignWorkspace (pipeline) + illustrative metrics. - Forensic Audit Ledger (
/dashboard/audit): reads the tenant's realaudit_logswith search/filter + CSV evidence export. - Financial Ledger (
/dashboard/finance): the tenant's realFinancialLedger. - New landing Hero + Tier Matrix pricing page; redundant page wrappers stripped to nest cleanly in the shell.
1.5.0 — 2026-06-20
Added — Content version control + marketing pages
- Asset/content version control (migration
0010): every content item carries acontent_versionsrevision history. Edit creates a new revision; revert appends a new revision copying an older one (history is never rewritten). Routes/api/content/[id]/{revise,versions,revert}, auditedCONTENT_REVISED/CONTENT_REVERTED; surfaced in the campaign workspace UI. - Public marketing + legal site:
/about,/manifesto,/pricing(Tier Matrix),/security(zero-trust overview),/contact(terminal form wired to lead capture),/terms,/privacy,/dpa— all obsidian-themed and in the sitemap. - Global chrome: unified
components/layout/Header(scroll-aware glass nav, hidden on authed routes) +Footer; redesigned terminal-style 404 (not-found.tsx).
1.4.0 — 2026-06-20
Added — Tax, self-serve RBAC, JIT access
- Tax/GST engine (
taxPolicy.ts, tested): 18% GST on INR, EU VAT reverse-charge for enterprise, applied to/api/finance/checkoutas a tax-inclusive total stored in the ledger. - Self-serve enterprise RBAC:
/api/admin/members/invite— admins invite teammates into their tenant with a role + secure handshake email (MEMBER_INVITED). - JIT access:
/api/admin/jit/request— time-boxed, justified support access to a target tenant, immutably logged (JIT_ACCESS_GRANTED).
1.3.0 — 2026-06-20
Added — Creative & Campaign Desk + live portal data
- Per-tenant content approval pipeline (Draft → Review → Approved → Live,
contentPipeline.tswith a tested state machine), campaigns, and lead capture (ContentService,LeadService, migration0009). Tenant-scoped routes:/api/campaigns,/api/campaigns/[id]/content,/api/content/[id]/status,/api/leads;/dashboard/campaignsworkspace UI. - Live portal data: Low-Touch shows real lead/draft counts; High-Touch shows live webhook
delivery counts + success rate via a
webhook_deliverieslog wired into all four webhooks. - Self-serve upgrade prompt (Low-Touch) and Forensic-Auditor link (High-Touch).
1.2.0 — 2026-06-20
Added — Tiered client portals
/dashboardnow segments by tenant tier (verified in the session):LowTouchPortal(SMB/Growth self-service) vsHighTouchPortal(enterprise control tower with RLS/key status + Forensic Auditor link).docs/CLIENT_TIERS.mddocuments the four-desk model with a live-vs-shell reconciliation.
1.2.0 — 2026-06-20
Changed — Edge-native JWT auth (jose)
- Replaced HMAC cookie sessions with jose HS256 JWTs (
lib/auth/session.ts,jti, 12h TTL) that verify at the edge.middleware.tsgates/dashboard+/admin, redirects to/login, and injects verifiedx-ektasi-{tenant-id,client-tier,user-role}headers downstream. - RBAC guards
withAdminGuard/withAuditorGuard(lib/auth/guards.ts); all guard call sites migrated toawait(auth-bypass-checked); login/setup now sign JWTs with tier. - CSP extended with Stripe/Razorpay/Sentry origins (payment redirects + telemetry).
Added — Branded onboarding email & Sentry hardening
components/emails/WelcomeHandshake.tsx(React Email + Tailwind, obsidian/violet);EmailServicenow dispatches it (keeps the audited, non-blocking path).- Zero-trust Sentry scrubbing (
lib/observability/scrub.tsviabeforeSend): strips sensitive headers + stack-frame vars (keys, secrets, password hashes) before egress. /api/webhooks/sentry— HMAC-verified alert webhook logsINFRASTRUCTURE_ALERT_TRIGGEREDto the immutable ledger (telemetry-poisoning resistant).
Added — Financial clearing house & live telemetry
FinancialLedger(migration0008) +financeRouting(tier/currency → gateway, tested)- session-secured
/api/finance/checkout(Stripe/Razorpay/WIRE) with PENDING intent logging.
- session-secured
- Unified
/api/webhooks/finance— signature-branched, idempotent ledger settlement. InvoiceTerminalUI +/dashboard/invoices/[referenceId]page.- Dunning grace window (
BILLING_DUNNING_MAX_FAILURES): softDUNNINGvs hardLOCK(billingApply.ts, migration0007); landingCheckoutCTA(pay → auto-provision). - Live Sentry issues via
lib/observability/sentryFetcher.tswired into the Copilot (getSentryAlerts).
Added — Billing & subscriptions
- Provider-agnostic billing: Stripe + Razorpay (UPI/cards/netbanking) behind one schema
(migration
0006_billing) and one pure policy (billingPolicy.ts, unit-tested). ProvisioningService(shared atomic path),BillingService(Stripe),RazorpayService(REST + HMAC verify, no SDK);/api/billing/checkout(provider-aware) and/api/webhooks/{stripe,razorpay}— payment provisions the tenant, dunning auto-locks it.docs/BILLING.md(incl. honest UPI-via-Razorpay vs. direct-NPCI note).
Added — Docs
docs/DASHBOARD_OPERATIONS.md— the control plane framed as five operational desks (sales intake, tenant lifecycle, SecOps, compliance/audit, secure offboarding), each mapped to backing code with a narrative-vs-shipped reconciliation.
Added — Self-hosted / air-gapped inference
- Provider-agnostic model factory
lib/agents/llm.ts: agents route to any OpenAI-compatible endpoint (vLLM/TGI/Ollama) viaEKTASI_LLM_BASE_URL+EKTASI_LLM_AUTH_TOKEN+EKTASI_LLM_MODEL, falling back to OpenAI when unset. - Copilot, Auditor, and Provisioning agents switched to the factory (no behavior change by default).
scripts/deploy-vllm.sh(Track 1 GPU deploy) anddocs/SELF_HOSTED_LLM.md(dual-track pipeline + secure bridge).
1.1.0 — 2026-06-20
Added — Security enforcement
- Tenant containment (SIRP Phase 2):
tenants.status, migration0003_tenant_lock(lock-aware RLS that blocks runtime data but keeps the audit ledger queryable),TenantService.lock/unlock,/api/admin/tenants/lock, and a console control. - Auth/session layer: HMAC-signed cookie sessions (
lib/security/session.ts),/api/auth/login/api/auth/logout,profiles.role, and a/loginpage.
- Server-side page guards (
lib/security/requireSession.ts) on/adminand/dashboard; real auth checks wired into the Copilot, Auditor, and admin-provision routes. - Database migrations:
0001_init(schema DDL) +0002_zero_trust(RLS tenant-isolation policies + append-onlyaudit_logstrigger) +lib/security/rls.tsforTenant()helper. - Real audit evidence:
KEY_ROTATION(SecretService.rotateSecret+/api/admin/keys/rotate) andAUTHENTICATION(login) events now emitted in production paths. - Rate limiting on login, the AI agent routes (Copilot/Auditor/Provision), and lead capture.
- Public
/api/request-accesslead capture;ContactTerminalno longer hits admin provisioning. - Sentry server + edge configs;
getTenantHealthMetricsreads live Redis with sample fallback. - Feature-flag kill-switch API (
/api/admin/flags) +FlagControlsadmin UI.
Added — Multi-factor authentication
- TOTP MFA (RFC 6238, no external deps) in
lib/security/totp.ts, verified against the canonical test vector. Enrolled during/auth/setup(encrypted secret), enforced at/api/auth/login;/api/auth/mfa/enableactivates it. Migration0005_mfa.
Added — Per-tenant cryptography
- HKDF per-tenant Data-Encryption-Keys derived from the platform KEK + a per-tenant salt
(
crypto.ts, migration0004_per_tenant_keys);SecretServiceseals/opens secrets under the tenant DEK. TenantKeyService.rotateTenantKeyre-keys all secrets +/api/admin/keys/rotate-tenant.- Crypto-shredding: decommission nulls the tenant salt, making its ciphertext underivable.
Added — Telemetry & offboarding
- Live Sentry telemetry:
SentryService.recentExceptionCountwired into the SecOps Copilot health tool (replaces sampled exception counts; graceful fallback). - Tenant decommissioning (SOC2 offboarding):
TenantService.decommission(wipes secrets + profiles, retains the append-only ledger, logsTENANT_DECOMMISSIONED), confirmation-guarded/api/admin/tenants/decommission, and a destruction runbook.
Added — Docs & pipeline
docs/DEPLOYMENT_PIPELINE.md(5-phase zero-trust CD) anddocs/TENANT_PROVISIONING_RUNBOOK.md(with an implementation-reconciliation section).- CI:
postinstall: prisma generate; PlaywrightwebServernow starts in CI with placeholder env; multi-region deploy["bom1","sin1"].
Added — Ops & polish
Dockerfile(+ standalone output) +.dockerignore,.eslintrc.json,CONTRIBUTING.md,LICENSE,scripts/restore.mjs(DR drill), and a generated OpenGraph image.
1.0.0 — 2026-06-20
First production-ready release. Enterprise-hardened, multi-tenant infrastructure ecosystem on Next.js 14 (App Router).
Added — Security & Infrastructure
- AES-256-GCM secret vault with authenticated encryption / tamper detection (
lib/security/crypto.ts). - Single-use, 24h onboarding tokens with SHA-256 storage hashing (
lib/security/token.ts). SecretService(audited resolution),AuditService(append-only forensic ledger),EmailService(Resend onboarding),FeatureFlagService(Redis kill-switch).- Per-tenant sliding-window rate limiting via Upstash Redis (
lib/middleware/rateLimit.ts). - Prisma schema:
tenants,profiles,tenant_secrets,audit_logs.
Added — API
- Atomic tenant provisioning route with async, non-blocking onboarding email
(
app/api/admin/provision/route.ts). - Sentry-tagged credential proxy with client-facing error masking
(
app/api/proxy/[...path]/route.ts).
Added — Frontend
- Component-driven landing page:
Nav,Hero,Manifesto,Protocol,Roadmap,ContactTerminal,Footer(components/landing/). - Gradient SVG
Logomarkwith per-instanceuseId()gradient ids (no DOM collisions). ProvisioningFormwith live validation + loading/success/error states;QuotaMonitor.- Obsidian-themed
error,loading, andnot-foundpages;LoadingSkeleton. - Privacy-first
AnalyticsProvider(no-op unless an analytics src is configured).
Added — Observability
- Sentry instrumentation (
instrumentation.ts,sentry.client.config.ts), every error tagged withtenant_id.
Added — SEO
- Root
metadata(OpenGraph + Twitter),sitemap.ts,robots.ts,public/robots.txt.
Added — CI/CD & Resilience
- Hardened pipeline: lint → unit (Vitest + coverage) → build → e2e (Playwright) → migrate → deploy.
- Nightly encrypted
pg_dump→ S3 WORM bucket (.github/workflows/backup.yml,scripts/backup.mjs). - Playwright provisioning suite + crypto unit tests (round-trip, random IV, tamper rejection).
Added — Deployment & Docs
vercel.json:sin1region,npm cibuilds, and security headers (X-Frame-Options, X-Content-Type-Options, HSTS, Permissions-Policy, Referrer-Policy).- Documentation:
SECURITY.md,docs/INCIDENT_RESPONSE.md,docs/OBSERVABILITY.md,docs/GO_LIVE_CHECKLIST.md.
Security notes
- Clients receive generic
500 Infrastructure Failure; full stack traces stay server-side. - No secret resolution or provisioning occurs without a corresponding
audit_logsentry.