What
An account can be a bot:
vole admin account create coding-agent --bot --key agent.pub --role contribute
A bot has no browser sign-in (account invite and adding a passkey are refused,
rather than leaving a secret nobody can use in the roster), cannot hold the
instance-admin role, and is marked as a bot in the user directory and on its
profile. The kind is fixed at creation, like the name, and a roster that predates
the column reads every account as a person.
Everything else is exactly what a person gets: the bot obeys the rules of its
role. A contribute bot pushes only refs/heads/contrib/<name>/ and its CI waits
for a maintainer to allow the exact tip; a maintain bot pushes shared branches,
runs CI immediately, receives the secrets its workflows declare, and its approval
counts. That is the decision recorded on #165 — no bot-specific CI, secrets, or
branch rules, because a parallel trust model is one more thing to keep in sync.
Why
The agent loop needs an identity it can be assigned as and be attributable to. An account already is that; what it lacked was the invariants a bot needs (no browser, no instance admin) and the word for it, so “this is an automation” is visible to a reader instead of being a naming convention.
Shape
- Identity (
forge/identity):Kindon the account,person|bot;CreateBot; refusals inInvite,AddCredentialandAcceptInvite; the instance-admin rule at creation and inSetInstanceRole. - Migration:
ALTER TABLE users ADD COLUMN kind …in both open paths, with the defaultperson, plus an assertion in the old-schema upgrade test that an existing account does not become a bot. - CLI:
--botonaccount create; the keyless form is refused with a message naming--key, because an enrollment link is the only way a keyless account gets in and a bot cannot use one. - Web: a
botmarker in the directory and on the profile, and the profile subtitle says “An automation account” rather than “Issues, changes, and reviews from …”. - Docs: a Bot accounts section in Accounts and access, the flag in the CLI reference, and a pointer from the agent example in the workflows guide.
Not in this slice
The per-run credential. A bot acts today with a key, provisioned like a person’s, so a workflow that acts as a bot still holds that key in a repository secret. That is slice 2 of #165: mint at lease, deliver like a secret, enforce at pre-receive, expire with the run. No push rule and no permission changes here.
Checks
go build ./...,go vet ./...,gofmt -l .clean.vole workflow run verifypasses in the pinned image, including the new CLI test (which needs the FTS5 build to initialise an instance).- New tests:
TestBotAccountsHaveNoBrowser(kind, roster, passkey and invite refusal, admin refusal at creation and role change),TestABotIsAnAccount(keyless bot is an ordinary account with no keys),TestRosterUpgradesFromTheOldSchemaextended to prove the migration default, andTestAccountCreateCanMakeABot.
Part of #165.