Skip to Content

Software factory for teams

With a team on one Tares, everyone runs their own crew on their own machine, and the projects, tickets and decisions are shared. Every action carries the person behind it: a project has a lead, a repo has an owner, a ticket has an assignee, and a grant records who gave it. The crew asks the right person instead of whoever is at the keyboard.

What a team gets:

  • People and keys: everyone signs in with a key of their own, and every record says who did it, for example “Kiran (crew-builder-1)”.
  • Project leads and private projects: a project has a lead and is shared with the team or kept private to its members.
  • Repo owners: each GitHub repo has an owner, and the spec asks them what it needs to know.
  • A crew per person: each crew works only on its own person’s tickets, next to the others.
  • Grants with consent: a grant that reaches into someone else’s repo waits for their yes.
  • A team home: everyone’s Home shows what is addressed to them, and from whom.

On your own, none of this is needed: a Tares with one person works as described in the rest of these pages.

Set up a team

Team features are included on Tares Cloud.

Invite your teammates

Open People in the console and choose Add a person, or invite them from the workspace page on console.tares-glassflow.com . Settings, Team, People is the one team list, with invite and remove, each person’s GitHub login and who is an admin.

Each teammate signs in

On their own machine, each person installs the CLI and signs in:

uv tool install tares tares login

The key tares login makes is bound to the person who signed in.

Each teammate starts a crew

tares factory crew up

The first run asks for a crew name, so the crews are told apart. A crew per person

What a teammate’s key needs

The person on the key says who is acting; the key’s scopes say what it may call.

ScopeWhat it adds
readReads, including list_people, list_areas, list_questions and read_grants.
ingestClaim a repo nobody owns, answer a question put to you, add, agree to and revoke grants, and change your own crew settings and personal AGENTS.md and memory.
adminEverything else: making and handing over projects, asking repo owners, project leads and members, and ticket and doc writes.

A teammate who only answers questions about their repos needs no more than read and ingest. Someone who leads projects needs admin. Tares checks who is calling: only the person a question is addressed to can answer it.

Project lead and privacy

The person who makes a project leads it. A project is for the Team (everyone sees it) or Private (only the lead and its members see it). On the project page, the People section has the lead, a Team or Private control, Change the lead and Add a member. In Claude Code:

set_project_access(project="payments", scope="private", add_members=["kiran@example.com"])

Only the lead changes the privacy and the members. An admin can change only the lead, which is how you claim a project nobody leads, or take one back from someone who left.

A private project is hidden from everyone who is not on it. To them its pages answer not found, its tickets, docs, crew, pull requests and sessions stay out of every list, and Ask and Slack leave it out. The Projects list shows it as a greyed “Private, led by” row with the lead’s name. Assigning a ticket of a private project to someone adds them as a member.

Repo owners

Each GitHub repo can have one owner, so the crew knows whom to ask about it. In the console, open Settings, Advanced, Areas. An admin adds, reassigns and removes owners. Anyone can claim a repo nobody owns, for themselves, and edit the note on a repo they own. A repo can be typed as owner/name or pasted as its GitHub address. In Claude Code:

list_areas() set_area(repo="acme/payments-api", person="kiran@example.com")

The People page lists the repos each person owns.

Questions to repo owners

When a spec depends on how another person’s repo works, the spec session asks that repo’s owner instead of guessing:

ask_area(repo="acme/payments-api", text="Do refunds go through the ledger service or the payments API?")

The question is numbered in the project (Q1, Q2) and reaches the owner’s Home, with who asked. The spec carries on with what does not depend on the answer. When it ends, it lists the open questions and who each is for. The project shows on the lead’s Home under You are waiting on until every question is answered, and is ready to start after that.

The owner answers from their own machine:

tares factory spec "payments"

Run by someone who is not the lead, this opens a contributor session. It needs no git repo in the folder. It asks the owner the open questions one at a time, each with a recommended answer, and shows the tickets in their repos to check. A change to a Tares ticket that needs the admin scope goes back to the lead in words. Owners can also answer right on their Home.

On a private project, a question to an owner who is not a member is refused until the lead adds them.

Tickets and assignees

Every ticket has an assignee. The spec assigns each ticket to the owner of its repo. Linear maps the assignee’s email, and GitHub Issues the first assignee’s login, to a person on the Tares. A Tares ticket takes assignee as a person’s id or email in write_ticket. A ticket with no assignee counts as its project lead’s.

A ticket can depend on a ticket in another repo that someone else’s crew builds. Your crew starts it once every ticket it depends on is merged, without anyone telling it.

A crew per person

Each person runs their own crew, with their own key, on their own machine. Give it a name so its stations are told apart from your teammates’:

export FACTORY_CREW_NAME=kiran tares factory crew up

When more than one person is on the Tares, the first crew up asks for the name and suggests one. The stations are then <name>-orchestrator, <name>-reviewer, <name>-releaser and <name>-<project>-build-<slug>. The name is saved as crew_name in ~/factory/crew.json. To rename the crew, run tares factory crew down and change crew_name there.

Your orchestrator works only on what belongs to you: your ready tickets, the milestones of projects you lead, and the questions addressed to you. The reviewer and releaser of a crew answer only that crew’s tickets.

