Files
zopu-code/docs/zopu-system-handoff-v2.md

3341 lines
77 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Zopu Timeline System — Product & Engineering Handoff
**Status:** Orange-light design handoff
**Scope:** Project onboarding, project setup artifact, global timeline, work-owned timelines, events, artifacts, frontend mechanics, and Convex control plane.
**Explicitly deferred:** AX intelligence, intent-routing quality, delivery workflows, autonomous coding behavior, and deep memory implementation.
---
## 1. Product idea
Zopu should feel like working with a capable employee over Slack or WhatsApp.
The user does not operate an agent dashboard, inspect hidden execution logs, or manually manage sessions. They talk naturally. The system responds quickly, organizes the work, runs execution threads in the background, and returns useful artifacts through a shared timeline.
The foundational interaction loop is:
```text
Event happens
→ it appears in a timeline immediately
→ Zopu acknowledges it like a coworker
→ the system creates or updates Work
→ one or more Threads execute beneath that Work
→ progress and results return as events
→ meaningful results appear as artifact cards
```
The timeline is not a transcript owned by one assistant session. It is an ordered stream of events emitted by users, system services, work, threads, tools, integrations, and artifacts.
---
## 2. Core product principles
### 2.1 Events first
Every visible or actionable change is represented by a durable event.
Messages, project setup completion, work creation, thread state changes, preview readiness, blockers, and artifact publication all enter the same event model.
### 2.2 Work owns conversation
A **Work** unit owns its timeline and the broader responsibility being pursued.
Threads execute beneath Work. Threads do not own separate chat timelines.
### 2.3 Projects are context, not chat surfaces
There is no project chat.
A Project stores repository context, environment information, setup artifacts, and knowledge that can be shared into related Work.
One Project can have many Work units and therefore many Work timelines.
### 2.4 Artifacts carry depth
The timeline stays compact and conversational.
Detailed output lives in artifacts. Each artifact has:
- a compact card rendered in the timeline
- a durable detailed representation such as Markdown, HTML, a file, a preview, or an external link
### 2.5 Background work should feel invisible
Repository exploration, environment inspection, workspace preparation, and pre-warming happen quietly.
The client may show a thin setup indicator, but it should not dump internal progress into the timeline. The user mainly sees the completed setup artifact or an actionable blocker.
---
## 3. Timeline surfaces
There are only two timeline scopes.
### 3.1 Global timeline
Organization-wide interaction surface.
Responsibilities:
- create new Work
- coordinate across Projects and Work
- receive Project setup artifacts
- handle admin and broad workflow management
- surface cross-work notifications and blockers
- let the user talk naturally before the system knows the final Work shape
The global timeline is the default surface after onboarding.
### 3.2 Work timeline
Dedicated interaction and control surface owned by one Work unit.
Contains:
- user messages about that Work
- system acknowledgements
- Thread lifecycle updates
- decisions and clarifications
- progress worth surfacing
- artifact cards
- preview and blocker updates
- handoff and completion events
A Work timeline may coordinate multiple Threads simultaneously or sequentially.
### 3.3 No Thread timeline
A Thread is an execution unit beneath Work.
Its important outputs are projected into the Work timeline. Internal logs and detailed execution history remain attached to the Thread or its Runs, not rendered as a separate chat surface.
---
## 4. First-time Project onboarding
## 4.1 User flow
```text
User logs in
→ opens Project setup
→ connects GitHub
→ selects repository
→ system starts exploration immediately
→ system detects required environment variables
→ user supplies missing values
→ system prepares AgentOS workspace
→ system attempts to run supported application
→ system prepares preview when possible
→ system creates Project setup artifact
→ system posts setup event to global timeline
→ user lands in global timeline ready to work
```
The Project setup artifact is generated and posted by the system. The user does not send a prompt to create it.
## 4.2 What setup should do
As soon as a repository is selected:
1. Resolve the repository and default branch.
2. Prepare or pre-warm an AgentOS workspace.
3. Scan the repository tree and important manifests.
4. Detect the application type and likely start commands.
5. Detect required environment variable names.
6. Classify variables:
- absolutely required to boot
- required for external integrations
- optional or development-only
7. Ask the user for missing values during setup.
8. Attempt a best-effort boot for supported stacks.
9. Record a preview URL when available.
10. Generate a concise repository and setup summary.
11. Publish the Project setup artifact.
## 4.3 Initial supported stacks
Keep setup intentionally narrow at first:
- React frontend
- static frontend served through Node
- Node API
- Hono API
- Express API
Unsupported or ambiguous repositories should still finish setup with a blocker artifact rather than trap the user in an endless setup process.
## 4.4 Setup visibility
Repository exploration and workspace warm-up are mostly invisible.
The Project setup screen may show a thin status such as:
```text
Connecting repository → Checking environment → Preparing workspace → Ready
```
Do not stream every file read, command, or exploration step into the global timeline.
## 4.5 Project setup artifact
The setup artifact is the first durable knowledge kernel for a Project.
It is:
- attached to Project context
- referenced once by an event in the global timeline
- available to future Work and Threads related to the Project
- regenerated only after meaningful setup changes, not on every Project load
Suggested contents:
```text
Project name
Repository and branch
Detected stack
Short architecture summary
Environment status
Required missing variables
Workspace status
Preview URL or preview blocker
Known start/test/build commands
Important directories
Suggested areas where work can begin
Setup timestamp and artifact version
```
The global timeline card should remain concise:
```text
zopu-code is ready
Stack: React · Hono · Convex
Environment: 7 / 7 configured
Preview: available on demand
[Open setup artifact] [Open preview]
```
Failure variant:
```text
zopu-code needs one setup fix
Workspace: ready
Preview: blocked by DATABASE_URL
[Add environment variable] [Open setup report]
```
## 4.6 Subsequent Project loads
Loading an already-onboarded Project should not create another first-time message.
The existing setup artifact remains in Project context. A new artifact/event is created only when:
- repository connection changes
- environment changes materially
- setup is explicitly refreshed
- the detected application shape changes
- a previously blocked preview becomes ready
---
## 5. Entity model
## 5.1 Organization
Top-level identity and collaboration boundary.
**Owns**
- global timeline
- Projects
- Work index
- organization policies and membership
**Does not own**
- execution boxes
- Pi sessions
- previews
**Lifetime:** long-lived.
## 5.2 Project
Repository-centered context kernel.
**Owns**
- repository connection
- branch metadata
- environment variable definitions and references
- setup state
- Project setup artifacts
- accumulated Project knowledge later
**Contributes to**
- Work context
- Thread execution context
**Does not own**
- a chat timeline
- Work conversation
**Lifetime:** long-lived.
## 5.3 Project setup artifact
First durable understanding of a connected repository.
**Contains**
- summary
- detected stack
- environment status
- workspace status
- preview URL or blocker
- start/build/test hints
**Created by:** system.
**Attached to:** Project.
**Surfaced in:** global timeline through an event reference.
## 5.4 Work
An evolving outcome, responsibility, or goal.
A Work unit may begin vague and become more precise as the user and system learn more.
Examples:
- migrate the current timeline model
- ship authentication v2
- improve deployment reliability
- maintain and monitor the payment system
**Owns**
- one Work timeline
- current goal and desired outcome
- context and decisions
- Threads
- artifact index
- status and lifecycle
**May reference**
- one primary Project initially
- Project setup artifact and Project knowledge
**Lifetime:** until the broader responsibility is complete.
## 5.5 Timeline
Ordered projection of heterogeneous events.
**Scopes**
- global
- work
**Input:** immutable events.
**Output:** messages, state changes, cards, system notices, and artifact references.
**Realtime owner:** Convex subscription.
A Timeline can be modeled as a stable scope record plus a query over Events. It does not need to duplicate the full message payload.
## 5.6 Thread
Bounded execution path beneath a Work unit.
A Thread works toward one coherent part of the Work goal.
Examples beneath “ship authentication v2”:
- inspect current authentication
- implement passkey backend
- build frontend screens
- review security model
- verify deployment
**Owns**
- Runs
- Pi sessions
- AgentOS boxes or workspace leases
- previews
- branches and generated files
- Thread-local artifacts
**Does not own**
- its own timeline
**Lifetime:** finite. It closes after delivery, handoff, cancellation, or failure.
## 5.7 Event
Immutable fact emitted by any actor.
**Core properties**
- identity
- actor
- event type
- timestamp and stable sequence
- scope
- causation and correlation links
- typed payload
- optional artifact references
Events form the causal history used to build timelines and later agent context.
## 5.8 Artifact
Durable work output with two faces.
### Timeline face
- label and title
- short summary
- status
- key facts
- actions
- link to full artifact
### Detail face
One of:
- Markdown
- static or generated HTML
- file
- preview
- external URL
- structured data rendered by a known frontend component
Artifacts are versioned. Updating an artifact should create a new revision rather than silently replacing history.
## 5.9 Execution resource
Delivery-side resource owned or leased by a Thread.
Examples:
- AgentOS box
- Pi session
- process
- preview
- Git branch
- generated file
Only important lifecycle changes become timeline events. Raw runtime chatter remains outside the user timeline.
---
## 6. Ownership hierarchy
```text
Organization
├── Global Timeline
├── Projects
│ └── Project
│ ├── Repository connection
│ ├── Environment configuration
│ ├── Project context
│ └── Project Setup Artifact
└── Work
└── Work Unit
├── Work Timeline
├── Decisions and context
├── Artifacts
└── Threads
└── Thread
├── Runs
├── AgentOS boxes / workspace leases
├── Pi sessions
├── Processes
├── Previews
└── Generated outputs
```
Important relationship:
```text
Project provides context → Work owns coordination → Thread owns execution
```
---
## 7. System boundaries
## 7.1 Client boundary
### Interactive client
Responsibilities:
- global timeline UI
- Work timeline UI
- composer
- Project setup experience
- artifact cards
- artifact detail routes
- thin workspace/preview status
- optimistic event submission
### Timeline renderer
Responsibilities:
- map event types to visual blocks
- group related events when useful
- render compact system events
- render artifact cards through safe components
- preserve chronological ordering
- support pending, failed, and retried client events
The client should not understand AX, AgentOS, Pi, or workflow internals.
## 7.2 Convex control plane
Responsibilities:
- durable event ledger
- global and Work timeline queries
- Organization, Project, Work, and Thread ownership records
- Project setup state
- artifact metadata and references
- realtime subscriptions
- idempotency
- dispatch/outbox records for runtime work
- authorization and tenant scoping
Convex is the source of truth for visible product state.
It does not need to host long-running AX or Pi execution.
## 7.3 Work runtime boundary
Initially Hono plus Effect and later AX flows.
Responsibilities:
- consume dispatch jobs or relevant events
- acknowledge user events
- interpret intent
- create or evolve Work
- create and supervise Threads
- call AgentOS through the gateway
- publish important events
- create artifacts and card data
For the timeline slice, this can be stubbed with deterministic handlers. The intelligence layer arrives later.
## 7.4 Delivery boundary
AgentOS plus Git and Pi sessions.
Responsibilities:
- route calls to the correct user/Project/Work/Thread workspace
- inspect repositories
- execute commands
- manage processes and previews
- manage generated files
- run Pi exploration, implementation, and review sessions
- return outputs and artifact manifests
The delivery boundary does not write arbitrary UI state directly. It returns results to the Work runtime, which publishes typed events and artifacts through Convex.
---
## 8. Event envelope
Use one shared envelope for every event.
```ts
export type TimelineScope =
| { kind: "global"; organizationId: Id<"organizations"> }
| { kind: "work"; organizationId: Id<"organizations">; workId: Id<"works"> };
export type Actor =
| { kind: "user"; userId: string }
| { kind: "system"; service: string }
| { kind: "work"; workId: Id<"works"> }
| { kind: "thread"; threadId: Id<"threads"> }
| { kind: "tool"; tool: string }
| { kind: "integration"; integration: string };
export interface EventEnvelope<TType extends string, TPayload> {
type: TType;
actor: Actor;
scope: TimelineScope;
payload: TPayload;
projectId?: Id<"projects">;
workId?: Id<"works">;
threadId?: Id<"threads">;
runId?: string;
causationId?: Id<"events">;
correlationId: string;
replyToEventId?: Id<"events">;
artifactIds?: Id<"artifacts">[];
idempotencyKey?: string;
occurredAt: number;
}
```
Convex adds `_id` and `_creationTime`. Use an explicit `sequence` if deterministic ordering beyond `_creationTime` is required.
## 8.1 Initial event types
### Client events
```text
client.prompt
client.media
client.action
client.retry_requested
```
### Project setup events
```text
project.setup.started
project.setup.environment_required
project.setup.environment_updated
project.setup.ready
project.setup.blocked
project.preview.ready
project.preview.blocked
```
Only `ready`, `blocked`, and meaningful user-action events generally belong in the global timeline. The rest may remain operational events outside the default visible feed.
### Conversation and coordination events
```text
assistant.acknowledged
system.notice
work.created
work.updated
work.status_changed
thread.started
thread.status_changed
thread.completed
thread.failed
```
### Artifact events
```text
artifact.published
artifact.revised
artifact.superseded
artifact.failed
```
## 8.2 Event visibility
Every event should have a visibility classification:
```ts
type EventVisibility = "timeline" | "compact" | "internal";
```
- `timeline`: render as a full timeline item
- `compact`: render as a small status divider or grouped state change
- `internal`: stored for causality/debugging but hidden by default
This avoids polluting the timeline without creating a second incompatible event system.
## 8.3 Causality example
```text
client.prompt event A
assistant.acknowledged caused by A
work.created caused by A
thread.started caused by work.created
artifact.published caused by thread.started
```
All events share one `correlationId` for the broader interaction.
---
## 9. Artifact contract
```ts
export type ArtifactKind =
| "project_setup"
| "plan"
| "repository_report"
| "issue"
| "patch"
| "preview"
| "review"
| "verification"
| "blocker"
| "report";
export interface ArtifactCard {
component: "summary" | "setup" | "plan" | "preview" | "blocker";
label: string;
title: string;
summary: string;
status: "working" | "ready" | "blocked" | "failed" | "superseded";
facts?: Array<{ label: string; value: string }>;
actions?: Array<{
id: string;
label: string;
style?: "primary" | "secondary" | "danger";
emits: "client.action";
payload?: unknown;
}>;
}
export type ArtifactContent =
| { type: "markdown"; body: string }
| { type: "html"; storageId: Id<"_storage">; sandboxed: true }
| { type: "file"; storageId: Id<"_storage">; mimeType: string }
| { type: "external"; url: string }
| { type: "structured"; schema: string; data: unknown };
```
Do not initially allow arbitrary generated JavaScript inside timeline cards.
Timeline cards should use a constrained component registry. Full generated HTML may open in a sandboxed artifact detail view.
---
## 10. Convex persistence model
The exact schema may adapt to the existing codebase, but preserve these domain boundaries.
## 10.1 `organizations`
```ts
{
name: string,
createdBy: string
}
```
## 10.2 `projects`
```ts
{
organizationId,
name,
repositoryProvider: "github",
repositoryOwner,
repositoryName,
repositoryId?,
defaultBranch,
setupStatus: "pending" | "needs_environment" | "warming" | "ready" | "blocked",
latestSetupArtifactId?,
workspaceStatus?: "none" | "warming" | "live" | "sleeping" | "failed",
updatedAt
}
```
Indexes:
```text
by_organization
by_repository
```
## 10.3 `projectEnvironmentVariables`
Store definitions and secret references, not raw secrets unless the chosen secret mechanism explicitly supports that.
```ts
{
organizationId,
projectId,
name,
category: "required" | "integration" | "optional",
status: "missing" | "configured" | "invalid",
secretReference?,
source: "detected" | "user" | "system",
description?,
updatedAt
}
```
Index:
```text
by_project
```
## 10.4 `works`
```ts
{
organizationId,
primaryProjectId?,
title,
summary,
desiredOutcome?,
status: "forming" | "active" | "waiting" | "blocked" | "completed" | "cancelled",
createdFromEventId,
createdBy,
lastActivityAt,
closedAt?
}
```
Indexes:
```text
by_organization_last_activity
by_project_status
```
## 10.5 `threads`
```ts
{
organizationId,
workId,
projectId?,
title,
purpose,
status: "queued" | "running" | "waiting" | "blocked" | "completed" | "failed" | "cancelled",
createdFromEventId,
activeRunId?,
startedAt?,
completedAt?,
lastActivityAt
}
```
Indexes:
```text
by_work_last_activity
by_work_status
```
## 10.6 `events`
```ts
{
organizationId,
scopeKind: "global" | "work",
workId?,
projectId?,
threadId?,
runId?,
type,
actor,
visibility: "timeline" | "compact" | "internal",
payload,
causationId?,
correlationId,
replyToEventId?,
artifactIds?,
idempotencyKey?,
occurredAt,
sequence?
}
```
Indexes:
```text
by_global_timeline: organizationId + scopeKind + occurredAt
by_work_timeline: workId + occurredAt
by_project: projectId + occurredAt
by_thread: threadId + occurredAt
by_correlation: correlationId + occurredAt
by_idempotency: organizationId + idempotencyKey
```
## 10.7 `artifacts`
```ts
{
organizationId,
projectId?,
workId?,
threadId?,
runId?,
kind,
title,
summary,
status,
card,
content,
logicalKey,
version,
supersedesArtifactId?,
createdByEventId,
createdAt
}
```
Indexes:
```text
by_project_kind
by_work_created_at
by_thread_created_at
by_logical_key_version
```
## 10.8 `projectSetups`
Operational state for onboarding.
```ts
{
organizationId,
projectId,
status,
currentStep?,
detectedStack?,
detectedCommands?,
workspaceLeaseId?,
previewUrl?,
blocker?,
startedAt,
updatedAt,
completedAt?
}
```
Index:
```text
by_project
```
## 10.9 `dispatchJobs`
Outbox between Convex and Hono runtime.
```ts
{
organizationId,
kind,
sourceEventId?,
projectId?,
workId?,
threadId?,
payload,
status: "pending" | "claimed" | "completed" | "failed",
attempt,
nextAttemptAt,
claimedBy?,
claimedAt?,
error?
}
```
Indexes:
```text
by_status_next_attempt
by_source_event
```
Create the source Event and Dispatch Job in the same mutation whenever processing must happen asynchronously.
---
## 11. Convex API surface
Names can match the existing codebase, but these capabilities are required.
## 11.1 Project setup mutations
### `projects.connectRepository`
- validates organization access
- creates/updates Project
- creates `projectSetups` record
- creates setup dispatch job
- returns `projectId` and setup status
### `projects.setEnvironmentVariable`
- validates Project access
- stores secret reference/configuration status
- updates variable record
- schedules setup resume when required values are ready
### `projects.refreshSetup`
- explicit user-triggered setup refresh
- creates a new setup attempt
## 11.2 Timeline mutations
### `timeline.sendPrompt`
Inputs:
```ts
{
scope: { kind: "global" } | { kind: "work"; workId },
text: string,
projectId?,
replyToEventId?,
clientIdempotencyKey: string
}
```
Behavior:
1. authorize scope
2. deduplicate by client key
3. insert `client.prompt` event
4. create dispatch job in the same transaction
5. return the inserted event
### `timeline.sendAction`
Used by artifact card actions such as:
- open or request preview
- add missing environment variable
- approve
- revise
- retry
- cancel
The action itself becomes `client.action` in the relevant timeline.
### `timeline.retryEvent`
Creates a retry request referencing the failed event. It does not mutate history.
## 11.3 Timeline queries
### `timeline.getGlobal`
- organization-scoped
- paginated newest/older event retrieval
- excludes internal events by default
- joins minimal artifact card data
### `timeline.getWork`
- Work-scoped
- same pagination model
- includes compact Thread state events
### `timeline.getAroundEvent`
Useful for navigation from notification or artifact to surrounding context.
### `timeline.getPendingClientEvents`
Optional helper if optimistic client events are separately tracked.
## 11.4 Work queries
### `works.listActive`
For global sidebar or command palette.
### `works.get`
Returns Work projection, Threads, latest artifacts, and status.
## 11.5 Artifact queries
### `artifacts.get`
Returns metadata and signed/readable content reference.
### `artifacts.listForWork`
Useful for artifact index inside a Work surface.
## 11.6 Internal mutations
Runtime-only APIs:
```text
internal.events.append
internal.works.createFromEvent
internal.works.update
internal.threads.create
internal.threads.updateStatus
internal.artifacts.publish
internal.artifacts.revise
internal.projects.publishSetupArtifact
internal.dispatch.claim
internal.dispatch.complete
internal.dispatch.fail
```
Every runtime mutation must validate service identity and idempotency.
---
## 12. Project setup backend sequence
```text
1. Client selects GitHub repository
2. projects.connectRepository mutation
3. Convex creates Project + projectSetups + dispatch job
4. Hono runtime claims setup job
5. Runtime asks AgentOS gateway for a workspace
6. Workspace scans repository and detects environment names
7. Runtime writes detected environment variable definitions
8. If required values are missing:
- Project setup status becomes needs_environment
- setup UI asks user for values
9. Once values are configured, setup resumes
10. AgentOS attempts supported start command
11. Runtime records workspace and preview state
12. Runtime creates Project setup artifact
13. Convex stores artifact attached to Project
14. Convex appends project.setup.ready or project.setup.blocked to global timeline
15. Client subscription renders the setup card
```
The setup artifact event is system-authored.
---
## 13. Normal Work creation sequence
For this slice, the intelligence may be mocked, but preserve the product contract.
```text
1. User sends a natural message in global timeline
2. client.prompt appears immediately
3. Runtime publishes assistant.acknowledged quickly
4. Runtime creates a rough Work unit
5. Work receives its own timeline scope
6. Runtime creates the first Thread beneath Work
7. Thread claims or creates required execution resources
8. Important Thread state changes appear in Work timeline
9. Thread publishes artifacts
10. Thread closes after delivery/handoff
11. Work remains active for future Threads until broader outcome is complete
```
Initially, Work and its first Thread may look almost identical. Their difference becomes important over time:
- Work evolves, accumulates responsibility, and survives multiple Threads.
- Thread remains a bounded execution path and closes.
---
## 14. Frontend experience
## 14.1 Project setup page
Required UI:
- GitHub repository selection
- thin setup progress
- detected environment variable form
- validation and missing-value state
- redirect to global timeline after setup reaches ready or blocked
Do not make the user wait for perfect Project understanding. Finish best-effort setup and surface blockers clearly.
## 14.2 Global timeline
Initial empty state before any Project:
- simple greeting
- connect/import Project action
- no fake chat history
After Project setup:
- system-authored setup message
- Project setup artifact card
- composer ready for natural input
The setup artifact may include suggested work, but clicking a suggestion should only prefill the global composer. It should not silently create Work.
## 14.3 Work timeline
Header should communicate:
- Work title
- status
- linked Project
- active Threads count
- latest preview or blocker if relevant
Timeline renders:
- user messages
- acknowledgements
- compact Work/Thread lifecycle events
- artifact cards
- blockers and questions
## 14.4 Timeline event renderer
Use a registry rather than one giant conditional component.
```ts
const eventRenderers = {
"client.prompt": UserMessage,
"assistant.acknowledged": CoworkerMessage,
"project.setup.ready": ProjectSetupMessage,
"project.setup.blocked": ProjectSetupMessage,
"work.created": CompactSystemEvent,
"thread.started": CompactSystemEvent,
"thread.completed": CompactSystemEvent,
"artifact.published": ArtifactMessage,
};
```
Unknown event types must degrade safely to a generic system event during development.
## 14.5 Realtime and optimistic behavior
When sending a prompt:
1. show optimistic user event immediately
2. call `timeline.sendPrompt`
3. reconcile optimistic ID with Convex event ID
4. show retry state on network failure
5. never duplicate after reconnect because of idempotency key
Convex subscriptions then deliver acknowledgement and later artifacts.
## 14.6 Pagination
The timeline must support:
- loading latest events first
- fetching older events when scrolling upward
- stable scroll anchoring
- live append at the bottom
- “new activity” indicator when the user is reading older history
## 14.7 Artifact cards
Initial card components:
- `ProjectSetupCard`
- `SummaryArtifactCard`
- `PlanArtifactCard`
- `PreviewArtifactCard`
- `BlockerArtifactCard`
Start with fixed card schemas. Generated custom UI is a later extension.
---
## 15. Context model for later intelligence
The timeline ledger becomes one source of agent context.
Later, agents may receive:
- recent timeline window directly
- Work summary and decisions
- Project setup artifact
- Project knowledge base
- artifact index
- MCP tools to search the complete event history
- RLM loop over long timeline context
Do not overload the initial timeline schema with a full memory architecture. Preserve stable IDs and causal links so a context/memory layer can be built later.
---
## 16. Security and ownership rules
Every record must carry or derive `organizationId`.
Authorization checks:
- user belongs to Organization
- Project belongs to Organization
- Work belongs to Organization
- Thread belongs to Work
- Event scope matches its Work/Organization
- Artifact references cannot cross tenant boundaries
- AgentOS gateway resolves resources using explicit Organization, Project, Work, and Thread identifiers
Environment values should be stored through a proper secret store or encrypted secret integration. The timeline and artifact payloads must never contain raw secret values.
Generated HTML artifacts must be sandboxed and must not inherit application credentials or same-origin access.
---
## 17. Reliability rules
1. Persist user Events before dispatching work.
2. Create dispatch jobs transactionally with source Events.
3. Deduplicate every client submission with an idempotency key.
4. Deduplicate runtime processing by source Event and handler version.
5. Never mutate an old Event to rewrite history.
6. Publish corrected state as a new Event.
7. Use immutable Artifact revisions.
8. A Thread crash must not destroy Work or its timeline.
9. Internal execution logs must not be required to reconstruct user-visible state.
10. Setup failure must still produce an actionable global timeline card.
---
## 18. Minimal implementation slice
The first implementation should prove mechanics, not intelligence.
## 18.1 Demo promise
```text
Connect repository
→ configure detected environment variables
→ system publishes Project setup artifact to global timeline
→ user sends natural prompt
→ prompt appears instantly
→ system acknowledges it
→ Work and first Thread are created
→ a mocked or simple background handler publishes an artifact card
→ artifact detail opens
```
## 18.2 Build order
### Phase 1 — Domain and Convex
1. Add Organization/Project/Work/Thread/Event/Artifact schema.
2. Implement global and Work timeline queries.
3. Implement prompt/action mutations with idempotency.
4. Add dispatch outbox.
5. Add internal event and artifact publication APIs.
### Phase 2 — Frontend timeline
1. Replace the old chat/session model with scope-based timelines.
2. Build renderer registry.
3. Build global timeline.
4. Build Work timeline.
5. Add optimistic send and pagination.
6. Add initial artifact cards and artifact detail route.
### Phase 3 — Project onboarding
1. Trigger setup immediately after repository selection.
2. Add setup progress state.
3. Detect and collect environment variable names.
4. Publish a mocked/basic Project setup artifact.
5. Redirect to global timeline and render setup card.
### Phase 4 — Runtime stub
1. Hono claims dispatch job.
2. Publish deterministic acknowledgement.
3. Create Work and first Thread.
4. Publish deterministic sample artifact.
5. Validate full realtime loop.
### Phase 5 — Delivery integration
1. Connect AgentOS workspace setup.
2. Add supported stack detection.
3. Attempt startup and preview.
4. Fill the real Project setup artifact.
5. Hand pre-warmed workspace to first relevant Thread when possible.
Only after this slice works should AX intent routing and real flows be introduced.
---
## 19. Acceptance criteria
### Project onboarding
- Selecting a repository starts setup without another user action.
- Missing required environment variables are requested during setup.
- Setup can finish as ready or blocked.
- A system-authored Project setup artifact appears once in the global timeline.
- The artifact is also attached to Project context.
- Revisiting the Project does not create a duplicate onboarding event.
### Global timeline
- User prompt appears immediately.
- Reconnect does not duplicate it.
- Timeline receives realtime system events.
- Setup cards and artifact cards render correctly.
- Suggested Project tasks only prefill the composer.
### Work
- A natural request can create rough Work.
- Work owns one timeline.
- The first Thread belongs to Work.
- Thread updates appear inside the Work timeline.
- Thread completion does not automatically close Work.
### Artifacts
- Artifact card and detail representation are separate.
- Artifact is linked to its source Event and owning entity.
- Revisions remain inspectable.
- Blocked setup produces an actionable blocker card.
### Reliability
- Source Event and dispatch job are created atomically.
- Duplicate runtime delivery does not create duplicate Work, Threads, or artifacts.
- Authorization prevents cross-Organization access.
---
## 20. Out of scope for this slice
- sophisticated intent classification
- AX Flow design
- RLM context retrieval
- multi-agent orchestration
- full knowledge base and memory system
- arbitrary generated timeline UI
- broad framework/build-system support
- autonomous code editing
- issue and pull-request creation
- production preview orchestration
- multiple simultaneous boxes per Thread
- advanced Work evolution and automatic merging/splitting
The data model should permit these later, but the first implementation should not attempt them.
---
## 21. Decisions still open
These are implementation choices, not product-model gaps:
1. Exact secret store used for Project environment values.
2. Convex push versus Hono polling/claiming for dispatch jobs.
3. Whether timelines require an explicit `timelines` table or remain pure scope projections.
4. Artifact body storage: Convex storage, object storage, or both.
5. Exact workspace lease and pre-warm handoff contract with AgentOS.
6. Naming of low-level Runs beneath Threads.
7. Retention and compaction strategy for internal Events.
None of these should block implementation of the visible timeline slice.
---
## 22. Final mental model
```text
PROJECT SETUP
Repository selected
→ Project context prepared
→ environment configured
→ AgentOS workspace pre-warmed
→ Project setup artifact stored
→ setup event shown in global timeline
NORMAL WORK
User talks in global timeline
→ prompt event
→ quick coworker acknowledgement
→ Work created/evolved
→ Work timeline becomes control surface
→ Threads execute beneath Work
→ Threads use Project context and delivery resources
→ results become artifacts
→ artifact events appear in Work timeline
→ Threads close
→ Work continues until the broader outcome is complete
```
The core contract is:
```text
Project provides context.
Work owns the timeline.
Threads own execution.
Events preserve history.
Artifacts communicate results.
```
---
# CONTINUATION — Intelligence & Delivery Runtime
**Status:** implementation-planning handoff
**Scope:** project runtime setup, Convex workflows, timeline dispatch, one project-bound Flue conversation agent, AgentOS VM binding, exploration flow, issue flow, and artifact generation/publication.
---
## 0. How this document relates to the timeline handoff
The previous handoff defines the stable product model:
```text
Project provides context.
Work owns the timeline.
Threads own bounded execution.
Events preserve history.
Artifacts communicate results.
```
This document adds the first intelligence and delivery runtime that operates on that model.
Where this document conflicts with the earlier onboarding implementation, this document wins for the first shipping slice.
### Explicit simplifications that supersede earlier assumptions
1. The first slice supports one active Project per user/organization.
2. One Project owns one AgentOS VM.
3. One Project owns one Flue conversation agent instance.
4. Project setup does not attempt broad framework detection, application boot, or preview generation.
5. Environment values are optional and never block setup.
6. Only a root-level `.env.example` is inspected.
7. Project setup succeeds only when:
- the AgentOS VM exists
- the repository is shallow-cloned into it
- the repository can be read
8. Deep repository exploration happens after `project.ready`, through the conversation agent.
9. Multi-project routing, multiple VMs, autonomous coding, pull requests, and production previews are deferred.
---
# Part I — Shipping goal
## 1. Demo promise
A user connects GitHub and selects a repository.
Zopu creates a dedicated AgentOS VM, shallow-clones the repository, scans the root `.env.example`, creates a project-bound Flue conversation agent, emits a durable `project.ready` event, and redirects the user to the global timeline.
The conversation agent receives the ready event, explores enough of the repository to onboard itself, stores a project summary, and posts a short coworker-style onboarding response plus a polished setup artifact.
The user can then ask for one of two supported kinds of work:
1. Explore or explain part of the repository.
2. Turn a request or finding into a well-formed issue.
The agent immediately acknowledges the request, creates Work and a first Thread when execution is required, performs the task inside the project VM, generates a polished static HTML artifact, stores it through Convex, and publishes its card into the appropriate timeline.
## 2. End-to-end loop
```text
PROJECT ONBOARDING
GitHub connected
→ repository selected
→ Convex projectSetupWorkflow starts
→ AgentOS VM created for project
→ depth-1 repository clone
→ root .env.example scanned
→ project marked ready
→ project.ready event appended
→ project conversation agent registered
→ ready event dispatched to agent
→ agent performs onboarding exploration
→ summary.md stored as Project context
→ setup HTML artifact published
→ onboarding response appears in global timeline
NORMAL INTERACTION
User sends timeline message
→ message event stored first
→ timelineDispatchWorkflow starts
→ event sent to project conversation agent
→ agent posts short acknowledgement
→ agent decides: answer / explore / create issue
→ Work created or evolved when execution is needed
→ Thread created for specialist execution
→ specialist uses project VM
→ artifact generation loop runs
→ HTML uploaded through Convex
→ artifact card appears in timeline
→ agent posts concise final handoff
```
---
# Part II — Runtime boundaries
## 3. Convex: durable control plane
Convex owns all user-visible and durable system state.
### Responsibilities
- Project records and setup state
- global timeline and Work timelines
- immutable Events and causal links
- Work and Thread records
- project runtime bindings
- conversation agent registrations
- dispatch records and workflow state
- project context documents
- artifact metadata and storage references
- realtime client subscriptions
- idempotency and retry state
### Convex does not own
- the live Flue model loop
- shell execution
- repository filesystem state
- Pi execution sessions
- static HTML rendering process
- long-running delivery work
## 4. Hono + Flue: intelligence runtime
Hono exposes the runtime service. Flue models the persistent project conversation agent and the specialist execution flows.
### Responsibilities
- addressable conversation agent instances
- receiving timeline and system events
- coworker-style responses
- deciding whether to answer, explore, or create an issue
- starting and supervising specialist flows
- mounting project context and tools
- binding the agent to its AgentOS VM
- publishing progress and results through typed tools
- invoking the artifact generation loop
### Agent identity
For the first slice:
```text
one active Project
→ one ConversationAgent
→ one AgentOS VM
```
Suggested stable identity:
```text
conversation:{organizationId}:{projectId}
```
The agent is project-bound even though it initially posts into the organization global timeline.
## 5. AgentOS VM: delivery environment
The VM is the agent's dedicated working environment for one Project.
### Responsibilities
- hold the shallow repository checkout
- provide read access to code and configuration
- run safe repository inspection commands
- host optional Pi execution sessions
- write generated working files and artifact drafts
- retain Project-scoped runtime state according to AgentOS lifecycle
### Initial constraints
- one VM per Project
- one repository per VM
- one workspace root
- read-oriented repository tools
- no autonomous code mutation flow yet
- no multi-VM routing
## 6. Pi sessions: optional deep workers
The conversation agent can inspect directly through sandbox tools for small tasks.
For deeper exploration, it may start or resume a Pi session inside the Project VM.
Pi is an execution worker, not the owner of Work, Thread, Event, or Artifact state.
```text
Work
└─ Thread
└─ specialist flow
└─ one or more Pi sessions
```
A Pi session may produce raw notes, Markdown, JSON, or files. Flue remains responsible for interpreting and publishing those outputs.
---
# Part III — Core entities added by this slice
## 7. ProjectRuntime
Represents the Project-to-AgentOS binding.
```ts
interface ProjectRuntime {
projectId: ProjectId;
organizationId: OrganizationId;
provider: "agentos";
runtimeId?: string;
vmId?: string;
workspacePath: string;
repositoryPath: string;
status:
| "requested"
| "creating_vm"
| "cloning"
| "checking_repository"
| "ready"
| "failed";
repositoryCommit?: string;
lastError?: RuntimeError;
createdAt: number;
updatedAt: number;
}
```
### Owns
- runtime provider identifiers
- workspace path
- clone/readiness state
- current repository commit
- setup failures
### Does not own
- user-facing timeline state
- agent conversational state
- Work or Thread lifecycle
## 8. ConversationAgentBinding
Maps one Project to one Flue agent instance.
```ts
interface ConversationAgentBinding {
id: AgentId;
organizationId: OrganizationId;
userId: string;
projectId: ProjectId;
runtimeId: string;
globalTimelineId: TimelineId;
status: "creating" | "ready" | "busy" | "error" | "disabled";
flueConversationId?: string;
lastEventId?: EventId;
createdAt: number;
updatedAt: number;
}
```
The binding is durable in Convex. Flue runtime state may be reconstructed from it and Project context.
## 9. AgentDispatch
One request to deliver one Event to one agent.
```ts
interface AgentDispatch {
id: DispatchId;
sourceEventId: EventId;
organizationId: OrganizationId;
projectId: ProjectId;
agentId: AgentId;
workId?: WorkId;
threadId?: ThreadId;
status: "queued" | "sending" | "accepted" | "completed" | "failed";
attempt: number;
handlerVersion: number;
idempotencyKey: string;
lastError?: string;
createdAt: number;
updatedAt: number;
}
```
## 10. FlowRun
Represents an execution of a Flue specialist flow beneath a Thread.
```ts
interface FlowRun {
id: FlowRunId;
flowType: "onboarding_explore" | "explore" | "issue";
flowVersion: number;
projectId: ProjectId;
workId?: WorkId;
threadId?: ThreadId;
sourceEventId: EventId;
agentId: AgentId;
status:
| "queued"
| "running"
| "waiting"
| "generating_artifact"
| "completed"
| "failed"
| "cancelled";
state?: unknown;
attempt: number;
startedAt?: number;
finishedAt?: number;
updatedAt: number;
}
```
## 11. ProjectContextDocument
Stores durable Project knowledge produced by onboarding and later work.
Initial context document:
```text
summary.md
```
```ts
interface ProjectContextDocument {
id: ContextDocumentId;
projectId: ProjectId;
kind: "repository_summary" | "environment_manifest" | "other";
title: string;
contentType: "text/markdown" | "application/json";
body?: string;
storageId?: string;
sourceFlowRunId?: FlowRunId;
revision: number;
status: "current" | "superseded" | "failed";
createdAt: number;
}
```
## 12. ArtifactBuild
Tracks the generation and publication of a static artifact.
```ts
interface ArtifactBuild {
id: ArtifactBuildId;
projectId: ProjectId;
workId?: WorkId;
threadId?: ThreadId;
flowRunId: FlowRunId;
artifactKind: "project_setup" | "exploration" | "issue";
status:
| "drafting"
| "rendering"
| "validating"
| "uploading"
| "published"
| "failed";
sourceManifest?: unknown;
outputStorageId?: string;
artifactId?: ArtifactId;
attempt: number;
lastError?: string;
createdAt: number;
updatedAt: number;
}
```
---
# Part IV — Project setup workflow
## 13. Entry point
The workflow starts immediately after the user connects GitHub and selects a repository.
Suggested client mutation:
```text
projects.createFromRepository
```
Input:
```ts
interface CreateProjectInput {
repositoryConnectionId: string;
repositoryOwner: string;
repositoryName: string;
repositoryUrl: string;
defaultBranch: string;
}
```
The mutation should:
1. Validate user and organization ownership.
2. Create the Project record.
3. Create or reuse a `ProjectRuntime` record.
4. Start `projectSetupWorkflow` with an idempotency key.
5. Return the Project ID and setup status route.
## 14. `projectSetupWorkflow`
```text
create_project_runtime
→ create_agentos_vm
→ shallow_clone_repository
→ verify_repository_readable
→ scan_root_env_example
→ register_project_agent
→ mark_project_ready
→ append_project_ready_event
→ trigger_timeline_dispatch
```
### Step 1 — Create AgentOS VM
Required result:
```ts
{
runtimeId: string;
vmId: string;
workspacePath: string;
}
```
The step must be idempotent by `projectId`.
A retry must find and reuse an existing valid VM rather than creating duplicates.
### Step 2 — Shallow clone
Clone only the selected branch and latest history:
```bash
git clone --depth=1 --single-branch --branch "$BRANCH" "$REPOSITORY_URL" "$REPOSITORY_PATH"
```
Repository credentials are handled by the AgentOS/runtime adapter. They are never exposed to the model or written into Events.
The clone step is idempotent:
- if the repository directory is absent, clone
- if it contains the expected repository, verify it
- if it is corrupt or mismatched, mark the runtime failed and require repair/retry
### Step 3 — Verify readability
Minimum checks:
```text
repository path exists
git rev-parse HEAD succeeds
root directory can be listed
at least one tracked file can be read
```
The current commit SHA is stored on `ProjectRuntime`.
### Step 4 — Scan `.env.example`
Narrow rule:
```text
only inspect <repository-root>/.env.example
```
If the file does not exist:
```text
environment manifest = empty
environment status = none_detected
```
If it exists:
- parse variable names
- preserve example/default text where safe
- never treat example values as secrets
- never require the user to complete them before proceeding
- present them later as optional Project configuration
No recursive env scanning, framework inference, or required/optional classification in this slice.
### Step 5 — Register conversation agent
Create one project-bound agent identity and associate it with the VM.
The registration must be idempotent by:
```text
organizationId + projectId + agentType
```
### Step 6 — Mark Project ready
Project setup is ready only when:
```text
VM exists
AND repository is cloned
AND repository is readable
```
Environment configuration is not part of the readiness predicate.
### Step 7 — Emit `project.ready`
The workflow appends an immutable system Event:
```ts
{
type: "project.ready",
scope: "global",
actor: { kind: "system", service: "project-setup" },
projectId,
payload: {
agentId,
runtimeId,
repositoryCommit,
environmentVariableNames
}
}
```
This event is the durable trigger for the onboarding conversation.
### Step 8 — Dispatch the ready event
Create an `AgentDispatch` for the Project conversation agent and start the normal timeline dispatch workflow.
The setup workflow itself does not fabricate the onboarding response.
The conversation agent produces it.
## 15. Setup failure behavior
Setup fails and onboarding remains blocked when any of these fail terminally:
- VM cannot be created
- repository cannot be cloned
- repository cannot be read
Behavior:
```text
project.status = setup_failed
projectRuntime.status = failed
setup page shows an actionable error card
user is not redirected as ready
project.ready is not emitted
```
The user can retry after fixing the connection or runtime problem.
Environment variables do not cause setup failure.
## 16. Deferred from Project setup
Do not implement these in this workflow yet:
- application boot
- preview creation
- package-manager detection beyond what exploration may report
- framework-specific environment inference
- dependency installation
- test execution
- deep architecture summary
- multi-repository Project
---
# Part V — Timeline dispatch workflow
## 17. User message entry point
The client sends a message through a Convex mutation.
Suggested mutation:
```text
timeline.sendMessage
```
It must atomically:
1. authenticate the user
2. validate timeline scope
3. append the user Event
4. create the `AgentDispatch`
5. start `timelineDispatchWorkflow`
6. return the Event ID immediately
The client optimistically renders the message, but Convex is authoritative.
## 18. `timelineDispatchWorkflow`
```text
load_source_event
→ resolve_project_agent
→ create_or_reuse_dispatch
→ send_event_to_flue
→ record_acceptance
→ wait_for_or_observe_completion
→ complete_dispatch
```
### Dispatch input
```ts
interface ConversationEventInput {
dispatchId: DispatchId;
sourceEvent: EventEnvelope;
agentId: AgentId;
organizationId: OrganizationId;
projectId: ProjectId;
globalTimelineId: TimelineId;
workId?: WorkId;
threadId?: ThreadId;
}
```
### Delivery contract
The Hono/Flue service must accept the Event using a service-authenticated endpoint.
Suggested logical route:
```text
POST /internal/agents/:agentId/events
```
The request must be idempotent by `dispatchId`.
A repeated Convex workflow step must not cause the agent to process the same source Event twice.
## 19. Agent-to-timeline tool
The conversation agent receives a constrained tool for publishing user-visible output.
Do not give the model direct database credentials or arbitrary Convex mutations.
Suggested tool surface:
```ts
interface TimelineTool {
postMessage(input: {
text: string;
replyToEventId?: EventId;
workId?: WorkId;
importance?: "normal" | "high";
idempotencyKey: string;
}): Promise<{ eventId: EventId }>;
postUpdate(input: {
text: string;
workId: WorkId;
threadId?: ThreadId;
status?: "working" | "blocked" | "waiting" | "done";
idempotencyKey: string;
}): Promise<{ eventId: EventId }>;
publishArtifact(input: {
artifactId: ArtifactId;
workId?: WorkId;
threadId?: ThreadId;
text?: string;
idempotencyKey: string;
}): Promise<{ eventId: EventId }>;
}
```
The implementation can call a Hono control endpoint that validates the agent binding and writes through Convex.
The agent can use this tool to:
- acknowledge a request
- publish a meaningful intermediate update
- ask a blocking question
- publish an artifact card
- post its final handoff
It should not post every internal tool call.
---
# Part VI — Conversation agent
## 20. Product behavior
The conversation agent behaves like an effective coworker who already understands the Project.
It should:
- reply quickly
- use short, natural messages
- begin work without reheating the entire context
- create or evolve Work when a real responsibility appears
- dispatch specialist execution
- send only meaningful progress updates
- return depth through artifacts rather than chat walls
- remain available after a specialist finishes
## 21. Initial supported decisions
For the first slice, the agent chooses among four actions:
```text
1. respond directly
2. ask one necessary clarification
3. start exploration
4. start issue creation
```
No broad autonomous planner is required yet.
## 22. Conversation style contract
### Default response size
- one to three short sentences
- usually under 50 words
- no long status essays
- no raw chain-of-thought
- no giant Markdown reports in the timeline
### Good acknowledgement examples
```text
Got it — I’m tracing that part of the repo now. I’ll bring back the relevant code path and the risky edges.
```
```text
Yep. I’m turning this into a concrete issue and checking the repository evidence before I lock the scope.
```
```text
I found the likely entry point. I’m checking the surrounding dependencies before I package the result.
```
### Final response examples
```text
The exploration is ready. The main path starts in `packages/server`, with two coupling risks worth handling first.
```
```text
I’ve drafted the issue with scope, acceptance criteria, and the files most likely involved.
```
The detailed result is linked through the artifact card.
## 23. Unsupported requests
The first runtime is read-oriented and does not yet implement autonomous code delivery.
The agent should not bluntly deny every writing request.
Instead it can:
- inspect and scope the request
- create Work
- produce an issue artifact
- explain the next delivery step
- preserve the request for a later implementation flow
It must not falsely claim that code was changed, tested, or shipped.
## 24. Context mounted for every turn
The agent should receive or be able to retrieve:
- Project identity and repository metadata
- `summary.md` Project context when available
- environment variable names, never secret values by default
- recent global timeline Events
- current Work timeline Events when the source Event belongs to Work
- active Work and Thread summaries
- recent Artifact cards and references
- direct access to the project-bound VM tools
Convex remains the source of durable truth. Flue persistent state is useful for conversational continuity, but it must be recoverable from durable records.
---
# Part VII — Flow loop
## 25. Definition
The flow loop is the event-driven supervisor around the conversation agent and specialist flows.
It is not a permanent `while(true)` process.
It advances when one of these Events occurs:
- user message
- `project.ready`
- specialist started
- specialist progress worth surfacing
- specialist completed
- specialist failed
- artifact published
- user clarification
- user cancellation
## 26. Loop behavior
```text
receive event
→ restore agent/project/work context
→ decide next conversational action
→ publish acknowledgement when needed
→ start or resume one specialist flow
→ persist run/thread state
→ return control
specialist later emits event
→ conversation agent receives it
→ publishes concise update or final response
→ starts next flow only if required
```
## 27. Work and Thread creation
A casual response does not require Work.
When the agent starts exploration or issue creation for a user goal:
```text
create or resolve Work
→ create first Thread beneath Work
→ attach source Event causally
→ start specialist FlowRun under Thread
```
### Work
Represents the broader desired outcome or responsibility.
It may begin vague and evolve as more context and Threads accumulate.
### Thread
Represents one bounded execution path.
Initial Thread types:
```text
exploration
issue-definition
onboarding-exploration
```
A Thread can close while its Work remains active.
## 28. Supervision rules
- one source Event creates at most one initial specialist run per handler version
- a run must have a stable `flowRunId`
- a specialist completion is emitted as an Event
- a failed run is visible and retryable
- the conversation agent never marks Work complete merely because one Thread completed
- important outputs are artifacts, not hidden runtime state
---
# Part VIII — Initial specialist flows
## 29. Onboarding exploration flow
Triggered by:
```text
project.ready
```
Purpose:
- let the agent onboard itself to the repository
- seed durable Project context
- create the first system-authored onboarding message and Project setup artifact
### Inputs
```ts
interface OnboardingExploreInput {
projectId: ProjectId;
runtimeId: string;
repositoryPath: string;
repositoryCommit: string;
environmentVariableNames: string[];
sourceEventId: EventId;
}
```
### Allowed actions
- list repository tree
- read important manifests and entry points
- search filenames and code
- inspect root documentation
- run safe read-only commands
- optionally start a Pi exploration session
- write generated notes under the Zopu artifact/context directory
### Outputs
1. `summary.md` Project context document.
2. Project setup artifact manifest.
3. Static HTML Project setup artifact.
4. Short onboarding timeline response.
### Suggested `summary.md` contents
```text
Project purpose
Detected stack
Repository shape
Primary entry points
Important packages/directories
Likely run/build/test commands, clearly marked as inferred or verified
Root .env.example variable names
Known constraints
Useful starting areas
Repository commit inspected
```
Do not invent repository facts. Mark assumptions explicitly.
## 30. Exploration specialist flow
Triggered by a user request such as:
```text
Explore the auth flow.
How does the event timeline work?
Find where previews are started.
Why is this package coupled to Convex?
```
### Responsibilities
- turn the request into a focused repository question
- inspect only relevant code and context
- collect code evidence with file paths
- identify the current behavior
- identify risks, unknowns, and boundaries
- produce an exploration artifact
- return a concise result to the conversation agent
### Recommended stages
```text
frame_question
→ inspect_project_context
→ inspect_repository
→ verify_findings
→ create_exploration_manifest
→ generate_artifact
→ publish_result
```
### Output contract
```ts
interface ExplorationResult {
question: string;
summary: string;
findings: Array<{
title: string;
detail: string;
evidence: Array<{
path: string;
lineRange?: string;
note: string;
}>;
}>;
systemMap?: Array<{
from: string;
to: string;
relationship: string;
}>;
risks: string[];
unknowns: string[];
suggestedNextActions: string[];
generatedFiles: string[];
}
```
### Exploration artifact visual sections
- concise answer
- visual system/code path
- key files
- current behavior
- evidence cards
- risks and unknowns
- recommended next actions
- inspected commit and scope
## 31. Issue specialist flow
Purpose:
Turn a user request or exploration result into a concrete, implementation-ready issue.
### Inputs
- source user Event
- Project context
- relevant exploration artifacts
- repository evidence when needed
- current Work goal
### Recommended stages
```text
understand_request
→ gather_repository_evidence
→ define_current_world
→ define_desired_world
→ bound_scope
→ write_acceptance_criteria
→ review_issue_quality
→ generate_artifact
→ publish_result
```
### Output contract
```ts
interface IssueResult {
title: string;
summary: string;
currentWorld: string;
desiredWorld: string;
scope: string[];
nonGoals: string[];
acceptanceCriteria: string[];
evidence: Array<{
path?: string;
note: string;
}>;
risks: string[];
openQuestions: string[];
suggestedImplementationShape?: string[];
generatedFiles: string[];
}
```
### Issue artifact visual sections
- issue title and status
- current world → desired world transition
- scope and non-goals
- acceptance checklist
- repository evidence
- affected areas
- risks and open questions
- next action
### GitHub publication boundary
Keep issue drafting and GitHub publication as separate operations.
The first slice must at minimum generate the issue artifact.
A later or optional explicit action can call `github.issue.create` using the final artifact. This avoids coupling artifact quality to a side-effecting integration call.
---
# Part IX — Artifact generation loop
## 32. Purpose
Specialist output is not automatically user-facing quality.
The artifact generation loop turns structured findings and generated files into a polished, durable static HTML artifact plus a compact timeline card.
## 33. Pipeline
```text
specialist result
→ normalize artifact manifest
→ select artifact kit
→ render static HTML
→ visual/content review
→ sanitize and validate
→ upload to Convex storage
→ create Artifact revision
→ append artifact.published Event
→ conversation agent posts short handoff
```
## 34. Artifact manifest
Every specialist must produce a typed manifest before HTML generation.
```ts
interface ArtifactManifest {
kind: "project_setup" | "exploration" | "issue";
title: string;
summary: string;
projectId: ProjectId;
workId?: WorkId;
threadId?: ThreadId;
flowRunId: FlowRunId;
sourceEventIds: EventId[];
card: {
label: string;
facts: Array<{ label: string; value: string }>;
actions?: Array<{
id: string;
label: string;
eventType: "client.action";
style?: "primary" | "secondary";
}>;
};
sections: unknown[];
evidence: Array<{
path?: string;
note: string;
}>;
generatedFiles: string[];
}
```
## 35. Artifact kits
Use a small curated component/template system rather than asking the model to invent an entire design language every time.
Initial kits:
```text
project-setup
repository-exploration
issue-definition
```
Each kit should provide:
- responsive page shell
- typography and spacing
- status and fact cards
- ownership/system diagrams
- file/evidence cards
- current-world/desired-world visual
- checklist component
- action/footer block
- light and dark compatibility if practical
The model supplies structured content and chooses components. The renderer supplies visual quality and safety.
## 36. Artifact output path
Suggested VM working path:
```text
<workspace>/.zopu/artifacts/<artifactBuildId>/
├─ manifest.json
├─ index.html
└─ optional generated supporting files
```
The publisher uploads `index.html` and allowed supporting files to Convex Storage or the chosen artifact storage behind Convex metadata.
## 37. Validation
Before publication:
- HTML parses successfully
- required title and summary are present
- no raw secrets are included
- no repository credentials are included
- no unsupported external scripts or remote dependencies
- links are safe and expected
- artifact stays within configured size limits
- card payload conforms to the UI registry contract
- source Event, FlowRun, Work, Thread, and Project links are valid
## 38. Review loop
Keep it bounded.
```text
render
→ inspect against artifact checklist
→ repair once if necessary
→ publish or fail visibly
```
Do not let the artifact agent redesign indefinitely.
## 39. Artifact revision
New evidence or a user revision request creates a new immutable Artifact revision.
Old revisions remain inspectable and are marked superseded.
---
# Part X — Initial tool surface
## 40. Conversation/control tools
```text
timeline.postMessage
timeline.postUpdate
timeline.publishArtifact
work.createOrResolve
work.update
thread.create
thread.update
flow.start
flow.inspect
flow.cancel
projectContext.get
artifact.get
```
## 41. AgentOS sandbox tools
Read-oriented first slice:
```text
sandbox.describe
sandbox.listFiles
sandbox.readFile
sandbox.search
sandbox.execSafe
sandbox.writeGeneratedFile
```
`execSafe` should use a narrow policy and deny destructive commands.
Generated-file writes are allowed only under controlled directories such as:
```text
<workspace>/.zopu/
```
## 42. Optional Pi tools
```text
pi.startSession
pi.prompt
pi.followUp
pi.status
pi.abort
pi.listGeneratedFiles
```
The conversation agent need not use Pi for every task.
## 43. Artifact tools
```text
artifact.beginBuild
artifact.writeManifest
artifact.render
artifact.validate
artifact.publish
```
## 44. Tool ownership rule
Tools emit typed proposals or commands that are validated by the runtime boundary.
The model must not receive arbitrary database mutation access, runtime credentials, or tenant routing control.
---
# Part XI — Convex persistence additions
## 45. Tables/components to add
The earlier handoff already defines Projects, Works, Threads, Events, Artifacts, ProjectSetups, and DispatchJobs.
Add or refine:
```text
projectRuntimes
conversationAgents
agentDispatches
flowRuns
projectContextDocuments
artifactBuilds
```
## 46. `projectRuntimes`
Suggested indexes:
```text
by_project
by_organization_status
by_runtime_id
```
## 47. `conversationAgents`
Suggested indexes:
```text
by_project
by_user_project
by_status
```
Enforce one active conversation agent per Project in the first slice.
## 48. `agentDispatches`
Suggested indexes:
```text
by_source_event_handler_version
by_agent_status
by_status_updated_at
```
Unique semantic key:
```text
sourceEventId + agentId + handlerVersion
```
## 49. `flowRuns`
Suggested indexes:
```text
by_thread
by_work_status
by_agent_status
by_source_event
```
## 50. `projectContextDocuments`
Suggested indexes:
```text
by_project_kind_status
by_project_created_at
```
Only one `current` document per Project and kind.
## 51. `artifactBuilds`
Suggested indexes:
```text
by_flow_run
by_status_updated_at
by_project_created_at
```
---
# Part XII — Convex functions and workflows
## 52. Public mutations
```text
projects.createFromRepository
timeline.sendMessage
timeline.sendAction
projectEnvironment.setOptionalValue
projectSetup.retry
flow.cancel
```
## 53. Public queries
```text
projectSetup.getStatus
projects.getCurrent
timeline.getGlobal
timeline.getWork
works.get
threads.listForWork
artifacts.get
projectContext.getCurrentSummary
```
## 54. Internal mutations
```text
projectRuntime.markCreating
projectRuntime.markCloning
projectRuntime.markReady
projectRuntime.markFailed
projectEnvironment.replaceDetectedManifest
conversationAgent.register
conversationAgent.markStatus
events.appendSystemEvent
events.appendAgentEvent
agentDispatch.create
agentDispatch.markSending
agentDispatch.markAccepted
agentDispatch.markCompleted
agentDispatch.markFailed
flowRun.create
flowRun.update
projectContext.publishRevision
artifactBuild.create
artifactBuild.update
artifacts.publishRevision
```
## 55. Workflows
Initial durable workflows:
```text
projectSetupWorkflow
timelineDispatchWorkflow
```
Do not put the full Flue specialist execution inside Convex.
Convex workflows coordinate durable external calls and state transitions. Flue runs the agent logic and specialists.
---
# Part XIII — Events added by this slice
## 56. Project/runtime Events
```text
project.setup.started
project.runtime.created
project.repository.cloned
project.environment.scanned
project.ready
project.setup.failed
```
Most setup progress remains hidden or setup-page-only. `project.ready` is the main global-timeline trigger.
## 57. Conversation Events
```text
agent.acknowledged
agent.message
agent.blocked
agent.final
```
## 58. Flow Events
```text
flow.started
flow.progress
flow.completed
flow.failed
flow.cancelled
```
Only meaningful flow progress should be user-visible.
## 59. Artifact Events
```text
artifact.build.started
artifact.published
artifact.failed
artifact.superseded
```
## 60. Causality
Every agent, flow, and artifact Event must carry:
```text
causationId = the Event that directly caused it
correlationId = the broader interaction/work chain
projectId
workId when applicable
threadId when applicable
flowRunId when applicable
```
---
# Part XIV — Security and policy
## 61. Repository credentials
- GitHub credentials are resolved by the runtime adapter.
- They are not sent to the model.
- They are not written to Events, artifacts, summaries, or generated files.
## 62. Environment values
- `.env.example` names may enter Project context.
- user-provided secret values must stay in a secret store or protected runtime configuration.
- raw values must never appear in the timeline or generated artifact.
- environment values are optional for this slice.
## 63. Service authentication
Hono/Flue and Convex communicate using service credentials and explicit tenant/project IDs.
Every agent timeline write validates:
```text
agent belongs to Project
Project belongs to Organization
requested timeline belongs to Organization/Work
Artifact belongs to the same Project/Work boundary
```
## 64. Sandbox policy
The first slice allows:
- reads anywhere inside the Project workspace
- safe search/list commands
- generated writes only under `.zopu/`
It does not allow autonomous destructive repository changes.
---
# Part XV — Reliability
## 65. Idempotency keys
Use stable keys for every external or repeatable operation.
```text
VM creation project:<projectId>:vm:v1
repository clone project:<projectId>:clone:<commit-or-branch>:v1
project ready project:<projectId>:ready:<setupRevision>
agent dispatch event:<eventId>:agent:<agentId>:handler:<version>
agent post dispatch:<dispatchId>:message:<logicalStep>
flow run event:<eventId>:flow:<flowType>:version:<version>
artifact build flow:<flowRunId>:artifact:<kind>:revision:<revision>
```
## 66. Retry rules
### Project setup
- retry VM and network failures with bounded backoff
- reuse existing runtime resources
- never emit `project.ready` twice for the same setup revision
### Timeline dispatch
- retry delivery until accepted or terminally failed
- the Flue endpoint deduplicates by `dispatchId`
### Agent timeline writes
- deduplicate by tool-call idempotency key
- repeated model turns cannot duplicate visible messages or artifacts
### Artifact generation
- one bounded repair attempt
- failure publishes a visible failure Event and retains the specialist result
## 67. Recovery
The system should be able to restart Hono/Flue and reconstruct the active state from:
- Project runtime binding
- conversation agent binding
- Events
- Work/Thread status
- FlowRun status
- Project context
- ArtifactBuild state
No critical product state may exist only inside one model process or Pi session.
---
# Part XVI — Frontend behavior added by this slice
## 68. Project setup screen
Show only a thin state progression:
```text
Creating workspace
→ Cloning repository
→ Checking repository
→ Ready
```
Show detected `.env.example` keys as optional configuration.
On blocking failure, show:
- concise failure reason
- retry action
- repository connection repair action when relevant
Do not redirect until Project readiness succeeds.
## 69. Redirect to global timeline
After `project.ready`:
- redirect immediately or as soon as the workflow marks ready
- global timeline subscribes normally
- onboarding response may arrive live after redirect
- show a small agent-working indicator while the first onboarding exploration runs
Do not fake a completed onboarding artifact before it exists.
## 70. Initial onboarding presentation
First agent message example:
```text
The repository is connected and I’m getting familiar with the important paths now. I’ll leave the project map here as soon as it’s ready.
```
Then publish the Project setup artifact card.
## 71. Normal request presentation
```text
user message appears immediately
→ short agent acknowledgement
→ Work card/link appears when Work is created
→ subtle running indicator
→ artifact card appears
→ concise final message
```
The full exploration or issue output lives in the artifact, not the chat message.
---
# Part XVII — Implementation order
## 72. Slice A — Project runtime foundation
1. Add `projectRuntimes` schema.
2. Add AgentOS runtime adapter in Hono/Effect.
3. Implement idempotent VM creation.
4. Implement depth-1 clone.
5. Implement readability verification.
6. Implement root `.env.example` parser.
7. Implement `projectSetupWorkflow`.
8. Build setup-state UI and retry.
### Exit condition
A repository can reliably become a ready Project with one VM and one readable clone.
## 73. Slice B — Agent registration and dispatch
1. Add `conversationAgents` and `agentDispatches`.
2. Register one Flue agent per Project.
3. Implement `project.ready` Event.
4. Implement `timelineDispatchWorkflow`.
5. Implement Hono/Flue event endpoint.
6. Implement agent timeline tool.
7. Have the agent post deterministic onboarding text.
### Exit condition
`project.ready` causes a real agent-authored message to appear in the global timeline.
## 74. Slice C — Onboarding exploration
1. Mount the Project VM as the agent sandbox.
2. Add read/list/search/safe-exec tools.
3. Implement onboarding exploration flow.
4. Generate and store `summary.md`.
5. Add Project context retrieval.
### Exit condition
The agent can onboard itself and persist a useful Project summary.
## 75. Slice D — Artifact generation
1. Add `artifactBuilds`.
2. Define typed artifact manifest.
3. Build the first static HTML kit.
4. Validate and upload through Convex.
5. Publish artifact card Event.
6. Render artifact detail in the existing frontend.
### Exit condition
Onboarding exploration produces a polished Project setup HTML artifact visible from the global timeline.
## 76. Slice E — Exploration Work
1. Add conversation decision for exploration.
2. Create/evolve Work.
3. Create exploration Thread.
4. Run exploration specialist.
5. Generate exploration artifact.
6. Return concise final message.
### Exit condition
A user can ask a repository question and receive an evidence-backed exploration artifact.
## 77. Slice F — Issue Work
1. Add issue intent decision.
2. Reuse relevant exploration context.
3. Create issue-definition Thread.
4. Generate issue result and artifact.
5. Add optional card action for later GitHub publication.
### Exit condition
A user request can become a clear implementation-ready issue artifact.
---
# Part XVIII — Acceptance scenarios
## 78. First-time setup
```text
Given a connected GitHub repository
When the user selects it
Then one AgentOS VM is created
And the selected branch is cloned with depth 1
And the repository can be read
And root .env.example names are stored when present
And missing env values do not block readiness
And one project conversation agent is registered
And project.ready is emitted exactly once
```
## 79. Setup failure
```text
Given VM creation or repository clone fails
Then the Project remains not ready
And the user remains on setup
And a retryable error is shown
And no onboarding agent event is dispatched
```
## 80. Onboarding response
```text
Given project.ready exists
When the dispatch workflow delivers it
Then the project agent posts a short acknowledgement
And explores the repository
And stores summary.md
And publishes a Project setup HTML artifact
And posts its card into the global timeline
```
## 81. Exploration request
```text
Given the Project agent is ready
When the user asks to explore a code path
Then the message is stored before execution
And the agent acknowledges quickly
And Work plus an exploration Thread are created
And repository evidence is collected inside the Project VM
And an exploration HTML artifact is published
And the final timeline response remains concise
```
## 82. Issue request
```text
Given a user request or exploration finding
When the agent starts issue creation
Then an issue-definition Thread is created
And the result includes current world, desired world, scope, non-goals, acceptance criteria, evidence, risks, and questions
And a polished issue artifact is published
```
## 83. Duplicate delivery
```text
Given Convex retries a dispatch
When the same dispatchId reaches Flue again
Then no duplicate agent response, Work, Thread, FlowRun, or Artifact is created
```
---
# Part XIX — Explicitly deferred
Do not add these while shipping this slice:
- one global agent routing across many Projects
- many active Projects per user
- multiple VMs per Project or Thread
- automatic VM escalation
- code implementation specialist
- PR creation or review specialist
- autonomous repository mutation
- broad build-system detection
- application boot and preview lifecycle
- required/optional env intelligence
- recursive env scanning
- full RLM over all organization history
- long-term memory/knowledge graph
- dynamic agent-generated agent definitions
- actor migration or dynamic Rivet registry
- arbitrary unvalidated generated UI
- complex artifact collaboration/editor
Preserve interfaces so these can be added later, but do not implement them now.
---
# Part XX — Technical planning choices that do not block the model
The implementation agent may choose these after inspecting the repository and installed library versions:
1. Whether the Flue process executes inside the Project VM or controls the VM through the AgentOS sandbox adapter. The product contract is one project-bound agent with direct access to one project-bound VM.
2. Exact Flue v2 APIs for registry, hooks, persistent state, sandbox mounting, and workflow execution.
3. Exact Convex Workflow component syntax and retry configuration.
4. Artifact renderer implementation, provided it consumes typed manifests and produces safe static HTML.
5. Whether GitHub issue publication is included immediately or added after issue artifact generation works.
These choices must not change the durable contracts in this document.
---
# Part XXI — Final mental model
```text
CONVEX
Owns durable truth:
Projects · Events · Timelines · Work · Threads · Agents · Runs · Context · Artifacts
FLUE / HONO
Owns intelligence:
conversation · decisions · specialist orchestration · supervision · artifact loop
AGENTOS VM
Owns project execution environment:
repo clone · filesystem · safe commands · generated files · optional Pi sessions
```
The first shipping contract is:
```text
Repository selected
→ Project VM and clone become ready
→ project.ready wakes one project conversation agent
→ agent talks briefly and works deeply
→ exploration and issue flows run beneath Work Threads
→ every meaningful result becomes a polished artifact
→ Convex publishes the result back into the timeline
```