Files
zopu-code/docs/TECH.md

24 KiB

Zopu Work OS — Technical Architecture

Working spec · engineering/platform/infra/security/agent teams · starts from an existing Better-T-Stack monorepo (web + Expo + shared packages).

Objective. Multi-tenant Work OS: durable orgs/projects/goals/work units/runs/artifacts/outcomes; one global conversation + scoped work-unit conversations; continuous candidate-work extraction from conversation and connected systems; coding agents in isolated reproducible environments; autonomous execution with explicit human-approval boundaries; agent progress streamed into durable state; inspectable artifacts (commits, PRs, test reports, previews, docs, reviews); scales across orgs/repos/concurrent units/environments; harnesses and model providers replaceable.

Central ownership rule. Work OS owns intent + durable state · Flow agents own orchestration · AgentOS owns agent runtime coordination · Harnesses own individual agent loops · Sandboxes own full-system execution · Git owns source history · Artifact storage owns generated outputs.

1. High-level architecture

Control plane + execution plane.

flowchart TB
  User --> Web[Web] & Mobile[Expo]
  Web & Mobile --> API[App API] & Realtime
  API --> Auth[Identity/tenancy] & WorkGraph[Work graph] & Conversation & Policy
  Conversation & WorkGraph --> Flow[Flow Agent]
  Flow --> Context & Scheduler & Policy & Gateway[Model gateway] & Integrations & Secrets[Secrets/workload identity broker]
  Scheduler --> Actor[AgentOS run actor]
  Actor <--> Harness[OpenCode/ACP] & Sandbox[Full Linux sandbox]
  Harness --> Gateway & Integrations
  Sandbox --> Git & Runtime[Services/browsers/tests/builds]
  Actor & Sandbox --> Secrets
  Runtime --> Preview
  Actor & Sandbox & Git --> Events[Event/provenance log]
  Events --> WorkGraph & Realtime & Observability
  Artifact[Object storage] --> WorkGraph
  Context & WorkGraph --> Search
  Policy --> Notifications

2. Components & ownership

Client apps (web, Expo) — product surfaces only: render org/project/work-unit/run/artifact/attention state; send domain commands via app API; subscribe realtime; upload via signed/brokered flows. Never reach model providers, Git internals, harnesses, or sandboxes directly. Commands: create work unit, continue work, change composer scope, approve plan, resolve blocker, review artifact, request changes, pause/cancel run, approve merge, approve deployment.

Application API — sole public backend: authz; org/project scoping; CRUD stable entities; command validation; conversation ingestion; attachment metadata; card/workspace/activity/attention queries; realtime-subscription authz; idempotency. Never expose internal runtime APIs.

Identity & tenancy — one Work OS identity per user; organizations are hard tenant boundaries. Every durable/transient entity carries organization_id (+ project_id/work_unit_id/run_id where applicable). Deny-by-default authz on every command/query. Cross-org queries are explicit portfolio ops; never blend underlying knowledge/execution context.

Secrets & workload-identity broker — shared service owning short-lived run identities and scoped credential minting/injection for Git, model gateway, integrations, artifact storage, preview routing, and optional cloud access; secrets remain outside repositories/actor state, and broker decisions are policy-bound and auditable.

Work graph (canonical product DB) — relational DB (authoritative) + event table (append-only provenance/replay) + materialized projections (cards, attention, portfolio, activity) + object storage (large artifacts) + search index. Entities: User, Organization, Membership, Project, Project source, Goal, Signal, Candidate, Work unit, Work-unit relation, Step, Run, Run attempt, Agent session, Blocker, Decision, Approval, Artifact, Source reference, Result, Learning, Conversation message, Composer scope, Integration connection, Policy, Workload identity. Work-unit record = structured fields + projections, not a big agent-authored JSON blob.

Event & provenance log — all meaningful changes are events. Envelope:

{
  "event_id": "evt_01...",
  "type": "run.verification_completed",
  "organization_id": "org_01...",
  "project_id": "prj_01...",
  "work_unit_id": "wrk_01...",
  "run_id": "run_01...",
  "actor_type": "agent",
  "actor_id": "opencode",
  "source_type": "agentos_session",
  "source_id": "session_01...",
  "sequence": 184,
  "payload": {
    "summary": "All unit and browser tests passed",
    "artifact_ids": ["art_01..."]
  },
  "created_at": "2026-07-23T12:00:00Z"
}