Each person can also set their own crew settings (autonomy, builders at once, second check, releaser). A personal autonomy or second check can be stricter than the team’s, never looser.

Grants

A grant lets a crew act without asking each time, in the giver’s own words. You give one by answering the crew with a standing yes, or with Allow on your Home. Settings, Crew, What you allowed lists them.

KindReachesWho can give it
Teamevery projectan admin
Projectone projectthe project’s lead, an admin, or the owner of the repos it names
Personalwhat may run on your own machineyou, and only you see it

A project grant that names repos someone else owns waits until each owner agrees. A project grant from someone who is neither the lead nor an admin also waits for the lead. Whoever a grant waits for finds it on their Home, and agrees to it or declines it there. In Claude Code:

add_grant(words="Builders may change the ledger schema for this project.", kind="project", project="payments", areas=["acme/ledger"]) consent_grant(id="G7")

A grant that still waits does not count. Production, secrets, billing and contacting people always go to a person, whatever the grants say.

Home on a team

Each person’s Home answers for them:

  • Waiting for you: what is addressed to you, each with who it comes from. Answer a question, agree to or decline a grant, and allow a command, from the page.
  • You are waiting on: the projects you lead with a question open for someone else, and who it is.
  • Projects: a Mine and Team switch, the lead of each project and a lock on private ones.
  • Your crew: your own crew’s stations, your crew’s limit in words, the team’s other crews, and the repos you own.

Move a one-person Tares to a team

A Tares used by one person has the one person local. Its keys act as local while it is the only person, so nothing changes until a second person joins.

On Tares Cloud, the workspace owner becomes a person with their own name, and their existing keys keep working.

On a self-hosted Tares, bind the existing keys when you add the second person: from then on a key bound to nobody acts as nobody. Pick the owner on each key under Settings, Team, Access keys, or:

curl -s -X PUT "$TARESD_URL/api/keys/<key id>/person" \ -H "Authorization: Bearer $TARES_AUTH_TOKEN" -H 'Content-Type: application/json' \ -d '{"person": {"email": "kiran@example.com", "name": "Kiran"}}'

Revoke keys nobody uses, and give each person a key of their own. A project from before has no lead and is shared with the team; an admin claims it by setting the lead.

What needs the enterprise licence

On a self-hosted Tares without a licence, Tares works for one person. These need the licence:

  • adding a second person
  • assigning tickets to people, and syncing assignees from Linear and GitHub Issues
  • repo owners and questions to repo owners
  • changing a project’s lead, privacy and members
  • grants that wait for someone else to agree
  • addressing a desk item to someone else
  • telling crews apart by person and machine

Without a licence these answer 402 licence_required. A private project stays private either way. Enterprise licence

Reference

MCP tools

ToolWhat it does
list_peopleThe people on the Tares: id, name, email, GitHub login and admin flag.
set_project_access(project, lead, scope, add_members, remove_members)Set a project’s lead, its scope (team or private) and members, by id or email.
list_areas, set_area(repo, person)Who owns which repo, and set an owner.
ask_area(repo, text, project)Ask a repo’s owner a question while the spec is written.
answer_question(id, answer, project)Answer a question put to you.
list_questions(state, project)The questions to repo owners, open or answered.
my_work(crew, project)Your ready and in-progress tickets, led projects, desk items and questions.
add_grant(words, kind, project, areas), read_grants, consent_grant(id)Give, list and agree to grants.
get_crew_settings, set_crew_settings(clear)Your crew settings over the team’s.
list_crew(mine), desk_list(mine)The crews and desk items that are yours.
write_ticket(assignee), desk_add(to)Assign a ticket, or address a desk item, to a person.
add_to_global(scope="personal")Add a line to your own AGENTS.md or memory.

HTTP routes

RouteWhat it does
GET /api/people, POST /api/people, PATCH /api/people/{id}, DELETE /api/people/{id}List, add, edit and remove people.
POST /api/keys, PUT /api/keys/{id}/personMake a key for a person, or bind an existing one.
GET /api/whoamiThe caller’s kind, person and scopes.
PATCH /api/projects/{id}Set a project’s lead and scope.
POST /api/projects/{id}/members, DELETE /api/projects/{id}/members/{person}Add and remove members.
GET /api/areas, PUT /api/areas, PUT /api/areas/{owner}/{name}, DELETE /api/areas/{owner}/{name}List, replace, set and remove repo owners.
GET /api/projects/{id}/questions, POST /api/projects/{id}/questions, POST /api/projects/{id}/questions/{qid}/answerList, ask and answer questions to repo owners.
GET /api/grants, POST /api/grantsList and add grants.
POST /api/grants/{id}/consent, POST /api/grants/{id}/decline, POST /api/grants/{id}/revokeAgree to, decline or end a grant.
GET /api/crew/my-workWhat belongs to the person of the key.
GET /api/crew/settings, PUT /api/crew/settingsYour crew settings over the team’s.
GET /api/crew?mine=1Your own crews, each with its machine and stations.
GET /api/licence, PUT /api/licenceThe licence’s organisation, seats and end date, and save a key.
Last updated on