DEV Community

Andrii Shupta
Andrii Shupta

Posted on Originally published at andriishupta.dev on

Encois: Building Organizational Intelligence on Google Cloud

I built Encois for the All Things Agentic Hackathon to explore how an AI system can follow changing company context without becoming an unrestricted chatbot. This article explains the system design behind its event-driven control plane, durable Temporal workflows, scoped agents and evidence model, including why PostgreSQL, raw artifacts, Organization Memory and Workflow Memory have separate responsibilities.

πŸ”— Links

The idea

Encois is a small organizational intelligence system. The easiest way to describe the idea is a mini-Palantir for companies: it connects information from different parts of a business and helps people understand what is changing. Its read-oriented product loop is deliberately narrow: observe β†’ correlate β†’ explain β†’ recommend.

A company with 50–100 people continuously produces new context. A Jira issue becomes blocked, a pull request fails its checks, a deployment goes wrong, a customer sends an important email or an internal decision changes a release plan.

Each event means little in isolation. The useful context appears when a failed check belongs to a pull request, the pull request blocks a Jira issue, the issue belongs to Friday's release and the release affects a customer commitment.

The question is:

β€œWhat changed, why does it matter, and what needs attention now?”

Why this is more than a RAG chatbot

The obvious implementation would collect company documents, put them into a vector database and add chat. Retrieval can help find relevant semantic context, but a company is a changing system rather than a static collection of documents.

Encois is therefore designed around Integrations, scoped Sources, webhooks, immutable revisions and durable Workflows. Every useful result should remain connected to real events, authorized data, user permissions, workflow history and inspectable evidence.

RAG may support retrieval, but it must not decide who can access data, whether a Workflow completed or whether an external action is allowed. Those decisions belong to deterministic application boundaries.

A release-safety example

Imagine a delivery manager asking:

β€œIs this release still safe to ship on Friday?”

The answer may depend on open Jira work, GitHub pull requests, failed checks, deployment events and a document containing the release requirements. An Encois Workflow can collect those signals and return three layers:

  1. Observed facts β€” what Jira, GitHub and other Sources returned.
  2. Interpretation β€” which blockers or dependencies were found across those facts.
  3. Recommendation β€” what a person should review or decide next.

The recommendation does not hide its evidence. The user can inspect the issue, failed check, source and observation time behind it. That product requirement drives the need for provenance, freshness, identity, scope and durable execution.

Starting with system design

Encois was a hackathon project built around Google Cloud and enterprise agents. Before building most of the application, I defined where state should live, how events should enter the system, how permissions should survive a long-running Workflow and how agents should access tools. The goal was one demonstrable vertical slice without collapsing the control plane, execution engine, agent runtime and data plane into one service.

The submission also needed to demonstrate autonomous behavior beyond a chat loop. I used Source ingestion and a multi-step release investigation as that vertical slice: an event enters through a typed boundary, Temporal keeps the work durable, bounded agents collect and interpret evidence, and the Dashboard presents a reviewable result.

At article scale, the architecture is easier to read as two connected views:

The architecture documentation contains the complete deployment view with service identities, secrets, telemetry and local adapters.

The important decision was giving each part one clear responsibility rather than adding services for the sake of the diagram.

Product concepts and immutable execution

Encois separates the product into a few explicit concepts:

  • Integration β€” an organization-level connection to GitHub, Jira or another provider.
  • Source β€” a repository, project, document or other scoped provider resource.
  • Source Revision β€” an immutable version of Source data.
  • Template β€” a reviewed starting pattern for a Workflow.
  • Blueprint β€” the resolved and approved definition of its steps.
  • Workflow β€” a named process the organization can run again.
  • Run β€” one durable execution of a Workflow.
  • Evidence β€” a reference supporting a fact or conclusion.

This structure makes execution inspectable. If a Template changes tomorrow, an old Run still points to the approved Blueprint used at the time instead of silently reinterpreting history through new configuration.

Events, Sources and changing context

An organizational intelligence system cannot depend only on manual questions. Integrations connect Encois to company systems, while Sources narrow those connections to resources a team is allowed to use. Webhooks and ingestion Workflows bring new events and revisions into the platform.

Provider credentials remain references resolved through Secret Manager. Large raw artifacts belong in Cloud Storage, while PostgreSQL stores the Source, its authorized scope, immutable revision and artifact reference. Temporal receives references and execution context rather than raw documents or credentials.

The private Agent Gateway reads the artifact, normalizes it and extracts facts with provenance. Evidence preserves the provider record, observed and ingestion times, freshness, transformation version and visibility scope where available. Hosted adapters can project structured facts into Spanner Graph and distill relevant semantic context into Memory Bank. Derived memory remains useful context, but it is never stronger evidence than the event or document it came from.

