Technology

Engineering principles that outlast any particular tool.

This page explains how we build, what we build with and how we approach AI. Tools change; the standards do not.

Engineering philosophy

Four habits behind every Insoftica product.

01

Boring where it matters

Databases, hosting and build tooling are chosen for reliability and a long support horizon, not novelty. Innovation goes into the product, not the plumbing.

02

Small, frequent releases

Changes ship in small pieces behind automated checks. A release is routine, not an event.

03

Measured, not assumed

Performance budgets, error rates and user-facing latency are tracked from the first deployment. If it is not measured we do not claim it.

04

Written down

Architecture decisions, runbooks and onboarding notes live with the code. The next engineer should not need to ask.

Reference architecture

The shape most of our systems take.

Boring on purpose. Each box is a well-understood component with a long support horizon, so the interesting work can happen in the product.

Reference architecture for an Insoftica productWeb and mobile clients connect through an edge layer to an API, which talks to application services, an AI layer with retrieval and evaluation, and a managed PostgreSQL database with object storage. Monitoring spans every layer.CLIENTSEDGEAPPLICATIONDATAWeb appMobile / PWAThird-party systemsCDN + WAFTLS, caching, rate limitsAPI gatewayauth, validation, auditApplication servicesAI layerretrieval · model callsevaluation · human reviewPostgreSQL (managed)Object storageVector index · cacheObservability: structured logs · traces · metrics · alerts · backups with tested restores
Reference architecture used as the starting point for Insoftica products. Every layer is monitored; AI output passes through evaluation before it reaches a user.

Delivery practices

How work actually gets to production.

Code review on everything

No change reaches production without a second pair of eyes. Reviews look for clarity as much as correctness.

Continuous integration

Lint, type-check, unit and integration tests on every push. A red build blocks the merge.

Feature flags and staged rollouts

New behaviour ships dark, turns on for a few users first, and can be switched off in seconds.

Dependency hygiene

Automated updates and scanning. Known vulnerabilities are patched within days, not quarters.

Performance budgets

Page weight, Core Web Vitals and API latency have numbers attached. Regressions fail the build.

Post-incident reviews

When something breaks we write down what happened, why, and what changed. Blameless, and shared.

The stack

What we build with.

A deliberately small set of well-understood tools. We add to it when a product needs something, not when something is fashionable.

Languages and frameworks

  • TypeScript
  • Node.js
  • React and Next.js
  • Astro
  • Python for data and ML work

Data

  • PostgreSQL
  • Redis
  • Object storage
  • Vector search where retrieval needs it

Infrastructure

  • Containers
  • Infrastructure as code
  • Multi-region cloud hosting
  • CDN and edge caching

AI and machine learning

  • Large language model APIs
  • Retrieval-augmented generation
  • Evaluation harnesses
  • Human review workflows

Quality

  • Automated testing
  • Continuous integration
  • Dependency and secret scanning
  • Accessibility checks

Operations

  • Structured logging and tracing
  • Uptime and error monitoring
  • Backups with tested restores
  • Incident runbooks

Applied AI

AI that does a job, and can show its work.

We treat language models as a powerful but fallible component. The engineering around them is what makes a product trustworthy.

  1. 01

    Input

    A request, document or record from the product.

  2. 02

    Retrieve

    Relevant facts pulled from your own data, with sources.

  3. 03

    Model

    A language model drafts an answer, bounded by the retrieved context.

  4. 04

    Evaluate

    Automated checks score accuracy, safety and format.

  5. 05

    Review

    A person confirms, edits or rejects before anything is saved or sent.

01Start with the jobWe define the task, the inputs and what a correct output looks like before choosing a model.
02Ground it in your dataRetrieval over your own documents and records, so answers cite something real rather than guessing.
03Evaluate continuouslyA test set of real examples is scored on every change, so quality is a number we watch, not an impression.
04Keep a person in the loopOutputs are reviewable, editable and logged. Where the stakes are high, nothing is sent or saved without a human decision.

Evaluation in practice

Quality is a number we watch on every change.

Each AI feature ships with a test set of real examples. Every change is scored against it before it can be released, so a regression is caught by a build, not by a customer.

The code shown is a simplified example of the pattern, not a product.

evaluate.tsts
import { evaluate, loadCases }from './harness';

const cases = await loadCases('support-assistant/v3'); // 240 real questionsconst result = await evaluate(cases, {
  checks: ['answer-matches-source', 'cites-at-least-one', 'no-pii-leak'],
  threshold: 0.95,
});

if (!result.passed) {// The build fails here. Nothing ships.throw new Error(`Accuracy ${result.score} below threshold`);
}

Security and privacy

Defaults, not add-ons.

In the code

Least-privilege access, secrets kept out of repositories, dependencies scanned on every build, input validated at the boundary, and encryption in transit and at rest.

In the organisation

Data kept in the region you choose, access reviewed regularly, backups restored and tested on a schedule, and a written plan for when something goes wrong.