01 / Surfaces
Project / 2026
Grivara OPS
A multi-tenant operating system connecting equipment, crews, work orders, maintenance, budgets, and governed agents in one operational model.
The thesis
Most teams start an agentic product with a chat box. I started with authority.
An agent is only as trustworthy as the system that defines what it can know, what it may change, and how every decision can be reconstructed. I built Grivara OPS from that premise: first model the operation, then make it durable, then expose carefully governed capabilities to agents. The intelligence sits on top of the truth; it never replaces it.
- Stage
- Early access
- Scope
- Product architecture · Full-stack engineering · Agent systems
System map
One authority, multiple execution surfaces.
02 / Contract
Typed at every boundary
ORPC and Zod carry one contract from React clients into organization-scoped procedures, with no client-trusted tenant identifiers.03 / Operational core
Shared domain truth
Assets, work orders, skills, calendars, dispatch, maintenance, parts, budgets, and workflows reference the same records.04 / Execution
Postgres owns the state
PostgreSQL and PostGIS hold business truth; transactional outboxes and background workers deliver effects without becoming the authority.01 / Product model
The operation is a graph, not a collection of screens
Every surface resolves through the same records and relationships.
One operating picture replaces tool reconciliation and hidden handoffs.
Shared entities make cross-domain decisions possible without duplicated state.
Every surface reads the same typed relationships instead of rebuilding joins in the UI.
The visible product promise is simple: know where every asset is, keep maintenance on schedule, send the right crew, and understand what the work is costing. The difficult part is that none of those questions belongs to a single module. Availability depends on bookings and maintenance. Dispatch depends on skills, calendars, geography, workload, and the work order itself. Budget depends on the asset and on every open or completed job around it.
I resisted the familiar SaaS pattern of building isolated feature areas and reconciling them later. Equipment, field work, and cost control were modeled as one operational graph. A work order is not a ticket floating in space; it can reference equipment, a location, required skills, assigned people or teams, parts, stops, evidence, SLA state, and a budget allocation. That shared model is what lets the map, calendar, maintenance history, and financial view agree with one another.
This decision made the product harder to fake and easier to extend. Every new surface inherits the same truth instead of creating a parallel version of it. More importantly, an agent can reason across the operation because the relationships already exist in the product model. Retrieval is not being asked to invent structure that the application failed to capture.
Foundational decisionModel the decisions the operation makes, not the pages the software happens to show.
02 / Tenancy and access
Make unsafe access structurally difficult
The trusted organization scope arrives from the session, not the browser: procedures receive it as an explicit argument, so unsafe access is structurally impossible.
Customer data separation is a product guarantee, not a team convention.
Tenant context and permissions are established before domain code can execute.
Procedures receive trusted organization scope from the session; browser input cannot override it.
Multi-tenancy is not middleware sprinkled onto handlers. Grivara OPS has an organization-scoped procedure builder that resolves the active organization and membership from the authenticated session, then injects authorization helpers into the request context. Domain procedures do not accept an organization ID from the browser. The trusted tenant boundary arrives from the server, and query functions receive it as an explicit argument.
I separated transport from business access. Routers validate input, enforce the permission required for the operation, and shape the response. Query functions own database behavior and accept a database handle, which keeps them testable and usable from both request paths and background tasks. Better Auth owns sessions and organization membership; a role-resource-action matrix owns what a member may do inside that organization.
This is not the most glamorous part of an agentic platform, but it is the part that determines whether autonomy can ever be trusted. When tools and agents arrived later, they inherited the same organization and permission boundary. There was no second security model to reconcile and no privileged shortcut around the application.
- Session-derived organization scope
- Role, resource, and action permissions
- Zod validation at procedure boundaries
- Pure query functions with injected database access
Foundational decisionIf a boundary matters, encode it in the construction of the API instead of relying on every caller to remember it.
03 / Extensibility
Configurable without becoming shapeless
The model proposes and the platform decides: drafts are validated, versioned, and published through governance before they can change the live business.
The platform adapts to a customer without turning into a one-off implementation.
A stable native core and governed extension layer preserve upgradeability.
Schemas, relations, workflows, and packages are versioned artifacts with explicit publication gates.
Operations software always meets the same tension: every company is different, but turning every record into untyped JSON makes the core product impossible to reason about. I kept equipment, work orders, budgets, and their support tables as typed native entities because scheduling, assignments, cost rollups, SLA behavior, and reporting need stable semantics.
Above that core, I designed business schemas for customer-specific fields and custom records, first-class relations between native and custom objects, versioned workflows, and packages that bundle those capabilities. A customer can model a specialized intake process or connect a custom commercial object to a work order without weakening the universal field-service model underneath it.
That package layer also creates the right handoff for generative systems. An agent may compose a draft package, but it cannot silently redefine the live business. Draft artifacts are validated, versioned, reviewed, and published through the same governance path as human-authored configuration. The model proposes; the platform decides what becomes real.
Foundational decisionGenerative flexibility belongs in a governed extension layer, not in the tables that carry operational truth.
04 / Workflow kernel
Durable workflows before autonomous agents
Postgres owns workflow truth; Trigger.dev and leased workers only deliver effects. A worker can retry or disappear and the run is still recoverable.
Critical processes remain explainable, recoverable, and approval-aware as automation grows.
Postgres owns workflow truth while workers provide replaceable delivery and compute.
Revision pins, idempotency keys, immutable events, leases, and bounded transitions contain failure.
I built the workflow engine as a deterministic state machine with immutable versions and revision-pinned runs. Commands, domain events, approvals, automatic transitions, and timers all enter the same transition planner. Guards are evaluated against the current business record, ambiguous transitions fail closed, and automatic chains are bounded so a definition cannot spin forever.
Every accepted transition writes the run revision, append-only event, planned capability actions, and idempotency evidence transactionally. External effects move through a Postgres outbox and leased workers. Trigger.dev provides delivery and compute, but it never becomes the workflow state authority. If a worker retries, the idempotency key prevents the business action from being applied twice. If a worker disappears, the database lease can be recovered.
Approvals, timers, and incoming events follow the same philosophy. Approval decisions are immutable and revalidate membership and permission at vote time. Timers are pinned to the workflow revision that created them. Event ingress is a durable, idempotent inbox. Before publication, definitions can be simulated without side effects and analyzed against the active version; blocking findings stop publication and warnings require explicit acknowledgement.
The result is a substrate that can accept instructions from people, system events, or agents without changing the meaning of execution. That was the goal: agents should be another governed source of intent, not a special bypass around the application.
- Immutable workflow versions and append-only run events
- Idempotent commands and transactional capability outbox
- Permission-aware approvals, revision-pinned timers, durable event ingress
- Side-effect-free simulation and publish governance
Foundational decisionThe workflow runtime owns truth; queues and workers only deliver work.
05 / Dispatch intelligence
Explainable recommendations beat theatrical AI
Qualification is a hard gate, not a score: proximity can never outrank competence. The result is a short, explainable list the dispatcher acts on.
Dispatchers spend less time searching while retaining control of the final assignment.
Deterministic ranking provides a measurable baseline before introducing learned models.
Hard qualification precedes weighted signals, preventing proximity from outranking competence.
Dispatch is where the operational graph becomes a decision. For each work order, Grivara OPS first removes technicians and teams that do not satisfy every required skill or minimum proficiency. It then ranks the qualified set using schedule conflicts, open assignments, recent workload, PostGIS distance from the job, and available quality signals. The dispatcher receives a short, sorted list and keeps the final assignment decision.
The order of operations matters. Qualification is a hard gate, not a score that can be outweighed by proximity. Availability conflicts carry a meaningful penalty. Distance is bounded so geography informs the decision without dominating every other signal. When the work is a shipment, the ranker changes its explanation and emphasizes availability, workload, and proximity to pickup instead of pretending that equipment-service skills are relevant.
I deliberately describe this as intelligent matching, not AI dispatch. The behavior is deterministic, inspectable, and testable. A dispatcher can understand why a candidate ranked well, and the rules can evolve as the operation produces better signals. That honesty makes the feature more useful today and creates a clean baseline against which a future learned ranker can be evaluated.
Foundational decisionUse models where uncertainty creates value. Use explicit rules where the business needs an explanation.
06 / Agent execution
Agents get capabilities, never the database
Models and runtimes are replaceable; the capability boundary is not. Every tool call is typed, permission-checked, allowlisted, and limited before it runs.
Agents can create leverage without receiving unlimited authority over the business.
Models and runtimes can change while the capability, policy, and audit boundaries remain stable.
Every tool call is typed, scoped, permission-checked, limited, and recorded before execution.
The agent layer began with a boundary decision: the agent runtime executes reasoning, while Grivara OPS remains the authority for tenants, permissions, business data, workflow state, money, and audit. The runtime receives an opaque run identifier, not database credentials or tenant claims. It exchanges that identifier for a short-lived capability token, and the platform reconstructs the organization, requesting user, membership, allowlist, policy, and run limits on every tool call.
Capabilities are exposed through a typed MCP surface. Tool input is validated, the same role-based permission is enforced again, the per-run allowlist is checked, and the call is claimed against a run limit before it executes. The audit stores the tool, sequence, outcome, duration, and an evidence hash without persisting raw credentials or sensitive payloads. A bearer credential that fails validation never falls back to a browser session.
I introduced autonomy in narrow, reversible increments. The first tools are read-only. Deterministic services calculate official values such as budget forecasts; the agent explains the result and cites the pinned snapshot instead of inventing a number. Package-composition agents can produce drafts, but publication remains governed by validation and human approval. The end-to-end runner path has been live-verified in an isolated environment before any production rollout decision.
This separation is the central architectural bet of Grivara OPS. Models, providers, and agent harnesses can change. The capability boundary, business authority, audit trail, and approval semantics must remain stable. That is what turns an impressive demo into a platform a company can trust with real operations.
- Typed MCP capabilities with existing RBAC enforcement
- Short-lived, run-scoped credentials and fail-closed authentication
- Per-run tool, turn, runtime, and cost ceilings
- Pinned context, append-only tool evidence, and idempotent callbacks
Foundational decisionLLMs are replaceable. Authority boundaries are architecture.
07 / Field reliability
The network is a dependency, not an assumption
The same architecture that governs agents governs humans on bad networks: intent is durable, execution is bounded, and the final state is the server's.
Field work continues through poor connectivity without losing technician intent.
The mobile client converges on server authority instead of becoming a second source of truth.
Persisted optimistic caches and a durable mutation outbox survive restarts and replay in order.
Field software fails when it is designed from an office connection. The mobile app treats connectivity as a changing system state. TanStack Query is wired to the device network signal, paused mutations are persisted as an outbox, and their mutation functions are registered again at boot so a queued action can survive the process that created it.
For visible field actions, I built one optimistic mutation path that patches the same persisted query caches read by the interface. Completing a work order, recording a task outcome, delivering a stop, logging a part, or capturing calibration state can update immediately while offline and remain visible after a cold restart. When connectivity returns, mutations resume in order and the app waits for the outbox to drain before reconciling with server truth, avoiding the flicker that appears when a mid-queue refetch erases later optimistic changes.
This is more than offline support. It is a product decision about trust. A technician should never wonder whether tapping Complete did anything. The interface reflects intent immediately, exposes queued and failed states honestly, and eventually converges on the server authority. The same architecture that governs agents also governs humans in unreliable environments: intent is durable, execution is bounded, and the final state is auditable.
Foundational decisionReliable systems preserve user intent across the failures they know will happen.
What this demonstrates
The real product is the foundation for safe autonomy
Grivara OPS looks like a field-operations product because that is the problem users need solved. Underneath, it is a carefully layered decision system: a shared operational model, structural tenancy, deterministic workflows, explainable recommendation engines, offline intent, and a capability boundary that lets agents participate without becoming the authority.
That sequence was deliberate. I did not add governance after an agent demo became dangerous. I designed the truth, permissions, durability, simulation, and audit surfaces first, then gave models the smallest useful window into them. It is slower than building a chatbot and calling it a platform. It is also how you build an agentic system that can earn more autonomy over time.
This is the kind of work I want to keep doing: finding the small set of architectural decisions that let a complex product move quickly without losing control, then carrying those decisions all the way from database invariants to the interface in a technician's hand.
Discuss an agentic platform