insigz docs

Architecture

Two planes on one Postgres, fail-closed RLS, and the enforced AI grounding contract.

Two planes, one Postgres

insigz splits cleanly into a business plane and a data plane that share one PostgreSQL instance but are managed very differently.

  • Business plane — Next.js 15 + Payload 3.77. Owns auth, admin, org/project/members, sources config, settings, invoice-only commercial, marketing CMS, and the metadata of cases and reports. This is reused wholesale from the proven estate.
  • Data plane — raw-SQL tables managed by forward-only migrations. Holds the canonical model: bitemporal, Ed25519-signed, monthly-partitioned observations, plus entities, entity_aliases, events, cases, and reports. Never modelled as Payload collections.

Row-level security (fail-closed)

Every data-plane table has RLS enabled and forced. Three independent predicates are AND-ed:

  1. Tenanttenant_id must match the request context.
  2. Clearance — the user's clearance must dominate the row's classification. Unset clearance ranks as OPEN, so a no-clearance user sees only OPEN rows.
  3. Cell — a NULL-cell row is tenant-shared; a cell-tagged row needs a matching cell, unless the user is faculty (visibility only, never approval).

The application connects as a dedicated non-owner role (NOBYPASSRLS, NOSUPERUSER) so RLS is actually enforced. Context is set per short transaction via SET LOCAL app.*.

The AI grounding contract

insigz-ai calls Claude through a typed tool layer (the model never gets raw DB access). Every customer-facing claim must cite a resolvable id: [OBS-####], [EVT-####], or [DOC-####]. A server-side validator resolves every citation against the tenant's data before the answer ships. Dangling or uncited claims are rejected and regenerated once; failing that, the assistant returns a plain "could not ground" response. Nothing customer-facing publishes autonomously.