Requirements: monotonic sequence per run/actor stream; idempotent ingestion; immutable original payload; normalized derived state; trace card→events; distinguish raw evidence vs agent interpretation vs human decision.

Conversation service — persistent conversation per user workspace, scoped. Message fields: org scope (+optional project/work-unit scope), author, content blocks, attachments, source references, extraction status, domain-event links. Persist exact user message; publish for extraction/orchestration; global + work-unit scope without new sessions; one message may reference several work units; preserve source links when structured state is extracted.

Flow Agent (orchestration above specialist agents) — interpret intent; extract signals/candidates; match new info to existing work; detect duplicates/relationships; build/update work briefs; decide whether a human question is required; select execution strategy; create runs; monitor run events; retry/fallback/escalate; summarize into work-unit state; create approval requests; propose follow-ups. Not the sole durable truth — outputs validated into commands/events. Does not directly mutate repos; coding is delegated to a harness in an isolated environment.

Memory classes (four)

  • Canonical project knowledge (versioned/reviewable, prefer in Git): product.md, design.md, tech.md, business.md, AGENTS.md, READMEs, decision records, repo-local conventions.
  • Structured operational memory (DB): goals, work-unit state, requirements, decisions, approvals, blockers, dependencies, results.
  • Episodic memory (events/transcripts): user messages, agent runs, tool calls, errors, reviews, deployments, human interventions.
  • Retrieval index (derived, non-authoritative → returns source refs): canonical docs, repo content, conversation, work-unit events, artifacts, connected external sources.

Context assembly — never inject all knowledge. Run context pack by precedence: (1) org policy (2) project goals + canonical context (3) repo conventions/instructions (4) work-unit objective/requirements/decisions (5) relevant evidence/artifacts (6) current run instructions (7) runtime + tool constraints. Each item retains source, scope, timestamp, confidence/verification status, revision id. Deterministic enough to audit/reproduce.

Policy & approval engine (above harness permissions + runtime capabilities) — per action: auto-allowed / allowed under standing policy / requires human approval / denied. Examples: create branch, push work branch, create PR → automatic; merge → approval; deploy preview → automatic; deploy production → approval; never send customer comms without review; never access prod data from a default coding run. Approval record = exact action, params, requested capability, evidence/rationale, risk level, expiration, user decision, resulting action event.

Run scheduler / workflow engine — converts accepted work → bounded runs. Owns queue, tenant quotas, priority, fairness, concurrency limits, run leasing, retry policy, budget allocation, cancellation, workflow checkpoints, waiting-for/resuming-after approvals. Run = idempotent steps; persist progress before waiting on human input.

AgentOS runtime — durable supervisor/harness runtime per active run. One actor per active run or isolated workbox (never one giant actor per user/org); durable run-environment identity; harness session lifecycle; event streaming; permission requests; lightweight fs/process coordination; sleep/wake when safe. Actor key: org:{orgId}:project:{projectId}:work:{workUnitId}:run:{runId}. Durable work unit survives actor destruction/replacement.

Agent harness — OpenCode is the initial coding harness (architecture supports other ACP-compatible/adapted harnesses later). Harness owns: model interaction loop, tool selection, repo inspection, file editing, shell requests, local reasoning state, session progress. Harness does not own: product work-unit state, org policy, billing, global memory, project permissions, long-term artifact retention. Drive OpenCode through AgentOS; never expose its standalone server to product clients.

Full Linux sandbox — compatibility/heavy-execution environment: repo checkout, writable branch/worktree, native binaries, package install, language runtimes, DBs, browser automation, dev servers, tests/builds, file watching, preview processes. AgentOS supervises via explicit adapters/bindings. Division:

AgentOS: durable run identity, harness session, approvals, lightweight coordination
Sandbox: full repo fs, native commands, services, browser, tests, builds

Known first-party templates may run in lighter env; imported arbitrary repos default to full sandbox.

