Skip to content

Commit ff0a707

Browse files
committed
docs: user manual, design docs, skills and screenshot
1 parent a2731b9 commit ff0a707

9 files changed

Lines changed: 1341 additions & 0 deletions

File tree

‎docs/ARCHITECTURE.md‎

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
# Builder: architecture
2+
3+
How Builder is structured and why. What it does for a person is in
4+
[PRODUCT.md](https://github.com/corbitsdev/corbits-builder/blob/main/docs/PRODUCT.md);
5+
the concrete technology and layout are in
6+
[IMPLEMENTATION.md](https://github.com/corbitsdev/corbits-builder/blob/main/docs/IMPLEMENTATION.md).
7+
8+
## Overview
9+
10+
Builder is a control plane (the hub) on top of an agent runtime (Interchange).
11+
The runtime owns agents, workflows, mail between them, approvals, credentials,
12+
sandboxed workers and run lifecycles. The hub adds what is specific to
13+
Builder: projects, versioned documents, the tools agents use to file and hand
14+
off work, the app repository and live preview, preferences, and an API for the
15+
interface.
16+
17+
```
18+
person -> interface -> client API -> hub -> runtime (workflows, mail, approvals)
19+
| |
20+
| +-> sidecars running the agents
21+
|
22+
+-> documents, app repository, live app
23+
```
24+
25+
## Components
26+
27+
### The hub
28+
29+
The hub is the server and the system of record. It:
30+
31+
- signs people in and holds tenancy: an install has workspaces, and each
32+
project is a tenant of its own under its workspace, holding the project's
33+
principals, documents, approvals and runs;
34+
- creates projects and starts each project's coordinator;
35+
- stores documents and their versions, and records which versions an approval
36+
covered;
37+
- provides the tools agents call to read and file documents, hand off work and
38+
ask the person things;
39+
- hosts each project's app repository and runs its live preview;
40+
- answers the interface's API and streams run progress to it.
41+
42+
It embeds the runtime's control plane in the same process and composes it
43+
directly. There is no separate embedding layer.
44+
45+
### Agents and roles
46+
47+
Each role is a workflow package: an agent definition (prompt, tools,
48+
capabilities, model tier) and a workflow definition (trigger, steps, lifetime).
49+
50+
- **Coordinator**: one per project, long-lived. Talks to the person, writes the
51+
problem brief, hands off work and asks for decisions.
52+
- **Writer**: one bounded write of one document of a named kind.
53+
- **Reviewer**: one bounded review of one document; its findings are advice
54+
mailed to the coordinator.
55+
- **Designer**: long-lived, one per design concept. Builds a clickable HTML
56+
and CSS mockup in its workspace.
57+
- **Coder**: long-lived, one per project. Builds the whole app in its
58+
workspace and takes later changes there.
59+
60+
All roles are triggered by mail. The writer and reviewer take exactly one
61+
message and end. The coordinator, designers and coder keep their warm agent
62+
and workspace and take each later message as another turn on the same state.
63+
64+
Only the coordinator talks to the person. Specialists put questions in their
65+
mail to it, and it decides whether to ask the person.
66+
67+
### Documents and versions
68+
69+
A document has a kind, a title and a sequence of versions. Each version has
70+
content and a content hash, and may carry open questions for the person and,
71+
for the approaches, structured options for side-by-side comparison. The kinds
72+
are the problem brief, constraints, approaches, product requirements, build
73+
plan, design options, the design and the app.
74+
75+
- Text documents are written whole by the coordinator or a writer.
76+
- A design option is filed from a designer's workspace once the design check
77+
passes; the design is filed when the person chooses an option.
78+
- The app is filed from the coder's workspace each time the app check passes.
79+
80+
The hub assigns each version's id, number and hash. Writing a version is never
81+
an approval. A writer gets the documents it builds on in full inside its
82+
assignment and has no read tool, so it works only from what it was given.
83+
84+
### Approvals
85+
86+
Approvals are the runtime's own human approvals. A tool that needs a person's
87+
go-ahead (`request_approval`, `design_app`, `instruct_coder`, adding a package)
88+
is declared as asking, so the runtime parks the call until a person resolves
89+
it. After it resolves, the hub records the exact document versions and hashes
90+
it covered, and only those whose hash still matches storage.
91+
92+
- Versions and hashes come from the hub, never from model input, so an
93+
approval cannot be pointed at a version the person did not see.
94+
- Choosing a design option and importing a project as approved are the
95+
person's own acts; the hub records that person as the approver.
96+
- Hand-off tools check approvals before they start the next writer.
97+
98+
### Questions
99+
100+
`ask_questions` puts a structured card (up to five questions with options and a
101+
recommended answer) in front of the person and returns at once. The answers
102+
reach the coordinator as the person's next message. A document's open
103+
questions carry over into such a card. Questions are never modelled as
104+
approvals.
105+
106+
### The app repository and live preview
107+
108+
Each project has one git repository for its app. A coder run gets push access
109+
to its main branch, scoped to that run and revoked when the run ends. A new
110+
coder workspace starts from main when main holds a version, else from the last
111+
filed app, else from the app starter.
112+
113+
The live preview runs the project's app in its own sandboxed process per
114+
project. While a coder works, it follows the coder's workspace; afterwards it
115+
runs the latest filed app. It installs packages when they change, restarts on
116+
file changes, restarts a crash once and then waits for the next change, and
117+
stops when no one has had the project open for a short while. Each project's
118+
app is served from its own origin, and a request reaches it only when the hub
119+
would show that person the project; the hub's cookies never reach the app.
120+
121+
### Sandboxes
122+
123+
The designer and coder run on sidecars that offer a POSIX runtime. Their shell,
124+
file and browser tools run inside a sandbox with a file policy (the workspace
125+
is writable, filed inputs and the design are read-only) and a network policy
126+
(the package registry only, or the public internet when the person allows it).
127+
Browser tools reach only the app running in the same sandbox.
128+
129+
### Models and profiles
130+
131+
A **provider** is a connected source of models: an API key (Anthropic, OpenAI,
132+
Google Gemini, xAI) or a subscription login (ChatGPT, xAI). A **profile** maps
133+
four **tiers** (Low, Medium, High, Max) to one model and reasoning effort each.
134+
Each role runs on a fixed tier, set in configuration:
135+
136+
| Role | Tier |
137+
| ----------- | ------ |
138+
| Coordinator | Medium |
139+
| Writer | Medium |
140+
| Designer | High |
141+
| App builder | High |
142+
| Reviewer | Low |
143+
144+
Every provider ships a ready-made profile, and a person can make their own. A
145+
person chooses only a profile, never a model per role. A project resolves its
146+
profile when its coordinator starts and keeps it for its whole life
147+
([how it resolves](https://github.com/corbitsdev/corbits-builder/blob/main/docs/DEV.md#model-profile-choice)).
148+
149+
### Preferences
150+
151+
Preferences are a registry of named choices, each with options and a default,
152+
and the roles it guides. A person's choices live in their settings; a project
153+
freezes its creator's choices and model profile when it starts. The coordinator
154+
reads the resolved preferences as guidance; the hub reads them where they
155+
change behaviour (approval gating, package installs, network access, design
156+
concept count).
157+
158+
### The client API and interface
159+
160+
The client API is a typed library over the hub's HTTP API. The interface uses
161+
only that library and the shared contract types; it never imports server code
162+
or the database. Every action in the interface is an authenticated API call
163+
that other clients can make too.
164+
165+
## Control flow and data flow
166+
167+
1. The person creates a project. The hub creates its tenant, installs the role
168+
packages on the project's model bindings and deploys the coordinator.
169+
2. The person's messages are mail to the coordinator. Its replies are mail
170+
back, shown as the conversation.
171+
3. The coordinator files the brief itself, then hands work off with hub tools:
172+
`deploy_writer` and `review_artifact` for documents, `design_app` for design
173+
concepts, `deploy_coder` once for the app and `instruct_coder` for later
174+
changes.
175+
4. The hub builds each assignment from its own templates: the task, the
176+
documents it builds on in full and pinned by version and hash, and the kind
177+
to write. The tool checks prerequisites first: earlier documents exist and
178+
are approved, and no coder is already running.
179+
5. The specialist works, files its result as a document version and mails a
180+
short summary back on the assignment's thread.
181+
6. The coordinator reads the filed document, judges it and either has it
182+
revised, asks the person, or asks for approval.
183+
7. The interface reads documents, approvals, run state and the live app
184+
through the API, and progress through a run event stream.
185+
186+
Work is handed off by mail and results are filed as documents. Mail carries
187+
the conversation; documents carry the work.
188+
189+
## Design decisions
190+
191+
- **No fixed stages.** The coordinator decides the order of work from the
192+
document list and the conversation. The order documents build on each other
193+
is enforced as prerequisites in the hand-off tools, not as a stage machine.
194+
- **Agent behaviour lives in agent definitions and tools.** Prompts describe
195+
the task and the domain. Turn order, reply termination and loop detection are
196+
the runtime's job. Hub code covers human decisions and tenant state.
197+
- **Use the runtime's machinery.** Loops, retries, waits, timeouts, mail,
198+
approvals and failure records come from the runtime rather than being
199+
rebuilt in the hub.
200+
- **Native state over model output.** Progress, the person's next step,
201+
in-flight specialists and decisions are read from run status, run events and
202+
approval records, never from parsing what a model wrote.
203+
- **Deterministic code over model turns.** Anything code can do, code does:
204+
assignment messages, design and app checks, starting the app, filing
205+
snapshots, notices when a specialist ends.
206+
- **Exact versions everywhere.** Assignments pin documents by version and
207+
hash; approvals bind to the hash the hub computed.
208+
- **Model-agnostic.** Roles are bound to tiers, and a profile maps tiers to a
209+
provider's models, so any connected provider can run any role.
210+
- **Configuration holds wording.** User-visible names and text live in
211+
configuration, so a rename is a configuration change.
212+
213+
## Failure handling
214+
215+
- **Refusals are results.** A tool that cannot act returns the reason and what
216+
to do instead (a missing or unapproved document, a coder already running),
217+
and the underlying error code passes through unchanged.
218+
- **Run outcomes come from the run.** A failed run's cause is read from its
219+
own terminal events.
220+
- **A specialist that ends without answering** is noticed by a reconciler,
221+
which mails the coordinator once with the reason so it can start the work
222+
again.
223+
- **A coordinator that ended** is replaced with a fresh run when the project is
224+
next opened; the earlier runs and filed documents are carried to it as
225+
context with the person's next message.
226+
- **Coordinator upgrades** wait for a safe point (parked on input, nothing
227+
pending, no specialist at work) before replacing the run.
228+
- **Runaway model output** that repeats one passage is cut off, and long
229+
histories are compacted to fit the model's context.
230+
- **Unavailable is a state.** A project with no usable model provider says
231+
why and waits; nothing falls back silently to another provider.
232+
- **Capacity.** Work is placed on a sidecar with room; a placement refused for
233+
room is retried by the runtime.

0 commit comments

Comments
 (0)