Architecture
The durable closed-loop model and guardrails every cross-layer change must preserve.
System Shape
Oblive is one local-first business runner with one organization operator, one always-running chat profile, optional Growth, Engineering, and Support profiles, and ephemeral workers for task execution.
The agent application depends on a provider-neutral harness interface. Codex is the first adapter, not a type system that should leak through shared domain contracts.
Closed Loops
Chat
durable user message + pending assistant message
→ live wakeup
→ claimed chat execution
→ revision-fenced updates
→ PostgreSQL projection
→ SSE to the browserChat may recover from missed live signals. Only chat may resume a stored harness session.
Tasks
task + run request in PostgreSQL
→ stream wakeup
→ worker revalidation
→ immutable attempt
→ heartbeat + workspace sync
→ task, dependency, and outcome finalizationWorkers create attempts. Scheduler and runbeat create or requeue run requests; they do not create attempts directly.
Human Handoff
active run stages typed blocker
→ finalization opens Human Inbox item
→ task waits
→ human response advances task version
→ fresh run requestDo not continue a stale process after a human response.
Managed Integration Authorization
organization chooses access mode
→ backend selects the runtime-specific or generic callback
→ backend creates one-use namespaced OAuth state containing that callback
→ MCP SDK discovers metadata, registers, and performs PKCE
→ callback validates the credential and resolves policy-eligible tools
→ encrypted organization credential + selected tools
→ execution-scoped backend gateway capabilityOAuth client information, refresh tokens, and cached discovery state remain backend-side. Automatic token rotation uses a compare-and-swap credential write and does not advance the authorization epoch. Human connect, reconnect, and disconnect operations use the normal invalidating transition. The callback persisted at authorization start is reused for token exchange. A deployment-specific Meta callback never changes the generic callback used by Apollo and other MCP providers. Agents receive neither API keys nor OAuth tokens.
Managed Integration Tools
execution-scoped gateway request
→ backend selects hosted or local managed tool provider
→ provider exposes MCP discovery and calls
→ gateway applies organization/profile/tool policy
→ reads execute or writes enter the durable action lifecycleHosted providers use their reviewed remote MCP endpoint. The default Meta Ads provider instead
registers fixed Graph tools on an in-memory server with the official MCP SDK and calls
graph.facebook.com/v25.0 with the encrypted organization token. This preserves one discovery,
schema-hash, filtering, proposal, execution, and reconciliation path without putting Meta
credentials or a static Meta server in the agent application.
Provider selection is deployment-owned. Meta graph mode cannot contact the hosted operational
endpoint; hosted_mcp is an explicit rollback. Other managed providers keep their existing remote
clients.
Direct provider mechanics live in workspace packages: @oblive/meta-ads, @oblive/x, and
@oblive/x-ads. Backend adapters add organization credential resolution, authorization, action
policy, and private file staging. Organic X uses OAuth 2.0 with PKCE; X Ads is a separate OAuth 1.0a
connector. Both reuse one composable media upload primitive while retaining separate runtime grants
and provider credentials.
Local Public URLs
The ignored local-stack JSON may opt into a public frontend origin and provider-specific HTTPS
callbacks for externally managed reverse-proxy testing. These values affect browser returns,
provider callbacks, and Vite’s explicit public origin/hostname only. Container and host service
traffic retains Compose DNS or loopback BACKEND_URL values.
The repository does not own a tunnel process or credentials. Public exposure requires an external access gate because the local control plane does not authenticate end users.
Component Boundaries
Backend
Owns authentication, validation, canonical transitions, repositories, Context construction, agent-pack publication and provisioning, OpenAPI, scheduling, repair, and external action policy.
Agent Application
Owns chat and worker loops, backend-client calls, context hydration, workspace synchronization, harness invocation, event normalization, heartbeat scheduling, and shutdown.
Shared Packages
@oblive/types: domain, transport, persistence, manifest, and integration contracts.@oblive/caching: connection-injected Redis primitives and canonical names.@oblive/objectstore: guarded object operations, keys, URIs, and workspace lifecycle.@oblive/agent-packs: catalog validation, composition, discovery, and deterministic revisions.@oblive/oblivectl: snapshot-scoped control-plane HTTP mechanics.
Packages own reusable mechanics, not app-specific policy.
Non-negotiable Invariants
- Scope applicable state by organization.
- Keep chat general; route departments when durable work is created.
- Keep
run_requestsas mutable task-only intent andrunsas immutable attempt history. - Make stale writes and duplicate wakeups harmless through durable revalidation.
- Route task dependencies through one cycle-checking service.
- Route consequential effects through typed actions.
- Synchronize validated output before success.
- Keep provider credentials out of agents and workspaces.
- Keep
oblivectlas the authenticated mutation boundary andcontextctllocal/read-only. - Persist useful summaries and evidence, never hidden reasoning.
Before Changing Architecture
- Name the workflow and failure mode.
- Identify canonical ownership.
- Trace current behavior through contracts and tests.
- Check accepted and rejected decisions.
- Reuse records and transitions.
- Update contracts, migrations, tests, OpenAPI, CLI, and knowledge-base surfaces together.