Workbox (product-neutral term for execution capsule beneath a run) — contains repo checkout, isolated branch, runtime recipe, harness config, project skills, temp credentials, running services, preview endpoints, test outputs. Ephemeral/replaceable; work unit is durable. Default isolation: one writable checkout per active work unit / mutating run. Parallel read-only runs may share immutable snapshots; parallel mutating runs use separate branches + separate Workboxes.

Git (managed/connected) — source history. Creation modes: managed template, connect external, import+mirror, managed-first then add external remote. Identity: one Work OS user identity, internal service identities for automation, repo-scoped short-lived credentials, no second visible Git account for users. Branching: main + work/{W-id}/{slug}. Git may be hidden in product but user retains portability (export, clone, patch download, external remotes).

Project templates — React web, Hono, Express, full-stack, API-only, Expo, monorepo starter. Template defines: source files, runtime versions, install/test/verify/dev commands, service ports, preview behavior, project context prompts, default policies, agent skills. Generates a reusable base snapshot after successful setup+verification.

Project config files — repo structure:

/  README.md, AGENTS.md, product.md, design.md, tech.md
/.zopu/ project.yaml, services.yaml, policies.yaml
        lifecycle/{setup,resume,verify,preview}  skills/{testing,reviewing,deploying}/SKILL.md
/apps/

project.yaml:

name: example-project
runtime: { template: react-hono, node: "24", packageManager: pnpm }
commands:
  {
    install: pnpm install --frozen-lockfile,
    test: pnpm test,
    verify: pnpm run verify,
    dev: pnpm dev,
  }
services: { web: { port: 3000 }, api: { port: 4000 } }
changes: { workflow: pull_request, baseBranch: main }
approvals:
  {
    pushBranch: automatic,
    createPullRequest: automatic,
    mergePullRequest: required,
    deployPreview: automatic,
    deployProduction: required,
  }

Executor / integration gateway — shared integration+tool gateway: GitHub, Slack, Linear, Intercom, analytics, CRM, cloud services, internal APIs, custom functions. Owns connection mgmt, tool catalog, scoped auth, tool-level policies, approval requirements, auditable invocation. Does not own: shell exec, repo fs ops, work-unit state, agent session state, sandbox lifecycle. Flow Agent may get broader org-level tools; OpenCode gets only project/run-scoped tools for the current task.

Model gateway — all model calls route here. Provider credentials, auto routing, tenant attribution, cost accounting, budget enforcement, rate limits, retries/fallback, prompt/response logging under policy, redaction, run-scoped credentials. Don't expose model selection by default. Run token (short-lived, scoped): {organization_id, project_id, work_unit_id, run_id, model_classes:["coding-standard","coding-fast"], budget_usd:8, expires_in_seconds:3600}.

Artifact storage (object storage, not actor state/DB rows) — types: patch, commit bundle, test report, build log, screenshot, video, preview snapshot, research doc, review report, generated file. Metadata: tenant/work-unit/run scope, type, content hash, producer, source event, retention policy, access policy.

Preview gateway — controlled exposure (not raw sandbox ports): authenticated access, project/run-scoped routing, short-lived URLs, service health, automatic shutdown, event on ready/fail, screenshot/browser verification integration.

Observability & billing — every path emits logs, metrics, traces, cost, token use, runtime duration, tool calls, network use, artifact size, retry count, user-intervention count. Correlation dims: organization_id, project_id, work_unit_id, run_id, actor_id, session_id, sandbox_id, sequence, timestamp. Cost per successful outcome, not per model request.

3. Core execution flows

Project onboarding. User creates project → Project service creates/imports/connects repo → apply template (commit initial files) → Context service drafts context docs → user reviews/commits canonical docs → template runs setup+verify → Snapshot service creates sanitized base snapshot → project active.

Prompt → candidate work. User describes request → Conversation persists scoped message → publishes extraction job → Flow searches related work/sources → creates/updates signal → if existing work matches: attach signal + update understanding; else if new outcome: create candidate → Work graph publishes materialized update → realtime shows updated/new card.

Accepted work → verified PR. User approves candidate → accept work unit → Flow persists objective + acceptance criteria → Scheduler creates implementation run → AgentOS provisions run actor → Workbox creates isolated sandbox → clone repo + create work branch → start OpenCode session → send run context pack. Execution loop: harness inspects/edits/executes, streams events/requests to AgentOS, which persists meaningful events → work card updates. On completion: run verification → upload reports/screenshots → commit/push branch → Flow creates PR + attaches artifacts + moves to Review → UI shows PR/preview/evidence/human action.

