feat(ops): add @ops Gitea-administrator agent #55

Merged
ffaerber merged 2 commits from feat/ops-agent into main 2026-07-05 13:19:30 +02:00
Owner

Adds an @ops operator agent that administers the Gitea instance from issues (target: the new gitea/ops repo).

  • Role (agents.json): comment-mode (never edits code), model opus, skill gitea-admin, always confirms before destructive ops.
  • gitea-admin skill: create orgs/users/repos, manage labels & Actions secrets, bootstrap a repo with the standard caller, and the least-privilege flow — create user → mint a scoped token as that user → store straight into a secret, never printing it (proven live: user inter + TOKEN_INTER). Emitted ONLY for @ops (gated on NAME) and denied to other agents via permission.skill.
  • agent.yml: skill step, uses AGENT_TOKEN.

Bootstrap trade-off (temporary): while AGENT_TOKEN is admin, every agents process holds an admin credential in env (skill-scoping hides the doc, not the env var). Plan per maintainer: use it to bring @ops up, then have @ops mint scoped per-user tokens and narrow AGENT_TOKEN / inject a dedicated admin token only for @ops.

Already done outside this PR: gitea org, gitea/ops repo + standard scoped labels + caller. Still needed to run: set the runtime secrets on the gitea org.

Adds an **@ops** operator agent that administers the Gitea instance from issues (target: the new `gitea/ops` repo). - **Role** (`agents.json`): comment-mode (never edits code), model opus, skill `gitea-admin`, always confirms before destructive ops. - **`gitea-admin` skill**: create orgs/users/repos, manage labels & Actions secrets, bootstrap a repo with the standard caller, and the least-privilege flow — create user → mint a **scoped** token as that user → store straight into a secret, never printing it (proven live: user `inter` + `TOKEN_INTER`). Emitted ONLY for @ops (gated on NAME) and denied to other agents via `permission.skill`. - **`agent.yml`**: skill step, uses `AGENT_TOKEN`. **Bootstrap trade-off (temporary):** while `AGENT_TOKEN` is admin, every agents process holds an admin credential in env (skill-scoping hides the doc, not the env var). Plan per maintainer: use it to bring `@ops` up, then have `@ops` mint scoped per-user tokens and narrow `AGENT_TOKEN` / inject a dedicated admin token only for `@ops`. Already done outside this PR: `gitea` org, `gitea/ops` repo + standard scoped labels + caller. Still needed to run: set the runtime secrets on the `gitea` org.
ffaerber added 1 commit 2026-07-05 13:03:59 +02:00
A comment-mode operator agent (opus) for administering Gitea itself from issues in gitea/ops:
create orgs/users/repos, manage labels & Actions secrets, and mint least-privilege per-user tokens.

- agents.json: new @ops role (comment-mode, skill gitea-admin, confirms before destructive ops).
- skill-gitea-admin.sh: SKILL.md documenting org/user/repo/label/secret ops + the create-user →
  mint-scoped-token → store-as-secret flow (never printing tokens). Gated on NAME=ops so the admin
  how-to is written ONLY for @ops; permission.skill also denies it to other agents.
- agent.yml: wire the skill step (uses AGENT_TOKEN — an admin PAT during bootstrap).

Bootstrap note: AGENT_TOKEN is admin for now, so every agent's process technically holds an admin
credential (skill-scoping hides the doc, not the env var). Once @ops is minting scoped per-user
tokens, narrow AGENT_TOKEN and inject a dedicated admin token only for @ops.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ffaerber added 1 commit 2026-07-05 13:09:15 +02:00
@ops now treats gitea/secrets/tokens.md as the source-of-truth inventory (readable by @ffaerber and
@ops only) and records every token it mints/rotates there, alongside storing the live value in the
matching Actions secret.
ffaerber merged commit 03c2bef880 into main 2026-07-05 13:19:30 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gitea/agents#55