Temporal as the execution source of truth

Agent work often lasts longer than one HTTP request. It can include several tools, temporary failures, retries, external events, human approval or a pause while waiting for more information.

Temporal owns the durable execution state: Workflow history, retries, timers, Signals, cancellation, recovery and state between steps. PostgreSQL stores the product-facing Run projection, evidence, actor, scope and audit data without trying to reproduce Temporal's state machine.

One Coordinator per organization

Each organization has one long-lived Coordinator Workflow. It receives versioned lifecycle events such as an Integration being connected, a Source becoming ready, a Workflow start being requested or a Run completing. Temporal Signals and Continue-As-New let it preserve coordination without growing one unbounded Workflow history.

The Gateway writes product state and an outbox event in the same PostgreSQL transaction. A dispatcher leases the row and delivers the versioned event to the Coordinator with retries. Delivery is at least once, so duplicate events are expected and deduplicated by stable event and Workflow identities. This avoids saving a Run while losing the request before Temporal receives it.

For the hackathon version, the dispatcher stays inside the Gateway API. It can later move behind Pub/Sub or Kafka without changing the event contract or creating a second workflow engine.

This also defines the consistency model shown to the user. A queued PostgreSQL Run appears as preparing before Temporal exposes the execution. After the start, Temporal owns execution status and history, while PostgreSQL stores the query-friendly projection, evidence, actor, scope and audit metadata. If either side is unavailable, the API reports stale or unavailable state instead of manufacturing agreement.

Generic Blueprint execution

The Go Runtime executes approved Blueprints through a generic Temporal Workflow. A Blueprint can contain tool steps, agent steps, deterministic transforms, dependencies, conditions, timers and approval Signals. Independent ready steps can run in parallel.

The current implementation runs one approved Google ADK Agent Definition as one Temporal Activity. Temporal can retry that bounded unit while model and tool calls remain outside deterministic Workflow code. This gives internal agent turns coarser visibility and retry behavior, a trade-off that a deeper Temporal and ADK integration could address later. A waiting Run remains durable while it waits for a timer, external condition or approval Signal; paused is a separate versioned product command.

Bounded agents and deterministic boundaries

Encois does not give one agent every tool and ask it to operate the organization. Each agent has a narrow role, typed input and output, an allowlist of tools, a timeout, retry limit, budget and organization scope.

Authentication, permissions, scope calculation, Workflow transitions, schema validation, deduplication and approval rules remain deterministic code. Google ADK and Gemini handle bounded reasoning and synthesis. The model can interpret evidence, but it cannot decide that a user belongs to another organization or that a failed Run succeeded.

The private Agent Gateway checks service identity, a short-lived signed execution capability, organization scope, actor, policy version and the requested tool. Provider credentials never enter the browser, model or Temporal history. Tool names, arguments and provider content remain untrusted until they pass registry, schema and policy checks. Tools are read-only by default; any future write to Jira, GitHub or another provider needs separate permission, approval, audit, idempotency and recovery boundaries.

A recommendation is not an automatic action.

Contracts are part of the architecture

The public Gateway is TypeScript, while the Runtime and Agent Gateway are Go. Their boundaries use versioned OpenAPI and JSON Schema contracts rather than shared source files or database models. Coordinator events, Workflow inputs, tool manifests, evidence and private service payloads are validated on both sides; unknown versions and invalid states fail closed.

The Runtime never queries the control-plane database to reconstruct missing application state. An approved Blueprint snapshot and execution context enter through Temporal, while provider-specific payloads stop at the Agent Gateway and become small typed evidence records. This keeps language and provider choices behind explicit adapters instead of turning PostgreSQL into an integration bus.

Clear ownership across Google Cloud

Each Google Cloud service has a specific responsibility:

  • Runtime β€” Cloud Run. Hosts the Dashboard, Gateway API, Agent Runtime and private Agent Gateway as independently deployable services.
  • Control and artifacts β€” Cloud SQL for PostgreSQL and Cloud Storage. PostgreSQL owns product state, permissions, Runs, outbox rows and projections; Storage owns large raw Source artifacts.
  • Organizational context β€” Spanner Graph. Stores structured company facts and relationships with provenance.
  • Agent context β€” Agent Platform Memory Bank. Stores agent-specific semantic context between Workflows without becoming the source of truth.
  • Reasoning β€” Vertex AI and Gemini. Receives validated, scoped inputs for reasoning and synthesis.
  • Trust and operations β€” Secret Manager, Cloud Logging and Cloud Trace. Protects provider credentials and records timing, retries, evidence reads and error classes.