Approval continuation. Harness requests sensitive action → AgentOS → Policy evaluates action/scope: auto-allow · or → creates approval request to attention queue → user sees action/evidence/risk/impact → approve/modify/reject → policy persists decision → AgentOS resumes with bounded permission · or → deny with reason.

4. State machines

Keep product, run, and environment state separate. Frontend primarily exposes work-unit state; run state = operational detail; Workbox state hidden except debugging/delayed startup.

Work unit:  proposed → clarifying → ready → active → waiting|review|monitoring → done
            modifiers: blocked, waiting_on_user, waiting_on_dependency, approval_required, autonomous, at_risk, scheduled
Run:        queued → provisioning → preparing → running → waiting_for_input|verifying → succeeded|failed|cancelled
Workbox:    creating → preparing → ready → busy → sleeping|waking → destroyed

5. Concurrency model

  • One writable checkout per active mutating run; one branch per independently shippable work unit.
  • Serialize mutating runs against same branch; permit parallel read-only analysis on immutable snapshots; permit parallel child work on separate branches; merge/integration = explicit controlled action.
  • A work unit may use multiple runs: research → implementation → automated review → verification → human review.
  • Never let agents share one writable working dir without deliberate coordination + conflict handling.

6. Persistence & recovery

Durable truth lives outside transient agent processes. Persist after every meaningful step: work-unit state changes, decisions, approval requests, agent summaries, audit-relevant tool results, commit/patch checkpoints, artifact metadata, verification results. Don't rely on running shells, in-memory harness state, open sockets, or uncommitted working dirs surviving. Before waiting for human input: persist findings, commit relevant files, upload artifacts, record exact requested decision, store resumable workflow state. All workflow steps idempotent or safely repeatable.

7. Security model

Trust boundaries — untrusted: imported repos, repo instructions, external docs, customer messages, MCP tools, tool responses, generated code, agent-authored summaries. A model recommendation is not an authorization decision.

Layered authorization — sensitive action requires ALL: product policy AND harness permission AND runtime capability AND scoped credential. Path: agent requests → harness permission check → Work OS policy eval → human approval when required → runtime capability check → credential minting → execution → provenance event.

Workload identity — each run gets short-lived identity: org_id, project_id, work_unit_id, run_id, initiating principal, permitted capabilities, expiration. Workbox exchanges it for scoped Git/model-gateway/integration/artifact/preview/cloud access. Never inject long-lived org credentials into sandboxes.

Network policy — deny-by-default or allowlisted by run type (package registry during setup, repo host, model gateway, approved external APIs; no unrestricted prod network by default).

Secrets — stored outside repos/actor state; org/project scoped; minted/injected only when required; short-lived; redacted from logs/transcripts; rotatable without rebuilding projects; audited on access.

Data isolation — every query/event/artifact/context lookup/runtime token is tenant-scoped. Cross-org portfolio views may aggregate summaries but never give one org's raw context to another org's agent run.

Human approvals required for: prod deployment, merging protected branches, accessing sensitive prod data, external communications, billing/financial changes, data deletion, org-level policy changes. Action-specific; expire after use or time.

Auditability — retain: who initiated, context provided, agent+model class, tools called, files changed, approvals requested/granted, artifacts produced, what was published/merged, outcome observed.

8. Scaling model

Scale via many small isolated actors + queued runs (not long-lived per-user machines).

Tenant scheduler enforces: max concurrent runs per org/project, priority classes, fair scheduling, subscription limits, model/sandbox budget, retry/runtime-duration limits. Work queue states: accepted → queued → leased → running → completed. Leases idempotent + recoverable (prevent duplicate expensive execution). Resource limits (hard + soft): tokens/run, cost/run, runtime duration, tool calls, file count + repo size, network bytes, process count, memory/CPU, artifact size, subagent depth, repeated-failure count. Artifact offloading — large logs/binaries → object storage; keep refs in work graph. Snapshots — sanitized reusable snapshots accelerate setup. Layers: base OS → language/toolchain → template → project deps. Never snapshot: long-lived creds, user secrets, active tokens, unreviewed prod data. Multi-region (not MVP unless demanded) — keep control-plane relational consistency explicit: org home region, region-local execution actors + artifact/cache placement, global routing to org's control plane, explicit data-residency restrictions.

