Writing a team package
A team is a folder of markdown and YAML, usually a git repository. Lucitra reads it where it lives:
nothing is copied into the store, so an edit to a file (or a git pull) applies to the next run.
COMPANY.md the team: name, slug, lead, what it is for
DIRECTION.md optional: status (active, paused or stopped)
agents/<id>/AGENTS.md one agent
agents/<id>/access.yaml optional: the tools, hosts and secrets it may use
agents/<group>/<id>/AGENTS.md an agent inside a sub-team
teams/<slug>/TEAM.md optional: a named group inside the team
policies/*.md optional: what is gated, what is autonomous, trading limits
projects/<p>/tasks/<t>/TASK.md optional: scheduled work
skills/<name>/SKILL.md optional: skills the agents reach for
Check a package before you add it, and add it once it reads clean:
lucitra validate-team ~/teams/support
lucitra team-add ~/teams/support
validate-team reports what is wrong without refusing to read the rest.
Use a team from GitHub
Keep the package in its own repository, clone it, and add the folder:
git clone https://github.com/you/support-team ~/teams/support
lucitra team-add ~/teams/support
Pull to update it. Lucitra reads the folder each time, so a git pull is picked up on the next run.
COMPANY.md
---
name: Support
slug: support
schema: lucitra-company/v1
lead: lead
description: Answers the support queue and escalates what it cannot close
goals:
- Answer every ticket within a working day
---
What the team is for, in prose, for whoever reads the package.
| Key | |
|---|---|
name | Shown wherever the team is named |
slug | What you type: lucitra teams support. Lower case, no spaces |
lead | The agent id that takes requests. With one agent at the top of the chart you can leave it out; with two, Lucitra will not guess |
schema | lucitra-company/v1. A package written for agentcompanies/v1 is read and converted |
description, goals | What the team is for |
color | Optional. Overrides the color Lucitra assigns the team |
Other keys are kept and ignored.
agents/<id>/AGENTS.md
An agent's id is its directory name, and every other file names it by that id.
---
name: Risk Manager
title: Chief Risk Manager
reportsTo: quant-strategist
skills: []
---
You are the Risk Manager. You validate every signal against the limits in the
trading policy and mark it approved, modified or rejected.
| Key | |
|---|---|
name, title | How the agent is shown |
reportsTo | The id it reports to. null, or leaving it out, makes it a top of the chart |
mayDelegateTo | Ids it may hand work to beyond its own reports |
skills | Skill names it reaches for |
The body is the agent's instructions, after a line naming its title and team, and its mandate
from access.yaml. The org chart is the permission: an agent may delegate to
its reports and to its mayDelegateTo list, and to no one else.
agents/<id>/access.yaml
What one agent may use. Without this file an agent works in its worktree and has no integration tools and no shell.
mandate: |
Validate every signal against the trading policy. Cannot change the policy.
allow:
tools:
- market-data:quote
- alpaca:portfolio-positions
network:
egress:
- finnhub.io
secrets:
- market-data-finnhub-api-key
deny:
tools:
- alpaca:orders-create
| Key | |
|---|---|
mandate | Added to the agent's instructions |
allow.tools | Integration tools, as integration:tool. github:* grants every GitHub tool except merge, approve and release, which are granted only by name |
allow.network.egress | Hosts the agent may reach. Settings → What leaves in the app lists them |
allow.secrets | Secret names, never values. Values come from your machine |
deny.tools | Tools the agent may never call |
An agent gets a shell only when allow.tools names at least one tool, and never one that can push,
merge or approve.
The tool names each integration offers are in Integrations.
policies/*.md
A policy's frontmatter is read; its body is for people.
---
gated:
- push
- alpaca:orders-create@live
autonomous:
- alpaca:orders-list
limits:
alpaca:
max_order_dollars: 500
---
# Trading policy
| Key | |
|---|---|
gated | Waits for you. A named action (push, deploy, publish, go-live), or an integration tool. A tool can name an environment: alpaca:orders-create@live holds only live orders |
autonomous | Runs without asking. Anything not gated already does; listing it records the decision |
limits | Trading limits, enforced on every order. See Integrations |
Every agent on the team is told what is gated and asks first. A gated item with a shell form, such as
deploy, is refused in the shell outright.
projects/<p>/tasks/<t>/TASK.md
Scheduled work. The body is what the agent is asked to do.
---
name: Triage Dependencies
assignee: devops
schedule: "0 9 * * 3"
timezone: America/New_York
---
Review this week's dependency updates and open one pull request for the safe ones.
| Key | |
|---|---|
schedule | A cron line |
timezone | An IANA zone. Without one, the machine's |
assignee | The agent id that runs it |
draft | true keeps it from ever running |
A schedule is off until you turn it on with lucitra schedule <team>/<project>/<task> on. See
Run a team.
teams/<slug>/TEAM.md
A named group inside the team, such as a release crew with its own manager.
---
name: Release
manager: ../../agents/eng-lead/AGENTS.md
includes:
- ../../agents/qa-engineer/AGENTS.md
- ../../agents/release-manager/AGENTS.md
---
manager and includes take an agent id or a path to its AGENTS.md.
DIRECTION.md
Optional. status: paused or status: stopped in its frontmatter stops the team's schedules from
firing. Work you start by hand still runs.