The source-of-truth split is easier to see as state ownership:

State Source of truth Consumer-facing role
Identity, permissions, configuration, Runs and outbox PostgreSQL Gateway authorization and Dashboard projections
Workflow history, retries, waits and cancellation Temporal Durable execution and live Run status
Original Source payloads and large artifacts Cloud Storage Scoped reads through the Agent Gateway
Structured facts and relationships Spanner Graph Evidence-linked organizational queries
Agent-specific semantic context Memory Bank Scoped retrieval across related Workflows

The separation between PostgreSQL, Spanner Graph and Memory Bank is deliberate. PostgreSQL is the control plane, Spanner Graph models durable organizational facts and relationships, and Memory Bank supports agent retrieval. None of them replaces Temporal's execution history or the original Source artifact.

The current Graph integration projects scoped fact nodes with provenance. Rich entity normalization and relationship edges remain future work, which is why the article treats them as a direction rather than a finished enterprise knowledge graph.

Go was outside my main stack, but it was a practical fit for the Temporal worker and Google ADK runtime. AI helped me build the first small implementation, although learning Go properly still requires more time with the language and SDK documentation.

Observability follows the same boundaries. Request and trace IDs, organization scope, Workflow identity and Run identity travel across the Gateway, outbox, Temporal Activities and private tool requests. Structured telemetry records duration, retry count, provider, model and error class without storing raw credentials, unrestricted documents or hidden model reasoning.

Permissions must survive the Workflow

Organization is the hard tenant boundary in Encois. Inside it, access narrows through organizational units:

The Gateway calculates effective scope from the authenticated membership and selected unit. Checking permission only during the first HTTP request would be insufficient because a Workflow can continue long after that request ends.

The same organization, actor, authorized unit IDs and capability travel through the outbox, Temporal Workflow and private tool requests. The Runtime and Agent Gateway verify them again at their own boundaries. A model-generated organization ID never becomes authorization simply because it appeared in a payload.

The system also fails closed. Missing onboarding data is an error, an unknown Run status is a contract mismatch and provider authentication failure remains visible as degraded or requiring reauthorization.

Turning the dashboard into an operational view

The first Dashboard exposed Integrations, Sources, Templates, Blueprints, Workflows, Runs, events, permissions and memory. That was useful for validating the backend and demonstrating that the control plane was real, but it also made the product feel like an interface to the database.

After testing that version, I shifted the UI toward one operational view that answers a smaller set of questions: what changed, what needs attention, which release is blocked, what has already been checked and which conclusion still needs a human decision.

The underlying control-plane screens remain necessary for configuration and debugging. They should support the intelligence experience rather than become its main interface.

Current limits and next steps

The local environment keeps the same application topology with Docker Compose, PostgreSQL, Temporal, Auth and Storage emulators, the Dashboard, Gateway, Runtime and Agent Gateway. It seeds a synthetic company called Sun Inc with real control-plane records and Temporal-backed Runs; provider fixtures and infrastructure mocks remain explicit adapter modes.

Real Gemini, Spanner Graph and Memory Bank integrations are opt-in because they require configured Google Cloud resources and may incur cost.

The hackathon MVP still needs:

  • richer Graph entities and relationships;
  • production validation of hosted IAM, retention and cost;
  • full organization-unit isolation in the hosted Memory Bank adapter;
  • hardened provider authorization and lifecycle behavior;
  • independent outbox delivery at larger scale;
  • more granular Temporal and ADK execution;
  • stronger deployment and disaster-recovery processes.

The next product step is a smaller and more useful operational picture. Scheduled briefings and change detection could surface investigations before a user asks, while conversational or voice interfaces could help explore evidence without replacing identity, scope and audit boundaries.

Agents may later propose Sources, Blueprints or Workflow configurations, but those proposals should remain reviewable. External actions need stronger approval and recovery guarantees than recommendations.

Summary

Encois explores organizational AI as an event-driven system rather than a chatbot over documents. Its design separates product state, durable execution, raw evidence, structured organizational facts, agent memory and model reasoning so each layer has one clear source of truth.

Temporal makes long-running agent work recoverable. Google Cloud provides explicit boundaries for services, artifacts, secrets, organizational context and model execution. Signed scope and capabilities preserve authorization after the original browser request has ended, while evidence keeps facts, interpretations and recommendations distinguishable.

The main product direction is equally clear: users need one operational view of what changed and what deserves attention, with the architecture underneath making every result scoped, durable and inspectable.

Top comments (0)