9. Better-T-Stack monorepo mapping

apps/ web, expo, api, worker, agent-runtime, preview-gateway
packages/ db, auth, domain, api-contract, events, realtime, work-graph, conversation,
          flow-agent, context, policy, scheduler, integrations, model-gateway, git,
          artifacts, sandbox, agentos, opencode, observability, billing, ui, config

Boundaries: domain=pure types + state transitions · events=envelopes/schemas/reducers/provenance · work-graph=work-entity queries + materialized views · conversation=message persistence/scopes/extraction jobs/source links · flow-agent=orchestration/planning/run coordination · context=canonical loading/retrieval/context-pack construction · policy=evaluation + approval workflows · scheduler=queues/leases/quotas/workflows/retries/cancellation · agentos=client/actor naming/session lifecycle/event translation · opencode=harness config/session prompts/tool policy/result normalization · sandbox=provider adapters/workspace lifecycle/commands/logs/previews · git=repo provisioning/branches/commits/pushes/PRs/mirrors · integrations=executor connection mgmt + tool scopes · model-gateway=provider routing/budgets/credentials/cost attribution.

10. API & command design

Prefer domain commands over generic entity mutation. Examples: CreateProject, ImportRepository, CreateWorkUnit, AcceptCandidate, AttachSignal, MergeCandidates, StartWork, UpdateRequirements, ApprovePlan, ResolveBlocker, RequestChanges, PauseRun, CancelRun, ApproveAction, RejectAction, ApproveMerge, ApproveDeployment, ReopenWorkUnit. Each command: validate tenant scope + current state; idempotent where practical; emit ≥1 domain event; no direct client control of infra details.

11. Event translation (harness → product)

Preserve raw harness events for audit; translate to human-meaningful product events:

tool_call bash "pnpm test"      → run.verification_started
tool_result exit_code=0         → run.test_suite_passed
permission_request git_push     → approval.requested
file_edit src/auth/callback.ts  → artifact.code_change_updated

Primary UI hides raw transcripts unless user opens technical details.

12. Implementation sequence

  • Phase 1 — Durable product model: orgs, projects, work units, candidates, runs, artifacts, conversation scopes, event log, card projections.
  • Phase 2 — One complete coding loop: one template project, managed Git, one sandbox provider, one AgentOS actor/run, OpenCode harness, model gateway, branch creation, tests, artifact upload, PR output, human approval.
  • Phase 3 — Context & memory: canonical Markdown files, context-pack construction, retrieval index, decision memory, source provenance.
  • Phase 4 — Autonomous discovery: continuous signal ingestion, candidate extraction, duplicate detection, existing-work matching, attention queue.
  • Phase 5 — Additional integrations/workflows: external Git, support, team comms, issue trackers, analytics, deployment + monitoring.

13. MVP success criteria

Reliably demonstrate: Prompt → candidate/work unit → clarified objective → isolated coding run → tested change → preview/evidence → pull request → human review → durable completed work card. The work unit must remain understandable + resumable even if the harness session or Workbox is destroyed.

14. Non-goals (first release)

Every harness; every sandbox provider; arbitrary multi-agent swarms; full replacement of external Git providers; multi-region active-active control plane; unlimited imported-repo compatibility; automatic prod deployment without approval; generic low-code workflow builder; exposing model selection + agent internals to users.

15. Architectural principles

  1. Durable work state outlives execution environments. 2. Every execution path is tenant-scoped. 3. One writable checkout per mutating unit of work. 4. Persist events before projecting summaries. 5. Treat agent outputs as claims with provenance, not unquestioned truth. 6. Separate product policy, harness permission, and runtime capability. 7. Short-lived credentials + explicit workload identity. 8. Keep harnesses, models, sandboxes, and Git providers replaceable. 9. Hide infrastructure state from the product surface unless actionable. 10. Measure successful outcomes and human attention, not merely agent activity.