An engineering team on your repository
From a repository and an empty enterprise to a cloned engineering team working on it: the steps, what only you can do, and a prompt your coding assistant can follow.
This page takes a repository you already have and puts an engineering team from the catalog to work on it: issues picked up on a schedule, tests written first, pull requests opened, reviewed and verified, and every merge waiting for you. Most of it can be done by a coding assistant working in the repository, such as Claude Code. The setup prompt below is written for one. The steps it cannot take are yours, and it stops and asks you for each.
What you end up with
- A repository that answers the commands the engineering tasks run: setup from a clean clone, and the tests, checks and coverage of Workspaces.
- An API token for the assistant, and your enterprise's MCP server connected to it.
- Your code host connected on Tools, filling the team's code host tool slot.
- An engineering team cloned from the Team directory, with a lead, a CTO among its members, the repository set as each task's input value, and the schedules you chose switched on.
- One small issue taken from intake to a pull request waiting at the merge gate.
Before you start
You need:
- an enterprise you own, with a model connected on Agents and a day cap on Spend (Spend and models);
- the repository, with permission to open pull requests on it and create labels;
- an account on the code host for the team to act as. A member of its own is best, so its work shows under its own name (GitHub). Your own account works too, and then everything the team does appears as you;
- room on your plan for the team's members and the schedules you want on.
What stays yours
A coding assistant with an API token can do most of the setup over the API. Some steps belong to a person, and the prompt hands them to you:
| Step | Why it is yours |
|---|---|
| Creating the API token | No token can manage tokens (Authentication). |
| Connecting a model | It is your account and your key. |
| Connecting a tool on the enterprise | Only the owner, or a person the owner allows, binds a tool on the enterprise itself. |
| Signing off the team's KPIs | A team cloned with a token arrives with its KPIs waiting for sign-off (Teams). |
| Merging the repository's own change | It is a change to your code. Review it like any other. |
| Every gate | A merge waits on you in Gates. Give the assistant's token no gates:write, and it cannot decide one. |
The steps
- The repository. Add the commands the engineering tasks call (
os:red,os:check,os:coverage), and a setup that works from a clean clone, as Workspaces specifies. Its migration instruction is the contract. Merge it before the first run, so every new branch has it. - A token and the MCP server. Create a token under Settings → API tokens with only the scopes the setup needs, and connect your assistant to the MCP server with it.
- The code host. On Tools, connect your code host's MCP server. Add the
git.*custom props, so a workspace can clone and push (The credential comes from the code host tool you bind). Set Fills slots tocodehost, and give it the action map (Slot actions). For GitHub, Add git settings and Add missing actions fill both in one save each. - The team. Clone an engineering team from the Team directory. Fill its
codehostslot with that connection, and switch every schedule off for now. Name the member who holds the CTO role, and make them the team's lead. - Inputs, labels and schedules. A clone brings each task's schedule but not its run input (Schedules on a clone), and these tasks need a repository. Set it as each task's own input value. Create the issue labels the tasks use. Then switch on the schedules you want.
- A first run. File one small issue and start intake by hand. Follow it to the merge gate, then decide it.
The setup prompt
Open the repository in a coding assistant that can read and edit files, run commands and call an API. Fill in the values at the top, then paste the prompt. It works phase by phase and checks each phase before the next. It stops for every step that is yours. It never changes what a task does: a cloned task stays linked to its publisher, and this setup only configures it.
You are onboarding this repository and its company into Zero Human OS, so a cloned
engineering team (led by a CTO) can work on it by itself. Work through the phases
below in order. Each phase ends with a check; do not start the next phase until the
check passes or I have said to skip it.
## Values (ask me for any left as <<…>> before Phase 1)
- Enterprise slug: <<acme>>
- Repository (owner/name): <<acme/app>>
- Code host: <<GitHub>>
- Team template: <<the engineering team I chose in the Team directory>>
- Team name / slug: <<Engineering>> / <<engineering>>
- CTO name and one-line persona: <<Ada: calm, exact, ships small pull requests>>
- Whose code host account the team acts as: <<a member account of its own | mine>>
- Timezone for schedules: <<Europe/London>>
- Team daily spend cap (USD): <<10>>
- Other tools to connect now: <<none>>
## Sources of truth (read these first, in full)
- https://zerohuman.com/docs/engineering-team (this guide)
- https://zerohuman.com/docs/tools/workspaces (the repository contract, including its
"LLM Instruction for migrating an existing workspace")
- https://zerohuman.com/docs/mcp/connect and https://zerohuman.com/docs/api/authentication
- https://zerohuman.com/docs/api/endpoints (every route and the scope it needs)
- https://zerohuman.com/docs/work/tool-slots (the codehost slot, action maps, slotFills)
- https://zerohuman.com/docs/tools/github (or the page for my code host)
- https://zerohuman.com/docs/work/schedules (including "Schedules on a clone")
- https://zerohuman.com/docs/work/tasks#your-own-input-values
If a page cannot be fetched, ask me to paste it. Never guess a route, field or exit code.
Where these pages and this prompt disagree, the pages win: tell me what differed.
## Hard rules
1. Never change what a task says or does. Cloned tasks are linked to their publisher.
Configure them only through input values, schedules, tool connections, and roles,
members and teams. Never publish a task version, never copy a task to edit it, and
never put this repository's name or paths into any task's text.
2. Secrets never enter git, logs, pull request bodies or chat output. The API token lives
in a gitignored .env and in the MCP client's local configuration. Print only its last
four characters.
3. You never decide a gate, merge a pull request, or create or revoke API tokens. For a
step only I can take (a token, a model, a tool on the enterprise, KPI sign-off), give
me the exact portal steps and values, then verify the result over the API once I say
"done".
4. Read before every write. GET the object first and show me the diff for anything
already set. Put related writes in one script outside the repository, show it to me,
and run it only after I say go.
5. Stay within the plan's members and schedules.
6. If anything fails, stop and report the exact status, error code and body. Do not try
another route around a refusal.
## Phase 0: Preflight (read only)
- Confirm `git remote -v` matches the repository value, and find the remote's real
default branch. Check that you can create labels on the code host (for GitHub,
`gh auth status`).
- Read this repository's AGENTS.md, CLAUDE.md, contributor docs and CI configuration.
- Summarise for me: stack, package manager, test frameworks, lint, typecheck and build,
git hooks, CI, coverage policy, release process, and any existing mise.toml or .os/.
Check: I confirm the summary and the Values block.
## Phase 1: API token
1. Ask me to create a token under Settings → API tokens, named for this assistant and
machine, with these scopes and nothing else:
catalog:write, tasks:write, teams:write, members:write, roles:read, tools:read,
runs:read, executions:read, blockers:read, gates:read, llm:read, spend:read,
enterprise:read.
2. When I give it to you, make sure .env is in .gitignore, then write to .env:
ZEROHUMAN_API_URL=https://api.zerohuman.com/v1
ZEROHUMAN_TOKEN=zhos_…
Add a .env.example with the two names and empty values.
Check: GET $ZEROHUMAN_API_URL/health answers ok, and GET /teams with the token answers
200 for this enterprise. A 403 names the missing scope. If you get one, tell me which
scope to add with Edit scopes.
## Phase 2: MCP server
1. Connect the MCP server for this project only, with the token from .env, as
docs/mcp/connect shows (for Claude Code: `claude mcp add --transport http zerohuman
https://mcp.zerohuman.com/v1/mcp --header "Authorization: Bearer $ZEROHUMAN_TOKEN"`).
Never commit the token. If the team wants the server in a shared .mcp.json, read
the token from the environment there instead.
2. Tell me to reload the session so the tools appear.
Check: the client lists the server as connected AND a tool call answers (os.list_blockers).
Connecting and listing tools do not check the token. Only a call does.
## Phase 3: The repository (a branch and a pull request; I merge)
Follow the Workspaces page's "LLM Instruction for migrating an existing workspace" as
the contract, on a new branch. In short:
- setup from a clean, non-interactive clone (.os/workspace.yml only when auto-detection
is not enough; explicit setup replaces all auto-detection);
- real `os:red`, `os:check` and `os:coverage` with the documented exit codes, the
ten-minute and 32,000-character limits, the real default branch and merge base, and
`--parts` where a check runs longer than ten minutes;
- git hooks that let a RED commit through while static checks still run, with no bypass;
- optional commands (os:deps*, os:release*, os:changelog*) only if I want them;
- validation in a disposable fresh clone with a clean home, CI=true and NODE_ENV=test,
exercising every command and exit, with commands, exits and timings reported.
If there is no coverage policy, propose one and ask me. Never default to zero.
Open the pull request with that evidence. Do not merge it.
Check: I have merged the pull request.
## Phase 4: Enterprise prerequisites (you check; I act in the portal)
- GET /llm/bindings shows a model connected for the enterprise. If not, tell me to add
one on Agents. Schedules wait without one, and show nothing on Blockers.
- GET /spend shows an enterprise day cap. If not, tell me to set one on Spend.
## Phase 5: The code host connection, filling the codehost slot
The engineering tasks name no vendor's tools. They name the slot `codehost` and actions
under it, and one connection of mine fills that slot and maps every action.
1. If the team acts as a member account of its own, it is created after Phase 6, with
the CTO's own address. Walk me through it then, as my code host's page describes,
and come back to this phase.
2. Ask me to connect the code host on Tools, on the enterprise or on the CTO member when
the account is the CTO's own, as its page describes (for GitHub: a classic token
with `repo read:org`, the MCP server URL left blank). Then ask me to:
- add the git.* custom props: git.host, git.username, git.repoTemplate (GitHub's are
github.com, x-access-token and https://github.com/{repo}.git; "Add git settings"
fills them);
- set Fills slots to codehost;
- give it the full action map ("Add missing actions").
Every connection of that tool that a run can reach before this one needs the git.*
props as well, including a member's own.
3. Connect any other tool from the Values block the same way.
Check over the API: GET /tools/bindings shows the connection with `codehost` in its slots,
its git.* props set, and `missingSlotActions` empty. Note its id.
## Phase 6: The team and its CTO
1. Find the team template in GET /catalog/teams, then read GET /catalog/teams/{id}/review.
Show me its roles, tasks, the tools they need, the slots to fill, the suggested
schedules and the plan size.
2. Clone it with POST /catalog/teams/{id}/clone:
{ name, slug, teammateNames (one per teammate, the CTO first),
moneyCentsDay (the cap in cents),
slotFills: [{ "slot": "codehost", "bindingId": "<the connection's id>" }],
schedules: [] }
An empty schedules list means every schedule arrives paused. They are switched on in
Phase 7, once their inputs are set. Record the team, member, role and task ids, plus
reusedTaskIds and awaitingSignOff. A role or task I already had is reused. Tell me
which were.
3. The CTO: the member holding the CTO role.
- PATCH /members/{id} with their name and persona.
- PATCH /teams/{teamId} with leadMemberId set to the CTO. A team with no lead shows
on Blockers.
- Tell me which KPIs wait for my sign-off on the team's page.
- Read the member's page data for any tool their tasks need that no connection reaches.
4. Successors: a clone keeps a task's successor only when the enterprise has that task.
For every cloned task, compare its successors with its catalog entry's
(GET /catalog/tasks/{id}) and list any edge that did not come across, with the task
it named.
Check: the team has its members, roles, lead and tasks, and Blockers shows nothing for a
tool that is not bound, an unmapped action or an ambiguous slot.
## Phase 7: Inputs, labels and schedules
1. Input values: for every cloned task whose current version declares a `repo` input,
PUT /tasks/{id}/input-values with { "values": { "repo": "<<owner/name>>" } }. Read the
task first and keep any value already set. Set no other key unless I agree.
2. Labels: read the cloned tasks (GET /tasks/{id}: skill, guardrails, inputs) and list
every issue label they read or write. Compare that list with the repository's labels,
show me the missing ones, and create them after I say go. A task that cannot find
its label stops.
3. Schedules: show me a table with every task the review suggests a schedule for. Give
each one's cron, timezone and run input { "repo": "<<owner/name>>" }, whether its
prerequisites hold (a tool it needs that is not connected, an optional repository
command that is not there, CI it reads that the repository does not run), and your
recommendation. Add the tasks that take a repo input and have no suggested schedule,
such as sweeps, verifications and measurements, and ask me whether any should run on
one. Recommend within the plan's allowance, intake first. I choose. Then, for each
row, PUT /tasks/{id}/schedule
{ "cron": "…", "timezone": "<<timezone>>", "enabled": <true|false>,
"input": { "repo": "<<owner/name>>" } }.
Check: each schedule reads back as chosen, an enabled one has a next run time, and
Blockers lists no task with a missing input.
## Phase 8: The first run (I decide; you watch)
1. Ask me to file one small, well-specified issue, or to point you at one.
2. Start intake by hand: POST /tasks/{id}/runs, with the run's input as the body,
{ "repo": "<<owner/name>>" }. The body is the input itself, not wrapped in "input".
3. Follow the run and its execution (os.list_runs, os.get_run), hop by hop until the
pull request reaches its merge gate. Report each step's outcome and cost, and
anything on Blockers, with the run id and the exact reason.
4. Stop at the merge gate and tell me it is waiting for me in Gates. Do not decide it.
Check: the pull request exists, carries a "## Verification: <commit>" note, and its merge
waits on me.
## Phase 9: Handover
On a branch, as a pull request, write a short onboarding note into the repository's
developer docs with no secrets in it:
- what the repository provides (commands, setup, optional commands adopted or declined);
- the team, its roles, its CTO, the code host connection (by name, never its token),
the schedules table and the input values;
- what is still mine: KPI sign-off, every merge gate, and the date the code host token
expires;
- how to pause everything (switch the schedules off) and where to look (Blockers, Gates,
Runs).
Then give me a table of each phase as done, waiting on me or skipped, and anything you
could not verify.
After the first run
- Watch Blockers for the first days. A run that stops says why there, and so does a schedule that cannot start (Schedules).
- Keep the merge for yourself. Every pull request reaches its merge gate with a verification note for the commit it would merge (Verification before merge).
- Updates arrive by themselves. A linked clone takes its publisher's quiet updates unless you turn that off on the Enterprise page (Enterprise). Your input values and schedules stay as you set them.
- Note when the code host token expires. The connection stops working when it lapses.