Home / Services
+ // CAPABILITIES

Three primitives.
Composed to fit.

Most automation problems decompose into three primitives: a workflow that runs on a trigger, an agent that reasons over context, an integration that moves data between systems. Each is delivered to spec, with documentation and access on day one.

01 // WORKFLOW

Workflow automation

End-to-end data flows that replace manual work. Specified as a sequence of triggers, transforms, branches, and retries. Built once. Run forever. Inspectable at every step.

A.01
Triggered execution Schedule, webhook, file drop, inbox event, database change. Whatever signals work needs to happen.
A.02
Deterministic transforms Parsing, validation, enrichment, branching. Specified inputs, specified outputs, no hidden state.
A.03
Failure handling Retries with backoff, dead-letter queues, alerting on real failures. Edge cases handled, not hidden.
A.04
Observability Run logs, execution traces, retention windows. The system explains itself in plain output.
Stack → n8n temporal postgres cron webhooks
SPEC // workflow.invoice_intake .yaml
trigger:
  source:   inbox.invoices@nullfield.ai
  schedule: on_receive

steps:
  - parse.attachment        → application/pdf
  - extract.line_items      → schema:line_item[]
  - classify.gl_account     → llm:claude-haiku-4-5
  - validate.totals         → assert: sum(items) == header.total
  - post.sevdesk            → endpoint:/v1/vouchers
  - notify.operator         → channel:slack#bookkeeping

retries: 3 (exponential, max 60s)
on_error: route → queue.review_manual
sla: p95 < 14s
02 // AGENTS

AI agents and assistants

Autonomous agents that reason over internal documentation, call tools, and execute multi-step tasks. Bounded by a specification, not by a prompt. Evaluated against real cases before they reach production.

B.01
Grounded retrieval Indexed access to internal documents, tickets, past decisions. Answers cite their source. Out-of-scope queries refuse, not improvise.
B.02
Tool use Defined function interfaces to internal systems. The agent calls real APIs, returns real artifacts, makes real changes when authorized.
B.03
Bounded autonomy Approval gates on consequential actions. Audit trail per decision. The agent operates inside a contract, not a chat window.
B.04
Evaluation harness Test cases derived from real history. Pass thresholds defined before launch. Regressions caught before deployment.
Stack → claude openai pgvector langgraph braintrust
CONTRACT // agent.support_triage .json
{
  "scope": {
    "inputs":  ["ticket.subject", "ticket.body", "customer.tier"],
    "outputs": ["category", "priority", "draft_reply", "needs_human"]
  },
  "tools": [
    "search.kb",
    "lookup.contract_terms",
    "fetch.recent_tickets"
  ],
  "guardrails": {
    "must_cite_source":     true,
    "must_escalate_when":   "priority >= P1 OR sentiment.angry",
    "must_not":             ["promise.refund", "modify.account"]
  },
  "evaluation": {
    "dataset":      "tickets_q1_2026 (n=412)",
    "threshold":    "category_accuracy >= 0.92",
    "human_review": "weekly, sample n=20"
  }
}
03 // INTEGRATION

System integration

The connective tissue between systems that were never meant to talk. API layers, webhooks, sync jobs, middleware. Data moves on a contract. State is reconciled. Nothing is silently dropped.

C.01
API layers Typed clients, idempotent endpoints, versioned contracts. The interface survives the systems behind it.
C.02
Bi-directional sync Records reconciled across systems. Conflict resolution made explicit. The source of truth is named, not assumed.
C.03
Legacy bridges Adapters for systems without modern APIs. CSV drops, SOAP, IMAP, scraped panels — wrapped in a clean interface upstream.
C.04
Inspectability Every transfer logged. Schema changes versioned. A broken sync is visible within minutes, not days.
Stack → openapi webhooks postgres kafka retool
INTERFACE // sync.crm_to_billing .contract
source:       hubspot.deal
target:       sevdesk.invoice
direction:    one-way (source → target)
trigger:      deal.stage = "closed-won"

mapping:
  deal.id              → invoice.external_ref
  deal.amount          → invoice.total
  deal.contact.email   → invoice.recipient.email
  deal.line_items[]    → invoice.positions[]

idempotency:  external_ref (upsert)
on_conflict:  source wins, log to audit.crm_billing
backfill:     supported via /sync/replay?from=:date

A workflow to specify, an agent to scope, a system to connect?