The unified development process for every Tawa repo. If your Claude Code session
loads tawa-docs/.claude/rules/tawa-agile-workflow.md, it will follow this flow
automatically.
git.tawa.pro. No GitHub, no
mcp__github__* tools. Git operations go through mcp__jci-mcp__git_* or the git CLI.https://git.insureco.io/org/repo.git). Never switch to
SSH to fix auth — run tawa login, see Auth failures.main is PR-only. Never commit to main; it advances solely through a merged PR —
one the agent merges itself (see Autonomous Merge below).Every feature, bug fix, or non-trivial task must have a git issue before code is written.
Create issue → branch → implement → PR → self-merge → close via commit message
git_issue_list); create one if missing (git_issue_create).feat: add tagline to branding (#42).fix #N, close #N, or resolve #N.Only truly trivial one-liners are exempt.
git_issue_createplanner agent breaks down the worktdd-guide agent, tests written first (RED → GREEN → refactor, 80%+ coverage)origin/main: claw/<task>-<shortid>code-reviewer agent after writing codefeat: add X (#N))git_pr_creategit fetch origin && git rebase origin/main, then run the
repo's typecheck / lint / tests. This is the gate that replaces human review.git_pr_merge. Automatic; do not wait for a human (see below).git_release_create after a deploy-worthy batchEvery agent runs the full pipeline end-to-end and merges its own PR. The merge is the default terminal step, not a handoff. The human ("vibe coder") does not review or click merge — they tell the agent to test before merging, and a green, rebased PR merges itself. Agents are pulled in only on a major error.
Do NOT wait for the human:
Escalate instead of merging — STOP and surface to the human ONLY when:
"I'm slightly unsure the feature is perfect" is not a major error — that's what the issue, the diff, and the next iteration are for. Outside the list above, proceed to merge.
Permissions & enforcement (already in place):
Bash(*) and the Forgejo PR tools (git_pr_create,
git_pr_merge, git_pr_get, git_pr_list) with no prompt.main (required_approvals=0) enforces PR-only mechanically while
still letting the agent self-merge — that is exactly why approvals are 0.v* or *-v*. See Release Management.tawa CLI (0.27.0+). tawa git create and tawa sample --git
protect main and release tags on the repository they create, with no further step. For a
repository that already exists, run tawa git protect <owner/repo> — a dry run that
prints what would change — then add --apply. tawa git protect --all sweeps every
repository in the org (--org <name>, default insureco); --all --apply prints how many
repositories need changes and asks first (--yes skips the question). --main or --tags
limits it to one kind of rule.Correction (2026-09-29): this section used to name
forgejo-protect-mainas what enforces PR-onlymain. No such command exists in thetawaCLI, so anyone who went looking for it found nothing and may have left a repository unprotected. Usetawa git protect(tawa 0.27.0+) instead. Forgejo 14 has tag protection per repository only, with no org-wide setting, which is why the CLI applies it repository by repository.
Deploy is still a separate, single-owner step. After the merge(s) land on origin/main,
one agent runs tawa deploy --prod once. Autonomous merge changes the merge gate, not the
ship gate. See deploy-pipeline.
Type labels: feature, bug, ux, infra, debt, phase
Status labels → Kanban columns (moving a card = swap the status:* label):
| Label | Column | Color |
|---|---|---|
status:backlog | Backlog | #64748b |
status:in-progress | In Progress | #2563eb |
status:review | In Review | #d97706 |
status:blocked | Blocked | #dc2626 |
| (closed, no label) | Done | automatic |
Forgejo labels are per-repo, and nothing creates them when a repo is made — so until
2026-09-18 most repos had none, and the first labelled issue on any of them failed with
Label "feature" does not exist in <repo>. Labels there: (none). Agents then hand-built a
label set one repo at a time, with drifting colors.
The ten labels above now exist once, on the insureco org, and jci-mcp resolves org
labels alongside a repo's own (jci-mcp#126).
Every insureco repo — including one created five minutes ago — accepts them with zero
labels of its own. There is nothing to bootstrap.
git_label { action: "list", org: "insureco" } # the shared taxonomy
git_label { action: "create", org: "insureco", name, color } # add to it — every repo gets it
git_label { action: "create", repo: "insureco/my-svc", name, color } # one repo only
git_issue_labels_list { repo } # what an issue here can carry; each label marked scope: org | repo
bug with its own color
silently replaces the shared one there.jci-mcp, bio-vault, iec-insurebio) still carry repo-level copies that
predate this. They are harmless. Do not delete them casually — deleting a label strips it
from every issue that carries it.git_pr_merge),
cuts a release, closes issues. No human merge gate.<type>: <description> (#N)
Types: feat, fix, refactor, docs, test, chore, perf, ci. Always link the issue when one
exists. Attribution is disabled globally.
Cut a release after every meaningful, deployed batch. Check existing releases first
(git_release_list), then git_release_create.
| Bump | Meaning |
|---|---|
Patch v1.0.x | Bug fixes, minor tweaks |
Minor v1.x.0 | New features, UI additions |
Major vX.0.0 | Breaking changes, rewrites |
Every repository created with tawa git create or tawa sample --git (tawa 0.27.0+), and
every repository tawa git protect --apply has been run on, carries tag rules for v* and
*-v*. Only the accounts on the rule's allow-list can create, move or delete a matching tag.
Forgejo has no admin bypass: a site or org admin who is not on the list is refused like
anyone else.
| Default allow-list | |
|---|---|
| Org-owned repository | the person who ran the command, plus the org's Owners team, plus its runners team when the org has one |
| Personal repository | the person who ran the command |
iec-admin is on the list only when it was the account that ran the command; it is never
added to a repository where it is only the builder's read collaborator. Each run prints who
is allowed. --allow-user, --allow-team and --pattern (all repeatable), or
release_tags in ~/.tawa/config.yaml, replace the defaults.
Patterns are Forgejo globs matched against the whole tag name, and * matches any
characters. v* matches v1.2.3 and also any other tag that starts with v, such as
vendor-thing; *-v* matches agent-v0.7.0 and any tag containing -v. A tag you did not
mean as a release can therefore be protected too.
git_release_create is refusedThe repository's tag rule does not include the account you are using. Do not work around it (a different account, a tag name chosen to dodge the pattern, deleting the rule). Check the rule instead:
tawa git protect <owner/repo> --tags # dry run: prints the current rule and who it allows
A rule whose allow-list is not the default is reported as DIFFERS and left alone; the line
says when it leaves you out. If you should be on it, ask an owner of the repository to add
you (--allow-user, then --apply --update). Changing someone else's rule to include
yourself is an owner's decision, not a workaround.
tawa git protect refuses to write a rule that would leave the person running it unable to
create matching tags, unless --lock-me-out is passed. If your git username is not known,
it makes no rule at all; run tawa login.
Use the wiki to capture the why — architecture decisions, non-obvious "why X instead
of Y" choices, onboarding context (data model, auth flow, deploy process). Tools:
git_wiki_create / git_wiki_update. Write a wiki page when a new pattern is introduced or
a non-obvious decision is made; update it when behavior changes.
The ecosystem is organized into Villages — high-level system components spanning multiple repos. All 15 Villages reaching v1 constitutes Voyager (Ecosystem Release 1).
v1 milestone (git_milestone_create).{village}-wiki repo (has_issues: false) for roadmap + ADRs.| Layer | Tool |
|---|---|
| Village roadmap & ADRs | Wiki on {village}-wiki repo |
| Village v1 target | v1 milestone per repo |
| Cross-repo board | Forgejo org Project (one per Village) |
| Ecosystem release | git_release_create on the voyager tracking repo |
tawa logintawa login is how a machine gets its Forgejo credential. One call authenticates, mints a
PAT, and stores it for both the tawa CLI (~/.tawa/forgejo-credentials.json) and git
(the OS credential helper). With saved credentials present it runs non-interactively.
tawa login --save
git ls-remote origin HEAD # verify, without touching the credential store
There is nothing to do afterwards. Do not hand-mint a PAT and store it yourself.
Superseded (2026-09-20). This page used to say "do NOT reflexively re-login", and told you to mint a stable
git-cli-*PAT through the Forgejo admin CLI and store it by hand so it would sit outside thetawa-cli-cull. That guidance is stale. Do not follow it. It read as a prohibition rather than a caveat: an agent avoidedtawa login, worked around it, and then minted a redundant token nobody needed.What is actually true, verified against
iec-builder/src/routes/users.tson 2026-09-22:deleteStaleTokens(username, machineId)deletes only this machine's tokens, those namedtawa-cli-<machineId>-*, and deletes nothing at all when the caller sends no machineId. A login on one machine never revokes another machine's token, so a laptop, a server and a cloud-runner session can all stay logged in as the same user at once.tawa loginalso rewrites the git credential in the same call, so this machine ends up holding a working credential. The separate stable PAT solved a problem that never existed.
Scopes — the one real limit. The token tawa login mints carries write:repository,
write:organization and write:user. That covers git and the Forgejo /pulls API. It does
not carry write:issue, so creating an issue with it returns 403, and logging in again
will not change that. Use the git_issue_* MCP tools for issues — they authenticate as the MCP
server rather than as your local token.
⚠️ Never test a token by putting it in a git URL (https://user:$TOK@host/…) — the
credential helper silently overwrites the stored credential with whatever the URL carried.
Uncommitted edits live only in the working tree — a branch switch, rebase, or another
agent's operation can discard them with no recovery. Commit as soon as a change is
coherent, to your claw/<task>-<shortid> branch (never main), staging explicit paths
(git add <paths> — never git add -u/-a, which sweep up other agents' uncommitted edits
on a shared checkout). Small WIP commits are fine — they squash at merge; lost work cannot.
There is no "Stop hook auto-commits
git add -uand pushes tomain" safety net — that older behavior is removed and superseded. Any automated commit must be branch-aware: refuse onmain, stage explicit paths, and go through a self-merged PR.
No work without an issue → plan → tests first → branch → commit referencing
#N→ PR → rebase + verify green → agent self-merges → cut a release per batch. Human is pulled in only on a major error. Issues live with the code; Villages aggregate cross-repo; Wikis hold the "why."
main directly, or using git add -u/-a on a shared checkout.#N reference when an issue exists.feature / status:* labels on a repo because an issue create said they were
missing — they live on the org. See Labels live on the org.forgejo-protect-main — it does not exist. Use tawa git protect (0.27.0+).tawa git protect --all --apply without first reading the dry run.DIFFERS rule as unchanged (tawa-cli#128).
Read the per-repository DIFFERS lines.tawa login when a push 401s — tawa login
is the supported fix and rewrites the git credential itself. See below.mcp__github__* tools — everything is Forgejo at git.tawa.pro.Last updated: October 6, 2026