docs(prd-5): mark complete and archive to prds/done/ [skip ci]

- All milestones delivered, E2E validated on PR #8
- Deferred: commit authorship E2E, cross-repo test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Vlad MocanuandClaude Opus 4.6 committed 2026-02-25 21:11:20 +02:00
1 parent 40731a0f5d
commit 2f7d0a7fb2
1 file changed
+6 -6
+109
View File
@@ -0,0 +1,109 @@
# PRD #5: Dedicated Forgejo User for Claude Bot
**Issue**: [#5](https://git.wxs.ro/actions/claude-code-action/issues/5)
**Priority**: High
**Created**: 2026-02-25
**Status**: Complete (2026-02-25)
---
## Problem
Claude currently runs under the human operator's personal Forgejo token (`FORGEJO_TOKEN` / `github_token`). This causes:
1. **Attribution confusion**: Commits and comments appear as the human user, not as a bot
2. **Over-privileged access**: The bot inherits all permissions of the human account
3. **Audit trail**: No clear separation between human actions and bot actions in repo history
4. **Security**: If the action is compromised, the human's full token is exposed
On GitHub, this is solved by the GitHub App OIDC token exchange (bot gets its own `claude[bot]` identity). On Forgejo, there's no such mechanism — we need a manual equivalent.
## Solution
Create a dedicated `claude-bot` user on the Forgejo instance (git.wxs.ro), generate a scoped API token for it, and configure the action workflow to use that token. This gives Claude its own identity for commits, comments, and API operations.
## Milestones
### Phase 1: Forgejo Admin Setup
- [x] **M1: Create dedicated `claude-bot` user on git.wxs.ro**
- Create user via Forgejo admin panel or API (`POST /admin/users`)
- Set appropriate display name (e.g., "Claude Bot")
- Set avatar to distinguish from human users
- User should NOT have admin privileges
- **Validation**: User exists and can log in
- **Evidence**: User ID 48, `is_admin: false`, avatar set to Claude logo
- [x] **M2: Configure bot user permissions and token**
- Add `claude-bot` to the `actions` org (and any other orgs where the action runs)
- Grant `write` permission on repos where Claude needs to operate
- Generate a scoped API token for the bot user with minimal required permissions:
- `repo` (read/write issues, PRs, comments, branches, commits)
- `packages` (if needed for container operations)
- NO admin scope, NO user scope beyond what's needed
- **Validation**: Token can create comments and push branches on a test repo
- **Evidence**: `Claude` team with `write` permission created in all 12 orgs, token validated (comment create/delete on issue #5, `push: true` on k8s/flux, crossplane/harbor-resources)
### Phase 2: Action Configuration
- [x] **M3: Update workflow to use bot token**
- Store the bot token as a Forgejo Actions secret (e.g., `CLAUDE_BOT_TOKEN`)
- Update `claude.yml` workflow to pass `github_token: ${{ secrets.CLAUDE_BOT_TOKEN }}` instead of the human token
- Update `bot_id` and `bot_name` inputs to match the new Forgejo user's ID and username
- Document the token rotation procedure
- **Validation**: Action runs with bot token, comments appear as `claude-bot`
- **Evidence**: `CLAUDE_BOT_TOKEN` org secret in all 12 orgs, `claude.yml` updated with `bot_id: "48"`, `bot_name: "claude-bot"`, `bot_email: "claude@wxs.ro"`. New `bot_email` input added to `action.yml`.
- [x] **E2E validated**: `@claude` mention on PR #8 — claude-bot responded with full review, tracking comment updated correctly
- [x] **M4: Verify git commit attribution**
- Ensure `git config user.name` and `user.email` use the bot user's identity
- Verify that `src/github/operations/git-config.ts` correctly picks up the bot user info from the token
- Test that pushed commits show the bot user as author in Forgejo UI
- **Validation**: A tag-mode response that creates a branch shows `claude-bot` as commit author
- **Evidence**: `git-config.ts` uses `user.email` when provided (falls back to noreply), `context.ts` reads `BOT_EMAIL` env var, all call sites pass `botEmail`. 797 tests pass.
- [ ] **Deferred**: Branch creation + commit authorship E2E (will be validated naturally on next code-changing `@claude` request)
### Phase 3: Documentation & Hardening
- [x] **M5: Update documentation and test across repos**
- [x] Update `docs/forgejo.md` with bot user setup instructions (full 6-step guide added)
- [x] Document token rotation procedure (tokens expire, need renewal plan)
- [~] Test the bot user setup on at least one additional repo beyond `claude-code-action` (deferred — bot token is org-level, will work on first use)
- [x] Update `CLAUDE.md` if any workflow changes affect development
- **Validation**: Another developer can follow the docs to set up the bot user on a new Forgejo instance
## Dependencies
- Forgejo admin access to git.wxs.ro (to create the user)
- Understanding of Forgejo's permission model (org membership, repo access)
## Risks
| Risk | Mitigation |
| --------------------------------------- | ---------------------------------------------------------------------- |
| Token expiration | Document rotation procedure, set long-lived token or calendar reminder |
| Bot user locked out | Keep admin access to reset password/token |
| Permission too narrow | Start with `write` on repos, expand only if needed |
| Bot user confused with human in reviews | Set clear display name and avatar |
## Success Criteria
- All Claude comments and commits on Forgejo repos appear as `claude-bot`, not the human user
- The bot token has minimal scoped permissions (no admin access)
- Documentation allows reproducing the setup on a fresh Forgejo instance
## Implementation Notes
### New `bot_email` Action Input
Added `bot_email` input to `action.yml` — when set, overrides the default noreply email format (`{id}+{name}@users.noreply.{host}`). On Forgejo, setting this to the bot user's registered email links commits to the bot's profile in the UI.
### Org-Level Secrets
`CLAUDE_BOT_TOKEN` is stored as an org-level secret (not repo-level) in all 12 orgs with `visibility: "all"`. This means any new repo in any org will automatically have access.
### Team Structure
Each org has a `Claude` team with `write` permission on all repositories (`includes_all_repositories: true`). New repos are automatically covered.