Write a team profile
On this page
A team profile is a plugin named kotharo-<team> that holds one team's own settings and rules on top of the Kotharo core. It is the heaviest way to fit Kotharo to a team, so use the lightest one that does the job:
- Bind a repo's tools with
/kotharo:setup, which writes the repo's### Toolchainsection. - Set a value for one repo, for you, or for all your repos with /kotharo:config.
- Write a team profile, when several repos and several people share the same settings, rules or checks.
Put nothing in a profile that another team could use. That belongs in the core, through a pull request to Kotharo.
Where it lives
A profile lives in the team's own repo, which is also its marketplace. It never ships in Kotharo's marketplace, since everyone who adds a marketplace sees its whole catalog.
Layout
| Path | What it holds |
|---|---|
skills/team-profile/profile.toml | Overrides for the core defaults |
skills/team-profile/SKILL.md | Tells the team to load the profile at intake |
skills/team-profile/learning/ | Lessons for the team's own domain |
rules/00-rules.md | Rules that add to or tighten the core rules |
hooks/hooks.json | A SessionStart hook that loads those rules |
hooks/guardrail-rules.mjs | Commands to refuse or hold for this team |
agents/ and skills/ | Anything only this team needs |
profile.toml
profile.toml overrides the core defaults. It must set schema_version = 1 and the profile's name, and may set only other keys the core defines, with the same types. Arrays replace and tables merge. It covers tool bindings, gate reviewers, risk signals, lane stops, role tiers, limits and the autonomy level. For example:
schema_version = 1
name = "kotharo-<team>"
[slots]
ticketing = ["jira"]
[roles.dev]
tier = "sonnet"
[autonomy]
level = "guided"
A profile can only tighten safety. It can set guided and add to autonomy.ask, but a looser level, a new autonomy.allow or a relaxed safety default such as deploy.dev_auto_deploy = true takes effect only from a lead's own ~/.claude/kotharo.toml or a repo's committed .claude/kotharo.toml.
Check the file with the core's checker. Claude Code sets CLAUDE_PLUGIN_ROOT for the core's skills and hooks; in a terminal, set it to the folder the core is installed in first:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-python" "${CLAUDE_PLUGIN_ROOT}/scripts/settings.py" check-profile <path to profile.toml>SKILL.md
skills/team-profile/SKILL.md tells the team to load profile.toml when it takes a ticket. Copy it from another team's profile, or write a short one that points at profile.toml.
Rules
rules/00-rules.md holds rules that add to or tighten the core rules, such as the team's naming or the column that scopes tenant data. A SessionStart hook in hooks/hooks.json loads them into every session, so keep them short.
Lessons
With teaching mode on, the team teaches from the core's lessons and the profile's own, in skills/team-profile/learning/: one TOML file per topic, in the format of the core's learning/ files. A lesson with a core lesson's id replaces it. Check them with kotharo teach check --profile <path to profile.toml>. Lessons teach the craft, never a customer's code or data, so one holding an email address, a link or a secret is refused.
Guardrails
hooks/guardrail-rules.mjs lists commands to refuse or hold for this team's own stacks, accounts and servers. A plugin can't load another plugin's files, so the profile also carries a copy of the core's hooks/guardrails/ engine and hooks/learning/guardrail-lesson.mjs. The fields are listed in the core's hooks/guardrail-rules.mjs. Turn each kind on in one plugin only, so a command is never held twice. See Guardrails.
Publish and install
Add the team's marketplace once on each machine:
claude plugin marketplace add <owner>/<team-repo>Then install the profile at project scope in each repo that uses it, so it is on for everyone who works there:
claude plugin install kotharo-<team>@<team marketplace> --scope project/kotharo:setup finds the profile once it is enabled, and offers to install it when it finds one that isn't.
So everyone on a repo is offered the marketplace without adding it by hand, declare it in the repo's committed .claude/settings.json. /kotharo:setup offers to do this when it installs the profile:
{
"extraKnownMarketplaces": {
"<team marketplace>": {
"source": { "source": "github", "repo": "<owner>/<team-repo>" }
}
}
}
Turn a profile off in one repo
To turn a profile off in one repo, for example where it was installed in user scope, add this to that repo's .claude/settings.local.json:
{
"enabledPlugins": {
"kotharo-<team>@<team marketplace>": false
}
}